Prevent templating unused variables for {%include%} (#68749)

Fixes #68699

(cherry picked from commit ff1ba39c8a)
pull/71986/head
Rick Elrod 4 years ago
parent a63baa3290
commit 9d54f13ec1

@ -0,0 +1,2 @@
bugfixes:
- "Prevent templating unused variables for {% include %} (https://github.com/ansible/ansible/issues/68699)"

@ -27,6 +27,7 @@ import pwd
import re import re
import time import time
from distutils.version import LooseVersion
from numbers import Number from numbers import Number
try: try:
@ -65,6 +66,8 @@ NON_TEMPLATED_TYPES = (bool, Number)
JINJA2_OVERRIDE = '#jinja2:' JINJA2_OVERRIDE = '#jinja2:'
from jinja2 import __version__ as j2_version
USE_JINJA2_NATIVE = False USE_JINJA2_NATIVE = False
if C.DEFAULT_JINJA2_NATIVE: if C.DEFAULT_JINJA2_NATIVE:
try: try:
@ -74,7 +77,6 @@ if C.DEFAULT_JINJA2_NATIVE:
except ImportError: except ImportError:
from jinja2 import Environment from jinja2 import Environment
from jinja2.utils import concat as j2_concat from jinja2.utils import concat as j2_concat
from jinja2 import __version__ as j2_version
display.warning( display.warning(
'jinja2_native requires Jinja 2.10 and above. ' 'jinja2_native requires Jinja 2.10 and above. '
'Version detected: %s. Falling back to default.' % j2_version 'Version detected: %s. Falling back to default.' % j2_version
@ -297,6 +299,40 @@ class AnsibleContext(Context):
self._update_unsafe(val) self._update_unsafe(val)
return val return val
def get_all(self):
"""Return the complete context as a dict including the exported
variables. For optimizations reasons this might not return an
actual copy so be careful with using it.
This is to prevent from running ``AnsibleJ2Vars`` through dict():
``dict(self.parent, **self.vars)``
In Ansible this means that ALL variables would be templated in the
process of re-creating the parent because ``AnsibleJ2Vars`` templates
each variable in its ``__getitem__`` method. Instead we re-create the
parent via ``AnsibleJ2Vars.add_locals`` that creates a new
``AnsibleJ2Vars`` copy without templating each variable.
This will prevent unnecessarily templating unused variables in cases
like setting a local variable and passing it to {% include %}
in a template.
Also see ``AnsibleJ2Template``and
https://github.com/pallets/jinja/commit/d67f0fd4cc2a4af08f51f4466150d49da7798729
"""
if LooseVersion(j2_version) >= LooseVersion('2.9'):
if not self.vars:
return self.parent
if not self.parent:
return self.vars
if isinstance(self.parent, AnsibleJ2Vars):
return self.parent.add_locals(self.vars)
else:
# can this happen in Ansible?
return dict(self.parent, **self.vars)
class JinjaPluginIntercept(MutableMapping): class JinjaPluginIntercept(MutableMapping):
def __init__(self, delegatee, pluginloader, *args, **kwargs): def __init__(self, delegatee, pluginloader, *args, **kwargs):

@ -26,9 +26,9 @@ __all__ = ['AnsibleJ2Template']
class AnsibleJ2Template(jinja2.environment.Template): class AnsibleJ2Template(jinja2.environment.Template):
''' '''
A helper class, which prevents Jinja2 from running _jinja2_vars through dict(). A helper class, which prevents Jinja2 from running AnsibleJ2Vars through dict().
Without this, {% include %} and similar will create new contexts unlike the special Without this, {% include %} and similar will create new contexts unlike the special
one created in template_from_file. This ensures they are all alike, except for one created in Templar.template. This ensures they are all alike, except for
potential locals. potential locals.
''' '''

@ -22,3 +22,6 @@ ansible-playbook filter_plugins.yml -v "$@"
# https://github.com/ansible/ansible/issues/55152 # https://github.com/ansible/ansible/issues/55152
ansible-playbook undefined_var_info.yml -v "$@" ansible-playbook undefined_var_info.yml -v "$@"
# https://github.com/ansible/ansible/issues/68699
ansible-playbook unused_vars_include.yml -v "$@"

@ -0,0 +1,2 @@
{% set var_set_in_template=test_var %}
{% include "unused_vars_include.j2" %}

@ -0,0 +1,8 @@
- hosts: localhost
gather_facts: no
vars:
test_var: foo
unused_var: "{{ undefined_var }}"
tasks:
- debug:
msg: "{{ lookup('template', 'unused_vars_template.j2') }}"
Loading…
Cancel
Save