use crate::application::application_resources_from_app;
use crate::bucket::bucket_resources_from_app;
use crate::certificate::certificate_resources_from_app;
use crate::dsh_api_client::DshApiClient;
use crate::error::DshApiResult;
use crate::secret::secret_resources_from_app;
use crate::topic::topic_resources_from_app;
use crate::types::{AppCatalogApp, AppCatalogAppResourcesValue};
use crate::vhost::vhost_resources_from_app;
use crate::volume::volume_resources_from_app;
use crate::DependantApp;
#[allow(unused_imports)]
use crate::DshApiError;
use itertools::Itertools;
use serde_json::from_str;
use std::collections::HashMap;
impl DshApiClient {
pub async fn app_configuration(&self, app_id: &str) -> DshApiResult<(AppCatalogApp, Option<HashMap<String, String>>)> {
match self.get_appcatalogapp_configuration(app_id).await {
Ok(app_catalog_app) => {
let configuration = app_catalog_app
.configuration
.clone()
.map(|configuration| from_str::<HashMap<String, String>>(configuration.as_str()))
.transpose()?;
Ok((app_catalog_app.clone(), configuration.to_owned()))
}
Err(e) => Err(e),
}
}
pub async fn app_configurations(&self) -> DshApiResult<Vec<(String, AppCatalogApp, Option<HashMap<String, String>>)>> {
let appcatalogapp_configuration_map = self.get_appcatalogapp_configuration_map().await?;
match appcatalogapp_configuration_map
.into_iter()
.map(|(app_id, app_catalog_app)| {
app_catalog_app
.configuration
.clone()
.map(|configuration| from_str::<HashMap<String, String>>(configuration.as_str()))
.transpose()
.map(|c| (app_id, app_catalog_app.clone(), c.to_owned()))
})
.collect::<Result<Vec<_>, _>>()
{
Ok(mut app_configurations) => {
app_configurations.sort_by(|(app_id_a, _, _), (app_id_b, _, _)| app_id_a.cmp(app_id_b));
Ok(app_configurations)
}
Err(error) => Err(DshApiError::Unexpected { message: "error parsing app configuration".to_string(), cause: Some(error.to_string()) }),
}
}
pub async fn app_ids(&self) -> DshApiResult<Vec<String>> {
let mut app_ids: Vec<String> = self.get_appcatalogapp_configuration_map().await?.keys().map(|app_id| app_id.to_string()).collect();
app_ids.sort();
Ok(app_ids)
}
pub async fn apps_dependant_on_application(&self, application_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_application(application_id, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_bucket(&self, bucket_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_resource(bucket_id, &self.get_appcatalogapp_configuration_map().await?, &bucket_resources_from_app)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_certificate(&self, certificate_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_certificate(certificate_id, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_secret(&self, secret_name: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_secret(secret_name, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_topic(&self, topic_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_topic(topic_id, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_vhost(&self, vhost_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_vhost(vhost_id, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
pub async fn apps_dependant_on_volume(&self, volume_id: &str) -> DshApiResult<Vec<DependantApp>> {
Ok(
apps_that_use_volume(volume_id, &self.get_appcatalogapp_configuration_map().await?)
.into_iter()
.map(|(app_id, _, resource_ids)| DependantApp::new(app_id.to_string(), resource_ids.iter().map(|resource_id| resource_id.to_string()).collect_vec()))
.collect_vec(),
)
}
}
pub fn apps_that_use_application<'a>(application_id: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(application_id, apps, &application_resources_from_app)
}
pub fn apps_that_use_certificate<'a>(certificate_id: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(certificate_id, apps, &certificate_resources_from_app)
}
pub fn apps_that_use_secret<'a>(secret_name: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(secret_name, apps, &secret_resources_from_app)
}
pub fn apps_that_use_topic<'a>(topic_id: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(topic_id, apps, &topic_resources_from_app)
}
pub fn apps_that_use_vhost<'a>(vhost_id: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(vhost_id, apps, &vhost_resources_from_app)
}
pub fn apps_that_use_volume<'a>(volume_id: &str, apps: &'a HashMap<String, AppCatalogApp>) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
apps_that_use_resource(volume_id, apps, &volume_resources_from_app)
}
pub(crate) fn app_resources<'a, T>(app: &'a AppCatalogApp, get_resource_variant: &dyn Fn(&'a AppCatalogAppResourcesValue) -> Option<&'a T>) -> Vec<(&'a str, &'a T)> {
let mut resources: Vec<(&str, &T)> = vec![];
for (resource_id, resource) in &app.resources {
if let Some(resource) = get_resource_variant(resource) {
resources.push((resource_id, resource))
}
}
resources.sort_by(|(resource_id_a, _), (resource_id_b, _)| resource_id_a.cmp(resource_id_b));
resources
}
pub(crate) fn apps_that_use_resource<'a, T: 'a>(
resource_id: &str,
apps: &'a HashMap<String, AppCatalogApp>,
get_resources_variants_from_app: &dyn Fn(&AppCatalogApp) -> Vec<(&str, &T)>,
) -> Vec<(&'a str, &'a AppCatalogApp, Vec<&'a str>)> {
let mut tuples: Vec<(&str, &'a AppCatalogApp, Vec<&str>)> = vec![];
for (app_id, app) in apps {
for (resource_id_from_app, _resource) in get_resources_variants_from_app(app) {
if resource_id_from_app == resource_id {
tuples.push((app_id, app, vec![resource_id_from_app]));
}
}
}
tuples.sort_by(|(app_id_a, _, _), (app_id_b, _, _)| app_id_a.cmp(app_id_b));
tuples
}