Skip to content

Commit

Permalink
Make add_host be idempotent/show changed status (ansible#69897)
Browse files Browse the repository at this point in the history
Change:
- The `add_host` action now shows an accurate change status.

Test Plan:
- Added a plethora of integration tests.

Tickets:
Fixes ansible#69881

Signed-off-by: Rick Elrod <[email protected]>
  • Loading branch information
relrod authored Jun 5, 2020
1 parent 062e780 commit efe103c
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/69881-add_host-show-changed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- add_host action now correctly shows idempotency/changed status
2 changes: 1 addition & 1 deletion lib/ansible/plugins/action/add_host.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ def run(self, tmp=None, task_vars=None):
if k not in special_args:
host_vars[k] = self._task.args[k]

result['changed'] = True
result['changed'] = False
result['add_host'] = dict(host_name=name, groups=new_groups, host_vars=host_vars)
return result
22 changes: 17 additions & 5 deletions lib/ansible/plugins/strategy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ def search_handler_blocks_by_name(handler_name, handler_blocks):
if 'add_host' in result_item:
# this task added a new host (add_host module)
new_host_info = result_item.get('add_host', dict())
self._add_host(new_host_info, iterator)
self._add_host(new_host_info, result_item)

elif 'add_group' in result_item:
# this task added a new group (group_by module)
Expand Down Expand Up @@ -792,32 +792,44 @@ def _wait_on_pending_results(self, iterator):

return ret_results

def _add_host(self, host_info, iterator):
def _add_host(self, host_info, result_item):
'''
Helper function to add a new host to inventory based on a task result.
'''

changed = False

if host_info:
host_name = host_info.get('host_name')

# Check if host in inventory, add if not
if host_name not in self._inventory.hosts:
self._inventory.add_host(host_name, 'all')
self._hosts_cache_all.append(host_name)
changed = True
new_host = self._inventory.hosts.get(host_name)

# Set/update the vars for this host
new_host.vars = combine_vars(new_host.get_vars(), host_info.get('host_vars', dict()))
new_host_vars = new_host.get_vars()
new_host_combined_vars = combine_vars(new_host_vars, host_info.get('host_vars', dict()))
if new_host_vars != new_host_combined_vars:
new_host.vars = new_host_combined_vars
changed = True

new_groups = host_info.get('groups', [])
for group_name in new_groups:
if group_name not in self._inventory.groups:
group_name = self._inventory.add_group(group_name)
changed = True
new_group = self._inventory.groups[group_name]
new_group.add_host(self._inventory.hosts[host_name])
if new_group.add_host(self._inventory.hosts[host_name]):
changed = True

# reconcile inventory, ensures inventory rules are followed
self._inventory.reconcile_inventory()
if changed:
self._inventory.reconcile_inventory()

result_item['changed'] = changed

def _add_group(self, host, result_item):
'''
Expand Down
78 changes: 78 additions & 0 deletions test/integration/targets/add_host/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,81 @@
- groups['bogusgroup'] is not defined # same check as above to ensure that bogus groups are undefined...
- groups['newdynamicgroup'] is defined
- "'newdynamichost' in groups['newdynamicgroup']"

# Tests for idempotency
- name: Add testhost01 dynamic host
add_host:
name: testhost01
register: add_testhost01

- name: Try adding testhost01 again, with no changes
add_host:
name: testhost01
register: add_testhost01_idem

- name: Add a host variable to testhost01
add_host:
name: testhost01
foo: bar
register: hostvar_testhost01

- name: Add the same host variable to testhost01, with no changes
add_host:
name: testhost01
foo: bar
register: hostvar_testhost01_idem

- name: Add another host, testhost02
add_host:
name: testhost02
register: add_testhost02

- name: Add it again for good measure
add_host:
name: testhost02
register: add_testhost02_idem

- name: Add testhost02 to a group
add_host:
name: testhost02
groups:
- testhostgroup
register: add_group_testhost02

- name: Add testhost01 to the same group
add_host:
name: testhost01
groups:
- testhostgroup
register: add_group_testhost01

- name: Add testhost02 to the group again
add_host:
name: testhost02
groups:
- testhostgroup
register: add_group_testhost02_idem

- name: Add testhost01 to the group again
add_host:
name: testhost01
groups:
- testhostgroup
register: add_group_testhost01_idem

- assert:
that:
- add_testhost01 is changed
- add_testhost01_idem is not changed
- hostvar_testhost01 is changed
- hostvar_testhost01_idem is not changed
- add_testhost02 is changed
- add_testhost02_idem is not changed
- add_group_testhost02 is changed
- add_group_testhost01 is changed
- add_group_testhost02_idem is not changed
- add_group_testhost01_idem is not changed
- groups['testhostgroup']|length == 2
- "'testhost01' in groups['testhostgroup']"
- "'testhost02' in groups['testhostgroup']"
- hostvars['testhost01']['foo'] == 'bar'

0 comments on commit efe103c

Please sign in to comment.