use crate::commands::request::server_request_with_payload;
use nebulous::models::{V1Meter, V1ResourceMetaRequest};
use nebulous::resources::v1::containers::models::{
RestartPolicy, V1ContainerRequest, V1ContainerResources, V1EnvVar,
};
use nebulous::resources::v1::secrets::models::V1SecretRequest;
use nebulous::resources::v1::volumes::models::{V1VolumeConfig, V1VolumeDriver, V1VolumePath};
use serde_json::Value;
use std::collections::HashMap;
use std::error::Error;
use std::str::FromStr;
pub async fn create_container(
command: crate::cli::ContainerCommands,
) -> Result<(), Box<dyn Error>> {
println!("Creating container");
let container_request = if let Some(file) = command.file {
println!("Reading file: {}", file);
let file_content = std::fs::read_to_string(file)?;
println!("File content read");
let container_request: V1ContainerRequest = serde_yaml::from_str(&file_content)?;
println!("Container request: {:?}", container_request);
container_request
} else {
let volumes = if let (Some(source), Some(destination)) =
(&command.volume_source, &command.volume_destination)
{
Some(V1VolumeConfig {
paths: vec![V1VolumePath {
source: source.clone(),
dest: destination.clone(),
resync: command.volume_resync,
driver: V1VolumeDriver::from_str(&command.volume_type.unwrap())?,
continuous: command.volume_continuous,
..Default::default()
}],
cache_dir: command.volume_cache_dir,
})
} else {
None
};
let env = command.env.map(|env_vec| {
env_vec
.into_iter()
.map(|(key, value)| V1EnvVar {
key,
value: Some(value),
..Default::default()
})
.collect::<Vec<V1EnvVar>>()
});
let labels = command
.label
.map(|label_vec| label_vec.into_iter().collect::<HashMap<String, String>>());
let meters = if command.meter_cost.is_some() || command.meter_cost_plus.is_some() {
Some(vec![V1Meter {
cost: command.meter_cost,
costp: command.meter_cost_plus,
unit: command.meter_unit.clone().unwrap_or_default(),
metric: command.meter_metric.clone().unwrap_or_default(),
currency: command.meter_currency.clone().unwrap_or_default(),
json_path: None,
}])
} else {
None
};
if command.image.is_none() {
return Err("Image is required".into());
}
V1ContainerRequest {
kind: "Container".to_string(),
image: command.image.unwrap(),
command: command.cmd,
args: None, accelerators: command.accelerators,
platform: command.platform,
env: env,
volumes: Some(volumes.unwrap().paths),
metadata: Some(V1ResourceMetaRequest {
name: command.name,
namespace: command.namespace,
owner: None,
owner_ref: None,
labels: labels,
}),
meters: meters,
restart: command.restart.unwrap_or(RestartPolicy::Always.to_string()),
queue: command.queue,
timeout: command.timeout,
resources: Some(V1ContainerResources {
min_cpu: command.min_cpu,
min_memory: command.min_memory,
max_cpu: command.max_cpu,
max_memory: command.max_memory,
}),
ssh_keys: None,
ports: None,
proxy_port: command.proxy_port,
authz: None,
health_check: None,
}
};
let response = server_request_with_payload(
"/v1/containers",
reqwest::Method::POST,
Some(container_request),
)
.await?;
if response.status().is_success() {
let container: Value = response.json().await?;
println!("Container created successfully!");
println!("ID: {}", container["metadata"]["id"]);
println!("Name: {}", container["metadata"]["name"]);
} else {
let error_text = response.text().await?;
return Err(format!("Failed to create container: {}", error_text).into());
}
Ok(())
}
pub async fn create_secret(
command: crate::cli::SecretCommands, ) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating secret...");
let metadata = V1ResourceMetaRequest {
name: Some(command.name.clone()),
namespace: command.namespace,
..Default::default()
};
let secret_request = if let Some(file) = command.file {
println!("Reading secret file: {}", file);
let file_content = std::fs::read_to_string(&file)?;
println!("File content read");
V1SecretRequest {
metadata,
value: file_content,
expires_at: command.expires_at,
}
} else {
if command.value.is_none() {
return Err("Missing required secret value (or a file)".into());
}
V1SecretRequest {
metadata,
value: command.value.clone().unwrap(),
expires_at: command.expires_at,
}
};
let response =
server_request_with_payload("/v1/secrets", reqwest::Method::POST, Some(secret_request))
.await?;
if response.status().is_success() {
let secret_response: serde_json::Value = response.json().await?;
println!("Secret created successfully!");
println!("ID: {}", secret_response["metadata"]["id"]);
println!("Name: {}", secret_response["metadata"]["name"]);
Ok(())
} else {
let error_text = response.text().await?;
Err(format!("Failed to create secret: {}", error_text).into())
}
}