| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | 
							- from __future__ import absolute_import
 
- from __future__ import unicode_literals
 
- import logging
 
- from docker.errors import NotFound
 
- from docker.utils import create_ipam_config
 
- from docker.utils import create_ipam_pool
 
- from .config import ConfigurationError
 
- log = logging.getLogger(__name__)
 
- class Network(object):
 
-     def __init__(self, client, project, name, driver=None, driver_opts=None,
 
-                  ipam=None, external_name=None):
 
-         self.client = client
 
-         self.project = project
 
-         self.name = name
 
-         self.driver = driver
 
-         self.driver_opts = driver_opts
 
-         self.ipam = create_ipam_config_from_dict(ipam)
 
-         self.external_name = external_name
 
-     def ensure(self):
 
-         if self.external_name:
 
-             try:
 
-                 self.inspect()
 
-                 log.debug(
 
-                     'Network {0} declared as external. No new '
 
-                     'network will be created.'.format(self.name)
 
-                 )
 
-             except NotFound:
 
-                 raise ConfigurationError(
 
-                     'Network {name} declared as external, but could'
 
-                     ' not be found. Please create the network manually'
 
-                     ' using `{command} {name}` and try again.'.format(
 
-                         name=self.external_name,
 
-                         command='docker network create'
 
-                     )
 
-                 )
 
-             return
 
-         try:
 
-             data = self.inspect()
 
-             if self.driver and data['Driver'] != self.driver:
 
-                 raise ConfigurationError(
 
-                     'Network "{}" needs to be recreated - driver has changed'
 
-                     .format(self.full_name))
 
-             if data['Options'] != (self.driver_opts or {}):
 
-                 raise ConfigurationError(
 
-                     'Network "{}" needs to be recreated - options have changed'
 
-                     .format(self.full_name))
 
-         except NotFound:
 
-             driver_name = 'the default driver'
 
-             if self.driver:
 
-                 driver_name = 'driver "{}"'.format(self.driver)
 
-             log.info(
 
-                 'Creating network "{}" with {}'
 
-                 .format(self.full_name, driver_name)
 
-             )
 
-             self.client.create_network(
 
-                 name=self.full_name,
 
-                 driver=self.driver,
 
-                 options=self.driver_opts,
 
-                 ipam=self.ipam,
 
-             )
 
-     def remove(self):
 
-         if self.external_name:
 
-             log.info("Network %s is external, skipping", self.full_name)
 
-             return
 
-         log.info("Removing network {}".format(self.full_name))
 
-         self.client.remove_network(self.full_name)
 
-     def inspect(self):
 
-         return self.client.inspect_network(self.full_name)
 
-     @property
 
-     def full_name(self):
 
-         if self.external_name:
 
-             return self.external_name
 
-         return '{0}_{1}'.format(self.project, self.name)
 
- def create_ipam_config_from_dict(ipam_dict):
 
-     if not ipam_dict:
 
-         return None
 
-     return create_ipam_config(
 
-         driver=ipam_dict.get('driver'),
 
-         pool_configs=[
 
-             create_ipam_pool(
 
-                 subnet=config.get('subnet'),
 
-                 iprange=config.get('ip_range'),
 
-                 gateway=config.get('gateway'),
 
-                 aux_addresses=config.get('aux_addresses'),
 
-             )
 
-             for config in ipam_dict.get('config', [])
 
-         ],
 
-     )
 
- def build_networks(name, config_data, client):
 
-     network_config = config_data.networks or {}
 
-     networks = {
 
-         network_name: Network(
 
-             client=client, project=name, name=network_name,
 
-             driver=data.get('driver'),
 
-             driver_opts=data.get('driver_opts'),
 
-             ipam=data.get('ipam'),
 
-             external_name=data.get('external_name'),
 
-         )
 
-         for network_name, data in network_config.items()
 
-     }
 
-     if 'default' not in networks:
 
-         networks['default'] = Network(client, name, 'default')
 
-     return networks
 
- class ProjectNetworks(object):
 
-     def __init__(self, networks, use_networking):
 
-         self.networks = networks or {}
 
-         self.use_networking = use_networking
 
-     @classmethod
 
-     def from_services(cls, services, networks, use_networking):
 
-         service_networks = {
 
-             network: networks.get(network)
 
-             for service in services
 
-             for network in get_network_names_for_service(service)
 
-         }
 
-         unused = set(networks) - set(service_networks) - {'default'}
 
-         if unused:
 
-             log.warn(
 
-                 "Some networks were defined but are not used by any service: "
 
-                 "{}".format(", ".join(unused)))
 
-         return cls(service_networks, use_networking)
 
-     def remove(self):
 
-         if not self.use_networking:
 
-             return
 
-         for network in self.networks.values():
 
-             try:
 
-                 network.remove()
 
-             except NotFound:
 
-                 log.warn("Network %s not found.", network.full_name)
 
-     def initialize(self):
 
-         if not self.use_networking:
 
-             return
 
-         for network in self.networks.values():
 
-             network.ensure()
 
- def get_network_defs_for_service(service_dict):
 
-     if 'network_mode' in service_dict:
 
-         return {}
 
-     networks = service_dict.get('networks', {'default': None})
 
-     return dict(
 
-         (net, (config or {}))
 
-         for net, config in networks.items()
 
-     )
 
- def get_network_names_for_service(service_dict):
 
-     return get_network_defs_for_service(service_dict).keys()
 
- def get_networks(service_dict, network_definitions):
 
-     networks = {}
 
-     for name, netdef in get_network_defs_for_service(service_dict).items():
 
-         network = network_definitions.get(name)
 
-         if network:
 
-             networks[network.full_name] = netdef
 
-         else:
 
-             raise ConfigurationError(
 
-                 'Service "{}" uses an undefined network "{}"'
 
-                 .format(service_dict['name'], name))
 
-     return networks
 
 
  |