1from .. import errors
2from ..utils import normalize_links, version_lt
3
4
5class EndpointConfig(dict):
6    def __init__(self, version, aliases=None, links=None, ipv4_address=None,
7                 ipv6_address=None, link_local_ips=None, driver_opt=None):
8        if version_lt(version, '1.22'):
9            raise errors.InvalidVersion(
10                'Endpoint config is not supported for API version < 1.22'
11            )
12
13        if aliases:
14            self["Aliases"] = aliases
15
16        if links:
17            self["Links"] = normalize_links(links)
18
19        ipam_config = {}
20        if ipv4_address:
21            ipam_config['IPv4Address'] = ipv4_address
22
23        if ipv6_address:
24            ipam_config['IPv6Address'] = ipv6_address
25
26        if link_local_ips is not None:
27            if version_lt(version, '1.24'):
28                raise errors.InvalidVersion(
29                    'link_local_ips is not supported for API version < 1.24'
30                )
31            ipam_config['LinkLocalIPs'] = link_local_ips
32
33        if ipam_config:
34            self['IPAMConfig'] = ipam_config
35
36        if driver_opt:
37            if version_lt(version, '1.32'):
38                raise errors.InvalidVersion(
39                    'DriverOpts is not supported for API version < 1.32'
40                )
41            if not isinstance(driver_opt, dict):
42                raise TypeError('driver_opt must be a dictionary')
43            self['DriverOpts'] = driver_opt
44
45
46class NetworkingConfig(dict):
47    def __init__(self, endpoints_config=None):
48        if endpoints_config:
49            self["EndpointsConfig"] = endpoints_config
50
51
52class IPAMConfig(dict):
53    """
54    Create an IPAM (IP Address Management) config dictionary to be used with
55    :py:meth:`~docker.api.network.NetworkApiMixin.create_network`.
56
57    Args:
58
59        driver (str): The IPAM driver to use. Defaults to ``default``.
60        pool_configs (:py:class:`list`): A list of pool configurations
61          (:py:class:`~docker.types.IPAMPool`). Defaults to empty list.
62        options (dict): Driver options as a key-value dictionary.
63          Defaults to `None`.
64
65    Example:
66
67        >>> ipam_config = docker.types.IPAMConfig(driver='default')
68        >>> network = client.create_network('network1', ipam=ipam_config)
69
70    """
71    def __init__(self, driver='default', pool_configs=None, options=None):
72        self.update({
73            'Driver': driver,
74            'Config': pool_configs or []
75        })
76
77        if options:
78            if not isinstance(options, dict):
79                raise TypeError('IPAMConfig options must be a dictionary')
80            self['Options'] = options
81
82
83class IPAMPool(dict):
84    """
85    Create an IPAM pool config dictionary to be added to the
86    ``pool_configs`` parameter of
87    :py:class:`~docker.types.IPAMConfig`.
88
89    Args:
90
91        subnet (str): Custom subnet for this IPAM pool using the CIDR
92            notation. Defaults to ``None``.
93        iprange (str): Custom IP range for endpoints in this IPAM pool using
94            the CIDR notation. Defaults to ``None``.
95        gateway (str): Custom IP address for the pool's gateway.
96        aux_addresses (dict): A dictionary of ``key -> ip_address``
97            relationships specifying auxiliary addresses that need to be
98            allocated by the IPAM driver.
99
100    Example:
101
102        >>> ipam_pool = docker.types.IPAMPool(
103            subnet='124.42.0.0/16',
104            iprange='124.42.0.0/24',
105            gateway='124.42.0.254',
106            aux_addresses={
107                'reserved1': '124.42.1.1'
108            }
109        )
110        >>> ipam_config = docker.types.IPAMConfig(
111                pool_configs=[ipam_pool])
112    """
113    def __init__(self, subnet=None, iprange=None, gateway=None,
114                 aux_addresses=None):
115        self.update({
116            'Subnet': subnet,
117            'IPRange': iprange,
118            'Gateway': gateway,
119            'AuxiliaryAddresses': aux_addresses
120        })
121