From c520d70bf4748c8ee6718a7d0d0254051ba1c2e9 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Thu, 20 Feb 2020 00:04:01 +0100 Subject: [PATCH] Templating: make sure only one variable results are cached (#67429) * Make sure only one variable results are cached. * Add changelog. * Add test. --- changelogs/fragments/67429-jinja2-caching.yml | 2 ++ lib/ansible/template/__init__.py | 2 +- .../template_lookups/tasks/main.yml | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/67429-jinja2-caching.yml diff --git a/changelogs/fragments/67429-jinja2-caching.yml b/changelogs/fragments/67429-jinja2-caching.yml new file mode 100644 index 00000000000..cd081050855 --- /dev/null +++ b/changelogs/fragments/67429-jinja2-caching.yml @@ -0,0 +1,2 @@ +bugfixes: +- "Templating - Ansible was caching results of Jinja2 expressions in some cases where these expressions could have dynamic results, like password generation (https://github.com/ansible/ansible/issues/34144)." diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index 7cea02bc771..b4e8118a4dd 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -628,7 +628,7 @@ class Templar: # we only cache in the case where we have a single variable # name, to make sure we're not putting things which may otherwise # be dynamic in the cache (filters, lookups, etc.) - if cache: + if cache and only_one: self._cached_result[sha1_hash] = result return result diff --git a/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml b/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml index 5988847b856..cfeea2d56c1 100644 --- a/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml +++ b/test/integration/targets/templating_lookups/template_lookups/tasks/main.yml @@ -71,3 +71,18 @@ - name: set with_dict shell: echo "{{ item.key + '=' + item.value }}" with_dict: "{{ mydict }}" + +# BUG #34144 bad template caching + +- name: generate two random passwords + set_fact: + password1: "{{ lookup('password', '/dev/null length=20') }}" + password2: "{{ lookup('password', '/dev/null length=20') }}" + # If the passwords are generated randomly, the chance that they + # coincide is neglectable (< 1e-18 assuming 120 bits of randomness + # per password). + +- name: make sure passwords are not the same + assert: + that: + - password1 != password2