Răsfoiți Sursa

Allow user to specify custom network aliases

Signed-off-by: Joffrey F <[email protected]>
Joffrey F 9 ani în urmă
părinte
comite
2f7a77e954

+ 3 - 0
compose/config/config.py

@@ -30,6 +30,7 @@ from .types import ServiceLink
 from .types import VolumeFromSpec
 from .types import VolumeSpec
 from .validation import match_named_volumes
+from .validation import match_network_aliases
 from .validation import validate_against_fields_schema
 from .validation import validate_against_service_schema
 from .validation import validate_depends_on
@@ -535,6 +536,8 @@ def validate_service(service_config, service_names, version):
     validate_network_mode(service_config, service_names)
     validate_depends_on(service_config, service_names)
 
+    match_network_aliases(service_config.config)
+
     if not service_dict.get('image') and has_uppercase(service_name):
         raise ConfigurationError(
             "Service '{name}' contains uppercase characters which are not valid "

+ 10 - 3
compose/config/service_schema_v2.0.json

@@ -107,9 +107,16 @@
         "network_mode": {"type": "string"},
 
         "networks": {
-          "type": "array",
-          "items": {"type": "string"},
-          "uniqueItems": true
+          "$ref": "#/definitions/list_of_strings"
+        },
+        "network_aliases": {
+          "type": "object",
+          "patternProperties": {
+            "^[a-zA-Z0-9._-]+$": {
+              "$ref": "#/definitions/list_of_strings"
+            }
+          },
+          "additionalProperties": false
         },
 
         "pid": {"type": ["string", "null"]},

+ 13 - 0
compose/config/validation.py

@@ -91,6 +91,19 @@ def match_named_volumes(service_dict, project_volumes):
             )
 
 
+def match_network_aliases(service_dict):
+    networks = service_dict.get('networks', [])
+    aliased_networks = service_dict.get('network_aliases', {}).keys()
+    for n in aliased_networks:
+        if n not in networks:
+            raise ConfigurationError(
+                'Network "{0}" is referenced in network_aliases, but is not'
+                'declared in the networks list for service "{1}"'.format(
+                    n, service_dict.get('name')
+                )
+            )
+
+
 def validate_top_level_service_objects(filename, service_dicts):
     """Perform some high level validation of the service name and value.
 

+ 8 - 3
compose/network.py

@@ -15,7 +15,7 @@ log = logging.getLogger(__name__)
 
 class Network(object):
     def __init__(self, client, project, name, driver=None, driver_opts=None,
-                 ipam=None, external_name=None):
+                 ipam=None, external_name=None, aliases=None):
         self.client = client
         self.project = project
         self.name = name
@@ -23,6 +23,7 @@ class Network(object):
         self.driver_opts = driver_opts
         self.ipam = create_ipam_config_from_dict(ipam)
         self.external_name = external_name
+        self.aliases = aliases or []
 
     def ensure(self):
         if self.external_name:
@@ -166,14 +167,18 @@ def get_network_names_for_service(service_dict):
 
 
 def get_networks(service_dict, network_definitions):
-    networks = []
+    networks = {}
+    aliases = service_dict.get('network_aliases', {})
     for name in get_network_names_for_service(service_dict):
+        log.debug(name)
         network = network_definitions.get(name)
         if network:
-            networks.append(network.full_name)
+            log.debug(aliases)
+            networks[network.full_name] = aliases.get(name, [])
         else:
             raise ConfigurationError(
                 'Service "{}" uses an undefined network "{}"'
                 .format(service_dict['name'], name))
 
+    log.debug(networks)
     return networks

+ 2 - 2
compose/project.py

@@ -69,11 +69,11 @@ class Project(object):
             if use_networking:
                 service_networks = get_networks(service_dict, networks)
             else:
-                service_networks = []
+                service_networks = {}
 
             service_dict.pop('networks', None)
             links = project.get_links(service_dict)
-            network_mode = project.get_network_mode(service_dict, service_networks)
+            network_mode = project.get_network_mode(service_dict, service_networks.keys())
             volumes_from = get_volumes_from(project, service_dict)
 
             if config_data.version != V1:

+ 6 - 6
compose/service.py

@@ -123,7 +123,7 @@ class Service(object):
         self.links = links or []
         self.volumes_from = volumes_from or []
         self.network_mode = network_mode or NetworkMode(None)
-        self.networks = networks or []
+        self.networks = networks or {}
         self.options = options
 
     def containers(self, stopped=False, one_off=False, filters={}):
@@ -431,14 +431,14 @@ class Service(object):
     def connect_container_to_networks(self, container):
         connected_networks = container.get('NetworkSettings.Networks')
 
-        for network in self.networks:
+        for network, aliases in self.networks.items():
             if network in connected_networks:
                 self.client.disconnect_container_from_network(
                     container.id, network)
 
             self.client.connect_container_to_network(
                 container.id, network,
-                aliases=self._get_aliases(container),
+                aliases=list(self._get_aliases(container).union(aliases)),
                 links=self._get_links(False),
             )
 
@@ -472,7 +472,7 @@ class Service(object):
             'image_id': self.image()['Id'],
             'links': self.get_link_names(),
             'net': self.network_mode.id,
-            'networks': self.networks,
+            'networks': self.networks.keys(),
             'volumes_from': [
                 (v.source.name, v.mode)
                 for v in self.volumes_from if isinstance(v.source, Service)
@@ -513,9 +513,9 @@ class Service(object):
 
     def _get_aliases(self, container):
         if container.labels.get(LABEL_ONE_OFF) == "True":
-            return []
+            return set()
 
-        return [self.name, container.short_id]
+        return set([self.name, container.short_id])
 
     def _get_links(self, link_to_self):
         links = {}