ironflow_ops_docker/networks/
manage.rs1use std::collections::HashMap;
4
5use async_trait::async_trait;
6use bollard::Docker;
7use bollard::models::NetworkCreateRequest;
8use bollard::query_parameters::{InspectNetworkOptions, ListNetworksOptions, PruneNetworksOptions};
9use ironflow_core::error::OperationError;
10use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
11use serde::{Deserialize, Serialize};
12use serde_json::Value;
13
14use crate::containers::DockerRef;
15use crate::helpers::{docker_error, to_value};
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct NetworkCreateOutput {
24 pub id: String,
26}
27
28pub struct NetworkCreate {
42 docker: Docker,
43 name: String,
44 driver: Option<String>,
45}
46
47impl NetworkCreate {
48 pub fn new(client: impl Into<DockerRef>, name: impl Into<String>) -> Self {
50 Self {
51 docker: client.into().0,
52 name: name.into(),
53 driver: None,
54 }
55 }
56
57 pub fn driver(mut self, driver: impl Into<String>) -> Self {
59 self.driver = Some(driver.into());
60 self
61 }
62
63 pub async fn run(
69 &self,
70 _ctx: &OperationContext,
71 ) -> Result<NetworkCreateOutput, OperationError> {
72 let request = NetworkCreateRequest {
73 name: self.name.clone(),
74 driver: Some(self.driver.clone().unwrap_or_else(|| "bridge".to_string())),
75 ..Default::default()
76 };
77 let response = self
78 .docker
79 .create_network(request)
80 .await
81 .map_err(docker_error)?;
82 Ok(NetworkCreateOutput { id: response.id })
83 }
84}
85
86#[async_trait]
87impl Operation for NetworkCreate {
88 fn kind(&self) -> &str {
89 "docker"
90 }
91
92 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
93 to_value(&self.run(ctx).await?)
94 }
95
96 fn input(&self) -> Option<Value> {
97 Some(serde_json::json!({
98 "operation": "network_create",
99 "name": self.name,
100 }))
101 }
102}
103
104impl TypedOperation for NetworkCreate {
105 type Output = NetworkCreateOutput;
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct NetworkInspectOutput {
115 pub data: Value,
117}
118
119pub struct NetworkInspect {
133 docker: Docker,
134 name: String,
135}
136
137impl NetworkInspect {
138 pub fn new(client: impl Into<DockerRef>, name: impl Into<String>) -> Self {
140 Self {
141 docker: client.into().0,
142 name: name.into(),
143 }
144 }
145
146 pub async fn run(
152 &self,
153 _ctx: &OperationContext,
154 ) -> Result<NetworkInspectOutput, OperationError> {
155 let options = InspectNetworkOptions {
156 verbose: false,
157 scope: Some("local".to_string()),
158 };
159 let response = self
160 .docker
161 .inspect_network(&self.name, Some(options))
162 .await
163 .map_err(docker_error)?;
164 let data = serde_json::to_value(&response).map_err(|e| OperationError::External {
165 origin: "docker".to_string(),
166 message: e.to_string(),
167 })?;
168 Ok(NetworkInspectOutput { data })
169 }
170}
171
172#[async_trait]
173impl Operation for NetworkInspect {
174 fn kind(&self) -> &str {
175 "docker"
176 }
177
178 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
179 to_value(&self.run(ctx).await?)
180 }
181
182 fn input(&self) -> Option<Value> {
183 Some(serde_json::json!({
184 "operation": "network_inspect",
185 "name": self.name,
186 }))
187 }
188}
189
190impl TypedOperation for NetworkInspect {
191 type Output = NetworkInspectOutput;
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct NetworkListEntry {
201 pub id: String,
203 pub name: String,
205 pub driver: String,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct NetworkListOutput {
212 pub networks: Vec<NetworkListEntry>,
214}
215
216pub struct NetworkList {
230 docker: Docker,
231 filters: HashMap<String, Vec<String>>,
232}
233
234impl NetworkList {
235 pub fn new(client: impl Into<DockerRef>) -> Self {
237 Self {
238 docker: client.into().0,
239 filters: HashMap::new(),
240 }
241 }
242
243 pub fn filter(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
245 self.filters
246 .entry(key.into())
247 .or_default()
248 .push(value.into());
249 self
250 }
251
252 pub async fn run(&self, _ctx: &OperationContext) -> Result<NetworkListOutput, OperationError> {
259 let options = ListNetworksOptions {
260 filters: Some(self.filters.clone()),
261 };
262 let networks = self
263 .docker
264 .list_networks(Some(options))
265 .await
266 .map_err(docker_error)?;
267 let entries = networks
268 .into_iter()
269 .map(|n| NetworkListEntry {
270 id: n.id.unwrap_or_default(),
271 name: n.name.unwrap_or_default(),
272 driver: n.driver.unwrap_or_default(),
273 })
274 .collect();
275 Ok(NetworkListOutput { networks: entries })
276 }
277}
278
279#[async_trait]
280impl Operation for NetworkList {
281 fn kind(&self) -> &str {
282 "docker"
283 }
284
285 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
286 to_value(&self.run(ctx).await?)
287 }
288
289 fn input(&self) -> Option<Value> {
290 Some(serde_json::json!({
291 "operation": "network_list",
292 }))
293 }
294}
295
296impl TypedOperation for NetworkList {
297 type Output = NetworkListOutput;
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
306pub struct NetworkRemoveOutput {
307 pub name: String,
309}
310
311pub struct NetworkRemove {
325 docker: Docker,
326 name: String,
327}
328
329impl NetworkRemove {
330 pub fn new(client: impl Into<DockerRef>, name: impl Into<String>) -> Self {
332 Self {
333 docker: client.into().0,
334 name: name.into(),
335 }
336 }
337
338 pub async fn run(
344 &self,
345 _ctx: &OperationContext,
346 ) -> Result<NetworkRemoveOutput, OperationError> {
347 self.docker
348 .remove_network(&self.name)
349 .await
350 .map_err(docker_error)?;
351 Ok(NetworkRemoveOutput {
352 name: self.name.clone(),
353 })
354 }
355}
356
357#[async_trait]
358impl Operation for NetworkRemove {
359 fn kind(&self) -> &str {
360 "docker"
361 }
362
363 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
364 to_value(&self.run(ctx).await?)
365 }
366
367 fn input(&self) -> Option<Value> {
368 Some(serde_json::json!({
369 "operation": "network_remove",
370 "name": self.name,
371 }))
372 }
373}
374
375impl TypedOperation for NetworkRemove {
376 type Output = NetworkRemoveOutput;
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
385pub struct NetworkPruneOutput {
386 pub networks_deleted: Vec<String>,
388}
389
390pub struct NetworkPrune {
404 docker: Docker,
405 filters: HashMap<String, Vec<String>>,
406}
407
408impl NetworkPrune {
409 pub fn new(client: impl Into<DockerRef>) -> Self {
411 Self {
412 docker: client.into().0,
413 filters: HashMap::new(),
414 }
415 }
416
417 pub fn filter(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
419 self.filters
420 .entry(key.into())
421 .or_default()
422 .push(value.into());
423 self
424 }
425
426 pub async fn run(&self, _ctx: &OperationContext) -> Result<NetworkPruneOutput, OperationError> {
433 let options = PruneNetworksOptions {
434 filters: Some(self.filters.clone()),
435 };
436 let response = self
437 .docker
438 .prune_networks(Some(options))
439 .await
440 .map_err(docker_error)?;
441 Ok(NetworkPruneOutput {
442 networks_deleted: response.networks_deleted.unwrap_or_default(),
443 })
444 }
445}
446
447#[async_trait]
448impl Operation for NetworkPrune {
449 fn kind(&self) -> &str {
450 "docker"
451 }
452
453 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
454 to_value(&self.run(ctx).await?)
455 }
456
457 fn input(&self) -> Option<Value> {
458 Some(serde_json::json!({
459 "operation": "network_prune",
460 }))
461 }
462}
463
464impl TypedOperation for NetworkPrune {
465 type Output = NetworkPruneOutput;
466}