From bda074d34e46ee9862a48ed067ad42260d3f92ab Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 21 Aug 2018 21:53:56 -0400 Subject: [PATCH] fix tempating issues with no_log and loops (#44468) * fix tempating issues with no_log and loops - task is no log if any item is - added test cases fixes #43294 --- changelogs/fragments/fix_no_log_loop.yml | 2 ++ lib/ansible/executor/task_executor.py | 11 +++++++-- lib/ansible/executor/task_result.py | 2 +- test/integration/targets/no_log/dynamic.yml | 27 +++++++++++++++++++++ test/integration/targets/no_log/runme.sh | 8 +++++- 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/fix_no_log_loop.yml create mode 100644 test/integration/targets/no_log/dynamic.yml diff --git a/changelogs/fragments/fix_no_log_loop.yml b/changelogs/fragments/fix_no_log_loop.yml new file mode 100644 index 0000000000..5db08ab2a0 --- /dev/null +++ b/changelogs/fragments/fix_no_log_loop.yml @@ -0,0 +1,2 @@ +bugfixes: + - always correctly template no log for tasks https://github.com/ansible/ansible/issues/43294 diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 2b622db344..c9fedb5986 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -171,9 +171,10 @@ class TaskExecutor: display.debug("done dumping result, returning") return res except AnsibleError as e: - return dict(failed=True, msg=wrap_var(to_text(e, nonstring='simplerepr'))) + return dict(failed=True, msg=wrap_var(to_text(e, nonstring='simplerepr')), _ansible_no_log=self._task.no_log) except Exception as e: - return dict(failed=True, msg='Unexpected failure during module execution.', exception=to_text(traceback.format_exc()), stdout='') + return dict(failed=True, msg='Unexpected failure during module execution.', exception=to_text(traceback.format_exc()), + stdout='', _ansible_no_log=self._task.no_log) finally: try: self._connection.close() @@ -303,6 +304,7 @@ class TaskExecutor: # Only squash with 'with_:' not with the 'loop:', 'magic' squashing can be removed once with_ loops are items = self._squash_items(items, loop_var, task_vars) + no_log = False for item_index, item in enumerate(items): task_vars[loop_var] = item if index_var: @@ -337,6 +339,9 @@ class TaskExecutor: (self._task, tmp_task) = (tmp_task, self._task) (self._play_context, tmp_play_context) = (tmp_play_context, self._play_context) + # update 'general no_log' based on specific no_log + no_log = no_log or tmp_task.no_log + # now update the result with the item info, and append the result # to the list of results res[loop_var] = item @@ -360,6 +365,8 @@ class TaskExecutor: results.append(res) del task_vars[loop_var] + self._task.no_log = no_log + return results def _squash_items(self, items, loop_var, variables): diff --git a/lib/ansible/executor/task_result.py b/lib/ansible/executor/task_result.py index d5eb10107c..cf1a522199 100644 --- a/lib/ansible/executor/task_result.py +++ b/lib/ansible/executor/task_result.py @@ -111,7 +111,7 @@ class TaskResult: else: ignore = _IGNORE - if self._task.no_log or self._result.get('_ansible_no_log', False): + if isinstance(self._task.no_log, bool) and self._task.no_log or self._result.get('_ansible_no_log', False): x = {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"} # preserve full diff --git a/test/integration/targets/no_log/dynamic.yml b/test/integration/targets/no_log/dynamic.yml new file mode 100644 index 0000000000..4a1123d574 --- /dev/null +++ b/test/integration/targets/no_log/dynamic.yml @@ -0,0 +1,27 @@ +- name: test dynamic no log + hosts: testhost + gather_facts: no + ignore_errors: yes + tasks: + - name: no loop, task fails, dynamic no_log + debug: + msg: "SHOW {{ var_does_not_exist }}" + no_log: "{{ not (unsafe_show_logs|bool) }}" + + - name: loop, task succeeds, dynamic does no_log + debug: + msg: "SHOW {{ item }}" + loop: + - a + - b + - c + no_log: "{{ not (unsafe_show_logs|bool) }}" + + - name: loop, task fails, dynamic no_log + debug: + msg: "SHOW {{ var_does_not_exist }}" + loop: + - a + - b + - c + no_log: "{{ not (unsafe_show_logs|bool) }}" diff --git a/test/integration/targets/no_log/runme.sh b/test/integration/targets/no_log/runme.sh index e20bb08c4f..474e755e13 100755 --- a/test/integration/targets/no_log/runme.sh +++ b/test/integration/targets/no_log/runme.sh @@ -4,6 +4,12 @@ set -eux # This test expects 7 loggable vars and 0 non-loggable ones. # If either mismatches it fails, run the ansible-playbook command to debug. - [ "$(ansible-playbook no_log_local.yml -i ../../inventory -vvvvv "$@" | awk \ 'BEGIN { logme = 0; nolog = 0; } /LOG_ME/ { logme += 1;} /DO_NOT_LOG/ { nolog += 1;} END { printf "%d/%d", logme, nolog; }')" = "26/0" ] + +# deal with corner cases with no log and loops +# no log enabled, should produce 6 censored messages +[ "$(ansible-playbook dynamic.yml -i ../../inventory -vvvvv "$@" -e unsafe_show_logs=no|grep -c 'output has been hidden')" = "6" ] + +# no log disabled, should produce 0 censored +[ "$(ansible-playbook dynamic.yml -i ../../inventory -vvvvv "$@" -e unsafe_show_logs=yes|grep -c 'output has been hidden')" = "0" ]