diff options
author | Aanand Prasad <aanand.prasad@gmail.com> | 2016-01-14 16:33:26 +0000 |
---|---|---|
committer | Aanand Prasad <aanand.prasad@gmail.com> | 2016-01-14 18:19:35 +0000 |
commit | d00a5bb08671dc43c4db1fb8dc2ea90b68bbc1d9 (patch) | |
tree | 85c95101938ddfdb5fe38d8389d0ea98823bf808 | |
parent | e2878cbcc3a7eef99917adc1be252800b0e41ece (diff) | |
download | docker-py-d00a5bb08671dc43c4db1fb8dc2ea90b68bbc1d9.tar.gz |
Implement support for network-scoped aliases
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
-rw-r--r-- | docker/api/container.py | 11 | ||||
-rw-r--r-- | docker/api/network.py | 9 | ||||
-rw-r--r-- | docker/utils/__init__.py | 2 | ||||
-rw-r--r-- | docker/utils/utils.py | 23 | ||||
-rw-r--r-- | tests/integration/network_test.py | 46 | ||||
-rw-r--r-- | tests/unit/container_test.py | 33 | ||||
-rw-r--r-- | tests/unit/network_test.py | 12 | ||||
-rw-r--r-- | tests/unit/utils_test.py | 10 |
8 files changed, 136 insertions, 10 deletions
diff --git a/docker/api/container.py b/docker/api/container.py index 78cd216..ceac173 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -4,6 +4,7 @@ from datetime import datetime from .. import errors from .. import utils +from ..utils.utils import create_networking_config, create_endpoint_config class ContainerApiMixin(object): @@ -98,7 +99,7 @@ class ContainerApiMixin(object): cpu_shares=None, working_dir=None, domainname=None, memswap_limit=None, cpuset=None, host_config=None, mac_address=None, labels=None, volume_driver=None, - stop_signal=None): + stop_signal=None, networking_config=None): if isinstance(volumes, six.string_types): volumes = [volumes, ] @@ -113,7 +114,7 @@ class ContainerApiMixin(object): tty, mem_limit, ports, environment, dns, volumes, volumes_from, network_disabled, entrypoint, cpu_shares, working_dir, domainname, memswap_limit, cpuset, host_config, mac_address, labels, - volume_driver, stop_signal + volume_driver, stop_signal, networking_config, ) return self.create_container_from_config(config, name) @@ -139,6 +140,12 @@ class ContainerApiMixin(object): kwargs['version'] = self._version return utils.create_host_config(*args, **kwargs) + def create_networking_config(self, *args, **kwargs): + return create_networking_config(*args, **kwargs) + + def create_endpoint_config(self, *args, **kwargs): + return create_endpoint_config(self._version, *args, **kwargs) + @utils.check_resource def diff(self, container): return self._result( diff --git a/docker/api/network.py b/docker/api/network.py index ce3f511..37b409c 100644 --- a/docker/api/network.py +++ b/docker/api/network.py @@ -47,8 +47,13 @@ class NetworkApiMixin(object): @check_resource @minimum_version('1.21') - def connect_container_to_network(self, container, net_id): - data = {"container": container} + def connect_container_to_network(self, container, net_id, aliases=None): + data = { + "Container": container, + "EndpointConfig": { + "Aliases": aliases, + }, + } url = self._url("/networks/{0}/connect", net_id) self._post_json(url, data=data) diff --git a/docker/utils/__init__.py b/docker/utils/__init__.py index 2f308bf..70c0e9d 100644 --- a/docker/utils/__init__.py +++ b/docker/utils/__init__.py @@ -4,7 +4,7 @@ from .utils import ( kwargs_from_env, convert_filters, datetime_to_timestamp, create_host_config, create_container_config, parse_bytes, ping_registry, parse_env_file, version_lt, version_gte, decode_json_header, split_command, - create_ipam_config, create_ipam_pool + create_ipam_config, create_ipam_pool, ) # flake8: noqa from .types import Ulimit, LogConfig # flake8: noqa diff --git a/docker/utils/utils.py b/docker/utils/utils.py index e7b6616..5a23201 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -715,6 +715,26 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None, return host_config +def create_networking_config(endpoints_config=None): + networking_config = {} + + if endpoints_config: + networking_config["EndpointsConfig"] = endpoints_config + + return networking_config + + +def create_endpoint_config(version, aliases=None): + endpoint_config = {} + + if aliases: + if version_lt(version, '1.22'): + raise host_config_version_error('endpoint_config.aliases', '1.22') + endpoint_config["Aliases"] = aliases + + return endpoint_config + + def parse_env_file(env_file): """ Reads a line-separated environment file. @@ -752,7 +772,7 @@ def create_container_config( dns=None, volumes=None, volumes_from=None, network_disabled=False, entrypoint=None, cpu_shares=None, working_dir=None, domainname=None, memswap_limit=None, cpuset=None, host_config=None, mac_address=None, - labels=None, volume_driver=None, stop_signal=None + labels=None, volume_driver=None, stop_signal=None, networking_config=None, ): if isinstance(command, six.string_types): command = split_command(command) @@ -878,6 +898,7 @@ def create_container_config( 'WorkingDir': working_dir, 'MemorySwap': memswap_limit, 'HostConfig': host_config, + 'NetworkingConfig': networking_config, 'MacAddress': mac_address, 'Labels': labels, 'VolumeDriver': volume_driver, diff --git a/tests/integration/network_test.py b/tests/integration/network_test.py index a99f555..a06e0d5 100644 --- a/tests/integration/network_test.py +++ b/tests/integration/network_test.py @@ -7,7 +7,6 @@ from .. import helpers from ..base import requires_api_version -@requires_api_version('1.21') class TestNetworks(helpers.BaseTestCase): def create_network(self, *args, **kwargs): net_name = u'dockerpy{}'.format(random.getrandbits(24))[:14] @@ -15,6 +14,7 @@ class TestNetworks(helpers.BaseTestCase): self.tmp_networks.append(net_id) return (net_name, net_id) + @requires_api_version('1.21') def test_list_networks(self): networks = self.client.networks() initial_size = len(networks) @@ -31,6 +31,7 @@ class TestNetworks(helpers.BaseTestCase): networks_by_partial_id = self.client.networks(ids=[net_id[:8]]) self.assertEqual([n['Id'] for n in networks_by_partial_id], [net_id]) + @requires_api_version('1.21') def test_inspect_network(self): net_name, net_id = self.create_network() @@ -41,12 +42,14 @@ class TestNetworks(helpers.BaseTestCase): self.assertEqual(net['Scope'], 'local') self.assertEqual(net['IPAM']['Driver'], 'default') + @requires_api_version('1.21') def test_create_network_with_host_driver_fails(self): net_name = 'dockerpy{}'.format(random.getrandbits(24))[:14] with pytest.raises(docker.errors.APIError): self.client.create_network(net_name, driver='host') + @requires_api_version('1.21') def test_remove_network(self): initial_size = len(self.client.networks()) @@ -56,6 +59,7 @@ class TestNetworks(helpers.BaseTestCase): self.client.remove_network(net_id) self.assertEqual(len(self.client.networks()), initial_size) + @requires_api_version('1.21') def test_connect_and_disconnect_container(self): net_name, net_id = self.create_network() @@ -76,6 +80,22 @@ class TestNetworks(helpers.BaseTestCase): network_data = self.client.inspect_network(net_id) self.assertFalse(network_data.get('Containers')) + @requires_api_version('1.22') + def test_connect_with_aliases(self): + net_name, net_id = self.create_network() + + container = self.client.create_container('busybox', 'top') + self.tmp_containers.append(container) + self.client.start(container) + + self.client.connect_container_to_network( + container, net_id, aliases=['foo', 'bar']) + container_data = self.client.inspect_container(container) + self.assertEqual( + container_data['NetworkSettings']['Networks'][net_name]['Aliases'], + ['foo', 'bar']) + + @requires_api_version('1.21') def test_connect_on_container_create(self): net_name, net_id = self.create_network() @@ -95,3 +115,27 @@ class TestNetworks(helpers.BaseTestCase): self.client.disconnect_container_from_network(container, net_id) network_data = self.client.inspect_network(net_id) self.assertFalse(network_data.get('Containers')) + + @requires_api_version('1.22') + def test_create_with_aliases(self): + net_name, net_id = self.create_network() + + container = self.client.create_container( + image='busybox', + command='top', + host_config=self.client.create_host_config( + network_mode=net_name, + ), + networking_config=self.client.create_networking_config({ + net_name: self.client.create_endpoint_config( + aliases=['foo', 'bar'], + ), + }), + ) + self.tmp_containers.append(container) + self.client.start(container) + + container_data = self.client.inspect_container(container) + self.assertEqual( + container_data['NetworkSettings']['Networks'][net_name]['Aliases'], + ['foo', 'bar']) diff --git a/tests/unit/container_test.py b/tests/unit/container_test.py index e1dda3e..c2b2573 100644 --- a/tests/unit/container_test.py +++ b/tests/unit/container_test.py @@ -7,6 +7,7 @@ import pytest import six from . import fake_api +from ..base import requires_api_version from .api_test import ( DockerClientTest, url_prefix, fake_request, DEFAULT_TIMEOUT_SECONDS, fake_inspect_container @@ -983,6 +984,38 @@ class CreateContainerTest(DockerClientTest): self.assertEqual(args[1]['headers'], {'Content-Type': 'application/json'}) + @requires_api_version('1.22') + def test_create_container_with_aliases(self): + self.client.create_container( + 'busybox', 'ls', + host_config=self.client.create_host_config( + network_mode='some-network', + ), + networking_config=self.client.create_networking_config({ + 'some-network': self.client.create_endpoint_config( + aliases=['foo', 'bar'], + ), + }), + ) + + args = fake_request.call_args + self.assertEqual(json.loads(args[1]['data']), + json.loads(''' + {"Tty": false, "Image": "busybox", + "Cmd": ["ls"], "AttachStdin": false, + "AttachStderr": true, + "AttachStdout": true, "OpenStdin": false, + "StdinOnce": false, + "NetworkDisabled": false, + "HostConfig": { + "NetworkMode": "some-network" + }, + "NetworkingConfig": { + "EndpointsConfig": { + "some-network": {"Aliases": ["foo", "bar"]} + } + }}''')) + class ContainerTest(DockerClientTest): def test_list_containers(self): diff --git a/tests/unit/network_test.py b/tests/unit/network_test.py index 7d2cc9a..fef3df3 100644 --- a/tests/unit/network_test.py +++ b/tests/unit/network_test.py @@ -147,7 +147,10 @@ class NetworkTest(DockerClientTest): with mock.patch('docker.Client.post', post): self.client.connect_container_to_network( - {'Id': container_id}, network_id) + {'Id': container_id}, + network_id, + aliases=['foo', 'bar'], + ) self.assertEqual( post.call_args[0][0], @@ -155,7 +158,12 @@ class NetworkTest(DockerClientTest): self.assertEqual( json.loads(post.call_args[1]['data']), - {'container': container_id}) + { + 'Container': container_id, + 'EndpointConfig': { + 'Aliases': ['foo', 'bar'], + }, + }) @base.requires_api_version('1.21') def test_disconnect_container_from_network(self): diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index d436de2..1ea13a9 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -18,8 +18,9 @@ from docker.utils import ( parse_repository_tag, parse_host, convert_filters, kwargs_from_env, create_host_config, Ulimit, LogConfig, parse_bytes, parse_env_file, exclude_paths, convert_volume_binds, decode_json_header, tar, - split_command, create_ipam_config, create_ipam_pool + split_command, create_ipam_config, create_ipam_pool, ) +from docker.utils.utils import create_endpoint_config from docker.utils.ports import build_port_bindings, split_port from .. import base @@ -69,6 +70,13 @@ class HostConfigTest(base.BaseTestCase): InvalidVersion, lambda: create_host_config(version='1.18.3', oom_kill_disable=True)) + def test_create_endpoint_config_with_aliases(self): + config = create_endpoint_config(version='1.22', aliases=['foo', 'bar']) + assert config == {'Aliases': ['foo', 'bar']} + + with pytest.raises(InvalidVersion): + create_endpoint_config(version='1.21', aliases=['foo', 'bar']) + class UlimitTest(base.BaseTestCase): def test_create_host_config_dict_ulimit(self): |