1use std::collections::HashMap;
4use std::time::Duration;
5
6use crate::state::{RestartPolicy, WorkloadState};
7
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
12pub struct DeployRequest {
13 pub name: String,
15 pub image: String,
17 pub command: Vec<String>,
19 pub args: Vec<String>,
21 pub environment: HashMap<String, String>,
23 pub labels: HashMap<String, String>,
25 pub annotations: HashMap<String, String>,
27 pub work_dir: String,
29 pub resources: Option<ResourceConfig>,
31 pub network: Option<NetworkConfig>,
33 pub volumes: Vec<VolumeMount>,
35 pub ports: Vec<PortMapping>,
37 pub restart_policy: RestartPolicy,
39 pub auto_remove: bool,
41 pub replicas: u32,
43 pub timeout: Option<Duration>,
45 pub platform: String,
47 pub namespace: String,
49 pub service_account: String,
51}
52
53impl DeployRequest {
54 #[must_use]
56 pub fn new(name: impl Into<String>, image: impl Into<String>) -> Self {
57 Self {
58 name: name.into(),
59 image: image.into(),
60 ..Self::default()
61 }
62 }
63}
64
65#[derive(Debug, Clone, Default, PartialEq, Eq)]
67pub struct ResourceConfig {
68 pub cpu_limit: String,
70 pub cpu_request: String,
72 pub memory_limit: String,
74 pub memory_request: String,
76}
77
78#[derive(Debug, Clone, Default, PartialEq, Eq)]
80pub struct NetworkConfig {
81 pub mode: String,
83 pub dns: Vec<String>,
85 pub hosts: HashMap<String, String>,
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct PortMapping {
92 pub host: u16,
94 pub container: u16,
96 pub protocol: String,
98}
99
100#[derive(Debug, Clone, Default, PartialEq, Eq)]
102pub struct VolumeMount {
103 pub source: String,
105 pub target: String,
107 pub read_only: bool,
109 pub kind: String,
111}
112
113#[derive(Debug, Clone, Default, PartialEq, Eq)]
115pub struct LogOptions {
116 pub tail: usize,
118 pub since: Option<Duration>,
120 pub follow: bool,
122}
123
124#[derive(Debug, Clone, Default, PartialEq, Eq)]
126pub struct ListFilter {
127 pub labels: HashMap<String, String>,
129 pub name: String,
131 pub state: Option<WorkloadState>,
133 pub namespace: String,
135}
136
137#[derive(Debug, Clone, Default, PartialEq, Eq)]
139pub struct ImageEventFilter {
140 pub actions: Vec<String>,
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn new_sets_name_and_image_with_defaults() {
150 let req = DeployRequest::new("api", "nginx:latest");
151 assert_eq!(req.name, "api");
152 assert_eq!(req.image, "nginx:latest");
153 assert_eq!(req.restart_policy, RestartPolicy::No);
154 assert!(req.timeout.is_none());
155 assert!(req.command.is_empty());
156 }
157
158 #[test]
159 fn deploy_request_is_cloneable_and_eq() {
160 let mut req = DeployRequest::new("api", "nginx");
161 req.labels.insert("team".into(), "core".into());
162 req.timeout = Some(Duration::from_secs(30));
163 assert_eq!(req.clone(), req);
164 }
165
166 #[test]
167 fn nested_specs_default_empty() {
168 assert_eq!(ResourceConfig::default(), ResourceConfig::default());
169 assert!(NetworkConfig::default().dns.is_empty());
170 assert!(ListFilter::default().state.is_none());
171 assert_eq!(LogOptions::default().tail, 0);
172 assert!(ImageEventFilter::default().actions.is_empty());
173 }
174}