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,
112}
113
114#[derive(Debug, Clone, Default, PartialEq, Eq)]
116pub struct LogOptions {
117 pub tail: usize,
119 pub since: Option<Duration>,
121 pub follow: bool,
123}
124
125#[derive(Debug, Clone, Default, PartialEq, Eq)]
127pub struct ListFilter {
128 pub labels: HashMap<String, String>,
130 pub name: String,
132 pub state: Option<WorkloadState>,
134 pub namespace: String,
136}
137
138#[derive(Debug, Clone, Default, PartialEq, Eq)]
140pub struct ImageEventFilter {
141 pub actions: Vec<String>,
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 fn new_sets_name_and_image_with_defaults() {
151 let req = DeployRequest::new("api", "nginx:latest");
152 assert_eq!(req.name, "api");
153 assert_eq!(req.image, "nginx:latest");
154 assert_eq!(req.restart_policy, RestartPolicy::No);
155 assert!(req.timeout.is_none());
156 assert!(req.command.is_empty());
157 }
158
159 #[test]
160 fn deploy_request_is_cloneable_and_eq() {
161 let mut req = DeployRequest::new("api", "nginx");
162 req.labels.insert("team".into(), "core".into());
163 req.timeout = Some(Duration::from_secs(30));
164 assert_eq!(req.clone(), req);
165 }
166
167 #[test]
168 fn nested_specs_default_empty() {
169 assert_eq!(ResourceConfig::default(), ResourceConfig::default());
170 assert!(NetworkConfig::default().dns.is_empty());
171 assert!(ListFilter::default().state.is_none());
172 assert_eq!(LogOptions::default().tail, 0);
173 assert!(ImageEventFilter::default().actions.is_empty());
174 }
175}