diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py index 9a2b6f4845a..4133b1b53da 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -86,7 +86,6 @@ class VariableManager: self._loader = loader self._hostvars = None self._omit_token = '__omit_place_holder__%s' % sha1(os.urandom(64)).hexdigest() - self._templar = Templar(loader=self._loader) self._options_vars = load_options_vars(version_info) @@ -318,7 +317,7 @@ class VariableManager: # and magic vars so we can properly template the vars_files entries temp_vars = combine_vars(all_vars, self._extra_vars) temp_vars = combine_vars(temp_vars, magic_variables) - self._templar.available_variables = temp_vars + templar = Templar(loader=self._loader, variables=temp_vars) # we assume each item in the list is itself a list, as we # support "conditional includes" for vars_files, which mimics @@ -332,7 +331,7 @@ class VariableManager: # raise an error, which is silently ignored at this point. try: for vars_file in vars_file_list: - vars_file = self._templar.template(vars_file) + vars_file = templar.template(vars_file) if not (isinstance(vars_file, Sequence)): raise AnsibleError( "Invalid vars_files entry found: %r\n" @@ -465,7 +464,8 @@ class VariableManager: if self._inventory is not None: variables['groups'] = self._inventory.get_groups_dict() if play: - if self._templar.is_template(play.hosts): + templar = Templar(loader=self._loader) + if templar.is_template(play.hosts): pattern = 'all' else: pattern = play.hosts or 'all' @@ -498,16 +498,16 @@ class VariableManager: # as we're fetching vars before post_validate has been called on # the task that has been passed in vars_copy = existing_variables.copy() - self._templar.available_variables = vars_copy + templar = Templar(loader=self._loader, variables=vars_copy) items = [] has_loop = True if task.loop_with is not None: if task.loop_with in lookup_loader: try: - loop_terms = listify_lookup_plugin_terms(terms=task.loop, templar=self._templar, + loop_terms = listify_lookup_plugin_terms(terms=task.loop, templar=templar, loader=self._loader, fail_on_undefined=True, convert_bare=False) - items = lookup_loader.get(task.loop_with, loader=self._loader, templar=self._templar).run(terms=loop_terms, variables=vars_copy) + items = lookup_loader.get(task.loop_with, loader=self._loader, templar=templar).run(terms=loop_terms, variables=vars_copy) except AnsibleTemplateError: # This task will be skipped later due to this, so we just setup # a dummy array for the later code so it doesn't fail @@ -516,7 +516,7 @@ class VariableManager: raise AnsibleError("Failed to find the lookup named '%s' in the available lookup plugins" % task.loop_with) elif task.loop is not None: try: - items = self._templar.template(task.loop) + items = templar.template(task.loop) except AnsibleTemplateError: # This task will be skipped later due to this, so we just setup # a dummy array for the later code so it doesn't fail @@ -533,8 +533,8 @@ class VariableManager: if item is not None: vars_copy[item_var] = item - self._templar.available_variables = vars_copy - delegated_host_name = self._templar.template(task.delegate_to, fail_on_undefined=False) + templar.set_available_variables = vars_copy + delegated_host_name = templar.template(task.delegate_to, fail_on_undefined=False) if delegated_host_name != task.delegate_to: cache_items = True if delegated_host_name is None: diff --git a/test/integration/targets/template/filter_plugins.yml b/test/integration/targets/template/filter_plugins.yml new file mode 100644 index 00000000000..c3e97a541a5 --- /dev/null +++ b/test/integration/targets/template/filter_plugins.yml @@ -0,0 +1,9 @@ +- hosts: localhost + gather_facts: no + tasks: + - debug: + msg: "force templating in delegate_to before we hit the second one with a filter" + delegate_to: "{{ 'localhost' }}" + + - include_role: + name: role_filter diff --git a/test/integration/targets/template/role_filter/filter_plugins/myplugin.py b/test/integration/targets/template/role_filter/filter_plugins/myplugin.py new file mode 100644 index 00000000000..44935ab0ea1 --- /dev/null +++ b/test/integration/targets/template/role_filter/filter_plugins/myplugin.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + + +class FilterModule(object): + def filters(self): + return {'parse_ip': self.parse_ip} + + def parse_ip(self, ip): + return ip diff --git a/test/integration/targets/template/role_filter/tasks/main.yml b/test/integration/targets/template/role_filter/tasks/main.yml new file mode 100644 index 00000000000..7d962a29fbd --- /dev/null +++ b/test/integration/targets/template/role_filter/tasks/main.yml @@ -0,0 +1,3 @@ +- name: test + command: echo hello + delegate_to: "{{ '127.0.0.1' | parse_ip }}" diff --git a/test/integration/targets/template/runme.sh b/test/integration/targets/template/runme.sh index c4f50b1c7e2..352b41a3f4d 100755 --- a/test/integration/targets/template/runme.sh +++ b/test/integration/targets/template/runme.sh @@ -16,3 +16,6 @@ ANSIBLE_ROLES_PATH=../ ansible-playbook custom_template.yml -i ../../inventory - # Test for several corner cases #57188 ansible-playbook corner_cases.yml -v "$@" + +# Test for #57351 +ansible-playbook filter_plugins.yml -v "$@"