From bd3ffbe10903125993d7d68fa8cfd687124a241f Mon Sep 17 00:00:00 2001 From: Nikita Korolev <66738864+doc-sheet@users.noreply.github.com> Date: Mon, 14 Aug 2023 13:59:40 +0000 Subject: [PATCH] fix incorrect ansible_managed formatting (#79129) Ansible breaks configs if file name could be parsed as jinja template or contains `%` chars. Especially `%n`[ame%] which is a line break pattern according to [strftime (3)](https://manpages.debian.org/bullseye/manpages-dev/strftime.3.en.html) --- ...79129-ansible-managed-filename-format.yaml | 6 ++++ lib/ansible/template/__init__.py | 6 ++-- .../template/ansible_managed_79129.yml | 29 +++++++++++++++++++ test/integration/targets/template/runme.sh | 5 +++- ...%necho Onii-chan help Im stuck;exit 1%n.j2 | 3 ++ .../completely{{ 1 % 0 }} safe template.j2 | 3 ++ 6 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/79129-ansible-managed-filename-format.yaml create mode 100644 test/integration/targets/template/ansible_managed_79129.yml create mode 100644 test/integration/targets/template/templates/%necho Onii-chan help Im stuck;exit 1%n.j2 create mode 100644 test/integration/targets/template/templates/completely{{ 1 % 0 }} safe template.j2 diff --git a/changelogs/fragments/79129-ansible-managed-filename-format.yaml b/changelogs/fragments/79129-ansible-managed-filename-format.yaml new file mode 100644 index 00000000000..36e162f2ea1 --- /dev/null +++ b/changelogs/fragments/79129-ansible-managed-filename-format.yaml @@ -0,0 +1,6 @@ +--- +bugfixes: + - template - Fix for formatting issues when a template path contains + valid jinja/strftime pattern (especially line break one) and + using the template path in ansible_managed + (https://github.com/ansible/ansible/pull/79129) diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index 07ef371754a..482d0e550f3 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -55,7 +55,7 @@ from ansible.template.vars import AnsibleJ2Vars from ansible.utils.display import Display from ansible.utils.listify import listify_lookup_plugin_terms from ansible.utils.native_jinja import NativeJinjaText -from ansible.utils.unsafe_proxy import wrap_var +from ansible.utils.unsafe_proxy import to_unsafe_text, wrap_var display = Display() @@ -103,9 +103,9 @@ def generate_ansible_template_vars(path, fullpath=None, dest_path=None): managed_str = managed_default.format( host=temp_vars['template_host'], uid=temp_vars['template_uid'], - file=temp_vars['template_path'], + file=temp_vars['template_path'].replace('%', '%%'), ) - temp_vars['ansible_managed'] = to_text(time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path)))) + temp_vars['ansible_managed'] = to_unsafe_text(time.strftime(to_native(managed_str), time.localtime(os.path.getmtime(b_path)))) return temp_vars diff --git a/test/integration/targets/template/ansible_managed_79129.yml b/test/integration/targets/template/ansible_managed_79129.yml new file mode 100644 index 00000000000..e00ada8c10a --- /dev/null +++ b/test/integration/targets/template/ansible_managed_79129.yml @@ -0,0 +1,29 @@ +--- +- hosts: testhost + gather_facts: false + tasks: + - set_fact: + output_dir: "{{ lookup('env', 'OUTPUT_DIR') }}" + + - name: check strftime + block: + - template: + src: "templates/%necho Onii-chan help Im stuck;exit 1%n.j2" + dest: "{{ output_dir }}/79129-strftime.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/79129-strftime.sh" + + - name: check jinja template + block: + - template: + src: !unsafe "templates/completely{{ 1 % 0 }} safe template.j2" + dest: "{{ output_dir }}/79129-jinja.sh" + mode: '0755' + + - shell: "exec {{ output_dir | quote }}/79129-jinja.sh" + register: result + + - assert: + that: + - "'Hello' in result.stdout" diff --git a/test/integration/targets/template/runme.sh b/test/integration/targets/template/runme.sh index eaaa6aa6a5c..d3913d971a2 100755 --- a/test/integration/targets/template/runme.sh +++ b/test/integration/targets/template/runme.sh @@ -8,7 +8,10 @@ ANSIBLE_ROLES_PATH=../ ansible-playbook template.yml -i ../../inventory -v "$@" ansible testhost -i testhost, -m debug -a 'msg={{ hostvars["localhost"] }}' -e "vars1={{ undef() }}" -e "vars2={{ vars1 }}" # Test for https://github.com/ansible/ansible/issues/27262 -ansible-playbook ansible_managed.yml -c ansible_managed.cfg -i ../../inventory -v "$@" +ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed.yml -i ../../inventory -v "$@" + +# Test for https://github.com/ansible/ansible/pull/79129 +ANSIBLE_CONFIG=ansible_managed.cfg ansible-playbook ansible_managed_79129.yml -i ../../inventory -v "$@" # Test for #42585 ANSIBLE_ROLES_PATH=../ ansible-playbook custom_template.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/template/templates/%necho Onii-chan help Im stuck;exit 1%n.j2 b/test/integration/targets/template/templates/%necho Onii-chan help Im stuck;exit 1%n.j2 new file mode 100644 index 00000000000..2d63c15870f --- /dev/null +++ b/test/integration/targets/template/templates/%necho Onii-chan help Im stuck;exit 1%n.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} +echo 79129 test passed +exit 0 diff --git a/test/integration/targets/template/templates/completely{{ 1 % 0 }} safe template.j2 b/test/integration/targets/template/templates/completely{{ 1 % 0 }} safe template.j2 new file mode 100644 index 00000000000..c9a04b4fab1 --- /dev/null +++ b/test/integration/targets/template/templates/completely{{ 1 % 0 }} safe template.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} +echo Hello +exit 0