docker_api/opts/
network.rs

1use crate::{models::Ipam, Error, Result};
2use containers_api::opts::{Filter, FilterItem};
3use containers_api::{
4    impl_field, impl_filter_func, impl_map_field, impl_opts_builder, impl_str_field, impl_vec_field,
5};
6
7use std::{collections::HashMap, convert::AsRef};
8
9use serde::Serialize;
10use serde_json::{json, Value};
11
12impl_opts_builder!(url =>
13    /// Options for filtering networks list results"
14    NetworkList
15);
16
17/// Used for [`NetworkFilter::Scope`](NetworkFilter::Scope).
18pub enum Scope {
19    Swarm,
20    Global,
21    Local,
22}
23
24impl AsRef<str> for Scope {
25    fn as_ref(&self) -> &str {
26        match &self {
27            Scope::Swarm => "swarm",
28            Scope::Global => "global",
29            Scope::Local => "local",
30        }
31    }
32}
33
34pub enum NetworkType {
35    Custom,
36    Builtin,
37}
38
39impl AsRef<str> for NetworkType {
40    fn as_ref(&self) -> &str {
41        match &self {
42            NetworkType::Custom => "custom",
43            NetworkType::Builtin => "builtin",
44        }
45    }
46}
47
48/// A single filter item used to filter the output of listing the networks.
49pub enum NetworkFilter {
50    /// When set to true (or 1), returns all networks that are not in use by a container.
51    /// When set to false (or 0), only networks that are in use by one or more containers are returned.
52    Dangling(bool),
53    /// Matches a network's driver.
54    Driver(String),
55    /// Matches all or part of a network ID.
56    Id(String),
57    /// Label in the form of `label=key`
58    LabelKey(String),
59    /// Label in the form of `label=key=val`
60    LabelKeyVal(String, String),
61    /// Matches all or part of a network name.
62    Name(String),
63    Scope(Scope),
64    Type(NetworkType),
65}
66
67impl Filter for NetworkFilter {
68    fn query_item(&self) -> FilterItem {
69        use NetworkFilter::*;
70
71        match &self {
72            Dangling(dangling) => FilterItem::new("dangling", dangling.to_string()),
73            Driver(driver) => FilterItem::new("driver", driver.to_owned()),
74            Id(id) => FilterItem::new("id", id.to_owned()),
75            LabelKey(key) => FilterItem::new("label", key.to_owned()),
76            LabelKeyVal(key, val) => FilterItem::new("label", format!("{key}={val}")),
77            Name(name) => FilterItem::new("name", name.to_owned()),
78            Scope(scope) => FilterItem::new("scope", scope.as_ref().to_owned()),
79            Type(type_) => FilterItem::new("type", type_.as_ref().to_owned()),
80        }
81    }
82}
83
84impl NetworkListOptsBuilder {
85    impl_filter_func!(
86        /// Filter the list of networks by one of the variants of the filter.
87        NetworkFilter
88    );
89}
90
91/// Interface for creating new docker network
92#[derive(Serialize, Debug, Clone)]
93pub struct NetworkCreateOpts {
94    params: HashMap<&'static str, Value>,
95}
96
97impl NetworkCreateOpts {
98    /// Return a new instance of a opts-builder for creating a network.
99    pub fn builder<N>(name: N) -> NetworkCreateOptsBuilder
100    where
101        N: AsRef<str>,
102    {
103        NetworkCreateOptsBuilder::new(name.as_ref())
104    }
105
106    /// Serializes the options as a JSON string.
107    pub fn serialize(&self) -> Result<String> {
108        serde_json::to_string(&self.params).map_err(Error::from)
109    }
110
111    /// Serializes the options as a JSON bytes.
112    pub fn serialize_vec(&self) -> Result<Vec<u8>> {
113        serde_json::to_vec(&self.params).map_err(Error::from)
114    }
115}
116
117#[derive(Default)]
118pub struct NetworkCreateOptsBuilder {
119    params: HashMap<&'static str, Value>,
120}
121
122impl NetworkCreateOptsBuilder {
123    pub(crate) fn new(name: &str) -> Self {
124        let mut params = HashMap::new();
125        params.insert("Name", json!(name));
126        NetworkCreateOptsBuilder { params }
127    }
128
129    impl_field!(
130        /// Check for networks with duplicate names. Since Network is primarily keyed based on a
131        /// random ID and not on the name, and network name is strictly a user-friendly alias to
132        /// the network which is uniquely identified using ID, there is no guaranteed way to check
133        /// for duplicates. CheckDuplicate is there to provide a best effort checking of any
134        /// networks which has the same name but it is not guaranteed to catch all name collisions.
135        check_duplicate: bool => "CheckDuplicate"
136    );
137
138    impl_str_field!(
139        /// Name of the network driver plugin to use.
140        driver => "Driver"
141    );
142
143    impl_field!(
144        /// Restrict external access to the network.
145        internal: bool => "Internal"
146    );
147
148    impl_field!(
149        /// Globally scoped network is manually attachable by regular containers from workers
150        /// in swarm mode.
151        attachable: bool => "Attachable"
152    );
153
154    impl_field!(
155        /// Ingress network is the network which provides the routing-mesh in swarm mode.
156        ingress: bool => "Ingress"
157    );
158
159    impl_field!(
160        /// Enable IPv6 on the network.
161        enable_ipv6: bool => "EnableIPv6"
162    );
163
164    impl_map_field!(json
165        /// Network specific options to be used by the drivers.
166        options => "Options"
167    );
168
169    impl_map_field!(json
170        /// User-defined key/value metadata.
171        labels => "Labels"
172    );
173
174    impl_field!(
175        /// IP Address Management configuration
176        ipam: Ipam => "IPAM"
177    );
178
179    pub fn build(&self) -> NetworkCreateOpts {
180        NetworkCreateOpts {
181            params: self.params.clone(),
182        }
183    }
184}
185#[derive(Serialize, Debug)]
186/// Interface for disconnecting a container from a network.
187pub struct ContainerDisconnectionOpts {
188    params: HashMap<&'static str, Value>,
189}
190
191impl ContainerDisconnectionOpts {
192    /// Serializes the options as a JSON string.
193    pub fn serialize(&self) -> Result<String> {
194        serde_json::to_string(&self.params).map_err(Error::from)
195    }
196
197    /// Serializes the options as a JSON bytes.
198    pub fn serialize_vec(&self) -> Result<Vec<u8>> {
199        serde_json::to_vec(&self.params).map_err(Error::from)
200    }
201
202    /// Return a new instance of a builder for disconnecting a container from a network.
203    pub fn builder<I>(container_id: I) -> ContainerDisconnectionOptsBuilder
204    where
205        I: AsRef<str>,
206    {
207        ContainerDisconnectionOptsBuilder::new(container_id.as_ref())
208    }
209}
210
211#[derive(Default)]
212pub struct ContainerDisconnectionOptsBuilder {
213    params: HashMap<&'static str, Value>,
214}
215
216impl ContainerDisconnectionOptsBuilder {
217    pub(crate) fn new(container_id: &str) -> Self {
218        ContainerDisconnectionOptsBuilder {
219            params: [("Container", json!(container_id.to_string()))].into(),
220        }
221    }
222
223    impl_field!(
224        /// Force the container to disconnect from the network.
225        force: bool => "Force"
226    );
227
228    pub fn build(self) -> ContainerDisconnectionOpts {
229        ContainerDisconnectionOpts {
230            params: self.params,
231        }
232    }
233}
234
235#[derive(Serialize, Debug)]
236/// Interface for connecting a container to a network.
237pub struct ContainerConnectionOpts {
238    params: HashMap<&'static str, Value>,
239}
240
241impl ContainerConnectionOpts {
242    /// Serializes the options as a JSON string.
243    pub fn serialize(&self) -> Result<String> {
244        serde_json::to_string(&self.params).map_err(Error::from)
245    }
246
247    /// Serializes the options as a JSON bytes.
248    pub fn serialize_vec(&self) -> Result<Vec<u8>> {
249        serde_json::to_vec(&self.params).map_err(Error::from)
250    }
251
252    /// Return a new instance of a builder for connecting a container to a network.
253    pub fn builder<I>(container_id: I) -> ContainerConnectionOptsBuilder
254    where
255        I: AsRef<str>,
256    {
257        ContainerConnectionOptsBuilder::new(container_id.as_ref())
258    }
259}
260
261#[derive(Default)]
262pub struct ContainerConnectionOptsBuilder {
263    params: HashMap<&'static str, Value>,
264    container: String,
265}
266
267impl ContainerConnectionOptsBuilder {
268    pub(crate) fn new(container_id: &str) -> Self {
269        ContainerConnectionOptsBuilder {
270            params: HashMap::new(),
271            container: container_id.to_string(),
272        }
273    }
274
275    /// Endpoint's IPAM configuration.
276    pub fn ipam_config(mut self, config: EndpointIpamConfig) -> Self {
277        self.params.insert("EndpointConfig", json!(config.params));
278        self
279    }
280
281    impl_vec_field!(aliases => "Aliases");
282
283    impl_vec_field!(links => "Links");
284
285    impl_str_field!(
286        /// Unique ID of the network.
287        network_id => "NetworkID"
288    );
289
290    impl_str_field!(
291        /// Unique ID for the service endpoint in a Sandbox.
292        endpoint_id => "EndpointID"
293    );
294
295    impl_str_field!(
296        /// Gateway address for this network.
297        gateway => "Gateway"
298    );
299
300    impl_str_field!(
301        /// IPv4 address.
302        ipv4 => "IPAddress"
303    );
304
305    impl_field!(
306        /// Mask length of the IPv4 address.
307        prefix_len: isize => "IPPrefixLen"
308    );
309
310    impl_str_field!(
311        /// IPv6 gateway address.
312        ipv6_gateway => "IPv6Gateway"
313    );
314
315    impl_str_field!(
316        /// Global IPv6 address.
317        ipv6 => "GlobalIPv6Address"
318    );
319
320    impl_field!(
321        /// Mask length of the global IPv6 address.
322        ipv6_prefix_len: i64 => "GlobalIPv6PrefixLen"
323    );
324
325    impl_str_field!(
326        /// MAC address for the endpoint on this network.
327        mac => "MacAddress"
328    );
329
330    impl_map_field!(json
331        /// DriverOpts is a mapping of driver options and values. These options are passed directly
332        /// to the driver and are driver specific.
333        driver_opts => "DriverOpts"
334    );
335
336    pub fn build(self) -> ContainerConnectionOpts {
337        let mut params = HashMap::new();
338        params.insert("EndpointConfig", json!(self.params));
339        params.insert("Container", json!(self.container));
340        ContainerConnectionOpts { params }
341    }
342}
343
344#[derive(Default)]
345/// Used to configure endpoint IPAM configuration when connection a container to a network.
346/// See [`ipam_config`](ContainerConnectOptsBuilder::ipam_config).
347pub struct EndpointIpamConfig {
348    params: HashMap<&'static str, serde_json::Value>,
349}
350
351impl EndpointIpamConfig {
352    pub fn new() -> Self {
353        Self::default()
354    }
355
356    pub fn ipv4<A>(mut self, address: A) -> Self
357    where
358        A: Into<String>,
359    {
360        self.params.insert("IPv4Address", json!(address.into()));
361        self
362    }
363
364    pub fn ipv6<A>(mut self, address: A) -> Self
365    where
366        A: Into<String>,
367    {
368        self.params.insert("IPv6Address", json!(address.into()));
369        self
370    }
371
372    pub fn link_local_ips<I>(mut self, ips: I) -> Self
373    where
374        I: IntoIterator,
375        I::Item: Into<String>,
376    {
377        self.params.insert(
378            "LinkLocalIPs",
379            json!(ips.into_iter().map(I::Item::into).collect::<Vec<_>>()),
380        );
381        self
382    }
383}
384
385impl_opts_builder!(url => NetworkPrune);
386
387pub enum NetworkPruneFilter {
388    /// Prune networks created before this timestamp. The <timestamp> can be Unix timestamps,
389    /// date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative
390    /// to the daemon machine’s time.
391    Until(String),
392    #[cfg(feature = "chrono")]
393    #[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
394    /// Prune networks created before this timestamp. Same as `Until` but takes a datetime object.
395    UntilDate(chrono::DateTime<chrono::Utc>),
396    /// Label in the form of `label=key`.
397    LabelKey(String),
398    /// Label in the form of `label=key=val`.
399    Label(String, String),
400}
401
402impl Filter for NetworkPruneFilter {
403    fn query_item(&self) -> FilterItem {
404        use NetworkPruneFilter::*;
405        match &self {
406            Until(until) => FilterItem::new("until", until.to_owned()),
407            #[cfg(feature = "chrono")]
408            UntilDate(until) => FilterItem::new("until", until.timestamp().to_string()),
409            LabelKey(label) => FilterItem::new("label", label.to_owned()),
410            Label(key, val) => FilterItem::new("label", format!("{key}={val}")),
411        }
412    }
413}
414
415impl NetworkPruneOptsBuilder {
416    impl_filter_func!(
417        /// Filter the networks to prune by one of the variants of the enum.
418        NetworkPruneFilter
419    );
420}