From 3cff54d69ba5d5c4e513e705342592f791e897ad Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Wed, 28 Apr 2021 13:24:38 -0400 Subject: [PATCH] Fix missing delegate display (#74370) * dont rely on vars, task already gives us info * ensure we always display delegation in host label * also added parens with ansible_host to show target host vs resolved host * delegating to self is not delegating * delegated vars restoration for backwards compat * tests need mock task with delegate_to --- changelogs/fragments/restore_delegate_label.yml | 2 ++ lib/ansible/executor/task_executor.py | 5 +++++ lib/ansible/plugins/callback/__init__.py | 16 +++++++++------- test/units/plugins/callback/test_callback.py | 10 ++++++++-- 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/restore_delegate_label.yml diff --git a/changelogs/fragments/restore_delegate_label.yml b/changelogs/fragments/restore_delegate_label.yml new file mode 100644 index 00000000000..9f9577b83b3 --- /dev/null +++ b/changelogs/fragments/restore_delegate_label.yml @@ -0,0 +1,2 @@ +bugfixes: + - callbacks, restore displaying delegation to host as host label. diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 9a803437fac..987ae4dc3d6 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -728,6 +728,11 @@ class TaskExecutor: for k in plugin_vars: result["_ansible_delegated_vars"][k] = cvars.get(k) + # note: here for callbacks that rely on this info to display delegation + for requireshed in ('ansible_host', 'ansible_port', 'ansible_user', 'ansible_connection'): + if requireshed not in result["_ansible_delegated_vars"] and requireshed in cvars: + result["_ansible_delegated_vars"][requireshed] = cvars.get(requireshed) + # and return display.debug("attempt loop complete, returning result") return result diff --git a/lib/ansible/plugins/callback/__init__.py b/lib/ansible/plugins/callback/__init__.py index 229728aa225..a1adf3b9ee1 100644 --- a/lib/ansible/plugins/callback/__init__.py +++ b/lib/ansible/plugins/callback/__init__.py @@ -21,9 +21,7 @@ __metaclass__ = type import difflib import json -import os import sys -import warnings from copy import deepcopy @@ -104,11 +102,15 @@ class CallbackBase(AnsiblePlugin): """Return label for the hostname (& delegated hostname) of a task result. """ - hostname = result._host.get_name() - delegated_vars = result._result.get('_ansible_delegated_vars', None) - if delegated_vars: - return "%s -> %s" % (hostname, delegated_vars['ansible_host']) - return "%s" % (hostname,) + label = "%s" % result._host.get_name() + if result._task.delegate_to and result._task.delegate_to != result._host.get_name(): + # show delegated host + label += " -> %s" % result._task.delegate_to + # in case we have 'extra resolution' + ahost = result._result.get('_ansible_delegated_vars', {}).get('ansible_host', result._task.delegate_to) + if result._task.delegate_to != ahost: + label += "(%s)" % ahost + return label def _run_is_verbose(self, result, verbosity=0): return ((self._display.verbosity > verbosity or result._result.get('_ansible_verbose_always', False) is True) diff --git a/test/units/plugins/callback/test_callback.py b/test/units/plugins/callback/test_callback.py index 43b9274baf5..c2ffbb4d880 100644 --- a/test/units/plugins/callback/test_callback.py +++ b/test/units/plugins/callback/test_callback.py @@ -32,6 +32,10 @@ from ansible.inventory.host import Host from ansible.plugins.callback import CallbackBase +mock_task = MagicMock() +mock_task.delegate_to = None + + class TestCallback(unittest.TestCase): # FIXME: This doesn't really test anything... def test_init(self): @@ -50,13 +54,15 @@ class TestCallback(unittest.TestCase): self.assertIs(cb._display, display_mock) def test_host_label(self): - result = TaskResult(host=Host('host1'), task=None, return_data={}) + result = TaskResult(host=Host('host1'), task=mock_task, return_data={}) + self.assertEquals(CallbackBase.host_label(result), 'host1') def test_host_label_delegated(self): + mock_task.delegate_to = 'host2' result = TaskResult( host=Host('host1'), - task=None, + task=mock_task, return_data={'_ansible_delegated_vars': {'ansible_host': 'host2'}}, ) self.assertEquals(CallbackBase.host_label(result), 'host1 -> host2')