docker_swarm_service: Use option_minimal_versions (#50609)

* 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 <hannes@5monkeys.se>

* Add force_update to option_minimal_versions

* Detect publish mode better

* Add a trailing comma
This commit is contained in:
Hannes Ljungberg 2019-01-21 19:45:47 +01:00 committed by John R Barker
parent ab70172651
commit 420c24ea55
3 changed files with 44 additions and 42 deletions

View file

@ -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]:

View file

@ -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()
)

View file

@ -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)