Blob Blame History Raw
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