From 30e70f4b6356e692c7ade3dd95f2e55d07f3e8f5 Mon Sep 17 00:00:00 2001 From: Sloane Hertel Date: Tue, 30 Jun 2020 09:31:58 -0400 Subject: [PATCH] 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 --- 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 ++ 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 0cb03d71414..87902ab547a 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -484,7 +484,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