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)
... | ... |
@@ -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] |