From ae35fc04c3a2068b1d37efe813d1c6938b4f2634 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 16 Feb 2022 11:55:03 -0500 Subject: [PATCH] Fix final fact delegation (#77008) (#77017) * fix facts delegation loop overwrite partial revert of change to allow facts to be present in each loop iteration was not needed in final results as result processing alreayd had the disctiontion and ended up breaking the assumptions in the calling code. fixes #76676 (cherry picked from commit c9d3518d2f3812787e1627806b5fa93f8fae48a6) --- .../fragments/fix_fax_delegation_loops.yml | 2 ++ lib/ansible/executor/task_executor.py | 8 +------ .../delegate_to/delegate_facts_loop.yml | 21 ++++++++++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/fix_fax_delegation_loops.yml diff --git a/changelogs/fragments/fix_fax_delegation_loops.yml b/changelogs/fragments/fix_fax_delegation_loops.yml new file mode 100644 index 0000000000..d9e07bf110 --- /dev/null +++ b/changelogs/fragments/fix_fax_delegation_loops.yml @@ -0,0 +1,2 @@ +bugfixes: + - task_executor reverts the change to push facts into delegated vars on loop finalization as result managing code already handles this and was duplicating effort to wrong result. diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 1a7c666fea..05dcb96446 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -745,13 +745,7 @@ class TaskExecutor: if 'ansible_facts' in result and self._task.action not in C._ACTION_DEBUG: if self._task.action in C._ACTION_WITH_CLEAN_FACTS: - if self._task.delegate_to and self._task.delegate_facts: - if '_ansible_delegated_vars' in variables: - variables['_ansible_delegated_vars'].update(result['ansible_facts']) - else: - variables['_ansible_delegated_vars'] = result['ansible_facts'] - else: - variables.update(result['ansible_facts']) + variables.update(result['ansible_facts']) else: # TODO: cleaning of facts should eventually become part of taskresults instead of vars af = wrap_var(result['ansible_facts']) diff --git a/test/integration/targets/delegate_to/delegate_facts_loop.yml b/test/integration/targets/delegate_to/delegate_facts_loop.yml index 90a25676dd..28a1488de3 100644 --- a/test/integration/targets/delegate_to/delegate_facts_loop.yml +++ b/test/integration/targets/delegate_to/delegate_facts_loop.yml @@ -5,7 +5,6 @@ test: 123 delegate_to: "{{ item }}" delegate_facts: true - when: test is not defined loop: "{{ groups['all'] | difference(['localhost']) }}" - name: ensure we didnt create it on current host @@ -19,3 +18,23 @@ - "'test' in hostvars[item]" - hostvars[item]['test'] == 123 loop: "{{ groups['all'] | difference(['localhost']) }}" + + +- name: test that we don't polute whole group with one value + hosts: localhost + gather_facts: no + vars: + cluster_name: bleh + tasks: + - name: construct different fact per host in loop + set_fact: + vm_name: "{{ cluster_name }}-{{item}}" + delegate_to: "{{ item }}" + delegate_facts: True + with_items: "{{ groups['all'] }}" + + - name: ensure the fact is personalized for each host + assert: + that: + - hostvars[item]['vm_name'].endswith(item) + loop: "{{ groups['all'] }}" -- 2.30.2