docker_wrapper/command/context/
update.rs1use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
26pub struct ContextUpdateCommand {
27 name: String,
29 description: Option<String>,
31 docker_host: Option<String>,
33 default_stack_orchestrator: Option<String>,
35 docker_api_endpoint: Option<String>,
37 kubernetes_config_file: Option<String>,
39 kubernetes_context: Option<String>,
41 kubernetes_namespace: Option<String>,
43 kubernetes_api_endpoint: Option<String>,
45 pub executor: CommandExecutor,
47}
48
49impl ContextUpdateCommand {
50 #[must_use]
52 pub fn new(name: impl Into<String>) -> Self {
53 Self {
54 name: name.into(),
55 description: None,
56 docker_host: None,
57 default_stack_orchestrator: None,
58 docker_api_endpoint: None,
59 kubernetes_config_file: None,
60 kubernetes_context: None,
61 kubernetes_namespace: None,
62 kubernetes_api_endpoint: None,
63 executor: CommandExecutor::new(),
64 }
65 }
66
67 #[must_use]
69 pub fn description(mut self, desc: impl Into<String>) -> Self {
70 self.description = Some(desc.into());
71 self
72 }
73
74 #[must_use]
76 pub fn docker_host(mut self, host: impl Into<String>) -> Self {
77 self.docker_host = Some(host.into());
78 self
79 }
80
81 #[must_use]
83 pub fn default_stack_orchestrator(mut self, orchestrator: impl Into<String>) -> Self {
84 self.default_stack_orchestrator = Some(orchestrator.into());
85 self
86 }
87
88 #[must_use]
90 pub fn docker_api_endpoint(mut self, endpoint: impl Into<String>) -> Self {
91 self.docker_api_endpoint = Some(endpoint.into());
92 self
93 }
94
95 #[must_use]
97 pub fn kubernetes_config_file(mut self, file: impl Into<String>) -> Self {
98 self.kubernetes_config_file = Some(file.into());
99 self
100 }
101
102 #[must_use]
104 pub fn kubernetes_context(mut self, context: impl Into<String>) -> Self {
105 self.kubernetes_context = Some(context.into());
106 self
107 }
108
109 #[must_use]
111 pub fn kubernetes_namespace(mut self, namespace: impl Into<String>) -> Self {
112 self.kubernetes_namespace = Some(namespace.into());
113 self
114 }
115
116 #[must_use]
118 pub fn kubernetes_api_endpoint(mut self, endpoint: impl Into<String>) -> Self {
119 self.kubernetes_api_endpoint = Some(endpoint.into());
120 self
121 }
122}
123
124#[async_trait]
125impl DockerCommand for ContextUpdateCommand {
126 type Output = CommandOutput;
127
128 fn get_executor(&self) -> &CommandExecutor {
129 &self.executor
130 }
131
132 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
133 &mut self.executor
134 }
135
136 fn build_command_args(&self) -> Vec<String> {
137 let mut args = vec!["context".to_string(), "update".to_string()];
138
139 if let Some(desc) = &self.description {
140 args.push("--description".to_string());
141 args.push(desc.clone());
142 }
143
144 if let Some(host) = &self.docker_host {
145 args.push("--docker".to_string());
146 args.push(format!("host={host}"));
147 }
148
149 if let Some(orchestrator) = &self.default_stack_orchestrator {
150 args.push("--default-stack-orchestrator".to_string());
151 args.push(orchestrator.clone());
152 }
153
154 if let Some(endpoint) = &self.docker_api_endpoint {
155 args.push("--docker".to_string());
156 args.push(format!("api-endpoint={endpoint}"));
157 }
158
159 if let Some(file) = &self.kubernetes_config_file {
160 args.push("--kubernetes".to_string());
161 args.push(format!("config-file={file}"));
162 }
163
164 if let Some(context) = &self.kubernetes_context {
165 args.push("--kubernetes".to_string());
166 args.push(format!("context={context}"));
167 }
168
169 if let Some(namespace) = &self.kubernetes_namespace {
170 args.push("--kubernetes".to_string());
171 args.push(format!("namespace={namespace}"));
172 }
173
174 if let Some(endpoint) = &self.kubernetes_api_endpoint {
175 args.push("--kubernetes".to_string());
176 args.push(format!("api-endpoint={endpoint}"));
177 }
178
179 args.push(self.name.clone());
180
181 args.extend(self.executor.raw_args.clone());
182 args
183 }
184
185 async fn execute(&self) -> Result<Self::Output> {
186 let args = self.build_command_args();
187 self.execute_command(args).await
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn test_context_update_basic() {
197 let cmd = ContextUpdateCommand::new("test-context");
198 let args = cmd.build_command_args();
199 assert_eq!(args[0], "context");
200 assert_eq!(args[1], "update");
201 assert!(args.contains(&"test-context".to_string()));
202 }
203
204 #[test]
205 fn test_context_update_with_description() {
206 let cmd = ContextUpdateCommand::new("test-context").description("Updated description");
207 let args = cmd.build_command_args();
208 assert!(args.contains(&"--description".to_string()));
209 assert!(args.contains(&"Updated description".to_string()));
210 }
211
212 #[test]
213 fn test_context_update_with_docker_host() {
214 let cmd = ContextUpdateCommand::new("remote").docker_host("tcp://127.0.0.1:2376");
215 let args = cmd.build_command_args();
216 assert!(args.contains(&"--docker".to_string()));
217 assert!(args.contains(&"host=tcp://127.0.0.1:2376".to_string()));
218 }
219}