mirror of
https://github.com/docker/compose.git
synced 2025-07-22 13:14:29 +02:00
Allow user to specify custom network aliases
Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
d78ea85301
commit
2f7a77e954
@ -30,6 +30,7 @@ from .types import ServiceLink
|
|||||||
from .types import VolumeFromSpec
|
from .types import VolumeFromSpec
|
||||||
from .types import VolumeSpec
|
from .types import VolumeSpec
|
||||||
from .validation import match_named_volumes
|
from .validation import match_named_volumes
|
||||||
|
from .validation import match_network_aliases
|
||||||
from .validation import validate_against_fields_schema
|
from .validation import validate_against_fields_schema
|
||||||
from .validation import validate_against_service_schema
|
from .validation import validate_against_service_schema
|
||||||
from .validation import validate_depends_on
|
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_network_mode(service_config, service_names)
|
||||||
validate_depends_on(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):
|
if not service_dict.get('image') and has_uppercase(service_name):
|
||||||
raise ConfigurationError(
|
raise ConfigurationError(
|
||||||
"Service '{name}' contains uppercase characters which are not valid "
|
"Service '{name}' contains uppercase characters which are not valid "
|
||||||
|
@ -107,9 +107,16 @@
|
|||||||
"network_mode": {"type": "string"},
|
"network_mode": {"type": "string"},
|
||||||
|
|
||||||
"networks": {
|
"networks": {
|
||||||
"type": "array",
|
"$ref": "#/definitions/list_of_strings"
|
||||||
"items": {"type": "string"},
|
},
|
||||||
"uniqueItems": true
|
"network_aliases": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
"^[a-zA-Z0-9._-]+$": {
|
||||||
|
"$ref": "#/definitions/list_of_strings"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"pid": {"type": ["string", "null"]},
|
"pid": {"type": ["string", "null"]},
|
||||||
|
@ -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):
|
def validate_top_level_service_objects(filename, service_dicts):
|
||||||
"""Perform some high level validation of the service name and value.
|
"""Perform some high level validation of the service name and value.
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class Network(object):
|
class Network(object):
|
||||||
def __init__(self, client, project, name, driver=None, driver_opts=None,
|
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.client = client
|
||||||
self.project = project
|
self.project = project
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -23,6 +23,7 @@ class Network(object):
|
|||||||
self.driver_opts = driver_opts
|
self.driver_opts = driver_opts
|
||||||
self.ipam = create_ipam_config_from_dict(ipam)
|
self.ipam = create_ipam_config_from_dict(ipam)
|
||||||
self.external_name = external_name
|
self.external_name = external_name
|
||||||
|
self.aliases = aliases or []
|
||||||
|
|
||||||
def ensure(self):
|
def ensure(self):
|
||||||
if self.external_name:
|
if self.external_name:
|
||||||
@ -166,14 +167,18 @@ def get_network_names_for_service(service_dict):
|
|||||||
|
|
||||||
|
|
||||||
def get_networks(service_dict, network_definitions):
|
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):
|
for name in get_network_names_for_service(service_dict):
|
||||||
|
log.debug(name)
|
||||||
network = network_definitions.get(name)
|
network = network_definitions.get(name)
|
||||||
if network:
|
if network:
|
||||||
networks.append(network.full_name)
|
log.debug(aliases)
|
||||||
|
networks[network.full_name] = aliases.get(name, [])
|
||||||
else:
|
else:
|
||||||
raise ConfigurationError(
|
raise ConfigurationError(
|
||||||
'Service "{}" uses an undefined network "{}"'
|
'Service "{}" uses an undefined network "{}"'
|
||||||
.format(service_dict['name'], name))
|
.format(service_dict['name'], name))
|
||||||
|
|
||||||
|
log.debug(networks)
|
||||||
return networks
|
return networks
|
||||||
|
@ -69,11 +69,11 @@ class Project(object):
|
|||||||
if use_networking:
|
if use_networking:
|
||||||
service_networks = get_networks(service_dict, networks)
|
service_networks = get_networks(service_dict, networks)
|
||||||
else:
|
else:
|
||||||
service_networks = []
|
service_networks = {}
|
||||||
|
|
||||||
service_dict.pop('networks', None)
|
service_dict.pop('networks', None)
|
||||||
links = project.get_links(service_dict)
|
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)
|
volumes_from = get_volumes_from(project, service_dict)
|
||||||
|
|
||||||
if config_data.version != V1:
|
if config_data.version != V1:
|
||||||
|
@ -123,7 +123,7 @@ class Service(object):
|
|||||||
self.links = links or []
|
self.links = links or []
|
||||||
self.volumes_from = volumes_from or []
|
self.volumes_from = volumes_from or []
|
||||||
self.network_mode = network_mode or NetworkMode(None)
|
self.network_mode = network_mode or NetworkMode(None)
|
||||||
self.networks = networks or []
|
self.networks = networks or {}
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
def containers(self, stopped=False, one_off=False, filters={}):
|
def containers(self, stopped=False, one_off=False, filters={}):
|
||||||
@ -431,14 +431,14 @@ class Service(object):
|
|||||||
def connect_container_to_networks(self, container):
|
def connect_container_to_networks(self, container):
|
||||||
connected_networks = container.get('NetworkSettings.Networks')
|
connected_networks = container.get('NetworkSettings.Networks')
|
||||||
|
|
||||||
for network in self.networks:
|
for network, aliases in self.networks.items():
|
||||||
if network in connected_networks:
|
if network in connected_networks:
|
||||||
self.client.disconnect_container_from_network(
|
self.client.disconnect_container_from_network(
|
||||||
container.id, network)
|
container.id, network)
|
||||||
|
|
||||||
self.client.connect_container_to_network(
|
self.client.connect_container_to_network(
|
||||||
container.id, network,
|
container.id, network,
|
||||||
aliases=self._get_aliases(container),
|
aliases=list(self._get_aliases(container).union(aliases)),
|
||||||
links=self._get_links(False),
|
links=self._get_links(False),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -472,7 +472,7 @@ class Service(object):
|
|||||||
'image_id': self.image()['Id'],
|
'image_id': self.image()['Id'],
|
||||||
'links': self.get_link_names(),
|
'links': self.get_link_names(),
|
||||||
'net': self.network_mode.id,
|
'net': self.network_mode.id,
|
||||||
'networks': self.networks,
|
'networks': self.networks.keys(),
|
||||||
'volumes_from': [
|
'volumes_from': [
|
||||||
(v.source.name, v.mode)
|
(v.source.name, v.mode)
|
||||||
for v in self.volumes_from if isinstance(v.source, Service)
|
for v in self.volumes_from if isinstance(v.source, Service)
|
||||||
@ -513,9 +513,9 @@ class Service(object):
|
|||||||
|
|
||||||
def _get_aliases(self, container):
|
def _get_aliases(self, container):
|
||||||
if container.labels.get(LABEL_ONE_OFF) == "True":
|
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):
|
def _get_links(self, link_to_self):
|
||||||
links = {}
|
links = {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user