manta_server/service/
ephemeral_env.rs1use csm_rs::ShastaClient;
6use manta_backend_dispatcher::error::Error;
7
8use crate::server::common::app_context::InfraContext;
9use manta_shared::common::jwt_ops;
10
11const EPHEMERAL_IMAGE_NAME: &str = "__ephemeral_image";
12
13pub async fn exec(
15 infra: &InfraContext<'_>,
16 token: &str,
17 image_id: &str,
18) -> Result<String, Error> {
19 let user_public_key_name =
20 jwt_ops::get_preferred_username(token).map_err(|e| {
21 Error::JwtMalformed(format!(
22 "claim 'preferred_user' not found in JWT token: {e}"
23 ))
24 })?;
25
26 tracing::info!("Looking for user '{}' public SSH key", user_public_key_name);
27
28 let shasta = ShastaClient::new(
29 infra.shasta_base_url,
30 infra.shasta_root_cert.to_vec(),
31 infra.socks5_proxy.map(|s| s.to_string()),
32 )
33 .map_err(|e| {
34 Error::BadRequest(format!("Could not build Shasta HTTP client: {e}"))
35 })?;
36
37 let user_public_ssh_id_value = if let Ok(Some(user_public_ssh_value)) = shasta
38 .ims_public_keys_v3_get_single(token, &user_public_key_name)
39 .await
40 {
41 user_public_ssh_value["id"].clone()
42 } else {
43 return Err(Error::NotFound(format!(
44 "User '{user_public_key_name}' does not have an SSH public key in Alps. \
45 Please contact platform sys admins."
46 )));
47 };
48
49 tracing::info!("SSH key found with ID {}", user_public_ssh_id_value);
50 tracing::info!(
51 "Creating ephemeral environment based on image ID {}",
52 image_id
53 );
54
55 let resp_json = shasta
56 .ims_job_post_customize(
57 token,
58 EPHEMERAL_IMAGE_NAME,
59 image_id,
60 user_public_ssh_id_value.as_str().ok_or_else(|| {
61 Error::MissingField("SSH key ID is not a string".to_string())
62 })?,
63 )
64 .await
65 .map_err(|e| {
66 Error::BadRequest(format!(
67 "Could not create ephemeral environment based on image ID {image_id}: {e}"
68 ))
69 })?;
70
71 let hostname = resp_json
72 .pointer("/ssh_containers/0/connection_info/customer_access/host")
73 .and_then(|v| v.as_str())
74 .ok_or_else(|| {
75 Error::MissingField(
76 "Failed to get SSH container hostname from ephemeral env response"
77 .to_string(),
78 )
79 })?
80 .to_string();
81
82 tracing::info!("Ephemeral environment created — SSH hostname: {}", hostname);
83
84 Ok(hostname)
85}