Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker_swarm: hopefully fix debug CI problems, and fix check mode #52825

Merged
merged 6 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bugfixes:
- "docker_swarm - improve Swarm detection."
- "docker_swarm - properly implement check mode (it did apply changes)."
2 changes: 2 additions & 0 deletions lib/ansible/module_utils/docker/swarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def check_if_swarm_node(self, node_id=None):
swarm_info = json.loads(json_str)
if swarm_info['Swarm']['NodeID']:
return True
if swarm_info['Swarm']['LocalNodeState'] in ('active', 'pending', 'locked'):
return True
return False
else:
try:
Expand Down
58 changes: 33 additions & 25 deletions lib/ansible/modules/cloud/docker/docker_swarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ def __init__(self, client, results):
self.client = client
self.results = results
self.check_mode = self.client.check_mode
self.swarm_info = {}

self.parameters = TaskParameters(client)

Expand Down Expand Up @@ -346,17 +347,18 @@ def init_swarm(self):
self.__update_swarm()
return

try:
self.client.init_swarm(
advertise_addr=self.parameters.advertise_addr, listen_addr=self.parameters.listen_addr,
force_new_cluster=self.parameters.force_new_cluster, swarm_spec=self.parameters.spec)
except APIError as exc:
self.client.fail("Can not create a new Swarm Cluster: %s" % to_native(exc))
if not self.check_mode:
try:
self.client.init_swarm(
advertise_addr=self.parameters.advertise_addr, listen_addr=self.parameters.listen_addr,
force_new_cluster=self.parameters.force_new_cluster, swarm_spec=self.parameters.spec)
except APIError as exc:
self.client.fail("Can not create a new Swarm Cluster: %s" % to_native(exc))

self.__isSwarmManager()
self.results['actions'].append("New Swarm cluster created: %s" % (self.swarm_info['ID']))
self.results['actions'].append("New Swarm cluster created: %s" % (self.swarm_info.get('ID')))
self.results['changed'] = True
self.results['swarm_facts'] = {u'JoinTokens': self.swarm_info['JoinTokens']}
self.results['swarm_facts'] = {u'JoinTokens': self.swarm_info.get('JoinTokens')}

def __update_spec(self, spec):
if (self.parameters.node_cert_expiry is None):
Expand Down Expand Up @@ -406,9 +408,10 @@ def __update_swarm(self):
self.results['actions'].append("No modification")
self.results['changed'] = False
return
self.client.update_swarm(
version=version, swarm_spec=new_spec, rotate_worker_token=self.parameters.rotate_worker_token,
rotate_manager_token=self.parameters.rotate_manager_token)
if not self.check_mode:
self.client.update_swarm(
version=version, swarm_spec=new_spec, rotate_worker_token=self.parameters.rotate_worker_token,
rotate_manager_token=self.parameters.rotate_manager_token)
except APIError as exc:
self.client.fail("Can not update a Swarm Cluster: %s" % to_native(exc))
return
Expand All @@ -424,29 +427,33 @@ def __isSwarmNode(self):
self.swarm_info = json.loads(json_str)
if self.swarm_info['Swarm']['NodeID']:
return True
if self.swarm_info['Swarm']['LocalNodeState'] in ('active', 'pending', 'locked'):
return True
return False

