summaryrefslogtreecommitdiff
blob: 80b9350d3e379aa7cc2c718c9e05602cc64a7ad7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
From fbe9ec58c7f48d2cef4a49ba96e84bce5933d654 Mon Sep 17 00:00:00 2001
From: Denis Dupeyron <calchan@gentoo.org>
Date: Wed, 9 Aug 2017 12:01:31 -0500
Subject: [PATCH] template: fix KeyError: 'undefined variable: 0

Fixes: https://github.com/ansible/ansible/issues/20494

Based on a patch by Zac Medico at:
https://github.com/zmedico/ansible/pull/1/commits/32e5613a95e525c3a25b8cd5aa1beaa75a4b0d5c
---
 lib/ansible/template/template.py | 10 ++++++++--
 lib/ansible/template/vars.py     | 14 +++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/ansible/template/template.py b/lib/ansible/template/template.py
index 55936f4..fe11471 100644
--- a/lib/ansible/template/template.py
+++ b/lib/ansible/template/template.py
@@ -33,5 +33,11 @@ class AnsibleJ2Template(jinja2.environment.Template):
     '''
 
     def new_context(self, vars=None, shared=False, locals=None):
-        return self.environment.context_class(self.environment, vars.add_locals(locals), self.name, self.blocks)
-
+        if vars is not None:
+            if isinstance(vars, dict):
+                vars = vars.copy()
+                if locals is not None:
+                    vars.update(locals)
+            else:
+                vars = vars.add_locals(locals)
+        return self.environment.context_class(self.environment, vars, self.name, self.blocks)
diff --git a/lib/ansible/template/vars.py b/lib/ansible/template/vars.py
index fc6140c..2bf95ac 100644
--- a/lib/ansible/template/vars.py
+++ b/lib/ansible/template/vars.py
@@ -19,6 +19,8 @@
 from __future__ import (absolute_import, division, print_function)
 __metaclass__ = type
 
+from collections import Mapping
+
 from ansible.compat.six import iteritems
 from jinja2.utils import missing
 from ansible.module_utils._text import to_native
@@ -27,7 +29,7 @@ from ansible.module_utils._text import to_native
 __all__ = ['AnsibleJ2Vars']
 
 
-class AnsibleJ2Vars:
+class AnsibleJ2Vars(Mapping):
     '''
     Helper class to template all variable content before jinja2 sees it. This is
     done by hijacking the variable storage that jinja2 uses, and overriding __contains__
@@ -68,6 +70,16 @@ class AnsibleJ2Vars:
             return True
         return False
 
+    def __iter__(self):
+        keys = set()
+        keys.update(self._templar._available_variables, self._locals, self._globals, *self._extras)
+        return iter(keys)
+
+    def __len__(self):
+        keys = set()
+        keys.update(self._templar._available_variables, self._locals, self._globals, *self._extras)
+        return len(keys)
+
     def __getitem__(self, varname):
         if varname not in self._templar._available_variables:
             if varname in self._locals:
-- 
2.13.3