Browse code

Create a raw lookup for hostvars that does not template the data

When using hostvars to get extra connection-specific vars for connection
plugins, use this raw lookup to avoid prematurely templating all of the
hostvar data (triggering unnecessary lookups).

Fixes #17024

(cherry picked from commit ac5ddf4aa092e12f9e1c85c6b74aa30b7ef0a382)

James Cammarata authored on 2016/09/22 00:34:57
Showing 2 changed files
... ...
@@ -409,7 +409,17 @@ class TaskExecutor:
409 409
         # get the connection and the handler for this execution
410 410
         if not self._connection or not getattr(self._connection, 'connected', False) or self._play_context.remote_addr != self._connection._play_context.remote_addr:
411 411
             self._connection = self._get_connection(variables=variables, templar=templar)
412
-            self._connection.set_host_overrides(host=self._host, hostvars=variables.get('hostvars', {}).get(self._host.name, {}))
412
+            hostvars = variables.get('hostvars', None)
413
+            if hostvars:
414
+                try:
415
+                    target_hostvars = hostvars.raw_get(self._host.name)
416
+                except:
417
+                    # FIXME: this should catch the j2undefined error here
418
+                    #        specifically instead of all exceptions
419
+                    target_hostvars = dict()
420
+            else:
421
+                target_hostvars = dict()
422
+            self._connection.set_host_overrides(host=self._host, hostvars=target_hostvars)
413 423
         else:
414 424
             # if connection is reused, its _play_context is no longer valid and needs
415 425
             # to be replaced with the one templated above, in case other data changed
... ...
@@ -68,13 +68,19 @@ class HostVars(collections.Mapping):
68 68
             host = self._inventory.get_host(host_name)
69 69
         return host
70 70
 
71
-    def __getitem__(self, host_name):
71
+    def raw_get(self, host_name):
72
+        '''
73
+        Similar to __getitem__, however the returned data is not run through
74
+        the templating engine to expand variables in the hostvars.
75
+        '''
72 76
         host = self._find_host(host_name)
73 77
         if host is None:
74 78
             raise j2undefined
75 79
 
76
-        data = self._variable_manager.get_vars(loader=self._loader, host=host, include_hostvars=False)
80
+        return self._variable_manager.get_vars(loader=self._loader, host=host, include_hostvars=False)
77 81
 
82
+    def __getitem__(self, host_name):
83
+        data = self.raw_get(host_name)
78 84
         sha1_hash = sha1(str(data).encode('utf-8')).hexdigest()
79 85
         if sha1_hash in self._cached_result:
80 86
             result = self._cached_result[sha1_hash]