From 420c24ea5584fd4de0146ec132aec8df7a5634d3 Mon Sep 17 00:00:00 2001 From: Hannes Ljungberg Date: Mon, 21 Jan 2019 19:45:47 +0100 Subject: [PATCH] docker_swarm_service: Use option_minimal_versions (#50609) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Pass client to detect_usage function * Use new client argument in detect_usage function * Use option_minimal_versions * Add min_docker_api_version * Skip default since publish is always a list * Add min Docker API version to module requirements * Remove redundant keys() * Move detect_ipvX_address_usage out of __init__ * Check for mode presence in publish ports * Remove unused import * Use port.get(‘mode’) to check for falsy values * Update lib/ansible/modules/cloud/docker/docker_swarm_service.py Co-Authored-By: hannseman * Add force_update to option_minimal_versions * Detect publish mode better * Add a trailing comma --- lib/ansible/module_utils/docker_common.py | 2 +- .../modules/cloud/docker/docker_container.py | 21 ++++--- .../cloud/docker/docker_swarm_service.py | 63 ++++++++++--------- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/lib/ansible/module_utils/docker_common.py b/lib/ansible/module_utils/docker_common.py index a0d5a77a746..1b5159622cc 100644 --- a/lib/ansible/module_utils/docker_common.py +++ b/lib/ansible/module_utils/docker_common.py @@ -442,7 +442,7 @@ class AnsibleDockerClient(Client): if not data['supported']: # Test whether option is specified if 'detect_usage' in data: - used = data['detect_usage']() + used = data['detect_usage'](self) else: used = self.module.params.get(option) is not None if used and 'default' in self.module.argument_spec[option]: diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index cdf39d02cc8..f4a8dc54d5f 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -2645,6 +2645,16 @@ class ContainerManager(DockerBaseClass): return response +def detect_ipvX_address_usage(client): + ''' + Helper function to detect whether any specified network uses ipv4_address or ipv6_address + ''' + for network in client.module.params.get("networks") or []: + if network.get('ipv4_address') is not None or network.get('ipv6_address') is not None: + return True + return False + + class AnsibleDockerClientContainer(AnsibleDockerClient): # A list of module options which are not docker container properties __NON_CONTAINER_PROPERTY_OPTIONS = ( @@ -2772,15 +2782,6 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): self.option_minimal_versions['stop_timeout']['supported'] = stop_timeout_supported def __init__(self, **kwargs): - def detect_ipvX_address_usage(): - ''' - Helper function to detect whether any specified network uses ipv4_address or ipv6_address - ''' - for network in self.module.params.get("networks") or []: - if network.get('ipv4_address') is not None or network.get('ipv6_address') is not None: - return True - return False - option_minimal_versions = dict( # internal options log_config=dict(), @@ -2814,7 +2815,7 @@ class AnsibleDockerClientContainer(AnsibleDockerClient): pids_limit=dict(docker_py_version='1.10.0', docker_api_version='1.23'), # specials ipvX_address_supported=dict(docker_py_version='1.9.0', detect_usage=detect_ipvX_address_usage, - usage_msg='ipv4_address or ipv6_address in networks'), # see above + usage_msg='ipv4_address or ipv6_address in networks'), stop_timeout=dict(), # see _get_additional_minimal_versions() ) diff --git a/lib/ansible/modules/cloud/docker/docker_swarm_service.py b/lib/ansible/modules/cloud/docker/docker_swarm_service.py index ffcce8ac61c..c2ceb5e28ad 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm_service.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm_service.py @@ -294,6 +294,7 @@ requirements: module has been superseded by L(docker,https://pypi.org/project/docker/) (see L(here,https://github.com/docker/docker-py/issues/1310) for details). Version 2.1.0 or newer is only available with the C(docker) module." +- "Docker API >= 1.24" ''' RETURN = ''' @@ -472,7 +473,6 @@ import time from ansible.module_utils.docker_common import ( DockerBaseClass, AnsibleDockerClient, - docker_version, DifferenceTracker, ) from ansible.module_utils.basic import human_to_bytes @@ -866,7 +866,7 @@ class DockerService(DockerBaseClass): ports = {} for port in self.publish: - if port['mode']: + if port.get('mode'): ports[int(port['published_port'])] = (int(port['target_port']), port['protocol'], port['mode']) else: ports[int(port['published_port'])] = (int(port['target_port']), port['protocol']) @@ -1046,36 +1046,7 @@ class DockerServiceManager(): self.client = client self.diff_tracker = DifferenceTracker() - def test_parameter_versions(self): - parameters_versions = [ - {'param': 'dns', 'attribute': 'dns', 'min_version': '1.25'}, - {'param': 'dns_options', 'attribute': 'dns_options', 'min_version': '1.25'}, - {'param': 'dns_search', 'attribute': 'dns_search', 'min_version': '1.25'}, - {'param': 'hostname', 'attribute': 'hostname', 'min_version': '1.25'}, - {'param': 'tty', 'attribute': 'tty', 'min_version': '1.25'}, - {'param': 'secrets', 'attribute': 'secrets', 'min_version': '1.25'}, - {'param': 'configs', 'attribute': 'configs', 'min_version': '1.30'}, - {'param': 'update_order', 'attribute': 'update_order', 'min_version': '1.29'}] - params = self.client.module.params - empty_service = DockerService() - for pv in parameters_versions: - if (params[pv['param']] != getattr(empty_service, pv['attribute']) and - (LooseVersion(self.client.version()['ApiVersion']) < - LooseVersion(pv['min_version']))): - self.client.module.fail_json( - msg=('%s parameter supported only with api_version>=%s' - % (pv['param'], pv['min_version']))) - - for publish_def in self.client.module.params.get('publish', []): - if 'mode' in publish_def.keys(): - if LooseVersion(self.client.version()['ApiVersion']) < LooseVersion('1.25'): - self.client.module.fail_json(msg='publish.mode parameter supported only with api_version>=1.25') - if LooseVersion(docker_version) < LooseVersion('3.0.0'): - self.client.module.fail_json(msg='publish.mode parameter requires docker python library>=3.0.0') - def run(self): - self.test_parameter_versions() - module = self.client.module try: current_service = self.get_service(module.params['name']) @@ -1145,6 +1116,13 @@ class DockerServiceManager(): return msg, changed, rebuilt, differences.get_legacy_docker_diffs(), facts +def _detect_publish_mode_usage(client): + for publish_def in client.module.params['publish']: + if publish_def.get('mode'): + return True + return False + + def main(): argument_spec = dict( name=dict(required=True), @@ -1186,14 +1164,37 @@ def main(): update_max_failure_ratio=dict(default=0, type='float'), update_order=dict(default=None, type='str'), user=dict(default='root')) + + option_minimal_versions = dict( + dns=dict(docker_py_version='2.6.0', docker_api_version='1.25'), + dns_options=dict(docker_py_version='2.6.0', docker_api_version='1.25'), + dns_search=dict(docker_py_version='2.6.0', docker_api_version='1.25'), + force_update=dict(docker_py_version='2.1.0', docker_api_version='1.25'), + hostname=dict(docker_py_version='2.2.0', docker_api_version='1.25'), + tty=dict(docker_py_version='2.4.0', docker_api_version='1.25'), + secrets=dict(docker_py_version='2.1.0', docker_api_version='1.25'), + configs=dict(docker_py_version='2.6.0', docker_api_version='1.30'), + update_order=dict(docker_py_version='2.7.0', docker_api_version='1.29'), + # specials + publish_mode=dict( + docker_py_version='3.0.0', + docker_api_version='1.25', + detect_usage=_detect_publish_mode_usage, + usage_msg='set publish.mode' + ) + ) + required_if = [ ('state', 'present', ['image']) ] + client = AnsibleDockerClient( argument_spec=argument_spec, required_if=required_if, supports_check_mode=True, min_docker_version='2.0.0', + min_docker_api_version='1.24', + option_minimal_versions=option_minimal_versions, ) dsm = DockerServiceManager(client)