From 212d2024f4d36c0ada0fdc75cda833729c62d387 Mon Sep 17 00:00:00 2001 From: Sloane Hertel Date: Fri, 17 Jul 2020 15:41:43 -0400 Subject: [PATCH] [2.10] Handle post_validate templating errors and fix tests (#70240) (#70389) * Handle post_validate templating errors and fix tests (#70240) * Handle unexpected templating errors * Fixes #70050 Fix up tests that weren't running and add tests for graceful templating error handling (cherry picked from commit 30e70f4b6356e692c7ade3dd95f2e55d07f3e8f5) * changelog ci_complete --- .../70240-fix-fatal-post_validate-error.yml | 2 ++ lib/ansible/executor/task_executor.py | 7 ++++- .../targets/templating_lookups/runme.sh | 2 +- .../targets/templating_lookups/runme.yml | 2 +- .../template_lookups/tasks/errors.yml | 31 +++++++++++++++++++ .../template_lookups/tasks/main.yml | 2 ++ 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/70240-fix-fatal-post_validate-error.yml create mode 100644 test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml diff --git a/changelogs/fragments/70240-fix-fatal-post_validate-error.yml b/changelogs/fragments/70240-fix-fatal-post_validate-error.yml new file mode 100644 index 00000000000..ca2fc8a1e2a --- /dev/null +++ b/changelogs/fragments/70240-fix-fatal-post_validate-error.yml @@ -0,0 +1,2 @@ +bugfixes: + - TaskExecutor - Handle unexpected errors as failed while post validating loops (https://github.com/ansible/ansible/issues/70050). diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 203cfbca81e..dec4b978643 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -575,7 +575,12 @@ class TaskExecutor: return dict(include_args=include_args) # Now we do final validation on the task, which sets all fields to their final values. - self._task.post_validate(templar=templar) + try: + self._task.post_validate(templar=templar) + except AnsibleError: + raise + except Exception: + return dict(changed=False, failed=True, _ansible_no_log=self._play_context.no_log, exception=to_text(traceback.format_exc())) if '_variable_params' in self._task.args: variable_params = self._task.args.pop('_variable_params') if isinstance(variable_params, dict): diff --git a/test/integration/targets/templating_lookups/runme.sh b/test/integration/targets/templating_lookups/runme.sh index e681070d770..e958bcfb648 100755 --- a/test/integration/targets/templating_lookups/runme.sh +++ b/test/integration/targets/templating_lookups/runme.sh @@ -2,7 +2,7 @@ set -eux -ANSIBLE_ROLES_PATH=../ UNICODE_VAR=café ansible-playbook runme.yml "$@" +ANSIBLE_ROLES_PATH=./ UNICODE_VAR=café ansible-playbook runme.yml "$@" ansible-playbook template_lookup_vaulted/playbook.yml --vault-password-file template_lookup_vaulted/test_vault_pass "$@" diff --git a/test/integration/targets/templating_lookups/runme.yml b/test/integration/targets/templating_lookups/runme.yml index 85328d2e987..a27337bb213 100644 --- a/test/integration/targets/templating_lookups/runme.yml +++ b/test/integration/targets/templating_lookups/runme.yml @@ -1,4 +1,4 @@ - hosts: localhost gather_facts: no roles: - - { role: templating_lookups } + - { role: template_lookups } diff --git a/test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml b/test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml new file mode 100644 index 00000000000..da57631a8d1 --- /dev/null +++ b/test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml @@ -0,0 +1,31 @@ +- name: Task that fails due to templating error for plugin option + debug: msg="{{ 5 / 0 | int }}" + ignore_errors: true + register: result + +- assert: + that: + - result.failed + - result.exception + +- name: Loop that fails due to templating error in first entry and ignores errors + debug: msg="{{ 5 / item }}" + ignore_errors: true + register: result + loop: [0, 0, 1] + +- debug: var=result + +- assert: + that: + - result.results[0].failed + - result.results[0].exception + - result.results[0].item == 0 + + - result.results[1].failed + - result.results[1].exception + - result.results[1].item == 0 + + - not result.results[2].failed + - result.results[2].exception is undefined + - result.results[2].item == 1 diff --git a/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml b/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml index cfeea2d56c1..f240a2340df 100644 --- a/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml +++ b/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml @@ -86,3 +86,5 @@ assert: that: - password1 != password2 + +- include_tasks: ./errors.yml