From ae35fc04c3a2068b1d37efe813d1c6938b4f2634 Mon Sep 17 00:00:00 2001
From: Brian Coca <bcoca@users.noreply.github.com>
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