Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions docker/api/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand All @@ -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 '
Expand Down Expand Up @@ -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)
17 changes: 11 additions & 6 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
57 changes: 55 additions & 2 deletions tests/integration/network_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/unit/network_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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})