From 9afdb7fec199c16b33d356ef8c6ab2a1ef812323 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 14 Jul 2022 21:14:25 +0200 Subject: [PATCH] template module/lookup: fix convert_data for macros (#78259) Fixes #78141 --- .../78141-template-fix-convert_data.yml | 2 ++ lib/ansible/plugins/lookup/template.py | 2 +- lib/ansible/template/__init__.py | 17 ++++++++++++----- .../integration/targets/template/tasks/main.yml | 8 ++++++++ .../targets/template/templates/json_macro.j2 | 2 ++ 5 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 changelogs/fragments/78141-template-fix-convert_data.yml create mode 100644 test/integration/targets/template/templates/json_macro.j2 diff --git a/changelogs/fragments/78141-template-fix-convert_data.yml b/changelogs/fragments/78141-template-fix-convert_data.yml new file mode 100644 index 00000000000..6623f972bf2 --- /dev/null +++ b/changelogs/fragments/78141-template-fix-convert_data.yml @@ -0,0 +1,2 @@ +bugfixes: + - template module/lookup - fix ``convert_data`` option that was effectively always set to True for Jinja macros (https://github.com/ansible/ansible/issues/78141) diff --git a/lib/ansible/plugins/lookup/template.py b/lib/ansible/plugins/lookup/template.py index 6e98d282819..9c575b53acd 100644 --- a/lib/ansible/plugins/lookup/template.py +++ b/lib/ansible/plugins/lookup/template.py @@ -153,7 +153,7 @@ class LookupModule(LookupBase): res = templar.template(template_data, preserve_trailing_newlines=True, convert_data=convert_data_p, escape_backslashes=False) - if C.DEFAULT_JINJA2_NATIVE and not jinja2_native: + if (C.DEFAULT_JINJA2_NATIVE and not jinja2_native) or not convert_data_p: # jinja2_native is true globally but off for the lookup, we need this text # not to be processed by literal_eval anywhere in Ansible res = NativeJinjaText(res) diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index 1c0bb8eac4f..ef33e74ef3f 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -1120,15 +1120,21 @@ class Templar: # save/restore cur_context to prevent overriding __UNSAFE__. cached_context = self.cur_context + # the concat function is set for each Ansible environment, + # however for convert_data=False we need to use the concat + # function that avoids any evaluation and set it temporarily + # on the environment so it is used correctly even when + # the concat function is called internally in Jinja, + # most notably for macro execution + cached_concat = self.environment.concat + if not self.jinja2_native and not convert_data: + self.environment.concat = ansible_concat + self.cur_context = t.new_context(jvars, shared=True) rf = t.root_render_func(self.cur_context) try: - if not self.jinja2_native and not convert_data: - res = ansible_concat(rf) - else: - res = self.environment.concat(rf) - + res = self.environment.concat(rf) unsafe = getattr(self.cur_context, 'unsafe', False) if unsafe: res = wrap_var(res) @@ -1142,6 +1148,7 @@ class Templar: raise AnsibleError("Unexpected templating type error occurred on (%s): %s" % (to_native(data), to_native(te))) finally: self.cur_context = cached_context + self.environment.concat = cached_concat if isinstance(res, string_types) and preserve_trailing_newlines: # The low level calls above do not preserve the newline diff --git a/test/integration/targets/template/tasks/main.yml b/test/integration/targets/template/tasks/main.yml index 94fe9abdfc3..102effeedf4 100644 --- a/test/integration/targets/template/tasks/main.yml +++ b/test/integration/targets/template/tasks/main.yml @@ -793,3 +793,11 @@ that: - override_colon_value_task is success - override_colon_value_diff.rc == 0 + +- assert: + that: + - data_not_converted | type_debug == 'NativeJinjaUnsafeText' + - data_converted | type_debug == 'dict' + vars: + data_not_converted: "{{ lookup('template', 'json_macro.j2', convert_data=False) }}" + data_converted: "{{ lookup('template', 'json_macro.j2') }}" diff --git a/test/integration/targets/template/templates/json_macro.j2 b/test/integration/targets/template/templates/json_macro.j2 new file mode 100644 index 00000000000..080f1648760 --- /dev/null +++ b/test/integration/targets/template/templates/json_macro.j2 @@ -0,0 +1,2 @@ +{% macro m() %}{{ {"foo":"bar"} }}{% endmacro %} +{{ m() }}