1use manta_backend_dispatcher::error::Error;
5use chrono::NaiveDateTime;
6use manta_backend_dispatcher::interfaces::cfs::CfsTrait;
7use manta_backend_dispatcher::interfaces::delete_configurations_and_data_related::DeleteConfigurationsAndDataRelatedTrait;
8use manta_backend_dispatcher::types::cfs::cfs_configuration_response::CfsConfigurationResponse;
9use manta_backend_dispatcher::types::cfs::session::CfsSessionGetResponse;
10
11use crate::server::common::app_context::InfraContext;
12use crate::server::common::authorization::get_groups_names_available;
13pub use manta_shared::shared::params::configuration::GetConfigurationParams;
14
15pub async fn get_configurations(
17 infra: &InfraContext<'_>,
18 token: &str,
19 params: &GetConfigurationParams,
20) -> Result<Vec<CfsConfigurationResponse>, Error> {
21 let target_hsm_group_vec = get_groups_names_available(
22 infra.backend,
23 token,
24 params.hsm_group.as_deref(),
25 params.settings_hsm_group_name.as_deref(),
26 )
27 .await?;
28
29 let limit_ref = params.limit.as_ref();
30
31 let cfs_configuration_vec = infra
32 .backend
33 .get_and_filter_configuration(
34 token,
35 infra.shasta_base_url,
36 infra.shasta_root_cert,
37 params.name.as_deref(),
38 params.pattern.as_deref(),
39 &target_hsm_group_vec,
40 params.since,
41 params.until,
42 limit_ref,
43 )
44 .await?;
45
46 Ok(cfs_configuration_vec)
47}
48
49#[derive(serde::Serialize)]
51pub struct DeletionCandidates {
52 pub cfs_sessions_to_delete: Vec<CfsSessionGetResponse>,
54 pub bos_sessiontemplate_tuples: Vec<(String, String, String)>,
56 pub image_ids: Vec<String>,
58 pub configuration_names: Vec<String>,
60 pub cfs_session_tuples: Vec<(String, String, String)>,
62 pub configurations: Vec<CfsConfigurationResponse>,
64}
65
66pub async fn get_deletion_candidates(
68 infra: &InfraContext<'_>,
69 token: &str,
70 settings_hsm_group_name_opt: Option<&str>,
71 configuration_name_pattern: Option<&str>,
72 since: Option<NaiveDateTime>,
73 until: Option<NaiveDateTime>,
74) -> Result<DeletionCandidates, Error> {
75 validate_date_range(since, until)?;
76
77 let target_hsm_group_vec =
78 if let Some(settings_hsm_group_name) = settings_hsm_group_name_opt {
79 vec![settings_hsm_group_name.to_string()]
80 } else {
81 get_groups_names_available(
82 infra.backend,
83 token,
84 None,
85 settings_hsm_group_name_opt,
86 )
87 .await?
88 };
89
90 let (
91 cfs_sessions_to_delete,
92 bos_sessiontemplate_tuples,
93 image_ids,
94 configuration_names,
95 cfs_session_tuples,
96 configurations,
97 ) = infra
98 .backend
99 .get_data_to_delete(
100 token,
101 infra.shasta_base_url,
102 infra.shasta_root_cert,
103 &target_hsm_group_vec,
104 configuration_name_pattern,
105 since,
106 until,
107 )
108 .await?;
109
110 Ok(DeletionCandidates {
111 cfs_sessions_to_delete,
112 bos_sessiontemplate_tuples,
113 image_ids,
114 configuration_names,
115 cfs_session_tuples,
116 configurations,
117 })
118}
119
120pub fn validate_date_range(
125 since: Option<NaiveDateTime>,
126 until: Option<NaiveDateTime>,
127) -> Result<(), Error> {
128 if let (Some(s), Some(u)) = (since, until)
129 && s > u
130 {
131 return Err(Error::BadRequest(
132 "'since' date can't be after 'until' date".to_string(),
133 ));
134 }
135 Ok(())
136}
137
138pub async fn delete_configurations_and_derivatives(
140 infra: &InfraContext<'_>,
141 token: &str,
142 candidates: &DeletionCandidates,
143) -> Result<(), Error> {
144 let cfs_session_name_vec: Vec<String> = candidates
145 .cfs_session_tuples
146 .iter()
147 .map(|(session, _, _)| session.clone())
148 .collect();
149
150 let bos_sessiontemplate_name_vec: Vec<String> = candidates
151 .bos_sessiontemplate_tuples
152 .iter()
153 .map(|(sessiontemplate, _, _)| sessiontemplate.clone())
154 .collect();
155
156 infra
157 .backend
158 .delete(
159 token,
160 infra.shasta_base_url,
161 infra.shasta_root_cert,
162 &candidates.configuration_names,
163 &candidates.image_ids,
164 &cfs_session_name_vec,
165 &bos_sessiontemplate_name_vec,
166 )
167 .await?;
168
169 Ok(())
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175 use chrono::NaiveDateTime;
176
177 fn dt(s: &str) -> NaiveDateTime {
178 NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S").unwrap()
179 }
180
181 #[test]
182 fn validate_date_range_ok_when_since_before_until() {
183 assert!(
184 validate_date_range(
185 Some(dt("2024-01-01T00:00:00")),
186 Some(dt("2024-01-02T00:00:00"))
187 )
188 .is_ok()
189 );
190 }
191
192 #[test]
193 fn validate_date_range_ok_when_equal() {
194 let d = dt("2024-01-01T00:00:00");
195 assert!(validate_date_range(Some(d), Some(d)).is_ok());
196 }
197
198 #[test]
199 fn validate_date_range_ok_when_either_none() {
200 let d = dt("2024-01-01T00:00:00");
201 assert!(validate_date_range(Some(d), None).is_ok());
202 assert!(validate_date_range(None, Some(d)).is_ok());
203 assert!(validate_date_range(None, None).is_ok());
204 }
205
206 #[test]
207 fn validate_date_range_err_when_since_after_until() {
208 let result = validate_date_range(
209 Some(dt("2024-01-02T00:00:00")),
210 Some(dt("2024-01-01T00:00:00")),
211 );
212 assert!(result.is_err());
213 assert!(
214 result
215 .unwrap_err()
216 .to_string()
217 .contains("'since' date can't be after 'until' date")
218 );
219 }
220}