Repository: ansible/ansible

Issue:
custom dynamic inventory caching
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME

##### ANSIBLE VERSION
ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ansible/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible-2.4.0.0-py2.7.egg/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Sep 15 2016, 22:37:39) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]

##### CONFIGURATION
```
ACCELERATE_CONNECT_TIMEOUT(default) = 1.0
ACCELERATE_DAEMON_TIMEOUT(default) = 30
ACCELERATE_KEYS_DIR(default) = ~/.fireball.keys
ACCELERATE_KEYS_DIR_PERMS(default) = 700
ACCELERATE_KEYS_FILE_PERMS(default) = 600
ACCELERATE_MULTI_KEY(default) = False
ACCELERATE_PORT(default) = 5099
ACCELERATE_TIMEOUT(default) = 30
ALLOW_WORLD_READABLE_TMPFILES(default) = False
ANSIBLE_COW_SELECTION(default) = default
ANSIBLE_COW_WHITELIST(default) = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes'
ANSIBLE_FORCE_COLOR(default) = False
ANSIBLE_NOCOLOR(default) = False
ANSIBLE_NOCOWS(default) = False
ANSIBLE_PIPELINING(default) = False
ANSIBLE_SSH_ARGS(default) = -C -o ControlMaster=auto -o ControlPersist=60s
ANSIBLE_SSH_CONTROL_PATH(default) = None
ANSIBLE_SSH_CONTROL_PATH_DIR(default) = ~/.ansible/cp
ANSIBLE_SSH_EXECUTABLE(default) = ssh
ANSIBLE_SSH_PIPELINING(default) = False
ANSIBLE_SSH_RETRIES(default) = 0
ANY_ERRORS_FATAL(default) = False
BECOME_ALLOW_SAME_USER(default) = False
CACHE_PLUGIN(/etc/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/etc/ansible/ansible.cfg) = /tmp/ansible
CACHE_PLUGIN_PREFIX(default) = ansible_facts
CACHE_PLUGIN_TIMEOUT(/etc/ansible/ansible.cfg) = 600
COLOR_CHANGED(default) = yellow
COLOR_DEBUG(default) = dark gray
COLOR_DEPRECATE(default) = purple
COLOR_DIFF_ADD(default) = green
COLOR_DIFF_LINES(default) = cyan
COLOR_DIFF_REMOVE(default) = red
COLOR_ERROR(default) = red
COLOR_HIGHLIGHT(default) = white
COLOR_OK(default) = green
COLOR_SKIP(default) = cyan
COLOR_UNREACHABLE(default) = bright red
COLOR_VERBOSE(default) = blue
COLOR_WARN(default) = bright purple
COMMAND_WARNINGS(default) = True
DEFAULT_ACTION_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/action_plugins']
DEFAULT_ALLOW_UNSAFE_LOOKUPS(default) = False
DEFAULT_ASK_PASS(default) = False
DEFAULT_ASK_SUDO_PASS(default) = False
DEFAULT_ASK_SU_PASS(default) = False
DEFAULT_ASK_VAULT_PASS(default) = False
DEFAULT_BECOME(default) = False
DEFAULT_BECOME_ASK_PASS(default) = False
DEFAULT_BECOME_EXE(default) = None
DEFAULT_BECOME_FLAGS(default) = None
DEFAULT_BECOME_METHOD(default) = sudo
DEFAULT_BECOME_USER(default) = root
DEFAULT_CACHE_PLUGIN_PATH(default) = [u'/home/ansible/.ansible/plugins/cache', u'/usr/share/ansible/plugins/cache']
DEFAULT_CALLABLE_WHITELIST(default) = []
DEFAULT_CALLBACK_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/callback_plugins']
DEFAULT_CALLBACK_WHITELIST(default) = []
DEFAULT_CONNECTION_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/connection_plugins']
DEFAULT_DEBUG(default) = False
DEFAULT_EXECUTABLE(default) = /bin/sh
DEFAULT_FACT_PATH(default) = None
DEFAULT_FILTER_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/filter_plugins']
DEFAULT_FORCE_HANDLERS(default) = False
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 5
DEFAULT_GATHERING(/etc/ansible/ansible.cfg) = smart
DEFAULT_GATHER_SUBSET(default) = all
DEFAULT_GATHER_TIMEOUT(default) = 10
DEFAULT_HANDLER_INCLUDES_STATIC(default) = False
DEFAULT_HASH_BEHAVIOUR(default) = replace
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = [u'/etc/ansible/hosts']
DEFAULT_INTERNAL_POLL_INTERVAL(default) = 0.001
DEFAULT_INVENTORY_PLUGIN_PATH(default) = [u'/home/ansible/.ansible/plugins/inventory', u'/usr/share/ansible/plugins/inventory']
DEFAULT_JINJA2_EXTENSIONS(default) = []
DEFAULT_KEEP_REMOTE_FILES(default) = False
DEFAULT_LIBVIRT_LXC_NOSECLABEL(default) = False
DEFAULT_LOAD_CALLBACK_PLUGINS(default) = False
DEFAULT_LOCAL_TMP(default) = /home/ansible/.ansible/tmp/ansible-local-27902k17bp3
DEFAULT_LOG_PATH(default) =
DEFAULT_LOOKUP_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/lookup_plugins']
DEFAULT_MANAGED_STR(/etc/ansible/ansible.cfg) = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
DEFAULT_MODULE_ARGS(default) =
DEFAULT_MODULE_COMPRESSION(default) = ZIP_DEFLATED
DEFAULT_MODULE_LANG(/etc/ansible/ansible.cfg) = C
DEFAULT_MODULE_NAME(default) = command
DEFAULT_MODULE_PATH(default) = [u'/home/ansible/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
DEFAULT_MODULE_SET_LOCALE(default) = False
DEFAULT_MODULE_UTILS_PATH(default) = [u'/home/ansible/.ansible/plugins/module_utils', u'/usr/share/ansible/plugins/module_utils']
DEFAULT_NO_LOG(default) = False
DEFAULT_NO_TARGET_SYSLOG(default) = False
DEFAULT_NULL_REPRESENTATION(default) = None
DEFAULT_POLL_INTERVAL(/etc/ansible/ansible.cfg) = 15
DEFAULT_PRIVATE_KEY_FILE(/etc/ansible/ansible.cfg) = /home/ansible/.ssh/id_rsa
DEFAULT_PRIVATE_ROLE_VARS(default) = False
DEFAULT_REMOTE_PORT(default) = None
DEFAULT_REMOTE_TMP(/etc/ansible/ansible.cfg) = $HOME/.ansible/tmp
DEFAULT_REMOTE_USER(/etc/ansible/ansible.cfg) = ansible
DEFAULT_ROLES_PATH(default) = [u'/home/ansible/.ansible/roles', u'/usr/share/ansible/roles', u'/etc/ansible/roles']
DEFAULT_SCP_IF_SSH(default) = smart
DEFAULT_SELINUX_SPECIAL_FS(default) = ['fuse', 'nfs', 'vboxsf', 'ramfs', '9p']
DEFAULT_SFTP_BATCH_MODE(default) = True
DEFAULT_SQUASH_ACTIONS(default) = ['apk', 'apt', 'dnf', 'homebrew', 'openbsd_pkg', 'pacman', 'pkgng', 'yum', 'zypper']
DEFAULT_SSH_TRANSFER_METHOD(default) = None
DEFAULT_STDOUT_CALLBACK(default) = default
DEFAULT_STRATEGY(default) = linear
DEFAULT_STRATEGY_PLUGIN_PATH(default) = [u'/home/ansible/.ansible/plugins/strategy', u'/usr/share/ansible/plugins/strategy']
DEFAULT_SU(default) = False
DEFAULT_SUDO(default) = False
DEFAULT_SUDO_EXE(default) = sudo
DEFAULT_SUDO_FLAGS(default) = -H -S -n
DEFAULT_SUDO_USER(default) = None
DEFAULT_SU_EXE(default) = su
DEFAULT_SU_FLAGS(default) = None
DEFAULT_SU_USER(default) = None
DEFAULT_SYSLOG_FACILITY(default) = LOG_USER
DEFAULT_TASK_INCLUDES_STATIC(default) = False
DEFAULT_TEST_PLUGIN_PATH(default) = [u'/home/ansible/.ansible/plugins/test', u'/usr/share/ansible/plugins/test']
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 10
DEFAULT_TRANSPORT(/etc/ansible/ansible.cfg) = smart
DEFAULT_UNDEFINED_VAR_BEHAVIOR(default) = True
DEFAULT_VARS_PLUGIN_PATH(/etc/ansible/ansible.cfg) = [u'/usr/share/ansible_plugins/vars_plugins']
DEFAULT_VAULT_IDENTITY(default) = default
DEFAULT_VAULT_IDENTITY_LIST(default) = []
DEFAULT_VAULT_ID_MATCH(default) = False
DEFAULT_VAULT_PASSWORD_FILE(default) = None
DEFAULT_VERBOSITY(default) = 0
DEPRECATION_WARNINGS(default) = True
DIFF_ALWAYS(default) = False
DIFF_CONTEXT(default) = 3
DISPLAY_ARGS_TO_STDOUT(default) = False
DISPLAY_SKIPPED_HOSTS(/etc/ansible/ansible.cfg) = False
ERROR_ON_MISSING_HANDLER(default) = True
GALAXY_IGNORE_CERTS(default) = False
GALAXY_ROLE_SKELETON(default) = None
GALAXY_ROLE_SKELETON_IGNORE(default) = ['^.git$', '^.*/.git_keep$']
GALAXY_SERVER(default) = https://galaxy.ansible.com
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
INVENTORY_ENABLED(default) = ['host_list', 'script', 'yaml', 'ini']
INVENTORY_IGNORE_EXTS(default) = eval(BLACKLIST_EXTS + ( '~', '.orig', '.ini', '.cfg', '.retry'))
INVENTORY_IGNORE_PATTERNS(default) = []
INVENTORY_UNPARSED_IS_FAILED(default) = False
MAX_FILE_SIZE_FOR_DIFF(default) = 104448
MERGE_MULTIPLE_CLI_TAGS(default) = True
NETWORK_GROUP_MODULES(default) = ['eos', 'nxos', 'ios', 'iosxr', 'junos', 'ce', 'vyos', 'sros', 'dellos9', 'dellos10', 'dellos6', 'asa',
PARAMIKO_HOST_KEY_AUTO_ADD(default) = False
PARAMIKO_LOOK_FOR_KEYS(default) = True
PARAMIKO_PROXY_COMMAND(default) = None
PARAMIKO_PTY(default) = True
PARAMIKO_RECORD_HOST_KEYS(default) = True
PERSISTENT_COMMAND_TIMEOUT(default) = 10
PERSISTENT_CONNECT_RETRY_TIMEOUT(default) = 15
PERSISTENT_CONNECT_TIMEOUT(default) = 30
PERSISTENT_CONTROL_PATH_DIR(default) = /home/ansible/.ansible/pc
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = True
RETRY_FILES_SAVE_PATH(/etc/ansible/ansible.cfg) = /home/ansible/.ansible-retry
SHOW_CUSTOM_STATS(default) = False
STRING_TYPE_FILTERS(default) = ['string', 'to_json', 'to_nice_json', 'to_yaml', 'ppretty', 'json']
SYSTEM_WARNINGS(default) = True
USE_PERSISTENT_CONNECTIONS(default) = False
VARIABLE_PRECEDENCE(default) = ['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play', 'groups_plugins_invent
YAML_FILENAME_EXTENSIONS(default) = ['.yml', '.yaml', '.json']
```
##### SUMMARY
I have a custom dynamic inventory script which generate a json file from a sqlite database.
I use CACHE_PLUGIN to keep ansible_fact.

