docker_swarm_service: Allow passing dicts in networks (#58961)
* Add support for passing networks as dicts * Add function to compare a list of different objects * Handle comparing falsy values to missing values * Pass docker versions to Service * Move can_update_networks to Service class * Pass Networks in TaskTemplate when supported * Remove weird __str__ * Add networks integration tests * Add unit tests * Add example * Add changelog fragment * Make sure that network options are clean Co-Authored-By: Felix Fontein <felix@fontein.de> * Set networks elements as raw in arg spec Co-Authored-By: Felix Fontein <felix@fontein.de> * Fix wrong variable naming * Check for network options that are not valid * Only check for None options * Validate that aliases is a list
This commit is contained in:
parent
aaaa4f1809
commit
13364fc530
5 changed files with 701 additions and 236 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- "docker_swarm_service - Support passing dictionaries in ``networks`` to allow setting ``aliases`` and ``options``."
|
|
@ -358,7 +358,9 @@ options:
|
|||
required: yes
|
||||
networks:
|
||||
description:
|
||||
- List of the service networks names.
|
||||
- List of the service networks names or dictionaries.
|
||||
- When passed dictionaries valid sub-options are C(name) which is required and
|
||||
C(aliases) and C(options).
|
||||
- Prior to API version 1.29, updating and removing networks is not supported.
|
||||
If changes are made the service will then be removed and recreated.
|
||||
- Corresponds to the C(--network) option of C(docker service create).
|
||||
|
@ -997,6 +999,17 @@ EXAMPLES = '''
|
|||
networks:
|
||||
- mynetwork
|
||||
|
||||
- name: Set networks as a dictionary
|
||||
docker_swarm_service:
|
||||
name: myservice
|
||||
image: alpine:edge
|
||||
networks:
|
||||
- name: "mynetwork"
|
||||
aliases:
|
||||
- "mynetwork_alias"
|
||||
options:
|
||||
foo: bar
|
||||
|
||||
- name: Set secrets
|
||||
docker_swarm_service:
|
||||
name: myservice
|
||||
|
@ -1048,6 +1061,7 @@ from ansible.module_utils.docker.common import (
|
|||
DockerBaseClass,
|
||||
convert_duration_to_nanosecond,
|
||||
parse_healthcheck,
|
||||
clean_dict_booleans_for_docker_api,
|
||||
RequestException,
|
||||
)
|
||||
|
||||
|
@ -1116,6 +1130,58 @@ def get_docker_environment(env, env_files):
|
|||
return sorted(env_list)
|
||||
|
||||
|
||||
def get_docker_networks(networks, network_ids):
|
||||
"""
|
||||
Validate a list of network names or a list of network dictionaries.
|
||||
Network names will be resolved to ids by using the network_ids mapping.
|
||||
"""
|
||||
if networks is None:
|
||||
return None
|
||||
parsed_networks = []
|
||||
for network in networks:
|
||||
if isinstance(network, string_types):
|
||||
parsed_network = {'name': network}
|
||||
elif isinstance(network, dict):
|
||||
if 'name' not in network:
|
||||
raise TypeError(
|
||||
'"name" is required when networks are passed as dictionaries.'
|
||||
)
|
||||
name = network.pop('name')
|
||||
parsed_network = {'name': name}
|
||||
aliases = network.pop('aliases', None)
|
||||
if aliases is not None:
|
||||
if not isinstance(aliases, list):
|
||||
raise TypeError('"aliases" network option is only allowed as a list')
|
||||
if not all(
|
||||
isinstance(alias, string_types) for alias in aliases
|
||||
):
|
||||
raise TypeError('Only strings are allowed as network aliases.')
|
||||
parsed_network['aliases'] = aliases
|
||||
options = network.pop('options', None)
|
||||
if options is not None:
|
||||
if not isinstance(options, dict):
|
||||
raise TypeError('Only dict is allowed as network options.')
|
||||
parsed_network['options'] = clean_dict_booleans_for_docker_api(options)
|
||||
# Check if any invalid keys left
|
||||
if network:
|
||||
invalid_keys = ', '.join(network.keys())
|
||||
raise TypeError(
|
||||
'%s are not valid keys for the networks option' % invalid_keys
|
||||
)
|
||||
|
||||
else:
|
||||
raise TypeError(
|
||||
'Only a list of strings or dictionaries are allowed to be passed as networks.'
|
||||
)
|
||||
network_name = parsed_network.pop('name')
|
||||
try:
|
||||
parsed_network['id'] = network_ids[network_name]
|
||||
except KeyError as e:
|
||||
raise ValueError('Could not find a network named: %s.' % e)
|
||||
parsed_networks.append(parsed_network)
|
||||
return parsed_networks or []
|
||||
|
||||
|
||||
def get_nanoseconds_from_raw_option(name, value):
|
||||
if value is None:
|
||||
return None
|
||||
|
@ -1154,14 +1220,17 @@ def has_dict_changed(new_dict, old_dict):
|
|||
if value is not None
|
||||
)
|
||||
for option, value in defined_options.items():
|
||||
if value != old_dict.get(option):
|
||||
old_value = old_dict.get(option)
|
||||
if not value and not old_value:
|
||||
continue
|
||||
if value != old_value:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def has_list_of_dicts_changed(new_list, old_list):
|
||||
def has_list_changed(new_list, old_list):
|
||||
"""
|
||||
Check two lists of dicts has differences.
|
||||
Check two lists has differences.
|
||||
"""
|
||||
if new_list is None:
|
||||
return False
|
||||
|
@ -1169,13 +1238,20 @@ def has_list_of_dicts_changed(new_list, old_list):
|
|||
if len(new_list) != len(old_list):
|
||||
return True
|
||||
for new_item, old_item in zip(new_list, old_list):
|
||||
is_same_type = type(new_item) == type(old_item)
|
||||
if not is_same_type:
|
||||
return True
|
||||
if isinstance(new_item, dict):
|
||||
if has_dict_changed(new_item, old_item):
|
||||
return True
|
||||
elif new_item != old_item:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class DockerService(DockerBaseClass):
|
||||
def __init__(self):
|
||||
def __init__(self, docker_api_version, docker_py_version):
|
||||
super(DockerService, self).__init__()
|
||||
self.image = ""
|
||||
self.command = None
|
||||
|
@ -1227,7 +1303,9 @@ class DockerService(DockerBaseClass):
|
|||
self.update_max_failure_ratio = None
|
||||
self.update_order = None
|
||||
self.working_dir = None
|
||||
self.can_update_networks = None
|
||||
|
||||
self.docker_api_version = docker_api_version
|
||||
self.docker_py_version = docker_py_version
|
||||
|
||||
def get_facts(self):
|
||||
return {
|
||||
|
@ -1281,6 +1359,22 @@ class DockerService(DockerBaseClass):
|
|||
'working_dir': self.working_dir,
|
||||
}
|
||||
|
||||
@property
|
||||
def can_update_networks(self):
|
||||
# Before Docker API 1.29 adding/removing networks was not supported
|
||||
return (
|
||||
self.docker_api_version >= LooseVersion('1.29') and
|
||||
self.docker_py_version >= LooseVersion('2.7')
|
||||
)
|
||||
|
||||
@property
|
||||
def can_use_task_template_networks(self):
|
||||
# In Docker API 1.25 attaching networks to TaskTemplate is preferred over Spec
|
||||
return (
|
||||
self.docker_api_version >= LooseVersion('1.25') and
|
||||
self.docker_py_version >= LooseVersion('2.7')
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_restart_config_from_ansible_params(params):
|
||||
restart_config = params['restart_config'] or {}
|
||||
|
@ -1474,11 +1568,18 @@ class DockerService(DockerBaseClass):
|
|||
|
||||
@classmethod
|
||||
def from_ansible_params(
|
||||
cls, ap, old_service, image_digest, can_update_networks, secret_ids, config_ids
|
||||
cls,
|
||||
ap,
|
||||
old_service,
|
||||
image_digest,
|
||||
secret_ids,
|
||||
config_ids,
|
||||
network_ids,
|
||||
docker_api_version,
|
||||
docker_py_version,
|
||||
):
|
||||
s = DockerService()
|
||||
s = DockerService(docker_api_version, docker_py_version)
|
||||
s.image = image_digest
|
||||
s.can_update_networks = can_update_networks
|
||||
s.args = ap['args']
|
||||
s.endpoint_mode = ap['endpoint_mode']
|
||||
s.dns = ap['dns']
|
||||
|
@ -1491,12 +1592,13 @@ class DockerService(DockerBaseClass):
|
|||
s.labels = ap['labels']
|
||||
s.container_labels = ap['container_labels']
|
||||
s.mode = ap['mode']
|
||||
s.networks = ap['networks']
|
||||
s.stop_signal = ap['stop_signal']
|
||||
s.user = ap['user']
|
||||
s.working_dir = ap['working_dir']
|
||||
s.read_only = ap['read_only']
|
||||
|
||||
s.networks = get_docker_networks(ap['networks'], network_ids)
|
||||
|
||||
s.command = ap['command']
|
||||
if isinstance(s.command, string_types):
|
||||
s.command = shlex.split(s.command)
|
||||
|
@ -1650,13 +1752,13 @@ class DockerService(DockerBaseClass):
|
|||
if self.mode != os.mode:
|
||||
needs_rebuild = True
|
||||
differences.add('mode', parameter=self.mode, active=os.mode)
|
||||
if has_list_of_dicts_changed(self.mounts, os.mounts):
|
||||
if has_list_changed(self.mounts, os.mounts):
|
||||
differences.add('mounts', parameter=self.mounts, active=os.mounts)
|
||||
if has_list_of_dicts_changed(self.configs, os.configs):
|
||||
if has_list_changed(self.configs, os.configs):
|
||||
differences.add('configs', parameter=self.configs, active=os.configs)
|
||||
if has_list_of_dicts_changed(self.secrets, os.secrets):
|
||||
if has_list_changed(self.secrets, os.secrets):
|
||||
differences.add('secrets', parameter=self.secrets, active=os.secrets)
|
||||
if self.networks is not None and self.networks != (os.networks or []):
|
||||
if has_list_changed(self.networks, os.networks):
|
||||
differences.add('networks', parameter=self.networks, active=os.networks)
|
||||
needs_rebuild = not self.can_update_networks
|
||||
if self.replicas != os.replicas:
|
||||
|
@ -1774,18 +1876,6 @@ class DockerService(DockerBaseClass):
|
|||
old_image = old_image.split('@')[0]
|
||||
return self.image != old_image, old_image
|
||||
|
||||
def __str__(self):
|
||||
return str({
|
||||
'mode': self.mode,
|
||||
'env': self.env,
|
||||
'endpoint_mode': self.endpoint_mode,
|
||||
'mounts': self.mounts,
|
||||
'configs': self.configs,
|
||||
'secrets': self.secrets,
|
||||
'networks': self.networks,
|
||||
'replicas': self.replicas
|
||||
})
|
||||
|
||||
def build_container_spec(self):
|
||||
mounts = None
|
||||
if self.mounts is not None:
|
||||
|
@ -2000,6 +2090,10 @@ class DockerService(DockerBaseClass):
|
|||
task_template_args['resources'] = resources
|
||||
if self.force_update:
|
||||
task_template_args['force_update'] = self.force_update
|
||||
if self.can_use_task_template_networks:
|
||||
networks = self.build_networks()
|
||||
if networks:
|
||||
task_template_args['networks'] = networks
|
||||
return types.TaskTemplate(container_spec=container_spec, **task_template_args)
|
||||
|
||||
def build_service_mode(self):
|
||||
|
@ -2007,22 +2101,17 @@ class DockerService(DockerBaseClass):
|
|||
self.replicas = None
|
||||
return types.ServiceMode(self.mode, replicas=self.replicas)
|
||||
|
||||
def build_networks(self, docker_networks):
|
||||
def build_networks(self):
|
||||
networks = None
|
||||
if self.networks is not None:
|
||||
networks = []
|
||||
for network_name in self.networks:
|
||||
network_id = None
|
||||
try:
|
||||
network_id = list(
|
||||
filter(lambda n: n['name'] == network_name, docker_networks)
|
||||
)[0]['id']
|
||||
except (IndexError, KeyError):
|
||||
pass
|
||||
if network_id:
|
||||
networks.append({'Target': network_id})
|
||||
else:
|
||||
raise Exception('no docker networks named: %s' % network_name)
|
||||
for network in self.networks:
|
||||
docker_network = {'Target': network['id']}
|
||||
if 'aliases' in network:
|
||||
docker_network['Aliases'] = network['aliases']
|
||||
if 'options' in network:
|
||||
docker_network['DriverOpts'] = network['options']
|
||||
networks.append(docker_network)
|
||||
return networks
|
||||
|
||||
def build_endpoint_spec(self):
|
||||
|
@ -2043,7 +2132,7 @@ class DockerService(DockerBaseClass):
|
|||
endpoint_spec_args['mode'] = self.endpoint_mode
|
||||
return types.EndpointSpec(**endpoint_spec_args) if endpoint_spec_args else None
|
||||
|
||||
def build_docker_service(self, docker_networks):
|
||||
def build_docker_service(self):
|
||||
container_spec = self.build_container_spec()
|
||||
placement = self.build_placement()
|
||||
task_template = self.build_task_template(container_spec, placement)
|
||||
|
@ -2051,7 +2140,6 @@ class DockerService(DockerBaseClass):
|
|||
update_config = self.build_update_config()
|
||||
rollback_config = self.build_rollback_config()
|
||||
service_mode = self.build_service_mode()
|
||||
networks = self.build_networks(docker_networks)
|
||||
endpoint_spec = self.build_endpoint_spec()
|
||||
|
||||
service = {'task_template': task_template, 'mode': service_mode}
|
||||
|
@ -2059,12 +2147,14 @@ class DockerService(DockerBaseClass):
|
|||
service['update_config'] = update_config
|
||||
if rollback_config:
|
||||
service['rollback_config'] = rollback_config
|
||||
if networks:
|
||||
service['networks'] = networks
|
||||
if endpoint_spec:
|
||||
service['endpoint_spec'] = endpoint_spec
|
||||
if self.labels:
|
||||
service['labels'] = self.labels
|
||||
if not self.can_use_task_template_networks:
|
||||
networks = self.build_networks()
|
||||
if networks:
|
||||
service['networks'] = networks
|
||||
return service
|
||||
|
||||
|
||||
|
@ -2075,15 +2165,12 @@ class DockerServiceManager(object):
|
|||
self.retries = 2
|
||||
self.diff_tracker = None
|
||||
|
||||
def get_networks_names_ids(self):
|
||||
return [{'name': n['Name'], 'id': n['Id']} for n in self.client.networks()]
|
||||
|
||||
def get_service(self, name):
|
||||
try:
|
||||
raw_data = self.client.inspect_service(name)
|
||||
except NotFound:
|
||||
return None
|
||||
ds = DockerService()
|
||||
ds = DockerService(self.client.docker_api_version, self.client.docker_py_version)
|
||||
|
||||
task_template_data = raw_data['Spec']['TaskTemplate']
|
||||
ds.image = task_template_data['ContainerSpec']['Image']
|
||||
|
@ -2263,24 +2350,22 @@ class DockerServiceManager(object):
|
|||
'mode': secret_data['File'].get('Mode')
|
||||
})
|
||||
|
||||
networks_names_ids = self.get_networks_names_ids()
|
||||
raw_networks_data = task_template_data.get('Networks', raw_data['Spec'].get('Networks'))
|
||||
if raw_networks_data:
|
||||
ds.networks = []
|
||||
for network_data in raw_networks_data:
|
||||
network_name = [network_name_id['name'] for network_name_id in networks_names_ids if
|
||||
network_name_id['id'] == network_data['Target']]
|
||||
if len(network_name) == 0:
|
||||
ds.networks.append(network_data['Target'])
|
||||
else:
|
||||
ds.networks.append(network_name[0])
|
||||
|
||||
network = {'id': network_data['Target']}
|
||||
if 'Aliases' in network_data:
|
||||
network['aliases'] = network_data['Aliases']
|
||||
if 'DriverOpts' in network_data:
|
||||
network['options'] = network_data['DriverOpts']
|
||||
ds.networks.append(network)
|
||||
ds.service_version = raw_data['Version']['Index']
|
||||
ds.service_id = raw_data['ID']
|
||||
return ds
|
||||
|
||||
def update_service(self, name, old_service, new_service):
|
||||
service_data = new_service.build_docker_service(self.get_networks_names_ids())
|
||||
service_data = new_service.build_docker_service()
|
||||
result = self.client.update_service(
|
||||
old_service.service_id,
|
||||
old_service.service_version,
|
||||
|
@ -2292,7 +2377,7 @@ class DockerServiceManager(object):
|
|||
self.client.report_warnings(result, ['Warning'])
|
||||
|
||||
def create_service(self, name, service):
|
||||
service_data = service.build_docker_service(self.get_networks_names_ids())
|
||||
service_data = service.build_docker_service()
|
||||
result = self.client.create_service(name=name, **service_data)
|
||||
self.client.report_warnings(result, ['Warning'])
|
||||
|
||||
|
@ -2313,11 +2398,9 @@ class DockerServiceManager(object):
|
|||
digest = distribution_data['Descriptor']['digest']
|
||||
return '%s@%s' % (name, digest)
|
||||
|
||||
def can_update_networks(self):
|
||||
# Before Docker API 1.29 adding/removing networks was not supported
|
||||
return (
|
||||
self.client.docker_api_version >= LooseVersion('1.29') and
|
||||
self.client.docker_py_version >= LooseVersion('2.7')
|
||||
def get_networks_names_ids(self):
|
||||
return dict(
|
||||
(network['Name'], network['Id']) for network in self.client.networks()
|
||||
)
|
||||
|
||||
def get_missing_secret_ids(self):
|
||||
|
@ -2392,16 +2475,18 @@ class DockerServiceManager(object):
|
|||
% (module.params['name'], e)
|
||||
)
|
||||
try:
|
||||
can_update_networks = self.can_update_networks()
|
||||
secret_ids = self.get_missing_secret_ids()
|
||||
config_ids = self.get_missing_config_ids()
|
||||
network_ids = self.get_networks_names_ids()
|
||||
new_service = DockerService.from_ansible_params(
|
||||
module.params,
|
||||
current_service,
|
||||
image_digest,
|
||||
can_update_networks,
|
||||
secret_ids,
|
||||
config_ids
|
||||
config_ids,
|
||||
network_ids,
|
||||
self.client.docker_api_version,
|
||||
self.client.docker_py_version
|
||||
)
|
||||
except Exception as e:
|
||||
return self.client.fail(
|
||||
|
@ -2567,7 +2652,7 @@ def main():
|
|||
gid=dict(type='str'),
|
||||
mode=dict(type='int'),
|
||||
)),
|
||||
networks=dict(type='list', elements='str'),
|
||||
networks=dict(type='list', elements='raw'),
|
||||
command=dict(type='raw'),
|
||||
args=dict(type='list', elements='str'),
|
||||
env=dict(type='raw'),
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
---
|
||||
|
||||
- name: Registering service name
|
||||
set_fact:
|
||||
service_name: "{{ name_prefix ~ '-networks' }}"
|
||||
network_name_1: "{{ name_prefix ~ '-network-1' }}"
|
||||
network_name_2: "{{ name_prefix ~ '-network-2' }}"
|
||||
|
||||
- name: Registering service name
|
||||
set_fact:
|
||||
service_names: "{{ service_names + [service_name] }}"
|
||||
network_names: "{{ network_names + [network_name_1, network_name_2] }}"
|
||||
|
||||
- docker_network:
|
||||
name: "{{ network_name }}"
|
||||
driver: "overlay"
|
||||
state: present
|
||||
loop:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
|
||||
#####################################################################
|
||||
## networks #########################################################
|
||||
#####################################################################
|
||||
|
||||
- name: networks
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
register: networks_1
|
||||
|
||||
- name: networks (idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
register: networks_2
|
||||
|
||||
- name: networks (dict idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
register: networks_3
|
||||
|
||||
- name: networks (change more)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_4
|
||||
|
||||
- name: networks (change more idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_5
|
||||
|
||||
- name: networks (change more dict idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
- name: "{{ network_name_2 }}"
|
||||
register: networks_6
|
||||
|
||||
- name: networks (change more mixed idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_7
|
||||
|
||||
- name: networks (change mixed order)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
- name: "{{ network_name_1 }}"
|
||||
register: networks_8
|
||||
|
||||
- name: networks (change mixed order idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
- name: "{{ network_name_1 }}"
|
||||
register: networks_9
|
||||
|
||||
- name: networks (change less)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_10
|
||||
|
||||
- name: networks (change less idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_11
|
||||
|
||||
- name: networks (empty)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks: []
|
||||
register: networks_12
|
||||
|
||||
- name: networks (empty idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks: []
|
||||
register: networks_13
|
||||
|
||||
- name: networks (unknown network)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "idonotexist"
|
||||
register: networks_14
|
||||
ignore_errors: yes
|
||||
|
||||
- name: networks (missing dict key name)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- foo: "bar"
|
||||
register: networks_15
|
||||
ignore_errors: yes
|
||||
|
||||
- name: networks (invalid list type)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- [1, 2, 3]
|
||||
register: networks_16
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
state: absent
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_1 is changed
|
||||
- networks_2 is not changed
|
||||
- networks_3 is not changed
|
||||
- networks_4 is changed
|
||||
- networks_5 is not changed
|
||||
- networks_6 is not changed
|
||||
- networks_7 is not changed
|
||||
- networks_8 is changed
|
||||
- networks_9 is not changed
|
||||
- networks_10 is changed
|
||||
- networks_11 is not changed
|
||||
- networks_12 is changed
|
||||
- networks_13 is not changed
|
||||
- networks_14 is failed
|
||||
- '"Could not find a network named: ''idonotexist''" in networks_14.msg'
|
||||
- networks_15 is failed
|
||||
- "'\"name\" is required when networks are passed as dictionaries.' in networks_15.msg"
|
||||
- networks_16 is failed
|
||||
- "'Only a list of strings or dictionaries are allowed to be passed as networks' in networks_16.msg"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_4.rebuilt == false
|
||||
- networks_7.rebuilt == false
|
||||
when: docker_api_version is version('1.29', '>=') and docker_py_version is version('2.7.0', '>=')
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_4.rebuilt == true
|
||||
- networks_7.rebuilt == true
|
||||
when: docker_api_version is version('1.29', '<') or docker_py_version is version('2.7.0', '<')
|
||||
|
||||
####################################################################
|
||||
## networks.aliases ################################################
|
||||
####################################################################
|
||||
|
||||
- name: networks.aliases
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases:
|
||||
- "alias1"
|
||||
- "alias2"
|
||||
register: networks_aliases_1
|
||||
|
||||
- name: networks.aliases (idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases:
|
||||
- "alias1"
|
||||
- "alias2"
|
||||
register: networks_aliases_2
|
||||
|
||||
- name: networks.aliases (change)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases:
|
||||
- "alias1"
|
||||
register: networks_aliases_3
|
||||
|
||||
- name: networks.aliases (empty)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases: []
|
||||
register: networks_aliases_4
|
||||
|
||||
- name: networks.aliases (empty idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases: []
|
||||
register: networks_aliases_5
|
||||
|
||||
- name: networks.aliases (invalid type)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
aliases:
|
||||
- [1, 2, 3]
|
||||
register: networks_aliases_6
|
||||
ignore_errors: yes
|
||||
|
||||
- name: cleanup
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
state: absent
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_aliases_1 is changed
|
||||
- networks_aliases_2 is not changed
|
||||
- networks_aliases_3 is changed
|
||||
- networks_aliases_4 is changed
|
||||
- networks_aliases_5 is not changed
|
||||
- networks_aliases_6 is failed
|
||||
- "'Only strings are allowed as network aliases' in networks_aliases_6.msg"
|
||||
|
||||
####################################################################
|
||||
## networks.options ################################################
|
||||
####################################################################
|
||||
|
||||
- name: networks.options
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options:
|
||||
foo: bar
|
||||
test: hello
|
||||
register: networks_options_1
|
||||
|
||||
- name: networks.options (idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options:
|
||||
foo: bar
|
||||
test: hello
|
||||
register: networks_options_2
|
||||
|
||||
- name: networks.options (change)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options:
|
||||
foo: bar
|
||||
test: hej
|
||||
register: networks_options_3
|
||||
|
||||
- name: networks.options (change less)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options:
|
||||
foo: bar
|
||||
register: networks_options_4
|
||||
|
||||
- name: networks.options (invalid type)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options: [1, 2, 3]
|
||||
register: networks_options_5
|
||||
ignore_errors: yes
|
||||
|
||||
- name: networks.options (empty)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options: {}
|
||||
register: networks_options_6
|
||||
|
||||
- name: networks.options (empty idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- name: "{{ network_name_1 }}"
|
||||
options: {}
|
||||
register: networks_options_7
|
||||
|
||||
- name: cleanup
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
state: absent
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_options_1 is changed
|
||||
- networks_options_2 is not changed
|
||||
- networks_options_3 is changed
|
||||
- networks_options_4 is changed
|
||||
- networks_options_5 is failed
|
||||
- "'Only dict is allowed as network options' in networks_options_5.msg"
|
||||
- networks_options_6 is changed
|
||||
- networks_options_7 is not changed
|
||||
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
|
||||
- name: Delete networks
|
||||
docker_network:
|
||||
name: "{{ network_name }}"
|
||||
state: absent
|
||||
force: yes
|
||||
loop:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
ignore_errors: yes
|
|
@ -1,25 +1,12 @@
|
|||
---
|
||||
|
||||
- name: Registering container name
|
||||
- name: Registering service name
|
||||
set_fact:
|
||||
service_name: "{{ name_prefix ~ '-options' }}"
|
||||
network_name_1: "{{ name_prefix ~ '-network-1' }}"
|
||||
network_name_2: "{{ name_prefix ~ '-network-2' }}"
|
||||
|
||||
- name: Registering container name
|
||||
- name: Registering service name
|
||||
set_fact:
|
||||
service_names: "{{ service_names + [service_name] }}"
|
||||
network_names: "{{ network_names + [network_name_1, network_name_2] }}"
|
||||
|
||||
- docker_network:
|
||||
name: "{{ network_name }}"
|
||||
driver: "overlay"
|
||||
state: present
|
||||
loop:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
|
||||
####################################################################
|
||||
## args ############################################################
|
||||
|
@ -1275,119 +1262,6 @@
|
|||
- mode_2 is not changed
|
||||
- mode_3 is changed
|
||||
|
||||
####################################################################
|
||||
## networks ########################################################
|
||||
####################################################################
|
||||
|
||||
- name: networks
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
register: networks_1
|
||||
|
||||
- name: networks (idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
register: networks_2
|
||||
|
||||
- name: networks (change more)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_3
|
||||
|
||||
- name: networks (change more idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_4
|
||||
|
||||
- name: networks (change less)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_5
|
||||
|
||||
- name: networks (change less idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks:
|
||||
- "{{ network_name_2 }}"
|
||||
register: networks_6
|
||||
|
||||
- name: networks (empty)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks: []
|
||||
register: networks_7
|
||||
|
||||
- name: networks (empty idempotency)
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
image: alpine:3.8
|
||||
resolve_image: no
|
||||
command: '/bin/sh -v -c "sleep 10m"'
|
||||
networks: []
|
||||
register: networks_8
|
||||
|
||||
- name: cleanup
|
||||
docker_swarm_service:
|
||||
name: "{{ service_name }}"
|
||||
state: absent
|
||||
diff: no
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_1 is changed
|
||||
- networks_2 is not changed
|
||||
- networks_3 is changed
|
||||
- networks_4 is not changed
|
||||
- networks_5 is changed
|
||||
- networks_6 is not changed
|
||||
- networks_7 is changed
|
||||
- networks_8 is not changed
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_3.rebuilt == false
|
||||
- networks_5.rebuilt == false
|
||||
when: docker_api_version is version('1.29', '>=') and docker_py_version is version('2.7.0', '>=')
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- networks_3.rebuilt == true
|
||||
- networks_5.rebuilt == true
|
||||
when: docker_api_version is version('1.29', '<') or docker_py_version is version('2.7.0', '<')
|
||||
|
||||
####################################################################
|
||||
## stop_grace_period ###############################################
|
||||
####################################################################
|
||||
|
@ -1915,30 +1789,3 @@
|
|||
- working_dir_1 is changed
|
||||
- working_dir_2 is not changed
|
||||
- working_dir_3 is changed
|
||||
|
||||
####################################################################
|
||||
####################################################################
|
||||
####################################################################
|
||||
|
||||
- name: Delete networks
|
||||
docker_network:
|
||||
name: "{{ network_name }}"
|
||||
state: absent
|
||||
force: yes
|
||||
loop:
|
||||
- "{{ network_name_1 }}"
|
||||
- "{{ network_name_2 }}"
|
||||
loop_control:
|
||||
loop_var: network_name
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Delete volumes
|
||||
docker_volume:
|
||||
name: "{{ volume_name }}"
|
||||
state: absent
|
||||
loop:
|
||||
- "{{ volume_name_1 }}"
|
||||
- "{{ volume_name_2 }}"
|
||||
loop_control:
|
||||
loop_var: volume_name
|
||||
ignore_errors: yes
|
||||
|
|
|
@ -168,8 +168,8 @@ def test_has_dict_changed(docker_swarm_service):
|
|||
)
|
||||
|
||||
|
||||
def test_has_list_of_dicts_changed(docker_swarm_service):
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
def test_has_list_changed(docker_swarm_service):
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"a": 1},
|
||||
{"b": 1}
|
||||
|
@ -178,7 +178,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"a": 1}
|
||||
]
|
||||
)
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"a": 1},
|
||||
],
|
||||
|
@ -187,7 +187,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"b": 1},
|
||||
]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"a": 1},
|
||||
{"b": 1},
|
||||
|
@ -197,33 +197,33 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"b": 1}
|
||||
]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
None,
|
||||
[
|
||||
{"b": 1},
|
||||
{"a": 1}
|
||||
]
|
||||
)
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[],
|
||||
[
|
||||
{"b": 1},
|
||||
{"a": 1}
|
||||
]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
None,
|
||||
None
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
[],
|
||||
None
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
None,
|
||||
[]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"src": 1, "dst": 2},
|
||||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
|
@ -233,7 +233,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
{"src": 1, "dst": 3, "protocol": "tcp"},
|
||||
|
@ -243,7 +243,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"src": 1, "dst": 3, "protocol": "tcp"},
|
||||
]
|
||||
)
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
{"src": 1, "dst": 2},
|
||||
|
@ -255,7 +255,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"src": 3, "dst": 4, "protocol": "tcp"},
|
||||
]
|
||||
)
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"src": 1, "dst": 3, "protocol": "tcp"},
|
||||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
|
@ -265,7 +265,7 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
]
|
||||
)
|
||||
assert docker_swarm_service.has_list_of_dicts_changed(
|
||||
assert docker_swarm_service.has_list_changed(
|
||||
[
|
||||
{"src": 1, "dst": 2, "protocol": "udp"},
|
||||
{"src": 1, "dst": 2, "protocol": "tcp", "extra": {"test": "foo"}},
|
||||
|
@ -275,3 +275,86 @@ def test_has_list_of_dicts_changed(docker_swarm_service):
|
|||
{"src": 1, "dst": 2, "protocol": "tcp"},
|
||||
]
|
||||
)
|
||||
assert not docker_swarm_service.has_list_changed(
|
||||
[{'id': '123', 'aliases': []}],
|
||||
[{'id': '123'}]
|
||||
)
|
||||
|
||||
|
||||
def test_get_docker_networks(docker_swarm_service):
|
||||
network_names = [
|
||||
'network_1',
|
||||
'network_2',
|
||||
'network_3',
|
||||
'network_4',
|
||||
]
|
||||
networks = [
|
||||
network_names[0],
|
||||
{'name': network_names[1]},
|
||||
{'name': network_names[2], 'aliases': ['networkalias1']},
|
||||
{'name': network_names[3], 'aliases': ['networkalias2'], 'options': {'foo': 'bar'}},
|
||||
]
|
||||
network_ids = {
|
||||
network_names[0]: '1',
|
||||
network_names[1]: '2',
|
||||
network_names[2]: '3',
|
||||
network_names[3]: '4',
|
||||
}
|
||||
parsed_networks = docker_swarm_service.get_docker_networks(
|
||||
networks,
|
||||
network_ids
|
||||
)
|
||||
assert len(parsed_networks) == 4
|
||||
for i, network in enumerate(parsed_networks):
|
||||
assert 'name' not in network
|
||||
assert 'id' in network
|
||||
expected_name = network_names[i]
|
||||
assert network['id'] == network_ids[expected_name]
|
||||
if i == 2:
|
||||
assert network['aliases'] == ['networkalias1']
|
||||
if i == 3:
|
||||
assert network['aliases'] == ['networkalias2']
|
||||
if i == 3:
|
||||
assert 'foo' in network['options']
|
||||
# Test missing name
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks([{'invalid': 'err'}], {'err': 1})
|
||||
# test for invalid aliases type
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
[{'name': 'test', 'aliases': 1}],
|
||||
{'test': 1}
|
||||
)
|
||||
# Test invalid aliases elements
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
[{'name': 'test', 'aliases': [1]}],
|
||||
{'test': 1}
|
||||
)
|
||||
# Test for invalid options type
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
[{'name': 'test', 'options': 1}],
|
||||
{'test': 1}
|
||||
)
|
||||
# Test for invalid networks type
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
1,
|
||||
{'test': 1}
|
||||
)
|
||||
# Test for non existing networks
|
||||
with pytest.raises(ValueError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
[{'name': 'idontexist'}],
|
||||
{'test': 1}
|
||||
)
|
||||
# Test empty values
|
||||
assert docker_swarm_service.get_docker_networks([], {}) == []
|
||||
assert docker_swarm_service.get_docker_networks(None, {}) is None
|
||||
# Test invalid options
|
||||
with pytest.raises(TypeError):
|
||||
docker_swarm_service.get_docker_networks(
|
||||
[{'name': 'test', 'nonexisting_option': 'foo'}],
|
||||
{'test': '1'}
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue