dsh_api/
certificate.rs

1//! # Additional methods to manage certificates
2//!
3//! Module that contains methods to manage certificates.
4//! * Derived methods - DshApiClient methods that add extra capabilities
5//!   but depend on the API methods.
6//!
7//! # Derived methods
8//!
9//! [`DshApiClient`] methods that add extra capabilities but do not directly call the
10//! DSH resource management API. These derived methods depend on the API methods for this.
11//!
12//! * [`get_certificate_with_usage(certificate_id) -> (certificate_status, [used_by])`](DshApiClient::get_certificate_with_usage)
13//! * [`list_certificates_with_usage() -> (certificate_id, certificate_status, [used_by])`](DshApiClient::list_certificates_with_usage)
14
15use crate::dsh_api_client::DshApiClient;
16use crate::types::{AppCatalogApp, Application, CertificateStatus};
17#[allow(unused_imports)]
18use crate::DshApiError;
19use crate::{app, application, DshApiResult, UsedBy};
20use futures::future::try_join_all;
21use futures::try_join;
22use std::collections::HashMap;
23
24/// # Additional methods to manage certificates
25///
26/// Module that contains methods to manage certificates.
27/// * Derived methods - DshApiClient methods that add extra capabilities
28///   but depend on the API methods.
29///
30/// # Derived methods
31///
32/// [`DshApiClient`] methods that add extra capabilities but do not directly call the
33/// DSH resource management API. These derived methods depend on the API methods for this.
34///
35/// * [`get_certificate_with_usage(certificate_id) -> (certificate_status, [used_by])`](DshApiClient::get_certificate_with_usage)
36/// * [`list_certificates_with_usage() -> (certificate_id, certificate_status, [used_by])`](DshApiClient::list_certificates_with_usage)
37impl DshApiClient {
38  /// # List all certificates with usage
39  ///
40  /// Returns a list of all certificate configurations,
41  /// together with the apps and applications that use this certificate.
42  ///
43  /// # Returns
44  /// * `Ok<Vec<(String, CertificateStatus, Vec<UsedBy>>>` - list of tuples
45  ///   containing the certificate id, certificate configuration and a vector of usages,
46  ///   which can be empty.
47  /// * `Err<`[`DshApiError`]`>` - when the request could not be processed by the DSH
48  pub async fn list_certificates_with_usage(&self) -> DshApiResult<Vec<(String, CertificateStatus, Vec<UsedBy>)>> {
49    let certificate_ids = self.get_certificate_ids().await?;
50    let certificates = try_join_all(certificate_ids.iter().map(|certificate_id| self.get_certificate(certificate_id.as_str()))).await?;
51    let (applications, apps) = try_join!(self.get_application_configuration_map(), self.get_appcatalogapp_configuration_map())?;
52    let mut certificates_with_usage: Vec<(String, CertificateStatus, Vec<UsedBy>)> = vec![];
53    for (certificate_id, certificate_status) in certificate_ids.iter().zip(certificates) {
54      let mut usages: Vec<UsedBy> = vec![];
55      if let Some(ref configuration) = certificate_status.configuration {
56        let secrets = match configuration.passphrase_secret {
57          Some(ref passphrase_secret) => vec![configuration.cert_chain_secret.clone(), configuration.key_secret.clone(), passphrase_secret.clone()],
58          None => vec![configuration.cert_chain_secret.clone(), configuration.key_secret.clone()],
59        };
60        for (application_id, application, secret_injections) in application::find_applications_that_use_secrets(&secrets, &applications) {
61          for (_, injections) in secret_injections {
62            usages.push(UsedBy::Application(application_id.clone(), application.instances, injections));
63          }
64        }
65        for (app_id, _, secret_resources) in app::find_apps_that_use_secrets(&secrets, &apps) {
66          usages.push(UsedBy::App(app_id.clone(), secret_resources));
67        }
68      }
69      certificates_with_usage.push((certificate_id.clone(), certificate_status, usages));
70    }
71    Ok(certificates_with_usage)
72  }
73
74  /// # Return certificate with usage
75  ///
76  /// Returns the certificate configuration for the provided certificate id,
77  /// together with the apps and applications that use this certificate.
78  ///
79  /// # Parameters
80  /// * `certificate_id` - id of the requested certificate
81  ///
82  /// # Returns
83  /// * `Ok<(CertificateStatus, Vec<UsedBy>>` - tuple containing the certificate configuration
84  ///   and a vector of usages, which can be empty.
85  /// * `Err<`[`DshApiError`]`>` - when the request could not be processed by the DSH
86  pub async fn get_certificate_with_usage(&self, certificate_id: &str) -> DshApiResult<(CertificateStatus, Vec<UsedBy>)> {
87    let (certificate_status, applications, apps): (CertificateStatus, HashMap<String, Application>, HashMap<String, AppCatalogApp>) = try_join!(
88      self.get_certificate(certificate_id),
89      self.get_application_configuration_map(),
90      self.get_appcatalogapp_configuration_map()
91    )?;
92    let mut used_by: Vec<UsedBy> = vec![];
93    if let Some(ref configuration) = certificate_status.configuration {
94      let secrets = match configuration.passphrase_secret {
95        Some(ref passphrase_secret) => vec![configuration.cert_chain_secret.clone(), configuration.key_secret.clone(), passphrase_secret.clone()],
96        None => vec![configuration.cert_chain_secret.clone(), configuration.key_secret.clone()],
97      };
98      for (application_id, application, secret_injections) in application::find_applications_that_use_secrets(&secrets, &applications) {
99        for (_, injections) in secret_injections {
100          used_by.push(UsedBy::Application(application_id.clone(), application.instances, injections));
101        }
102      }
103      for (app_id, _, secret_resources) in app::find_apps_that_use_secrets(&secrets, &apps) {
104        used_by.push(UsedBy::App(app_id.clone(), secret_resources));
105      }
106    }
107    Ok((certificate_status, used_by))
108  }
109}