Skip to main content

zlayer_types/api/
deployments.rs

1//! Deployment DTOs.
2
3use serde::{Deserialize, Serialize};
4
5/// Deployment summary
6#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
7pub struct DeploymentSummary {
8    /// Deployment name
9    pub name: String,
10    /// Deployment status
11    pub status: String,
12    /// Number of services
13    pub service_count: usize,
14    /// Created timestamp
15    pub created_at: String,
16}
17
18/// Per-service health info included in deployment details
19#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
20pub struct ServiceHealthInfo {
21    /// Service name
22    pub name: String,
23    /// Running replica count
24    pub replicas_running: u32,
25    /// Desired replica count
26    pub replicas_desired: u32,
27    /// Health status ("healthy", "unhealthy", "unknown")
28    pub health: String,
29    /// Endpoint URLs for this service
30    pub endpoints: Vec<String>,
31}
32
33/// Deployment details (enhanced with per-service health and endpoints)
34#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
35pub struct DeploymentDetails {
36    /// Deployment name
37    pub name: String,
38    /// Deployment status
39    pub status: String,
40    /// Service names (for backwards compatibility)
41    pub services: Vec<String>,
42    /// Per-service health and endpoint info
43    pub service_health: Vec<ServiceHealthInfo>,
44    /// Created timestamp
45    pub created_at: String,
46    /// Updated timestamp
47    pub updated_at: String,
48}
49
50/// Create deployment request
51#[derive(Debug, Deserialize, utoipa::ToSchema)]
52pub struct CreateDeploymentRequest {
53    /// Deployment specification (YAML content)
54    pub spec: String,
55}
56
57/// Deployment progress event sent over SSE during orchestration.
58#[derive(Debug, Clone, Serialize)]
59#[serde(tag = "kind", rename_all = "snake_case")]
60pub enum DeploymentProgressEvent {
61    /// Deployment orchestration has started
62    Started {
63        /// Deployment name
64        deployment: String,
65        /// List of services being deployed
66        services: Vec<String>,
67    },
68    /// A service was successfully registered with the service manager
69    ServiceRegistered {
70        /// Service name
71        service: String,
72    },
73    /// A service failed to register
74    ServiceRegistrationFailed {
75        /// Service name
76        service: String,
77        /// Error message
78        error: String,
79    },
80    /// Overlay network created for a service
81    OverlayCreated {
82        /// Service name
83        service: String,
84        /// Network interface name
85        interface: String,
86    },
87    /// Overlay creation failed (non-fatal)
88    OverlayFailed {
89        /// Service name
90        service: String,
91        /// Error message
92        error: String,
93    },
94    /// Proxy routes configured for a service
95    ProxyConfigured {
96        /// Service name
97        service: String,
98    },
99    /// Proxy configuration failed (non-fatal)
100    ProxyFailed {
101        /// Service name
102        service: String,
103        /// Error message
104        error: String,
105    },
106    /// Service scaling has started
107    ServiceScaling {
108        /// Service name
109        service: String,
110        /// Target replica count
111        target: u32,
112    },
113    /// Service successfully scaled
114    ServiceScaled {
115        /// Service name
116        service: String,
117        /// Number of replicas running
118        replicas: u32,
119    },
120    /// Service scaling failed
121    ServiceScaleFailed {
122        /// Service name
123        service: String,
124        /// Error message
125        error: String,
126    },
127    /// Waiting for stabilization
128    Stabilizing,
129    /// Deployment is ready and running
130    Ready,
131    /// Deployment failed
132    Failed {
133        /// Error message describing the failure
134        message: String,
135    },
136}
137
138/// Wrapper for serializing deployment progress events as SSE.
139///
140/// Converts each [`DeploymentProgressEvent`] variant into an `event_type` string
141/// and a JSON `data` payload, following the same pattern as `BuildEventWrapper`.
142#[derive(Debug, Clone, Serialize)]
143pub struct DeploymentEventWrapper {
144    /// SSE event type (used as the `event:` field)
145    #[serde(rename = "type")]
146    pub event_type: String,
147    /// JSON data payload
148    pub data: serde_json::Value,
149}
150
151impl From<DeploymentProgressEvent> for DeploymentEventWrapper {
152    fn from(event: DeploymentProgressEvent) -> Self {
153        match event {
154            DeploymentProgressEvent::Started {
155                deployment,
156                services,
157            } => DeploymentEventWrapper {
158                event_type: "started".to_string(),
159                data: serde_json::json!({
160                    "deployment": deployment,
161                    "services": services,
162                }),
163            },
164            DeploymentProgressEvent::ServiceRegistered { service } => DeploymentEventWrapper {
165                event_type: "service_registered".to_string(),
166                data: serde_json::json!({ "service": service }),
167            },
168            DeploymentProgressEvent::ServiceRegistrationFailed { service, error } => {
169                DeploymentEventWrapper {
170                    event_type: "service_registration_failed".to_string(),
171                    data: serde_json::json!({ "service": service, "error": error }),
172                }
173            }
174            DeploymentProgressEvent::OverlayCreated { service, interface } => {
175                DeploymentEventWrapper {
176                    event_type: "overlay_created".to_string(),
177                    data: serde_json::json!({ "service": service, "interface": interface }),
178                }
179            }
180            DeploymentProgressEvent::OverlayFailed { service, error } => DeploymentEventWrapper {
181                event_type: "overlay_failed".to_string(),
182                data: serde_json::json!({ "service": service, "error": error }),
183            },
184            DeploymentProgressEvent::ProxyConfigured { service } => DeploymentEventWrapper {
185                event_type: "proxy_configured".to_string(),
186                data: serde_json::json!({ "service": service }),
187            },
188            DeploymentProgressEvent::ProxyFailed { service, error } => DeploymentEventWrapper {
189                event_type: "proxy_failed".to_string(),
190                data: serde_json::json!({ "service": service, "error": error }),
191            },
192            DeploymentProgressEvent::ServiceScaling { service, target } => DeploymentEventWrapper {
193                event_type: "service_scaling".to_string(),
194                data: serde_json::json!({ "service": service, "target": target }),
195            },
196            DeploymentProgressEvent::ServiceScaled { service, replicas } => {
197                DeploymentEventWrapper {
198                    event_type: "service_scaled".to_string(),
199                    data: serde_json::json!({ "service": service, "replicas": replicas }),
200                }
201            }
202            DeploymentProgressEvent::ServiceScaleFailed { service, error } => {
203                DeploymentEventWrapper {
204                    event_type: "service_scale_failed".to_string(),
205                    data: serde_json::json!({ "service": service, "error": error }),
206                }
207            }
208            DeploymentProgressEvent::Stabilizing => DeploymentEventWrapper {
209                event_type: "stabilizing".to_string(),
210                data: serde_json::json!({}),
211            },
212            DeploymentProgressEvent::Ready => DeploymentEventWrapper {
213                event_type: "ready".to_string(),
214                data: serde_json::json!({}),
215            },
216            DeploymentProgressEvent::Failed { message } => DeploymentEventWrapper {
217                event_type: "failed".to_string(),
218                data: serde_json::json!({ "message": message }),
219            },
220        }
221    }
222}