manta_server/server/handlers/
configuration.rs1use axum::{Json, extract::Query, http::StatusCode, response::IntoResponse};
4use serde::Deserialize;
5use utoipa::IntoParams;
6
7use super::{
8 ErrorResponse, RequestCtx, SiteHeader, parse_iso_datetime, serialize_or_500,
9 to_handler_error,
10};
11use crate::service;
12
13#[derive(Deserialize, IntoParams)]
19pub struct ConfigurationQuery {
20 pub name: Option<String>,
22 pub pattern: Option<String>,
24 pub hsm_group: Option<String>,
26 pub limit: Option<u8>,
28}
29
30#[utoipa::path(get, path = "/configurations", tag = "configurations",
32 params(ConfigurationQuery, SiteHeader),
33 security(("bearerAuth" = [])),
34 responses(
35 (status = 200, description = "List of configurations", body = serde_json::Value),
36 (status = 401, description = "Unauthorized", body = ErrorResponse),
37 (status = 500, description = "Internal error", body = ErrorResponse),
38 )
39)]
40#[tracing::instrument(skip_all)]
41pub async fn get_configurations(
42 ctx: RequestCtx,
43 Query(q): Query<ConfigurationQuery>,
44) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
45 let infra = ctx.infra();
46
47 let params = service::configuration::GetConfigurationParams {
48 name: q.name,
49 pattern: q.pattern,
50 hsm_group: q.hsm_group,
51 settings_hsm_group_name: None,
52 since: None,
53 until: None,
54 limit: q.limit,
55 };
56
57 let configs =
58 service::configuration::get_configurations(&infra, &ctx.token, ¶ms)
59 .await
60 .map_err(to_handler_error)?;
61
62 Ok(Json(configs))
63}
64
65#[derive(Deserialize, IntoParams)]
71pub struct DeleteConfigurationsQuery {
72 pub pattern: Option<String>,
74 pub since: Option<String>,
76 pub until: Option<String>,
78 #[serde(default)]
80 pub dry_run: bool,
81}
82
83#[utoipa::path(delete, path = "/configurations", tag = "configurations",
85 params(DeleteConfigurationsQuery, SiteHeader),
86 security(("bearerAuth" = [])),
87 responses(
88 (status = 200, description = "Configurations deleted or preview", body = serde_json::Value),
89 (status = 400, description = "Bad request", body = ErrorResponse),
90 (status = 401, description = "Unauthorized", body = ErrorResponse),
91 (status = 500, description = "Internal error", body = ErrorResponse),
92 )
93)]
94#[tracing::instrument(skip_all)]
95pub async fn delete_configurations(
96 ctx: RequestCtx,
97 Query(q): Query<DeleteConfigurationsQuery>,
98) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
99 tracing::info!("delete_configurations dry_run={}", q.dry_run);
100 let infra = ctx.infra();
101
102 let since = q
103 .since
104 .as_deref()
105 .map(|s| parse_iso_datetime("since", s))
106 .transpose()?;
107 let until = q
108 .until
109 .as_deref()
110 .map(|s| parse_iso_datetime("until", s))
111 .transpose()?;
112
113 let candidates = service::configuration::get_deletion_candidates(
114 &infra,
115 &ctx.token,
116 None,
117 q.pattern.as_deref(),
118 since,
119 until,
120 )
121 .await
122 .map_err(to_handler_error)?;
123
124 if q.dry_run {
125 return Ok((StatusCode::OK, Json(serialize_or_500(&candidates)?)));
126 }
127
128 service::configuration::delete_configurations_and_derivatives(
129 &infra,
130 &ctx.token,
131 &candidates,
132 )
133 .await
134 .map_err(to_handler_error)?;
135
136 Ok((
137 StatusCode::OK,
138 Json(serde_json::json!({
139 "deleted_configurations": candidates.configuration_names,
140 "deleted_images": candidates.image_ids,
141 })),
142 ))
143}
144
145