lmrc_docker/networks/
mod.rs

1//! Network management operations.
2
3use crate::DockerClient;
4use crate::error::{DockerError, Result};
5use bollard::models::*;
6use bollard::network::*;
7use tracing::{debug, info};
8
9/// Network operations manager.
10pub struct Networks<'a> {
11    client: &'a DockerClient,
12}
13
14impl<'a> Networks<'a> {
15    pub(crate) fn new(client: &'a DockerClient) -> Self {
16        Self { client }
17    }
18
19    /// Create a new network.
20    ///
21    /// # Example
22    ///
23    /// ```no_run
24    /// use lmrc_docker::DockerClient;
25    ///
26    /// #[tokio::main]
27    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
28    ///     let client = DockerClient::new()?;
29    ///     let network_id = client.networks()
30    ///         .create("my-network", "bridge")
31    ///         .await?;
32    ///     println!("Created network: {}", network_id);
33    ///     Ok(())
34    /// }
35    /// ```
36    pub async fn create(
37        &self,
38        name: impl Into<String>,
39        driver: impl Into<String>,
40    ) -> Result<String> {
41        let name = name.into();
42        info!("Creating network: {}", name);
43
44        let config = CreateNetworkOptions {
45            name: name.clone(),
46            driver: driver.into(),
47            ..Default::default()
48        };
49
50        let response = self
51            .client
52            .docker
53            .create_network(config)
54            .await
55            .map_err(|e| DockerError::Other(format!("Failed to create network: {}", e)))?;
56
57        info!("Network created: {}", response.id);
58        Ok(response.id)
59    }
60
61    /// List all networks.
62    ///
63    /// # Example
64    ///
65    /// ```no_run
66    /// use lmrc_docker::DockerClient;
67    ///
68    /// #[tokio::main]
69    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
70    ///     let client = DockerClient::new()?;
71    ///     let networks = client.networks().list().await?;
72    ///     for network in networks {
73    ///         println!("{}: {:?}", network.id.unwrap(), network.name);
74    ///     }
75    ///     Ok(())
76    /// }
77    /// ```
78    pub async fn list(&self) -> Result<Vec<Network>> {
79        self.client
80            .docker
81            .list_networks(Some(
82                bollard::query_parameters::ListNetworksOptions::default(),
83            ))
84            .await
85            .map_err(|e| DockerError::Other(format!("Failed to list networks: {}", e)))
86    }
87
88    /// Get a reference to a specific network.
89    pub fn get(&self, name_or_id: impl Into<String>) -> NetworkRef<'a> {
90        NetworkRef::new(self.client, name_or_id.into())
91    }
92
93    /// Prune unused networks.
94    pub async fn prune(&self) -> Result<NetworkPruneResponse> {
95        info!("Pruning unused networks...");
96        self.client
97            .docker
98            .prune_networks(Some(
99                bollard::query_parameters::PruneNetworksOptions::default(),
100            ))
101            .await
102            .map_err(|e| DockerError::Other(format!("Failed to prune networks: {}", e)))
103    }
104}
105
106/// Reference to a specific network.
107pub struct NetworkRef<'a> {
108    client: &'a DockerClient,
109    id: String,
110}
111
112impl<'a> NetworkRef<'a> {
113    pub(crate) fn new(client: &'a DockerClient, id: String) -> Self {
114        Self { client, id }
115    }
116
117    /// Get the network ID.
118    pub fn id(&self) -> &str {
119        &self.id
120    }
121
122    /// Inspect the network to get detailed information.
123    pub async fn inspect(&self) -> Result<Network> {
124        debug!("Inspecting network: {}", self.id);
125        self.client
126            .docker
127            .inspect_network(
128                &self.id,
129                Some(bollard::query_parameters::InspectNetworkOptions::default()),
130            )
131            .await
132            .map_err(|e| DockerError::NetworkNotFound(format!("{}: {}", self.id, e)))
133    }
134
135    /// Connect a container to this network.
136    ///
137    /// # Example
138    ///
139    /// ```no_run
140    /// use lmrc_docker::DockerClient;
141    ///
142    /// #[tokio::main]
143    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
144    ///     let client = DockerClient::new()?;
145    ///     client.networks()
146    ///         .get("my-network")
147    ///         .connect("my-container")
148    ///         .await?;
149    ///     Ok(())
150    /// }
151    /// ```
152    pub async fn connect(&self, container: impl Into<String>) -> Result<()> {
153        let container = container.into();
154        info!("Connecting container {} to network {}", container, self.id);
155
156        let config = ConnectNetworkOptions {
157            container,
158            ..Default::default()
159        };
160
161        self.client
162            .docker
163            .connect_network(&self.id, config)
164            .await
165            .map_err(|e| DockerError::Other(format!("Failed to connect to network: {}", e)))
166    }
167
168    /// Disconnect a container from this network.
169    pub async fn disconnect(&self, container: impl Into<String>, force: bool) -> Result<()> {
170        let container = container.into();
171        info!(
172            "Disconnecting container {} from network {}",
173            container, self.id
174        );
175
176        let config = DisconnectNetworkOptions { container, force };
177
178        self.client
179            .docker
180            .disconnect_network(&self.id, config)
181            .await
182            .map_err(|e| DockerError::Other(format!("Failed to disconnect from network: {}", e)))
183    }
184
185    /// Remove the network.
186    pub async fn remove(&self) -> Result<()> {
187        info!("Removing network: {}", self.id);
188        self.client
189            .docker
190            .remove_network(&self.id)
191            .await
192            .map_err(|e| DockerError::Other(format!("Failed to remove network: {}", e)))
193    }
194}
195
196impl DockerClient {
197    /// Access network operations.
198    ///
199    /// # Example
200    ///
201    /// ```no_run
202    /// use lmrc_docker::DockerClient;
203    ///
204    /// #[tokio::main]
205    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
206    ///     let client = DockerClient::new()?;
207    ///     let networks = client.networks().list().await?;
208    ///     Ok(())
209    /// }
210    /// ```
211    pub fn networks(&self) -> Networks<'_> {
212        Networks::new(self)
213    }
214}