diff --git a/docker/api/network.py b/docker/api/network.py index 34cd8987a1..0ee0dab6ea 100644 --- a/docker/api/network.py +++ b/docker/api/network.py @@ -22,7 +22,8 @@ def networks(self, names=None, ids=None): @minimum_version('1.21') def create_network(self, name, driver=None, options=None, ipam=None, - check_duplicate=None, internal=False): + check_duplicate=None, internal=False, labels=None, + enable_ipv6=False): if options is not None and not isinstance(options, dict): raise TypeError('options must be a dictionary') @@ -34,6 +35,22 @@ def create_network(self, name, driver=None, options=None, ipam=None, 'CheckDuplicate': check_duplicate } + if labels is not None: + if version_lt(self._version, '1.23'): + raise InvalidVersion( + 'network labels were introduced in API 1.23' + ) + if not isinstance(labels, dict): + raise TypeError('labels must be a dictionary') + data["Labels"] = labels + + if enable_ipv6: + if version_lt(self._version, '1.23'): + raise InvalidVersion( + 'enable_ipv6 was introduced in API 1.23' + ) + data['EnableIPv6'] = True + if internal: if version_lt(self._version, '1.22'): raise InvalidVersion('Internal networks are not ' @@ -76,8 +93,15 @@ def connect_container_to_network(self, container, net_id, @check_resource @minimum_version('1.21') - def disconnect_container_from_network(self, container, net_id): - data = {"container": container} + def disconnect_container_from_network(self, container, net_id, + force=False): + data = {"Container": container} + if force: + if version_lt(self._version, '1.22'): + raise InvalidVersion( + 'Forced disconnect was introduced in API 1.22' + ) + data['Force'] = force url = self._url("/networks/{0}/disconnect", net_id) res = self._post_json(url, data=data) self._raise_for_status(res) diff --git a/docs/api.md b/docs/api.md index 895d7d4574..1699344a66 100644 --- a/docs/api.md +++ b/docs/api.md @@ -283,22 +283,25 @@ The utility can be used as follows: ```python >>> import docker.utils >>> my_envs = docker.utils.parse_env_file('/path/to/file') ->>> docker.utils.create_container_config('1.18', '_mongodb', 'foobar', environment=my_envs) +>>> client.create_container('myimage', 'command', environment=my_envs) ``` -You can now use this with 'environment' for `create_container`. - - ## create_network -Create a network, similar to the `docker network create` command. +Create a network, similar to the `docker network create` command. See the +[networks documentation](networks.md) for details. **Params**: * name (str): Name of the network * driver (str): Name of the driver used to create the network - * options (dict): Driver options as a key-value dictionary +* ipam (dict): Optional custom IP scheme for the network +* check_duplicate (bool): Request daemon to check for networks with same name. + Default: `True`. +* internal (bool): Restrict external access to the network. Default `False`. +* labels (dict): Map of labels to set on the network. Default `None`. +* enable_ipv6 (bool): Enable IPv6 on the network. Default `False`. **Returns** (dict): The created network reference object @@ -352,6 +355,8 @@ Inspect changes on a container's filesystem. * container (str): container-id/name to be disconnected from a network * net_id (str): network id +* force (bool): Force the container to disconnect from a network. + Default: `False` ## events diff --git a/tests/integration/network_test.py b/tests/integration/network_test.py index 27e1b14dec..6726db4b49 100644 --- a/tests/integration/network_test.py +++ b/tests/integration/network_test.py @@ -115,7 +115,8 @@ def test_connect_and_disconnect_container(self): network_data = self.client.inspect_network(net_id) self.assertEqual( list(network_data['Containers'].keys()), - [container['Id']]) + [container['Id']] + ) with pytest.raises(docker.errors.APIError): self.client.connect_container_to_network(container, net_id) @@ -127,6 +128,33 @@ def test_connect_and_disconnect_container(self): with pytest.raises(docker.errors.APIError): self.client.disconnect_container_from_network(container, net_id) + @requires_api_version('1.22') + def test_connect_and_force_disconnect_container(self): + net_name, net_id = self.create_network() + + container = self.client.create_container('busybox', 'top') + self.tmp_containers.append(container) + self.client.start(container) + + network_data = self.client.inspect_network(net_id) + self.assertFalse(network_data.get('Containers')) + + self.client.connect_container_to_network(container, net_id) + network_data = self.client.inspect_network(net_id) + self.assertEqual( + list(network_data['Containers'].keys()), + [container['Id']] + ) + + self.client.disconnect_container_from_network(container, net_id, True) + network_data = self.client.inspect_network(net_id) + self.assertFalse(network_data.get('Containers')) + + with pytest.raises(docker.errors.APIError): + self.client.disconnect_container_from_network( + container, net_id, force=True + ) + @requires_api_version('1.22') def test_connect_with_aliases(self): net_name, net_id = self.create_network() @@ -300,7 +328,8 @@ def test_create_check_duplicate(self): net_name, net_id = self.create_network() with self.assertRaises(docker.errors.APIError): self.client.create_network(net_name, check_duplicate=True) - self.client.create_network(net_name, check_duplicate=False) + net_id = self.client.create_network(net_name, check_duplicate=False) + self.tmp_networks.append(net_id['Id']) @requires_api_version('1.22') def test_connect_with_links(self): @@ -387,3 +416,27 @@ def test_create_internal_networks(self): _, net_id = self.create_network(internal=True) net = self.client.inspect_network(net_id) assert net['Internal'] is True + + @requires_api_version('1.23') + def test_create_network_with_labels(self): + _, net_id = self.create_network(labels={ + 'com.docker.py.test': 'label' + }) + + net = self.client.inspect_network(net_id) + assert 'Labels' in net + assert len(net['Labels']) == 1 + assert net['Labels'] == { + 'com.docker.py.test': 'label' + } + + @requires_api_version('1.23') + def test_create_network_with_labels_wrong_type(self): + with pytest.raises(TypeError): + self.create_network(labels=['com.docker.py.test=label', ]) + + @requires_api_version('1.23') + def test_create_network_ipv6_enabled(self): + _, net_id = self.create_network(enable_ipv6=True) + net = self.client.inspect_network(net_id) + assert net['EnableIPv6'] is True diff --git a/tests/unit/network_test.py b/tests/unit/network_test.py index 5bba9db230..2521688de8 100644 --- a/tests/unit/network_test.py +++ b/tests/unit/network_test.py @@ -184,4 +184,4 @@ def test_disconnect_container_from_network(self): self.assertEqual( json.loads(post.call_args[1]['data']), - {'container': container_id}) + {'Container': container_id})