diff --git a/changelogs/fragments/34209-template-lookup-vault-support.yaml b/changelogs/fragments/34209-template-lookup-vault-support.yaml new file mode 100644 index 00000000000..e3bdec0a7dc --- /dev/null +++ b/changelogs/fragments/34209-template-lookup-vault-support.yaml @@ -0,0 +1,2 @@ +minor_changes: + - Allow for vaulted templates in template lookup (https://github.com/ansible/ansible/issues/34209) diff --git a/lib/ansible/plugins/lookup/template.py b/lib/ansible/plugins/lookup/template.py index a5b2d8a16ce..a5b30b06261 100644 --- a/lib/ansible/plugins/lookup/template.py +++ b/lib/ansible/plugins/lookup/template.py @@ -73,41 +73,41 @@ class LookupModule(LookupBase): lookupfile = self.find_file_in_search_path(variables, 'templates', term) display.vvvv("File lookup using %s as file" % lookupfile) if lookupfile: - with open(to_bytes(lookupfile, errors='surrogate_or_strict'), 'rb') as f: - template_data = to_text(f.read(), errors='surrogate_or_strict') - - # set jinja2 internal search path for includes - searchpath = variables.get('ansible_search_path', []) - if searchpath: - # our search paths aren't actually the proper ones for jinja includes. - # We want to search into the 'templates' subdir of each search path in - # addition to our original search paths. - newsearchpath = [] - for p in searchpath: - newsearchpath.append(os.path.join(p, 'templates')) - newsearchpath.append(p) - searchpath = newsearchpath - searchpath.insert(0, os.path.dirname(lookupfile)) - - self._templar.environment.loader.searchpath = searchpath - if variable_start_string is not None: - self._templar.environment.variable_start_string = variable_start_string - if variable_end_string is not None: - self._templar.environment.variable_end_string = variable_end_string - - # The template will have access to all existing variables, - # plus some added by ansible (e.g., template_{path,mtime}), - # plus anything passed to the lookup with the template_vars= - # argument. - vars = variables.copy() - vars.update(generate_ansible_template_vars(lookupfile)) - vars.update(lookup_template_vars) - self._templar.set_available_variables(vars) - - # do the templating - res = self._templar.template(template_data, preserve_trailing_newlines=True, - convert_data=convert_data_p, escape_backslashes=False) - ret.append(res) + b_template_data, show_data = self._loader._get_file_contents(lookupfile) + template_data = to_text(b_template_data, errors='surrogate_or_strict') + + # set jinja2 internal search path for includes + searchpath = variables.get('ansible_search_path', []) + if searchpath: + # our search paths aren't actually the proper ones for jinja includes. + # We want to search into the 'templates' subdir of each search path in + # addition to our original search paths. + newsearchpath = [] + for p in searchpath: + newsearchpath.append(os.path.join(p, 'templates')) + newsearchpath.append(p) + searchpath = newsearchpath + searchpath.insert(0, os.path.dirname(lookupfile)) + + self._templar.environment.loader.searchpath = searchpath + if variable_start_string is not None: + self._templar.environment.variable_start_string = variable_start_string + if variable_end_string is not None: + self._templar.environment.variable_end_string = variable_end_string + + # The template will have access to all existing variables, + # plus some added by ansible (e.g., template_{path,mtime}), + # plus anything passed to the lookup with the template_vars= + # argument. + vars = variables.copy() + vars.update(generate_ansible_template_vars(lookupfile)) + vars.update(lookup_template_vars) + self._templar.set_available_variables(vars) + + # do the templating + res = self._templar.template(template_data, preserve_trailing_newlines=True, + convert_data=convert_data_p, escape_backslashes=False) + ret.append(res) else: raise AnsibleError("the template file %s could not be found for the lookup" % term) diff --git a/test/integration/targets/lookups/runme.sh b/test/integration/targets/lookups/runme.sh index 5fc31826685..4fda3bfdf3d 100755 --- a/test/integration/targets/lookups/runme.sh +++ b/test/integration/targets/lookups/runme.sh @@ -7,3 +7,5 @@ set -eux pip install passlib ANSIBLE_ROLES_PATH=../ ansible-playbook lookups.yml -i ../../inventory -e @../../integration_config.yml "$@" + +ansible-playbook template_lookup_vaulted.yml -i ../../inventory -e @../../integration_config.yml --vault-password-file test_vault_pass "$@" diff --git a/test/integration/targets/lookups/template_lookup_vaulted.yml b/test/integration/targets/lookups/template_lookup_vaulted.yml new file mode 100644 index 00000000000..23f32e8f411 --- /dev/null +++ b/test/integration/targets/lookups/template_lookup_vaulted.yml @@ -0,0 +1,13 @@ +# https://github.com/ansible/ansible/issues/34209 +- hosts: localhost + gather_facts: no + vars: + hello_world: Hello World + tasks: + - name: Test that template lookup can handle vaulted templates + set_fact: + vaulted_hello_world: "{{ lookup('template', 'vaulted_hello.j2') }}" + + - assert: + that: + - "vaulted_hello_world|trim == 'Unvaulted Hello World!'" diff --git a/test/integration/targets/lookups/templates/vaulted_hello.j2 b/test/integration/targets/lookups/templates/vaulted_hello.j2 new file mode 100644 index 00000000000..a6e98bd8a8e --- /dev/null +++ b/test/integration/targets/lookups/templates/vaulted_hello.j2 @@ -0,0 +1,6 @@ +$ANSIBLE_VAULT;1.1;AES256 +33623433323331343363343830343365376233386637366264646634663632343963396664393463 +3734626234626639323061643863613164643365363063310a663336663762356135396430353435 +39303930613231336135623761363130653235666433383965306235653963343166633233323638 +6635303662333734300a623063393761376531636535383164333632613839663237336463616436 +62643437623538633335366435346532636666616139386332323034336530356131 diff --git a/test/integration/targets/lookups/test_vault_pass b/test/integration/targets/lookups/test_vault_pass new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/test/integration/targets/lookups/test_vault_pass @@ -0,0 +1 @@ +test