From 833512b07c3d653987398f09f473f3875744014f Mon Sep 17 00:00:00 2001 From: Hannes Ljungberg Date: Sun, 31 Mar 2019 22:56:55 +0200 Subject: [PATCH] docker_swarm: Add support for default_addr_pool and subnet_size (#54642) * Add support for default_addr_pool and subnet_size * Add changelog fragment * Document options only used on init / join --- .../54642-docker_swarm-remote_addr_pool.yml | 2 + .../modules/cloud/docker/docker_swarm.py | 45 ++++++++- .../tasks/tests/remote-addr-pool.yml | 93 +++++++++++++++++++ 3 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/54642-docker_swarm-remote_addr_pool.yml create mode 100644 test/integration/targets/docker_swarm/tasks/tests/remote-addr-pool.yml diff --git a/changelogs/fragments/54642-docker_swarm-remote_addr_pool.yml b/changelogs/fragments/54642-docker_swarm-remote_addr_pool.yml new file mode 100644 index 00000000000..0dc0585dea4 --- /dev/null +++ b/changelogs/fragments/54642-docker_swarm-remote_addr_pool.yml @@ -0,0 +1,2 @@ +minor_changes: + - "docker_swarm - Added support for ``default_addr_pool`` and ``subnet_size``." diff --git a/lib/ansible/modules/cloud/docker/docker_swarm.py b/lib/ansible/modules/cloud/docker/docker_swarm.py index f9882f89c03..c5cc5e17e58 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm.py @@ -29,7 +29,25 @@ options: the port number from the listen address is used. - If C(advertise_addr) is not specified, it will be automatically detected when possible. + - Only used when swarm is initialised or joined. Because of this it's not + considered for idempotency checking. type: str + default_addr_pool: + description: + - Default address pool in CIDR format. + - Only used when swarm is initialised. Because of this it's not considered + for idempotency checking. + - Requires API version >= 1.39. + type: list + version_added: "2.8" + subnet_size: + description: + - Default address pool subnet mask length. + - Only used when swarm is initialised. Because of this it's not considered + for idempotency checking. + - Requires API version >= 1.39. + type: int + version_added: "2.8" listen_addr: description: - Listen address used for inter-manager communication. @@ -38,6 +56,8 @@ options: like C(eth0:4567). - If the port number is omitted, the default swarm listening port is used. + - Only used when swarm is initialised or joined. Because of this it's not + considered for idempotency checking. type: str default: 0.0.0.0:2377 force: @@ -283,6 +303,8 @@ class TaskParameters(DockerBaseClass): self.autolock_managers = None self.rotate_worker_token = None self.rotate_manager_token = None + self.default_addr_pool = None + self.subnet_size = None @staticmethod def from_ansible_params(client): @@ -366,7 +388,8 @@ class TaskParameters(DockerBaseClass): def compare_to_active(self, other, client, differences): for k in self.__dict__: if k in ('advertise_addr', 'listen_addr', 'remote_addrs', 'join_token', - 'rotate_worker_token', 'rotate_manager_token', 'spec'): + 'rotate_worker_token', 'rotate_manager_token', 'spec', + 'default_addr_pool', 'subnet_size'): continue if not client.option_minimal_versions[k]['supported']: continue @@ -438,10 +461,18 @@ class SwarmManager(DockerBaseClass): return if not self.check_mode: + init_arguments = { + 'advertise_addr': self.parameters.advertise_addr, + 'listen_addr': self.parameters.listen_addr, + 'force_new_cluster': self.force, + 'swarm_spec': self.parameters.spec, + } + if self.parameters.default_addr_pool is not None: + init_arguments['default_addr_pool'] = self.parameters.default_addr_pool + if self.parameters.subnet_size is not None: + init_arguments['subnet_size'] = self.parameters.subnet_size try: - self.client.init_swarm( - advertise_addr=self.parameters.advertise_addr, listen_addr=self.parameters.listen_addr, - force_new_cluster=self.force, swarm_spec=self.parameters.spec) + self.client.init_swarm(**init_arguments) except APIError as exc: self.client.fail("Can not create a new Swarm Cluster: %s" % to_native(exc)) @@ -559,7 +590,9 @@ def main(): autolock_managers=dict(type='bool'), node_id=dict(type='str'), rotate_worker_token=dict(type='bool', default=False), - rotate_manager_token=dict(type='bool', default=False) + rotate_manager_token=dict(type='bool', default=False), + default_addr_pool=dict(type='list', elements='str'), + subnet_size=dict(type='int'), ) required_if = [ @@ -579,6 +612,8 @@ def main(): detect_usage=_detect_remove_operation, usage_msg='remove swarm nodes' ), + default_addr_pool=dict(docker_py_version='4.0.0', docker_api_version='1.39'), + subnet_size=dict(docker_py_version='4.0.0', docker_api_version='1.39'), ) client = AnsibleDockerSwarmClient( diff --git a/test/integration/targets/docker_swarm/tasks/tests/remote-addr-pool.yml b/test/integration/targets/docker_swarm/tasks/tests/remote-addr-pool.yml new file mode 100644 index 00000000000..28f40485ce0 --- /dev/null +++ b/test/integration/targets/docker_swarm/tasks/tests/remote-addr-pool.yml @@ -0,0 +1,93 @@ +--- + +- name: Remove Swarm cluster + docker_swarm: + state: absent + force: true + diff: yes + register: output_2 + +#################################################################### +## default_addr_pool ############################################### +#################################################################### + +- name: default_addr_pool + docker_swarm: + state: present + default_addr_pool: + - "2.0.0.0/16" + diff: yes + register: output_1 + ignore_errors: yes + +- name: default_addr_pool (idempotent) + docker_swarm: + state: present + default_addr_pool: + - "2.0.0.0/16" + diff: yes + register: output_2 + ignore_errors: yes + +- name: cleanup + docker_swarm: + state: absent + force: true + diff: no + +- name: assert default_addr_pool + assert: + that: + - 'output_1 is changed' + - 'output_2 is not changed' + - 'output_2.swarm_facts.DefaultAddrPool == ["2.0.0.0/16"]' + when: docker_api_version is version('1.39', '>=') and docker_py_version is version('4.0.0', '>=') + +- name: assert default_addr_pool failed when unsupported + assert: + that: + - 'output_1 is failed' + - "'Minimum version required' in output_1.msg" + when: docker_api_version is version('1.39', '<') or docker_py_version is version('4.0.0', '<') + +#################################################################### +## subnet_size ##################################################### +#################################################################### + +- name: subnet_size + docker_swarm: + state: present + force: yes + subnet_size: 26 + diff: yes + register: output_1 + ignore_errors: yes + +- name: subnet_size (idempotent) + docker_swarm: + state: present + subnet_size: 26 + diff: yes + register: output_2 + ignore_errors: yes + +- name: assert subnet_size + assert: + that: + - 'output_1 is changed' + - 'output_2 is not changed' + - 'output_2.swarm_facts.SubnetSize == 26' + when: docker_api_version is version('1.39', '>=') and docker_py_version is version('4.0.0', '>=') + +- name: cleanup + docker_swarm: + state: absent + force: true + diff: no + +- name: assert subnet_size failed when unsupported + assert: + that: + - output_1 is failed + - "'Minimum version required' in output_1.msg" + when: docker_api_version is version('1.39', '<') or docker_py_version is version('4.0.0', '<')