def join(self):
if self.__isSwarmNode():
self.results['actions'].append("This node is already part of a swarm.")
return
try:
self.client.join_swarm(
remote_addrs=self.parameters.remote_addrs, join_token=self.parameters.join_token, listen_addr=self.parameters.listen_addr,
advertise_addr=self.parameters.advertise_addr)
except APIError as exc:
self.client.fail("Can not join the Swarm Cluster: %s" % to_native(exc))
if not self.check_mode:
try:
self.client.join_swarm(
remote_addrs=self.parameters.remote_addrs, join_token=self.parameters.join_token, listen_addr=self.parameters.listen_addr,
advertise_addr=self.parameters.advertise_addr)
except APIError as exc:
self.client.fail("Can not join the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("New node is added to swarm cluster")
self.results['changed'] = True

def leave(self):
if not(self.__isSwarmNode()):
self.results['actions'].append("This node is not part of a swarm.")
return
try:
self.client.leave_swarm(force=self.parameters.force)
except APIError as exc:
self.client.fail("This node can not leave the Swarm Cluster: %s" % to_native(exc))
if not self.check_mode:
try:
self.client.leave_swarm(force=self.parameters.force)
except APIError as exc:
self.client.fail("This node can not leave the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("Node has left the swarm cluster")
self.results['changed'] = True

Expand Down Expand Up @@ -479,10 +486,11 @@ def remove(self):
if not(status_down):
self.client.fail("Can not remove the node. The status node is ready and not down.")

try:
self.client.remove_node(node_id=self.parameters.node_id, force=self.parameters.force)
except APIError as exc:
self.client.fail("Can not remove the node from the Swarm Cluster: %s" % to_native(exc))
if not self.check_mode:
try:
self.client.remove_node(node_id=self.parameters.node_id, force=self.parameters.force)
except APIError as exc:
self.client.fail("Can not remove the node from the Swarm Cluster: %s" % to_native(exc))
self.results['actions'].append("Node is removed from swarm cluster.")
self.results['changed'] = True

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
- block:
- shell: "docker info --format '{% raw %}{{json .}}{% endraw %}' | python -m json.tool"

- name: Make sure we're not already using Docker swarm
docker_swarm:
state: absent
force: true

- shell: "docker info --format '{% raw %}{{json .}}{% endraw %}' | python -m json.tool"

- name: Create a Swarm cluster
docker_swarm:
state: present
Expand Down
59 changes: 51 additions & 8 deletions test/integration/targets/docker_swarm/tasks/test_swarm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,73 @@
- 'output.failed'
- 'output.msg == "state is remove but all of the following are missing: node_id"'

- name: Create a Swarm cluster (check mode)
docker_swarm:
state: present
check_mode: yes
register: output_1

- name: Create a Swarm cluster
docker_swarm:
state: present
register: output
register: output_2

- name: Create a Swarm cluster (idempotent)
docker_swarm:
state: present
register: output_3

- name: Create a Swarm cluster (idempotent, check mode)
docker_swarm:
state: present
check_mode: yes
register: output_4

- name: assert changed when create a new swarm cluster
assert:
that:
- 'output.changed'
- 'output.actions[0] | regex_search("New Swarm cluster created: ")'
- 'output.swarm_facts.JoinTokens.Manager'
- 'output.swarm_facts.JoinTokens.Worker'
- 'output_1 is changed'
- 'output_2 is changed'
- 'output_2.actions[0] | regex_search("New Swarm cluster created: ")'
- 'output_2.swarm_facts.JoinTokens.Manager'
- 'output_2.swarm_facts.JoinTokens.Worker'
- 'output_3 is not changed'
- 'output_4 is not changed'

- name: Remove a Swarm cluster (check mode)
docker_swarm:
state: absent
force: true
check_mode: yes
register: output_1

- name: Remove a Swarm cluster
docker_swarm:
state: absent
force: true
register: output
register: output_2

- name: Remove a Swarm cluster (idempotent)
docker_swarm:
state: absent
force: true
register: output_3

- name: Remove a Swarm cluster (idempotent, check mode)
docker_swarm:
state: absent
force: true
check_mode: yes
register: output_4

- name: assert changed when remove a swarm cluster
assert:
that:
- 'output.changed'
- 'output.actions[0] == "Node has left the swarm cluster"'
- 'output_1 is changed'
- 'output_2 is changed'
- 'output_2.actions[0] == "Node has left the swarm cluster"'
- 'output_3 is not changed'
- 'output_4 is not changed'

always:
- name: Cleanup
Expand Down