I update my database and modification are not apply to the playbook execution.
I get the output of my dynamic inventory script which is OK: all my modification are in.

I remark that my inventory json is cached with other ansible_facts.

this behavior appear with ansible 2.4
 
##### STEPS TO REPRODUCE

##### EXPECTED RESULTS
I would like to not cache the result of my dynamic inventory in order to have a up to date inventory while executing a playbook

##### ACTUAL RESULTS
I need to clear the cache in order to have an inventory that reflect the up to date configuration of my inventory.



Discussion:

Resolving patch:
diff --git a/lib/ansible/plugins/inventory/openstack.py b/lib/ansible/plugins/inventory/openstack.py
--- a/lib/ansible/plugins/inventory/openstack.py
+++ b/lib/ansible/plugins/inventory/openstack.py
@@ -117,7 +117,7 @@ class InventoryModule(BaseInventoryPlugin):
 
     NAME = 'openstack'
 
-    def parse(self, inventory, loader, path, cache=True):
+    def parse(self, inventory, loader, path, cache=False):
 
         super(InventoryModule, self).parse(inventory, loader, path)
 
diff --git a/lib/ansible/plugins/inventory/script.py b/lib/ansible/plugins/inventory/script.py
--- a/lib/ansible/plugins/inventory/script.py
+++ b/lib/ansible/plugins/inventory/script.py
@@ -61,7 +61,7 @@ def verify_file(self, path):
 
         return valid
 
-    def parse(self, inventory, loader, path, cache=True):
+    def parse(self, inventory, loader, path, cache=False):
 
         super(InventoryModule, self).parse(inventory, loader, path)
 
diff --git a/lib/ansible/plugins/inventory/virtualbox.py b/lib/ansible/plugins/inventory/virtualbox.py
--- a/lib/ansible/plugins/inventory/virtualbox.py
+++ b/lib/ansible/plugins/inventory/virtualbox.py
@@ -159,7 +159,7 @@ def verify_file(self, path):
                 valid = True
         return valid
 
-    def parse(self, inventory, loader, path, cache=True):
+    def parse(self, inventory, loader, path, cache=False):
 
         super(InventoryModule, self).parse(inventory, loader, path)
 


Test patch: