Repository: ansible/ansible

Issue:
foreman.py: Host recently created not found if cache is enabled
The foreman inventory doesn't allow to discover and use recently created foreman hosts if the cache is enabled. 

##### ISSUE TYPE
 - Feature Idea

##### COMPONENT NAME
foreman.py

##### ANSIBLE VERSION
```
$ ./bin/ansible --version
ansible 2.5.0 (pull-issue-foreman 604a2132d4) last updated 2017/12/07 00:55:40 (GMT +200)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/gsciorti/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/gsciorti/PycharmProjects/ansible/lib/ansible
  executable location = ./bin/ansible
  python version = 2.7.14 (default, Nov  3 2017, 10:55:25) [GCC 7.2.1 20170915 (Red Hat 7.2.1-2)]
```

##### CONFIGURATION
Not related to ansible.cfg

##### OS / ENVIRONMENT
N/A

##### SUMMARY
On large foreman infrastructure(thousands of hosts) the foreman inventory takes half hour or hours to scan the foreman hosts so the cache usually is enabled. Until the cache expire, the new hosts created in foreman aren't added in ansible foreman inventory because when the ansible foreman inventory doesn't manage a cache miss calling the foreman api to retrieve the data of the new host.
Feature of Foreman(or Red Hat Satellite) like ansible callback( https://www.youtube.com/watch?v=gY-lbZ8XoLA ) after the provisioning of a new host fails with an error because the new host isn't present in the inventory if the cache of foreman inventory is enabled.

##### STEPS TO REPRODUCE
1) Run foreman.py enabling cache
2) Create a new host on foreman
3) Run foreman.py before cache expire

##### EXPECTED RESULTS
During the step 3), foreman inventory should call foreman API to collect the data of the new host 

##### ACTUAL RESULTS
During the step 3), foreman inventory doesn't return the new host


Discussion:

Resolving patch:
diff --git a/contrib/inventory/foreman.py b/contrib/inventory/foreman.py
--- a/contrib/inventory/foreman.py
+++ b/contrib/inventory/foreman.py
@@ -139,6 +139,10 @@ def read_settings(self):
             self.cache_max_age = config.getint('cache', 'max_age')
         except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
             self.cache_max_age = 60
+        try:
+            self.scan_new_hosts = config.getboolean('cache', 'scan_new_hosts')
+        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
+            self.scan_new_hosts = False
 
         return True
 
@@ -267,13 +271,15 @@ def to_safe(self, word):
         regex = "[^A-Za-z0-9\_]"
         return re.sub(regex, "_", word.replace(" ", ""))
 
-    def update_cache(self):
+    def update_cache(self, scan_only_new_hosts=False):
         """Make calls to foreman and save the output in a cache"""
 
         self.groups = dict()
         self.hosts = dict()
 
         for host in self._get_hosts():
+            if host['name'] in self.cache.keys() and scan_only_new_hosts:
+                continue
             dns_name = host['name']
 
             host_data = self._get_host_data_by_id(host['id'])
@@ -387,6 +393,8 @@ def get_inventory(self):
             self.load_facts_from_cache()
             self.load_hostcollections_from_cache()
             self.load_cache_from_cache()
+            if self.scan_new_hosts:
+                self.update_cache(True)
 
     def get_host_info(self):
         """Get variables about a specific host"""


Test patch: