diff --git a/changelogs/fragments/53290-docker_swarm_service-add_hosts_option.yml b/changelogs/fragments/53290-docker_swarm_service-add_hosts_option.yml new file mode 100644 index 0000000000..8f17c94691 --- /dev/null +++ b/changelogs/fragments/53290-docker_swarm_service-add_hosts_option.yml @@ -0,0 +1,2 @@ +minor_changes: + - "docker_swarm_service - Added support for ``hosts`` parameter." diff --git a/lib/ansible/modules/cloud/docker/docker_swarm_service.py b/lib/ansible/modules/cloud/docker/docker_swarm_service.py index 1b1336b274..b2315e37fd 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm_service.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm_service.py @@ -121,6 +121,14 @@ options: - Corresponds to the C(--hostname) option of C(docker service create). - Requires API version >= 1.25. type: str + hosts: + description: + - Dict of host-to-IP mappings, where each host name is a key in the dictionary. + Each host name will be added to the container's /etc/hosts file. + - Corresponds to the C(--host) option of C(docker service create). + - Requires API version >= 1.25. + type: dict + version_added: "2.8" tty: description: - Allocate a pseudo-TTY. @@ -934,6 +942,7 @@ class DockerService(DockerBaseClass): self.healthcheck = None self.healthcheck_disabled = None self.hostname = None + self.hosts = None self.tty = None self.dns_search = None self.dns_options = None @@ -990,6 +999,7 @@ class DockerService(DockerBaseClass): 'healthcheck': self.healthcheck, 'healthcheck_disabled': self.healthcheck_disabled, 'hostname': self.hostname, + 'hosts': self.hosts, 'env': self.env, 'force_update': self.force_update, 'groups': self.groups, @@ -1202,6 +1212,7 @@ class DockerService(DockerBaseClass): s.dns_options = ap['dns_options'] s.healthcheck, s.healthcheck_disabled = parse_healthcheck(ap['healthcheck']) s.hostname = ap['hostname'] + s.hosts = ap['hosts'] s.tty = ap['tty'] s.labels = ap['labels'] s.container_labels = ap['container_labels'] @@ -1420,6 +1431,8 @@ class DockerService(DockerBaseClass): differences.add('healthcheck', parameter=self.healthcheck, active=os.healthcheck) if self.hostname is not None and self.hostname != os.hostname: differences.add('hostname', parameter=self.hostname, active=os.hostname) + if self.hosts is not None and self.hosts != (os.hosts or {}): + differences.add('hosts', parameter=self.hosts, active=os.hosts) if self.tty is not None and self.tty != os.tty: differences.add('tty', parameter=self.tty, active=os.tty) if self.working_dir is not None and self.working_dir != os.working_dir: @@ -1544,6 +1557,8 @@ class DockerService(DockerBaseClass): container_spec_args['healthcheck'] = types.Healthcheck(**self.healthcheck) if self.hostname is not None: container_spec_args['hostname'] = self.hostname + if self.hosts is not None: + container_spec_args['hosts'] = self.hosts if self.stop_grace_period is not None: container_spec_args['stop_grace_period'] = self.stop_grace_period if self.stop_signal is not None: @@ -1762,6 +1777,11 @@ class DockerServiceManager(object): ds.dns_options = dns_config.get('Options') ds.hostname = task_template_data['ContainerSpec'].get('Hostname') + + hosts = task_template_data['ContainerSpec'].get('Hosts') + if hosts: + hosts = [host.split(' ', 1) for host in hosts] + ds.hosts = dict((hostname, ip) for ip, hostname in hosts) ds.tty = task_template_data['ContainerSpec'].get('TTY') placement = task_template_data.get('Placement') @@ -2111,6 +2131,7 @@ def main(): retries=dict(type='int'), )), hostname=dict(type='str'), + hosts=dict(type='dict'), labels=dict(type='dict'), container_labels=dict(type='dict'), mode=dict(type='str', default='replicated'), @@ -2179,6 +2200,7 @@ def main(): force_update=dict(docker_py_version='2.1.0', docker_api_version='1.25'), healthcheck=dict(docker_py_version='2.0.0', docker_api_version='1.25'), hostname=dict(docker_py_version='2.2.0', docker_api_version='1.25'), + hosts=dict(docker_py_version='2.6.0', docker_api_version='1.25'), groups=dict(docker_py_version='2.6.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'), diff --git a/test/integration/targets/docker_swarm_service/tasks/tests/options.yml b/test/integration/targets/docker_swarm_service/tasks/tests/options.yml index 98e0915303..cc4c36e81b 100644 --- a/test/integration/targets/docker_swarm_service/tasks/tests/options.yml +++ b/test/integration/targets/docker_swarm_service/tasks/tests/options.yml @@ -1064,6 +1064,58 @@ - "('version is ' ~ docker_api_version ~'. Minimum version required is 1.25') in hostname_1.msg" when: docker_api_version is version('1.25', '<') +################################################################### +## hosts ########################################################## +################################################################### + +- name: hosts + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + hosts: + example.com: 1.2.3.4 + example.org: 4.3.2.1 + register: hosts_1 + +- name: hosts (idempotency) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + hosts: + example.com: 1.2.3.4 + example.org: 4.3.2.1 + register: hosts_2 + +- name: hosts (change) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + hosts: + example.com: 1.2.3.4 + register: hosts_3 + +- name: cleanup + docker_swarm_service: + name: "{{ service_name }}" + state: absent + diff: no + +- assert: + that: + - hosts_1 is changed + - hosts_2 is not changed + - hosts_3 is changed + when: docker_api_version is version('1.25', '>=') +- assert: + that: + - hosts_1 is failed + - "('version is ' ~ docker_api_version ~'. Minimum version required is 1.25') in hosts_1.msg" + when: docker_api_version is version('1.25', '<') + + ################################################################### ## image ########################################################## ################################################################### diff --git a/test/integration/targets/docker_swarm_service/vars/main.yml b/test/integration/targets/docker_swarm_service/vars/main.yml index ca4e3f0ae7..cfabafed9a 100644 --- a/test/integration/targets/docker_swarm_service/vars/main.yml +++ b/test/integration/targets/docker_swarm_service/vars/main.yml @@ -16,6 +16,7 @@ service_expected_output: healthcheck: null healthcheck_disabled: null hostname: null + hosts: null image: busybox labels: null limit_cpu: null