1 //! Network API: Networks are user-defined networks that containers can be attached to.
2 
3 use arrayvec::ArrayVec;
4 use http::request::Builder;
5 use hyper::{Body, Method};
6 use serde::ser::Serialize;
7 use serde_json;
8 
9 use std::cmp::Eq;
10 use std::collections::HashMap;
11 use std::hash::Hash;
12 
13 use super::Docker;
14 use crate::docker::{FALSE_STR, TRUE_STR};
15 use crate::errors::Error;
16 use crate::errors::ErrorKind::JsonSerializeError;
17 
18 /// Network configuration used in the [Create Network API](../struct.Docker.html#method.create_network)
19 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
20 #[serde(rename_all = "PascalCase")]
21 pub struct CreateNetworkOptions<T>
22 where
23     T: AsRef<str> + Eq + Hash,
24 {
25     /// The network's name.
26     pub name: T,
27     /// Check for networks with duplicate names. Since Network is primarily keyed based on a random
28     /// ID and not on the name, and network name is strictly a user-friendly alias to the network
29     /// which is uniquely identified using ID, there is no guaranteed way to check for duplicates.
30     /// CheckDuplicate is there to provide a best effort checking of any networks which has the
31     /// same name but it is not guaranteed to catch all name collisions.
32     pub check_duplicate: bool,
33     /// Name of the network driver plugin to use.
34     pub driver: T,
35     /// Restrict external access to the network.
36     pub internal: bool,
37     /// Globally scoped network is manually attachable by regular containers from workers in swarm mode.
38     pub attachable: bool,
39     /// Ingress network is the network which provides the routing-mesh in swarm mode.
40     pub ingress: bool,
41     /// Controls IP address management when creating a network.
42     #[serde(rename = "IPAM")]
43     pub ipam: IPAM<T>,
44     /// Enable IPv6 on the network.
45     #[serde(rename = "EnableIPv6")]
46     pub enable_ipv6: bool,
47     /// Network specific options to be used by the drivers.
48     pub options: HashMap<T, T>,
49     /// User-defined key/value metadata.
50     pub labels: HashMap<T, T>,
51 }
52 
53 /// IPAM represents IP Address Management
54 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
55 #[serde(rename_all = "PascalCase")]
56 #[allow(missing_docs)]
57 pub struct IPAM<T>
58 where
59     T: AsRef<str> + Eq + Hash,
60 {
61     /// Name of the IPAM driver to use.
62     pub driver: T,
63     /// List of IPAM configuration options, specified as a map: {"Subnet": <CIDR>, "IPRange": <CIDR>, "Gateway": <IP address>, "AuxAddress": <device_name:IP address>}
64     pub config: Vec<IPAMConfig<T>>,
65     /// Driver-specific options, specified as a map.
66     pub options: Option<HashMap<T, T>>,
67 }
68 
69 /// IPAMConfig represents IPAM configurations
70 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
71 #[serde(rename_all = "PascalCase")]
72 #[allow(missing_docs)]
73 pub struct IPAMConfig<T>
74 where
75     T: AsRef<str> + Eq + Hash,
76 {
77     pub subnet: Option<T>,
78     #[serde(rename = "IPRange")]
79     pub ip_range: Option<T>,
80     pub gateway: Option<T>,
81     pub aux_address: Option<HashMap<T, T>>,
82 }
83 
84 /// Result type for the [Create Network API](../struct.Docker.html#method.create_network)
85 #[derive(Debug, Clone, Serialize, Deserialize)]
86 #[serde(rename_all = "PascalCase")]
87 #[allow(missing_docs)]
88 pub struct CreateNetworkResults {
89     pub id: String,
90     pub warning: String,
91 }
92 
93 /// Parameters used in the [Inspect Network API](../struct.Docker.html#method.inspect_network)
94 ///
95 /// ## Examples
96 ///
97 /// ```rust
98 /// use bollard::network::InspectNetworkOptions;
99 ///
100 /// InspectNetworkOptions{
101 ///     verbose: true,
102 ///     scope: "global",
103 /// };
104 /// ```
105 ///
106 /// ```rust
107 /// # use bollard::network::InspectNetworkOptions;
108 /// # use std::default::Default;
109 /// InspectNetworkOptions::<&str>{
110 ///     ..Default::default()
111 /// };
112 /// ```
113 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
114 #[serde(rename_all = "PascalCase")]
115 pub struct InspectNetworkOptions<T> {
116     /// Detailed inspect output for troubleshooting.
117     pub verbose: bool,
118     /// Filter the network by scope (swarm, global, or local)
119     pub scope: T,
120 }
121 
122 #[allow(missing_docs)]
123 /// Trait providing implementations for [Inspect Network Options](struct.InspectNetworkOptions.html)
124 /// struct.
125 pub trait InspectNetworkQueryParams<'a, V>
126 where
127     V: AsRef<str>,
128 {
into_array(self) -> Result<ArrayVec<[(&'a str, V); 2]>, Error>129     fn into_array(self) -> Result<ArrayVec<[(&'a str, V); 2]>, Error>;
130 }
131 
132 impl<'a> InspectNetworkQueryParams<'a, &'a str> for InspectNetworkOptions<&'a str> {
into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 2]>, Error>133     fn into_array(self) -> Result<ArrayVec<[(&'a str, &'a str); 2]>, Error> {
134         Ok(ArrayVec::from([
135             ("verbose", if self.verbose { TRUE_STR } else { FALSE_STR }),
136             ("scope", self.scope),
137         ]))
138     }
139 }
140 
141 impl<'a> InspectNetworkQueryParams<'a, String> for InspectNetworkOptions<String> {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 2]>, Error>142     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 2]>, Error> {
143         Ok(ArrayVec::from([
144             ("verbose", self.verbose.to_string()),
145             ("scope", self.scope),
146         ]))
147     }
148 }
149 
150 /// Result type for the [Inspect Network API](../struct.Docker.html#method.inspect_network)
151 #[derive(Debug, Clone, Serialize, Deserialize)]
152 #[serde(rename_all = "PascalCase")]
153 #[allow(missing_docs)]
154 pub struct InspectNetworkResults {
155     pub name: String,
156     pub id: String,
157     pub created: String,
158     pub scope: String,
159     pub driver: String,
160     #[serde(rename = "EnableIPv6")]
161     pub enable_ipv6: bool,
162     #[serde(rename = "IPAM")]
163     pub ipam: IPAM<String>,
164     pub internal: bool,
165     pub attachable: bool,
166     pub ingress: bool,
167     pub containers: HashMap<String, InspectNetworkResultsContainers>,
168     pub options: HashMap<String, String>,
169     pub labels: HashMap<String, String>,
170     pub config_from: HashMap<String, String>,
171     pub config_only: bool,
172 }
173 
174 /// Result type for the [Inspect Network API](../struct.Docker.html#method.inspect_network)
175 #[derive(Debug, Clone, Serialize, Deserialize)]
176 #[serde(rename_all = "PascalCase")]
177 #[allow(missing_docs)]
178 pub struct InspectNetworkResultsContainers {
179     pub name: String,
180     #[serde(rename = "EndpointID")]
181     pub endpoint_id: Option<String>,
182     pub mac_address: Option<String>,
183     #[serde(rename = "IPv4Address")]
184     pub ipv4_address: Option<String>,
185     #[serde(rename = "IPv6Address")]
186     pub ipv6_address: Option<String>,
187 }
188 
189 /// Result type for the [List Networks API](../struct.Docker.html#method.list_networks)
190 #[derive(Debug, Clone, Serialize, Deserialize)]
191 #[serde(rename_all = "PascalCase")]
192 #[allow(missing_docs)]
193 pub struct ListNetworksResults {
194     pub name: String,
195     pub id: String,
196     pub created: String,
197     pub scope: String,
198     pub driver: String,
199     #[serde(rename = "EnableIPv6")]
200     pub enable_ipv6: bool,
201     pub internal: bool,
202     pub attachable: bool,
203     pub ingress: bool,
204     #[serde(rename = "IPAM")]
205     pub ipam: IPAM<String>,
206     pub options: HashMap<String, String>,
207     pub config_from: HashMap<String, String>,
208     pub config_only: bool,
209     pub containers: HashMap<String, InspectNetworkResultsContainers>,
210     pub labels: HashMap<String, String>,
211 }
212 
213 /// Parameters used in the [List Networks API](../struct.Docker.html#method.list_networks)
214 ///
215 /// ## Examples
216 ///
217 /// ```rust
218 /// use bollard::network::ListNetworksOptions;
219 ///
220 /// use std::collections::HashMap;
221 ///
222 /// let mut filters = HashMap::new();
223 /// filters.insert("label", vec!("maintainer=some_maintainer"));
224 ///
225 /// ListNetworksOptions{
226 ///     filters: filters
227 /// };
228 /// ```
229 ///
230 /// ```rust
231 /// # use bollard::network::ListNetworksOptions;
232 /// # use std::default::Default;
233 ///
234 /// ListNetworksOptions::<&str> {
235 ///     ..Default::default()
236 /// };
237 /// ```
238 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
239 #[serde(rename_all = "PascalCase")]
240 pub struct ListNetworksOptions<T>
241 where
242     T: AsRef<str> + Eq + Hash,
243 {
244     /// JSON encoded value of the filters (a `map[string][]string`) to process on the networks list. Available filters:
245     ///  - `driver=<driver-name>` Matches a network's driver.
246     ///  - `id=<network-id>` Matches all or part of a network ID.
247     ///  - `label=<key>` or `label=<key>=<value>` of a network label.
248     ///  - `name=<network-name>` Matches all or part of a network name.
249     ///  - `scope=["swarm"|"global"|"local"]` Filters networks by scope (`swarm`, `global`, or `local`).
250     ///  - `type=["custom"|"builtin"]` Filters networks by type. The `custom` keyword returns all user-defined networks.
251     pub filters: HashMap<T, Vec<T>>,
252 }
253 
254 #[allow(missing_docs)]
255 /// Trait providing implementations for [List Networks Options](struct.ListNetworksOptions.html)
256 /// struct.
257 pub trait ListNetworksQueryParams<K, V>
258 where
259     K: AsRef<str>,
260     V: AsRef<str>,
261 {
into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>262     fn into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>;
263 }
264 
265 impl<'a> ListNetworksQueryParams<&'a str, String> for ListNetworksOptions<&'a str> {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error>266     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error> {
267         Ok(ArrayVec::from([(
268             "filters",
269             serde_json::to_string(&self.filters)
270                 .map_err::<Error, _>(|e| JsonSerializeError { err: e }.into())?,
271         )]))
272     }
273 }
274 
275 /// Network configuration used in the [Connect Network API](../struct.Docker.html#method.connect_network)
276 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
277 #[serde(rename_all = "PascalCase")]
278 pub struct ConnectNetworkOptions<T>
279 where
280     T: AsRef<str> + Eq + Hash,
281 {
282     /// The ID or name of the container to connect to the network.
283     pub container: T,
284     /// Configuration for a network endpoint.
285     pub endpoint_config: EndpointSettings<T>,
286 }
287 
288 /// Configuration for a network endpoint.
289 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
290 #[serde(rename_all = "PascalCase")]
291 pub struct EndpointSettings<T>
292 where
293     T: AsRef<str> + Eq + Hash,
294 {
295     /// EndpointIPAMConfig represents an endpoint's IPAM configuration.
296     #[serde(rename = "IPAMConfig")]
297     pub ipam_config: EndpointIPAMConfig<T>,
298     #[allow(missing_docs)]
299     pub links: Vec<T>,
300     #[allow(missing_docs)]
301     pub aliases: Vec<T>,
302     /// Unique ID of the network.
303     #[serde(rename = "NetworkID")]
304     pub network_id: T,
305     /// Unique ID for the service endpoint in a Sandbox.
306     #[serde(rename = "EndpointID")]
307     pub endpoint_id: T,
308     /// Gateway address for this network.
309     pub gateway: T,
310     /// IPv4 address.
311     #[serde(rename = "IPAddress")]
312     pub ip_address: T,
313     /// Mask length of the IPv4 address.
314     #[serde(rename = "IPPrefixLen")]
315     pub ip_prefix_len: isize,
316     /// IPv6 gateway address.
317     #[serde(rename = "IPv6Gateway")]
318     pub ipv6_gateway: T,
319     /// Global IPv6 address.
320     #[serde(rename = "GlobalIPv6Address")]
321     pub global_ipv6_address: T,
322     /// Mask length of the global IPv6 address.
323     #[serde(rename = "GlobalIPv6PrefixLen")]
324     pub global_ipv6_prefix_len: i64,
325     /// MAC address for the endpoint on this network.
326     pub mac_address: T,
327     /// DriverOpts is a mapping of driver options and values. These options are passed directly to
328     /// the driver and are driver specific.
329     pub driver_opts: Option<HashMap<T, T>>,
330 }
331 
332 #[derive(Debug, Default, Clone, Serialize, Deserialize)]
333 #[allow(missing_docs)]
334 pub struct EndpointIPAMConfig<T>
335 where
336     T: AsRef<str>,
337 {
338     #[serde(rename = "IPv4Address")]
339     pub ipv4_address: Option<T>,
340     #[serde(rename = "IPv6Address")]
341     pub ipv6_address: Option<T>,
342     #[serde(rename = "LinkLocalIPs")]
343     pub link_local_ips: Option<Vec<T>>,
344 }
345 
346 /// Network configuration used in the [Disconnect Network API](../struct.Docker.html#method.disconnect_network)
347 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
348 #[serde(rename_all = "PascalCase")]
349 pub struct DisconnectNetworkOptions<T>
350 where
351     T: AsRef<str>,
352 {
353     /// The ID or name of the container to disconnect from the network.
354     pub container: T,
355     /// Force the container to disconnect from the network.
356     pub force: bool,
357 }
358 
359 /// Parameters used in the [Prune Networks API](../struct.Docker.html#method.prune_networks)
360 ///
361 /// ## Examples
362 ///
363 /// ```rust
364 /// use bollard::network::PruneNetworksOptions;
365 ///
366 /// use std::collections::HashMap;
367 ///
368 /// let mut filters = HashMap::new();
369 /// filters.insert("label!", vec!("maintainer=some_maintainer"));
370 ///
371 /// PruneNetworksOptions{
372 ///     filters: filters
373 /// };
374 /// ```
375 ///
376 /// ```rust
377 /// # use bollard::network::PruneNetworksOptions;
378 /// # use std::default::Default;
379 ///
380 /// PruneNetworksOptions::<&str>{
381 ///     ..Default::default()
382 /// };
383 /// ```
384 #[derive(Debug, Clone, Default)]
385 pub struct PruneNetworksOptions<T>
386 where
387     T: AsRef<str> + Eq + Hash,
388 {
389     /// Filters to process on the prune list, encoded as JSON.
390     ///  - `until=<timestamp>` Prune networks created before this timestamp. The `<timestamp>` can be
391     ///  Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`)
392     ///  computed relative to the daemon machine’s time.
393     ///  - label (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`)
394     ///  Prune networks with (or without, in case `label!=...` is used) the specified labels.
395     pub filters: HashMap<T, Vec<T>>,
396 }
397 
398 /// Trait providing implementations for [Prune Networks Options](struct.PruneNetworksOptions.html)
399 /// struct.
400 #[allow(missing_docs)]
401 pub trait PruneNetworksQueryParams<K, V>
402 where
403     K: AsRef<str>,
404     V: AsRef<str>,
405 {
into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>406     fn into_array(self) -> Result<ArrayVec<[(K, String); 1]>, Error>;
407 }
408 
409 impl<'a> PruneNetworksQueryParams<&'a str, String> for PruneNetworksOptions<&'a str> {
into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error>410     fn into_array(self) -> Result<ArrayVec<[(&'a str, String); 1]>, Error> {
411         Ok(ArrayVec::from([(
412             "filters",
413             serde_json::to_string(&self.filters)
414                 .map_err::<Error, _>(|e| JsonSerializeError { err: e }.into())?,
415         )]))
416     }
417 }
418 
419 /// Result type for the [Prune Networks API](../struct.Docker.html#method.prune_networks)
420 #[derive(Debug, Clone, Serialize, Deserialize)]
421 #[serde(rename_all = "PascalCase")]
422 #[allow(missing_docs)]
423 pub struct PruneNetworksResults {
424     pub networks_deleted: Option<Vec<String>>,
425 }
426 
427 impl Docker {
428     /// ---
429     ///
430     /// # Create Network
431     ///
432     /// Create a new network.
433     ///
434     /// # Arguments
435     ///
436     ///  - [Create Network Options](network/struct.CreateNetworkOptions.html) struct.
437     ///
438     /// # Returns
439     ///
440     ///  - A [Create Network Results](network/struct.CreateNetworkResults.html) struct, wrapped in a
441     ///  Future.
442     ///
443     /// # Examples
444     ///
445     /// ```rust
446     /// # use bollard::Docker;
447     /// # let docker = Docker::connect_with_http_defaults().unwrap();
448     ///
449     /// use bollard::network::CreateNetworkOptions;
450     ///
451     /// use std::default::Default;
452     ///
453     /// let config = CreateNetworkOptions {
454     ///     name: "certs",
455     ///     ..Default::default()
456     /// };
457     ///
458     /// docker.create_network(config);
459     /// ```
create_network<T>( &self, config: CreateNetworkOptions<T>, ) -> Result<CreateNetworkResults, Error> where T: AsRef<str> + Eq + Hash + Serialize,460     pub async fn create_network<T>(
461         &self,
462         config: CreateNetworkOptions<T>,
463     ) -> Result<CreateNetworkResults, Error>
464     where
465         T: AsRef<str> + Eq + Hash + Serialize,
466     {
467         let url = "/networks/create";
468 
469         let req = self.build_request::<_, String, String>(
470             &url,
471             Builder::new().method(Method::POST),
472             Ok(None::<ArrayVec<[(_, _); 0]>>),
473             Docker::serialize_payload(Some(config)),
474         );
475 
476         self.process_into_value(req).await
477     }
478 
479     /// ---
480     ///
481     /// # Remove a Network
482     ///
483     /// # Arguments
484     ///
485     ///  - Network name as a string slice.
486     ///
487     /// # Returns
488     ///
489     ///  - unit type `()`, wrapped in a Future.
490     ///
491     /// # Examples
492     ///
493     /// ```rust
494     /// # use bollard::Docker;
495     /// # let docker = Docker::connect_with_http_defaults().unwrap();
496     ///
497     /// docker.remove_network("my_network_name");
498     /// ```
remove_network(&self, network_name: &str) -> Result<(), Error>499     pub async fn remove_network(&self, network_name: &str) -> Result<(), Error> {
500         let url = format!("/networks/{}", network_name);
501 
502         let req = self.build_request::<_, String, String>(
503             &url,
504             Builder::new().method(Method::DELETE),
505             Ok(None::<ArrayVec<[(_, _); 0]>>),
506             Ok(Body::empty()),
507         );
508 
509         self.process_into_unit(req).await
510     }
511 
512     /// ---
513     ///
514     /// # Inspect a Network
515     ///
516     /// # Arguments
517     ///
518     ///  - Network name as a string slice.
519     ///
520     /// # Returns
521     ///
522     ///  - A [Inspect Network Results](network/struct.CreateNetworkResults.html) struct, wrapped in a
523     ///  Future.
524     ///
525     /// # Examples
526     ///
527     /// ```rust
528     /// # use bollard::Docker;
529     /// # let docker = Docker::connect_with_http_defaults().unwrap();
530     ///
531     /// use bollard::network::InspectNetworkOptions;
532     ///
533     /// use std::default::Default;
534     ///
535     /// let config = InspectNetworkOptions {
536     ///     verbose: true,
537     ///     scope: "global"
538     /// };
539     ///
540     /// docker.inspect_network("my_network_name", Some(config));
541     /// ```
inspect_network<'a, T, V>( &self, network_name: &str, options: Option<T>, ) -> Result<InspectNetworkResults, Error> where T: InspectNetworkQueryParams<'a, V>, V: AsRef<str>,542     pub async fn inspect_network<'a, T, V>(
543         &self,
544         network_name: &str,
545         options: Option<T>,
546     ) -> Result<InspectNetworkResults, Error>
547     where
548         T: InspectNetworkQueryParams<'a, V>,
549         V: AsRef<str>,
550     {
551         let url = format!("/networks/{}", network_name);
552 
553         let req = self.build_request(
554             &url,
555             Builder::new().method(Method::GET),
556             Docker::transpose_option(options.map(|o| o.into_array())),
557             Ok(Body::empty()),
558         );
559 
560         self.process_into_value(req).await
561     }
562 
563     /// ---
564     ///
565     /// # List Networks
566     ///
567     /// # Arguments
568     ///
569     ///  - Optional [List Network Options](network/struct.ListNetworksOptions.html) struct.
570     ///
571     /// # Returns
572     ///
573     ///  - A vector of [List Networks Results](network/struct.CreateNetworkResults.html) struct, wrapped in a
574     ///  Future.
575     ///
576     /// # Examples
577     ///
578     /// ```rust
579     /// # use bollard::Docker;
580     /// # let docker = Docker::connect_with_http_defaults().unwrap();
581     ///
582     /// use bollard::network::ListNetworksOptions;
583     ///
584     /// use std::collections::HashMap;
585     ///
586     /// let mut list_networks_filters = HashMap::new();
587     /// list_networks_filters.insert("label", vec!["maintainer=some_maintainer"]);
588     ///
589     /// let config = ListNetworksOptions {
590     ///     filters: list_networks_filters,
591     /// };
592     ///
593     /// docker.list_networks(Some(config));
594     /// ```
list_networks<T, K, V>( &self, options: Option<T>, ) -> Result<Vec<ListNetworksResults>, Error> where T: ListNetworksQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,595     pub async fn list_networks<T, K, V>(
596         &self,
597         options: Option<T>,
598     ) -> Result<Vec<ListNetworksResults>, Error>
599     where
600         T: ListNetworksQueryParams<K, V>,
601         K: AsRef<str>,
602         V: AsRef<str>,
603     {
604         let url = "/networks";
605 
606         let req = self.build_request(
607             &url,
608             Builder::new().method(Method::GET),
609             Docker::transpose_option(options.map(|o| o.into_array())),
610             Ok(Body::empty()),
611         );
612 
613         self.process_into_value(req).await
614     }
615 
616     /// ---
617     ///
618     /// # Connect Network
619     ///
620     /// # Arguments
621     ///
622     ///  - A [Connect Network Options](network/struct.ConnectNetworkOptions.html) struct.
623     ///
624     /// # Returns
625     ///
626     ///  - unit type `()`, wrapped in a Future.
627     ///
628     /// # Examples
629     ///
630     /// ```rust
631     /// # use bollard::Docker;
632     /// # let docker = Docker::connect_with_http_defaults().unwrap();
633     ///
634     /// use bollard::network::{EndpointSettings, EndpointIPAMConfig, ConnectNetworkOptions};
635     ///
636     /// use std::default::Default;
637     ///
638     /// let config = ConnectNetworkOptions {
639     ///     container: "3613f73ba0e4",
640     ///     endpoint_config: EndpointSettings {
641     ///         ipam_config: EndpointIPAMConfig {
642     ///             ipv4_address: Some("172.24.56.89"),
643     ///             ipv6_address: Some("2001:db8::5689"),
644     ///             ..Default::default()
645     ///         },
646     ///         ..Default::default()
647     ///     }
648     /// };
649     ///
650     /// docker.connect_network("my_network_name", config);
651     /// ```
connect_network<T>( &self, network_name: &str, config: ConnectNetworkOptions<T>, ) -> Result<(), Error> where T: AsRef<str> + Eq + Hash + Serialize,652     pub async fn connect_network<T>(
653         &self,
654         network_name: &str,
655         config: ConnectNetworkOptions<T>,
656     ) -> Result<(), Error>
657     where
658         T: AsRef<str> + Eq + Hash + Serialize,
659     {
660         let url = format!("/networks/{}/connect", network_name);
661 
662         let req = self.build_request::<_, String, String>(
663             &url,
664             Builder::new().method(Method::POST),
665             Ok(None::<ArrayVec<[(_, _); 0]>>),
666             Docker::serialize_payload(Some(config)),
667         );
668 
669         self.process_into_unit(req).await
670     }
671 
672     /// ---
673     ///
674     /// # Disconnect Network
675     ///
676     /// # Arguments
677     ///
678     ///  - A [Disconnect Network Options](network/struct.DisconnectNetworkOptions.html) struct.
679     ///
680     /// # Returns
681     ///
682     ///  - unit type `()`, wrapped in a Future.
683     ///
684     /// # Examples
685     ///
686     /// ```rust
687     /// # use bollard::Docker;
688     /// # let docker = Docker::connect_with_http_defaults().unwrap();
689     ///
690     /// use bollard::network::DisconnectNetworkOptions;
691     ///
692     /// use std::default::Default;
693     ///
694     /// let config = DisconnectNetworkOptions {
695     ///     container: "3613f73ba0e4",
696     ///     force: true
697     /// };
698     ///
699     /// docker.disconnect_network("my_network_name", config);
700     /// ```
disconnect_network<T>( &self, network_name: &str, config: DisconnectNetworkOptions<T>, ) -> Result<(), Error> where T: AsRef<str> + Serialize,701     pub async fn disconnect_network<T>(
702         &self,
703         network_name: &str,
704         config: DisconnectNetworkOptions<T>,
705     ) -> Result<(), Error>
706     where
707         T: AsRef<str> + Serialize,
708     {
709         let url = format!("/networks/{}/disconnect", network_name);
710 
711         let req = self.build_request::<_, String, String>(
712             &url,
713             Builder::new().method(Method::POST),
714             Ok(None::<ArrayVec<[(_, _); 0]>>),
715             Docker::serialize_payload(Some(config)),
716         );
717 
718         self.process_into_unit(req).await
719     }
720 
721     /// ---
722     ///
723     /// # Prune Networks
724     ///
725     /// Deletes networks which are unused.
726     ///
727     /// # Arguments
728     ///
729     ///  - A [Prune Networks Options](network/struct.PruneNetworksOptions.html) struct.
730     ///
731     /// # Returns
732     ///
733     ///  - A [Prune Networks Results](network/struct.PruneNetworksResults.html) struct.
734     ///
735     /// # Examples
736     ///
737     /// ```rust
738     /// # use bollard::Docker;
739     /// # let docker = Docker::connect_with_http_defaults().unwrap();
740     ///
741     /// use bollard::network::PruneNetworksOptions;
742     ///
743     /// use std::collections::HashMap;
744     ///
745     /// let mut filters = HashMap::new();
746     /// filters.insert("label", vec!("maintainer=some_maintainer"));
747     ///
748     /// let options = PruneNetworksOptions {
749     ///     filters: filters,
750     /// };
751     ///
752     /// docker.prune_networks(Some(options));
753     /// ```
prune_networks<T, K, V>( &self, options: Option<T>, ) -> Result<PruneNetworksResults, Error> where T: PruneNetworksQueryParams<K, V>, K: AsRef<str>, V: AsRef<str>,754     pub async fn prune_networks<T, K, V>(
755         &self,
756         options: Option<T>,
757     ) -> Result<PruneNetworksResults, Error>
758     where
759         T: PruneNetworksQueryParams<K, V>,
760         K: AsRef<str>,
761         V: AsRef<str>,
762     {
763         let url = "/networks/prune";
764 
765         let req = self.build_request(
766             &url,
767             Builder::new().method(Method::POST),
768             Docker::transpose_option(options.map(|o| o.into_array())),
769             Ok(Body::empty()),
770         );
771 
772         self.process_into_value(req).await
773     }
774 }
775