mirror of https://github.com/docker/docker-py.git
Implement support for network-scoped aliases
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
This commit is contained in:
parent
e2878cbcc3
commit
d00a5bb086
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue