Skip to content

Commit e011ff5

Browse files
committed
More sanity checking of EndpointConfig params
Signed-off-by: Mariano Scazzariello <marianoscazzariello@gmail.com>
1 parent 7870503 commit e011ff5

File tree

3 files changed

+157
-4
lines changed

3 files changed

+157
-4
lines changed

docker/models/containers.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ def run(self, image, command=None, stdout=True, stderr=False,
703703
(IPv4/IPv6) addresses.
704704
- ``driver_opt`` (dict): A dictionary of options to provide to
705705
the network driver. Defaults to ``None``.
706+
- ``mac_address`` (str): MAC Address to assign to the network
707+
interface. Defaults to ``None``. Requires API >= 1.25.
706708
707709
Used in conjuction with ``network``.
708710
Incompatible with ``network_mode``.
@@ -1122,6 +1124,17 @@ def prune(self, filters=None):
11221124
]
11231125

11241126

1127+
NETWORKING_CONFIG_ARGS = [
1128+
'aliases',
1129+
'links',
1130+
'ipv4_address',
1131+
'ipv6_address',
1132+
'link_local_ips',
1133+
'driver_opt',
1134+
'mac_address'
1135+
]
1136+
1137+
11251138
def _create_container_args(kwargs):
11261139
"""
11271140
Convert arguments to create() to arguments to create_container().
@@ -1148,10 +1161,18 @@ def _create_container_args(kwargs):
11481161
network = kwargs.pop('network', None)
11491162
network_config = kwargs.pop('network_config', None)
11501163
if network:
1151-
endpoint_config = EndpointConfig(
1152-
host_config_kwargs['version'],
1153-
**network_config
1154-
) if network_config else None
1164+
endpoint_config = None
1165+
1166+
if network_config:
1167+
clean_endpoint_args = {}
1168+
for arg_name in NETWORKING_CONFIG_ARGS:
1169+
if arg_name in network_config:
1170+
clean_endpoint_args[arg_name] = network_config[arg_name]
1171+
1172+
if clean_endpoint_args:
1173+
endpoint_config = EndpointConfig(
1174+
host_config_kwargs['version'], **clean_endpoint_args
1175+
)
11551176

11561177
create_kwargs['networking_config'] = NetworkingConfig(
11571178
{network: endpoint_config}

tests/integration/models_containers_test.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,63 @@ def test_run_with_network(self):
104104
assert 'Networks' in attrs['NetworkSettings']
105105
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
106106

107+
def test_run_with_network_config(self):
108+
net_name = random_name()
109+
client = docker.from_env(version=TEST_API_VERSION)
110+
client.networks.create(net_name)
111+
self.tmp_networks.append(net_name)
112+
113+
test_aliases = ['hello']
114+
test_driver_opt = {'key1': 'a'}
115+
116+
container = client.containers.run(
117+
'alpine', 'echo hello world', network=net_name,
118+
network_config={'aliases': test_aliases,
119+
'driver_opt': test_driver_opt},
120+
detach=True
121+
)
122+
self.tmp_containers.append(container.id)
123+
124+
attrs = container.attrs
125+
126+
assert 'NetworkSettings' in attrs
127+
assert 'Networks' in attrs['NetworkSettings']
128+
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
129+
assert attrs['NetworkSettings']['Networks'][net_name]['Aliases'] == \
130+
test_aliases
131+
assert attrs['NetworkSettings']['Networks'][net_name]['DriverOpts'] \
132+
== test_driver_opt
133+
134+
def test_run_with_network_config_undeclared_params(self):
135+
net_name = random_name()
136+
client = docker.from_env(version=TEST_API_VERSION)
137+
client.networks.create(net_name)
138+
self.tmp_networks.append(net_name)
139+
140+
test_aliases = ['hello']
141+
test_driver_opt = {'key1': 'a'}
142+
143+
container = client.containers.run(
144+
'alpine', 'echo hello world', network=net_name,
145+
network_config={'aliases': test_aliases,
146+
'driver_opt': test_driver_opt,
147+
'undeclared_param': 'random_value'},
148+
detach=True
149+
)
150+
self.tmp_containers.append(container.id)
151+
152+
attrs = container.attrs
153+
154+
assert 'NetworkSettings' in attrs
155+
assert 'Networks' in attrs['NetworkSettings']
156+
assert list(attrs['NetworkSettings']['Networks'].keys()) == [net_name]
157+
assert attrs['NetworkSettings']['Networks'][net_name]['Aliases'] == \
158+
test_aliases
159+
assert attrs['NetworkSettings']['Networks'][net_name]['DriverOpts'] \
160+
== test_driver_opt
161+
assert 'undeclared_param' not in \
162+
attrs['NetworkSettings']['Networks'][net_name]
163+
107164
def test_run_with_none_driver(self):
108165
client = docker.from_env(version=TEST_API_VERSION)
109166

tests/unit/models_containers_test.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,44 @@ def test_run_network_config(self):
390390
host_config={'NetworkMode': 'foo'}
391391
)
392392

393+
def test_run_network_config_undeclared_params(self):
394+
client = make_fake_client()
395+
396+
client.containers.run(
397+
image='alpine',
398+
network='foo',
399+
network_config={'aliases': ['test'],
400+
'driver_opt': {'key1': 'a'},
401+
'undeclared_param': 'random_value'}
402+
)
403+
404+
client.api.create_container.assert_called_with(
405+
detach=False,
406+
image='alpine',
407+
command=None,
408+
networking_config={'EndpointsConfig': {
409+
'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
410+
},
411+
host_config={'NetworkMode': 'foo'}
412+
)
413+
414+
def test_run_network_config_only_undeclared_params(self):
415+
client = make_fake_client()
416+
417+
client.containers.run(
418+
image='alpine',
419+
network='foo',
420+
network_config={'undeclared_param': 'random_value'}
421+
)
422+
423+
client.api.create_container.assert_called_with(
424+
detach=False,
425+
image='alpine',
426+
command=None,
427+
networking_config={'foo': None},
428+
host_config={'NetworkMode': 'foo'}
429+
)
430+
393431
def test_create(self):
394432
client = make_fake_client()
395433
container = client.containers.create(
@@ -467,6 +505,43 @@ def test_create_network_config(self):
467505
host_config={'NetworkMode': 'foo'}
468506
)
469507

508+
def test_create_network_config_undeclared_params(self):
509+
client = make_fake_client()
510+
511+
client.containers.create(
512+
image='alpine',
513+
network='foo',
514+
network_config={'aliases': ['test'],
515+
'driver_opt': {'key1': 'a'},
516+
'undeclared_param': 'random_value'}
517+
)
518+
519+
client.api.create_container.assert_called_with(
520+
image='alpine',
521+
command=None,
522+
networking_config={'EndpointsConfig': {
523+
'foo': {'Aliases': ['test'], 'DriverOpts': {'key1': 'a'}}}
524+
},
525+
host_config={'NetworkMode': 'foo'}
526+
)
527+
528+
def test_create_network_config_only_undeclared_params(self):
529+
client = make_fake_client()
530+
531+
client.containers.create(
532+
image='alpine',
533+
network='foo',
534+
network_config={'undeclared_param': 'random_value'}
535+
)
536+
537+
client.api.create_container.assert_called_with(
538+
image='alpine',
539+
command=None,
540+
networking_config={'foo': None},
541+
host_config={'NetworkMode': 'foo'}
542+
)
543+
544+
470545
def test_get(self):
471546
client = make_fake_client()
472547
container = client.containers.get(FAKE_CONTAINER_ID)

0 commit comments

Comments
 (0)