manta_server/server/handlers/
template.rs1use axum::{
10 Json,
11 extract::{Path, Query},
12 http::StatusCode,
13 response::IntoResponse,
14};
15
16use super::{
17 ErrorResponse, RequestCtx, SiteHeader, serialize_or_500, to_handler_error,
18};
19use crate::server::audit::AuditNote;
20use crate::service;
21
22pub use manta_shared::types::api::queries::TemplateQuery;
27
28#[utoipa::path(get, path = "/templates", tag = "templates",
30 params(TemplateQuery, SiteHeader),
31 security(("bearerAuth" = [])),
32 responses(
33 (status = 200, description = "List of session templates", 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_templates(
42 ctx: RequestCtx,
43 Query(q): Query<TemplateQuery>,
44) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
45 let infra = ctx.infra();
46
47 let params = service::template::GetTemplateParams {
48 name: q.name,
49 group_name: q.hsm_group,
50 settings_group_name: None,
51 limit: q.limit,
52 };
53
54 let templates = service::template::get_templates(&infra, &ctx.token, ¶ms)
55 .await
56 .map_err(to_handler_error)?;
57
58 Ok(Json(templates))
59}
60
61pub use manta_shared::types::api::template::{
66 BosOperation, PostTemplateSessionRequest,
67};
68
69#[utoipa::path(post, path = "/templates/{name}/sessions", tag = "templates",
71 params(("name" = String, Path, description = "Template name"), SiteHeader),
72 request_body = PostTemplateSessionRequest,
73 security(("bearerAuth" = [])),
74 responses(
75 (status = 200, description = "Dry run preview", body = serde_json::Value),
77 (status = 201, description = "Session created", body = serde_json::Value),
80 (status = 400, description = "Bad request", body = ErrorResponse),
81 (status = 401, description = "Unauthorized", body = ErrorResponse),
82 (status = 500, description = "Internal error", body = ErrorResponse),
83 )
84)]
85#[tracing::instrument(skip_all)]
86pub async fn post_template_session(
87 ctx: RequestCtx,
88 note: AuditNote,
89 Path(name): Path<String>,
90 Json(body): Json<PostTemplateSessionRequest>,
91) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
92 note
93 .action("template.session.create")
94 .target("template", &name)
95 .target("hosts", &body.limit)
96 .targets("session", body.session_name.as_deref())
97 .detail("operation", body.operation)
98 .detail("include_disabled", body.include_disabled)
99 .dry_run(body.dry_run);
100
101 tracing::info!(
102 "post_template_session template={} op={:?} dry_run={}",
103 name,
104 body.operation,
105 body.dry_run
106 );
107 let infra = ctx.infra();
108
109 let params = service::template::ApplyTemplateParams {
110 bos_session_name: body.session_name,
111 bos_sessiontemplate_name: name,
112 bos_session_operation: body.operation.as_str().to_string(),
113 limit: body.limit,
114 include_disabled: body.include_disabled,
115 };
116
117 let (bos_session, _) =
118 service::template::validate_and_prepare_template_session(
119 &infra, &ctx.token, ¶ms,
120 )
121 .await
122 .map_err(to_handler_error)?;
123
124 if body.dry_run {
125 return Ok((StatusCode::OK, Json(serialize_or_500(&bos_session)?)));
126 }
127
128 let created =
129 service::template::create_bos_session(&infra, &ctx.token, bos_session)
130 .await
131 .map_err(to_handler_error)?;
132 if let Some(session) = &created.name {
133 note.produced("session", session);
134 }
135
136 Ok((StatusCode::CREATED, Json(serialize_or_500(&created)?)))
137}