ignore/warn for undefined vars in unused handler names (#75244)

* Make undefined variables in handler names non-fatal if the handler is not used

* If the handler has no way to be notified (i.e. the name can't be templated and the handler has no listen topics), display a warning

* Add tests for variables in handler names

* changelog
pull/75253/head
Sloane Hertel 4 years ago committed by GitHub
parent d8dcfe737a
commit c8d413164d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- Give a warning instead of an error if a handler name contains undefined variables and has no listen topics (https://github.com/ansible/ansible/issues/58841).

@ -492,16 +492,16 @@ class StrategyBase:
for handler_block in reversed(handler_blocks):
for handler_task in handler_block.block:
if handler_task.name:
if not handler_task.cached_name:
if handler_templar.is_template(handler_task.name):
handler_templar.available_variables = self._variable_manager.get_vars(play=iterator._play,
task=handler_task,
_hosts=self._hosts_cache,
_hosts_all=self._hosts_cache_all)
handler_task.name = handler_templar.template(handler_task.name)
handler_task.cached_name = True
try:
if not handler_task.cached_name:
if handler_templar.is_template(handler_task.name):
handler_templar.available_variables = self._variable_manager.get_vars(play=iterator._play,
task=handler_task,
_hosts=self._hosts_cache,
_hosts_all=self._hosts_cache_all)
handler_task.name = handler_templar.template(handler_task.name)
handler_task.cached_name = True
# first we check with the full result of get_name(), which may
# include the role name (if the handler is from a role). If that
# is not found, we resort to the simple name field, which doesn't
@ -514,11 +514,17 @@ class StrategyBase:
if handler_name in candidates:
return handler_task
except (UndefinedError, AnsibleUndefinedVariable):
except (UndefinedError, AnsibleUndefinedVariable) as e:
# We skip this handler due to the fact that it may be using
# a variable in the name that was conditionally included via
# set_fact or some other method, and we don't want to error
# out unnecessarily
if not handler_task.listen:
display.warning(
"Handler '%s' is unusable because it has no listen topics and "
"the name could not be templated (host-specific variables are "
"not supported in handler names). The error: %s" % (handler_task.name, to_text(e))
)
continue
return None

@ -0,0 +1,9 @@
---
- hosts: localhost
gather_facts: no
tasks:
- include_role:
name: import_template_handler_names
tags:
- lazy_evaluation
- evaluation_time

@ -0,0 +1,11 @@
- import_role:
name: template_handler_names
tasks_from: lazy_evaluation
tags:
- lazy_evaluation
- import_role:
name: template_handler_names
tasks_from: evaluation_time
tags:
- evaluation_time

@ -0,0 +1,5 @@
- name: handler name with {{ test_var }}
debug: msg='handler with var ran'
- name: handler name
debug: msg='handler ran'

@ -0,0 +1,5 @@
- debug: msg='notify handler with variable in name'
notify: handler name with myvar
changed_when: True
tags:
- evaluation_time

@ -0,0 +1,5 @@
- debug: msg='notify handler'
notify: handler name
changed_when: True
tags:
- lazy_evaluation

@ -96,3 +96,21 @@ result="$(ansible-playbook test_handlers_template_run_once.yml -i inventory.hand
set -e
grep -q "handler A" <<< "$result"
grep -q "handler B" <<< "$result"
# Test an undefined variable in another handler name isn't a failure
ansible-playbook 58841.yml "$@" --tags lazy_evaluation 2>&1 | tee out.txt ; cat out.txt
grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
[ "$(grep out.txt -ce 'handler ran')" = "1" ]
[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]
# Test templating a handler name with a defined variable
ansible-playbook 58841.yml "$@" --tags evaluation_time -e test_var=myvar | tee out.txt ; cat out.txt
[ "$(grep out.txt -ce 'handler ran')" = "0" ]
[ "$(grep out.txt -ce 'handler with var ran')" = "1" ]
# Test the handler is not found when the variable is undefined
ansible-playbook 58841.yml "$@" --tags evaluation_time 2>&1 | tee out.txt ; cat out.txt
grep out.txt -e "ERROR! The requested handler 'handler name with myvar' was not found"
grep out.txt -e "\[WARNING\]: Handler 'handler name with {{ test_var }}' is unusable"
[ "$(grep out.txt -ce 'handler ran')" = "0" ]
[ "$(grep out.txt -ce 'handler with var ran')" = "0" ]

Loading…
Cancel
Save