use serde::{Deserialize, Serialize};
use utoipa::IntoParams;
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ServiceSummary {
pub name: String,
pub deployment: String,
pub status: String,
pub replicas: u32,
pub desired_replicas: u32,
pub endpoints: Vec<ServiceEndpoint>,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ServiceDetails {
pub name: String,
pub deployment: String,
pub status: String,
pub replicas: u32,
pub desired_replicas: u32,
pub endpoints: Vec<ServiceEndpoint>,
pub metrics: ServiceMetrics,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ServiceEndpoint {
pub name: String,
pub protocol: String,
pub port: u16,
pub url: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ServiceMetrics {
pub cpu_percent: f64,
pub memory_percent: f64,
pub rps: Option<f64>,
}
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct ScaleRequest {
pub replicas: u32,
}
#[derive(Debug, Deserialize, IntoParams)]
pub struct LogQuery {
#[serde(default = "default_lines")]
pub lines: u32,
#[serde(default)]
pub follow: bool,
pub instance: Option<String>,
}
fn default_lines() -> u32 {
100
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ContainerSummary {
pub id: String,
pub service: String,
pub replica: u32,
pub state: String,
pub pid: Option<u32>,
pub overlay_ip: Option<String>,
}
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct ExecRequest {
pub command: Vec<String>,
#[serde(default)]
pub replica: Option<u32>,
}
#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
pub struct ExecResponse {
pub exit_code: i32,
pub stdout: String,
pub stderr: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_service_summary_serialize() {
let summary = ServiceSummary {
name: "api".to_string(),
deployment: "my-app".to_string(),
status: "running".to_string(),
replicas: 3,
desired_replicas: 3,
endpoints: vec![ServiceEndpoint {
name: "http".to_string(),
protocol: "http".to_string(),
port: 8080,
url: None,
}],
};
let json = serde_json::to_string(&summary).unwrap();
assert!(json.contains("api"));
assert!(json.contains("my-app"));
}
#[test]
fn test_scale_request_deserialize() {
let json = r#"{"replicas": 5}"#;
let request: ScaleRequest = serde_json::from_str(json).unwrap();
assert_eq!(request.replicas, 5);
}
#[test]
fn test_log_query_defaults() {
let query: LogQuery = serde_json::from_str("{}").unwrap();
assert_eq!(query.lines, 100);
assert!(!query.follow);
assert!(query.instance.is_none());
}
}