From cace91df5684aea6703fa41da5d9b8cc58893b5c Mon Sep 17 00:00:00 2001
From: James Cammarata <jimi@sngx.net>
Date: Tue, 27 Oct 2015 14:12:17 -0400
Subject: [PATCH] Allow hostvars cache to be invalidated so hostvars contain
 all hosts after add_host

Fixes #12925
---
 lib/ansible/plugins/strategy/__init__.py | 8 ++++++--
 lib/ansible/vars/__init__.py             | 5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index b9746f45cda..1ead5c8438a 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -226,7 +226,7 @@ class StrategyBase:
                     result_item = result[1]
                     new_host_info = result_item.get('add_host', dict())
 
-                    self._add_host(new_host_info)
+                    self._add_host(new_host_info, iterator)
 
                 elif result[0] == 'add_group':
                     host = result[1]
@@ -309,7 +309,7 @@ class StrategyBase:
 
         return ret_results
 
-    def _add_host(self, host_info):
+    def _add_host(self, host_info, iterator):
         '''
         Helper function to add a new host to inventory based on a task result.
         '''
@@ -352,6 +352,10 @@ class StrategyBase:
         # patterns may have referenced the group
         self._inventory.clear_pattern_cache()
 
+        # also clear the hostvar cache entry for the given play, so that
+        # the new hosts are available if hostvars are referenced
+        self._variable_manager.invalidate_hostvars_cache(play=iterator._play)
+
     def _add_group(self, host, result_item):
         '''
         Helper function to add a group (if it does not exist), and to assign the
diff --git a/lib/ansible/vars/__init__.py b/lib/ansible/vars/__init__.py
index 3afb0455671..7ce24f0b0a9 100644
--- a/lib/ansible/vars/__init__.py
+++ b/lib/ansible/vars/__init__.py
@@ -332,6 +332,11 @@ class VariableManager:
         debug("done with get_vars()")
         return all_vars
 
+    def invalidate_hostvars_cache(self, play):
+        hostvars_cache_entry = self._get_cache_entry(play=play)
+        if hostvars_cache_entry in HOSTVARS_CACHE:
+            del HOSTVARS_CACHE[hostvars_cache_entry]
+
     def _get_magic_variables(self, loader, play, host, task, include_hostvars, include_delegate_to):
         '''
         Returns a dictionary of so-called "magic" variables in Ansible,