Skip to main content

manta_server/server/handlers/
ephemeral_env.rs

1//! Ephemeral environment handler.
2//!
3//! `POST /v2/ephemeral-env` → [`create_ephemeral_env`] — wraps
4//! `service::ephemeral_env::exec`. Launches a short-lived CFS
5//! environment booted from a caller-supplied IMS image and returns
6//! the hostname the user can attach to via the console endpoint.
7
8use axum::{Json, http::StatusCode, response::IntoResponse};
9use serde::Deserialize;
10use utoipa::ToSchema;
11
12use super::{ErrorResponse, RequestCtx, SiteHeader, to_handler_error};
13use crate::server::audit::AuditNote;
14
15// ---------------------------------------------------------------------------
16// POST /v2/ephemeral-env — Create ephemeral CFS environment
17// ---------------------------------------------------------------------------
18
19/// Request body for `POST /ephemeral-env`.
20#[derive(Deserialize, ToSchema)]
21pub struct CreateEphemeralEnvRequest {
22  /// IMS image ID to boot the ephemeral environment from.
23  pub image_id: String,
24}
25
26/// `POST /v2/ephemeral-env` — launch an ephemeral CFS environment from an IMS image.
27#[utoipa::path(post, path = "/ephemeral-env", tag = "ephemeral-env",
28  params(SiteHeader),
29  request_body = CreateEphemeralEnvRequest,
30  security(("bearerAuth" = [])),
31  responses(
32    (status = 201, description = "Ephemeral env created", body = manta_shared::types::api::responses::EphemeralEnvResponse),
33    (status = 401, description = "Unauthorized",          body = ErrorResponse),
34    (status = 500, description = "Internal error",        body = ErrorResponse),
35  )
36)]
37#[tracing::instrument(skip_all)]
38pub async fn create_ephemeral_env(
39  ctx: RequestCtx,
40  note: AuditNote,
41  Json(body): Json<CreateEphemeralEnvRequest>,
42) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
43  note
44    .action("ephemeral_env.create")
45    .target("image", &body.image_id);
46
47  tracing::info!("create_ephemeral_env image_id={}", body.image_id);
48  let infra = ctx.infra();
49
50  let hostname =
51    crate::service::ephemeral_env::exec(&infra, &ctx.token, &body.image_id)
52      .await
53      .map_err(to_handler_error)?;
54  note.produced("hostname", &hostname);
55
56  Ok((
57    StatusCode::CREATED,
58    Json(serde_json::json!({ "hostname": hostname })),
59  ))
60}