use anyhow::{Context, Error, bail};
use chrono::NaiveDateTime;
use manta_backend_dispatcher::interfaces::cfs::CfsTrait;
use manta_backend_dispatcher::interfaces::delete_configurations_and_data_related::DeleteConfigurationsAndDataRelatedTrait;
use manta_backend_dispatcher::types::cfs::cfs_configuration_details::{
ConfigurationDetails, LayerDetails,
};
use manta_backend_dispatcher::types::cfs::cfs_configuration_response::CfsConfigurationResponse;
use manta_backend_dispatcher::types::cfs::session::CfsSessionGetResponse;
use manta_backend_dispatcher::types::bos::session_template::BosSessionTemplate;
use manta_backend_dispatcher::types::ims::Image;
use crate::common::app_context::InfraContext;
use crate::common::authorization::get_groups_names_available;
pub struct GetConfigurationParams {
pub name: Option<String>,
pub pattern: Option<String>,
pub hsm_group: Option<String>,
pub settings_hsm_group_name: Option<String>,
pub since: Option<NaiveDateTime>,
pub until: Option<NaiveDateTime>,
pub limit: Option<u8>,
}
pub async fn get_configurations(
infra: &InfraContext<'_>,
token: &str,
params: &GetConfigurationParams,
) -> Result<Vec<CfsConfigurationResponse>, Error> {
let target_hsm_group_vec = get_groups_names_available(
infra.backend,
token,
params.hsm_group.as_deref(),
params.settings_hsm_group_name.as_deref(),
)
.await?;
let limit_ref = params.limit.as_ref();
let cfs_configuration_vec = infra.backend
.get_and_filter_configuration(
token,
infra.shasta_base_url,
infra.shasta_root_cert,
params.name.as_deref(),
params.pattern.as_deref(),
&target_hsm_group_vec,
params.since,
params.until,
limit_ref,
)
.await?;
Ok(cfs_configuration_vec)
}
pub async fn get_configuration_details(
infra: &InfraContext<'_>,
token: &str,
config: &CfsConfigurationResponse,
) -> Result<
(
ConfigurationDetails,
Option<Vec<CfsSessionGetResponse>>,
Option<Vec<BosSessionTemplate>>,
Option<Vec<Image>>,
),
Error,
> {
let vault_base_url = infra
.vault_base_url
.context("vault_base_url is required for configuration details")?;
let gitea_token =
crate::common::vault::http_client::fetch_shasta_vcs_token(
token,
vault_base_url,
infra.site_name,
)
.await
.context("Failed to fetch VCS token from vault")?;
let mut layer_details_vec: Vec<LayerDetails> = vec![];
for layer in &config.layers {
let layer_details = infra.backend
.get_configuration_layer_details(
infra.shasta_root_cert,
infra.gitea_base_url,
&gitea_token,
layer.clone(),
infra.site_name,
)
.await
.context("Could not fetch configuration layer details")?;
layer_details_vec.push(layer_details);
}
let (cfs_session_vec_opt, bos_sessiontemplate_vec_opt, image_vec_opt) =
infra.backend
.get_derivatives(token, infra.shasta_base_url, infra.shasta_root_cert, &config.name)
.await
.context("Could not fetch configuration derivatives")?;
let details = ConfigurationDetails::new(
&config.name,
&config.last_updated,
layer_details_vec,
);
Ok((
details,
cfs_session_vec_opt,
bos_sessiontemplate_vec_opt,
image_vec_opt,
))
}
pub struct DeletionCandidates {
pub cfs_sessions_to_delete: Vec<CfsSessionGetResponse>,
pub bos_sessiontemplate_tuples: Vec<(String, String, String)>,
pub image_ids: Vec<String>,
pub configuration_names: Vec<String>,
pub cfs_session_tuples: Vec<(String, String, String)>,
pub configurations: Vec<CfsConfigurationResponse>,
}
pub async fn get_deletion_candidates(
infra: &InfraContext<'_>,
token: &str,
settings_hsm_group_name_opt: Option<&str>,
configuration_name_pattern: Option<&str>,
since: Option<NaiveDateTime>,
until: Option<NaiveDateTime>,
) -> Result<DeletionCandidates, Error> {
if let (Some(s), Some(u)) = (since, until) {
if s > u {
bail!("'since' date can't be after 'until' date");
}
}
let target_hsm_group_vec =
if let Some(settings_hsm_group_name) = settings_hsm_group_name_opt {
vec![settings_hsm_group_name.to_string()]
} else {
get_groups_names_available(
infra.backend,
token,
None,
settings_hsm_group_name_opt,
)
.await?
};
let (
cfs_sessions_to_delete,
bos_sessiontemplate_tuples,
image_ids,
configuration_names,
cfs_session_tuples,
configurations,
) = infra
.backend
.get_data_to_delete(
token,
infra.shasta_base_url,
infra.shasta_root_cert,
&target_hsm_group_vec,
configuration_name_pattern,
since,
until,
)
.await?;
Ok(DeletionCandidates {
cfs_sessions_to_delete,
bos_sessiontemplate_tuples,
image_ids,
configuration_names,
cfs_session_tuples,
configurations,
})
}
pub async fn delete_configurations_and_derivatives(
infra: &InfraContext<'_>,
token: &str,
candidates: &DeletionCandidates,
) -> Result<(), Error> {
let cfs_session_name_vec: Vec<String> = candidates
.cfs_session_tuples
.iter()
.map(|(session, _, _)| session.clone())
.collect();
let bos_sessiontemplate_name_vec: Vec<String> = candidates
.bos_sessiontemplate_tuples
.iter()
.map(|(sessiontemplate, _, _)| sessiontemplate.clone())
.collect();
infra
.backend
.delete(
token,
infra.shasta_base_url,
infra.shasta_root_cert,
&candidates.configuration_names,
&candidates.image_ids,
&cfs_session_name_vec,
&bos_sessiontemplate_name_vec,
)
.await?;
Ok(())
}