manta_server/server/handlers/
configuration.rs1use axum::{Json, extract::Query, http::StatusCode, response::IntoResponse};
13
14use super::{
15 ErrorResponse, RequestCtx, SiteHeader, parse_iso_datetime, serialize_or_500,
16 to_handler_error,
17};
18use crate::service;
19use manta_shared::types::api::configuration_analysis::ConfigurationAnalysis;
20
21pub use manta_shared::types::api::queries::{
26 ConfigurationQuery, DeleteConfigurationsQuery,
27};
28
29#[utoipa::path(get, path = "/configurations", tag = "configurations",
35 params(ConfigurationQuery, SiteHeader),
36 security(("bearerAuth" = [])),
37 responses(
38 (status = 200, description = "Configurations with components-only safe_to_delete verdict",
39 body = Vec<ConfigurationAnalysis>),
40 (status = 401, description = "Unauthorized", body = ErrorResponse),
41 (status = 500, description = "Internal error", body = ErrorResponse),
42 )
43)]
44#[tracing::instrument(skip_all)]
45pub async fn get_configurations(
46 ctx: RequestCtx,
47 Query(q): Query<ConfigurationQuery>,
48) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
49 let infra = ctx.infra();
50
51 let params = service::configuration::GetConfigurationParams {
52 name: q.name,
53 pattern: q.pattern,
54 group_name: q.hsm_group,
55 settings_hsm_group_name: None,
56 since: None,
57 until: None,
58 limit: q.limit,
59 };
60
61 let rows = service::configuration::get_configurations_with_analysis(
62 &infra, &ctx.token, ¶ms,
63 )
64 .await
65 .map_err(to_handler_error)?;
66
67 Ok(Json(rows))
68}
69
70#[utoipa::path(delete, path = "/configurations", tag = "configurations",
76 params(DeleteConfigurationsQuery, SiteHeader),
77 security(("bearerAuth" = [])),
78 responses(
79 (status = 200, description = "Configurations deleted or preview", body = serde_json::Value),
81 (status = 400, description = "Bad request", body = ErrorResponse),
82 (status = 401, description = "Unauthorized", body = ErrorResponse),
83 (status = 500, description = "Internal error", body = ErrorResponse),
84 )
85)]
86#[tracing::instrument(skip_all)]
87pub async fn delete_configurations(
88 ctx: RequestCtx,
89 Query(q): Query<DeleteConfigurationsQuery>,
90) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
91 tracing::info!("delete_configurations dry_run={}", q.dry_run);
92 let infra = ctx.infra();
93
94 let since = q
95 .since
96 .as_deref()
97 .map(|s| parse_iso_datetime("since", s))
98 .transpose()?;
99 let until = q
100 .until
101 .as_deref()
102 .map(|s| parse_iso_datetime("until", s))
103 .transpose()?;
104
105 let candidates = service::configuration::get_deletion_candidates(
106 &infra,
107 &ctx.token,
108 None,
109 q.pattern.as_deref(),
110 since,
111 until,
112 )
113 .await
114 .map_err(to_handler_error)?;
115
116 if q.dry_run {
117 return Ok((StatusCode::OK, Json(serialize_or_500(&candidates)?)));
118 }
119
120 service::configuration::delete_configurations_and_derivatives(
121 &infra,
122 &ctx.token,
123 &candidates,
124 )
125 .await
126 .map_err(to_handler_error)?;
127
128 Ok((
129 StatusCode::OK,
130 Json(serde_json::json!({
131 "deleted_configurations": candidates.configuration_names,
132 "deleted_images": candidates.image_ids,
133 })),
134 ))
135}
136
137