From 3bec27dc34e946f5ea69e1d0651a8a22f7ab88db Mon Sep 17 00:00:00 2001 From: Rick Elrod Date: Tue, 4 Aug 2020 11:54:28 -0500 Subject: [PATCH] Allow cache_timeout=0 to reach inv. cache plugins (#70977) Change: - Previously, `cache_timeout=0` was seen as falsey and not passed along to cache plugins as an option. Now only "nulley" values are not sent. Test Plan: - New integration tests Tickets: - Fixes #70702 Signed-off-by: Rick Elrod --- lib/ansible/plugins/inventory/__init__.py | 4 +- .../cache_plugins/none.py | 62 +++++++++++++++++++ .../config_with_parameter.yml | 2 + .../plugin_config_for_inventory/runme.sh | 6 ++ .../test_inventory.py | 32 ++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py diff --git a/lib/ansible/plugins/inventory/__init__.py b/lib/ansible/plugins/inventory/__init__.py index d34c1e0a0f8..b7777ef881a 100644 --- a/lib/ansible/plugins/inventory/__init__.py +++ b/lib/ansible/plugins/inventory/__init__.py @@ -232,7 +232,7 @@ class BaseInventoryPlugin(AnsiblePlugin): self.set_options(direct=config) if 'cache' in self._options and self.get_option('cache'): cache_option_keys = [('_uri', 'cache_connection'), ('_timeout', 'cache_timeout'), ('_prefix', 'cache_prefix')] - cache_options = dict((opt[0], self.get_option(opt[1])) for opt in cache_option_keys if self.get_option(opt[1])) + cache_options = dict((opt[0], self.get_option(opt[1])) for opt in cache_option_keys if self.get_option(opt[1]) is not None) self._cache = get_cache_plugin(self.get_option('cache_plugin'), **cache_options) return config @@ -320,7 +320,7 @@ class Cacheable(object): def load_cache_plugin(self): plugin_name = self.get_option('cache_plugin') cache_option_keys = [('_uri', 'cache_connection'), ('_timeout', 'cache_timeout'), ('_prefix', 'cache_prefix')] - cache_options = dict((opt[0], self.get_option(opt[1])) for opt in cache_option_keys if self.get_option(opt[1])) + cache_options = dict((opt[0], self.get_option(opt[1])) for opt in cache_option_keys if self.get_option(opt[1]) is not None) self._cache = get_cache_plugin(plugin_name, **cache_options) def get_cache_key(self, path): diff --git a/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py b/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py new file mode 100644 index 00000000000..62a91c850d3 --- /dev/null +++ b/test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py @@ -0,0 +1,62 @@ +# (c) 2014, Brian Coca, Josh Drake, et al +# (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.cache import BaseCacheModule + +DOCUMENTATION = ''' + cache: none + short_description: write-only cache (no cache) + description: + - No caching at all + version_added: historical + author: core team (@ansible-core) + options: + _timeout: + default: 86400 + description: Expiration timeout for the cache plugin data + env: + - name: ANSIBLE_CACHE_PLUGIN_TIMEOUT + ini: + - key: fact_caching_timeout + section: defaults + type: integer +''' + + +class CacheModule(BaseCacheModule): + def __init__(self, *args, **kwargs): + super(CacheModule, self).__init__(*args, **kwargs) + self.empty = {} + self._timeout = self.get_option('_timeout') + + def get(self, key): + return self.empty.get(key) + + def set(self, key, value): + return value + + def keys(self): + return self.empty.keys() + + def contains(self, key): + return key in self.empty + + def delete(self, key): + del self.emtpy[key] + + def flush(self): + self.empty = {} + + def copy(self): + return self.empty.copy() + + def __getstate__(self): + return self.copy() + + def __setstate__(self, data): + self.empty = data diff --git a/test/integration/targets/plugin_config_for_inventory/config_with_parameter.yml b/test/integration/targets/plugin_config_for_inventory/config_with_parameter.yml index 8ff39884be8..b9e367b8bcc 100644 --- a/test/integration/targets/plugin_config_for_inventory/config_with_parameter.yml +++ b/test/integration/targets/plugin_config_for_inventory/config_with_parameter.yml @@ -1,3 +1,5 @@ plugin: test_inventory departments: - paris +cache: yes +cache_timeout: 0 diff --git a/test/integration/targets/plugin_config_for_inventory/runme.sh b/test/integration/targets/plugin_config_for_inventory/runme.sh index 119a073ac58..2a223258542 100755 --- a/test/integration/targets/plugin_config_for_inventory/runme.sh +++ b/test/integration/targets/plugin_config_for_inventory/runme.sh @@ -14,3 +14,9 @@ ansible-inventory --list -i ./config_without_parameter.yml --export | \ ansible-inventory --list -i ./config_with_parameter.yml --export | \ env python -c "import json, sys; inv = json.loads(sys.stdin.read()); \ assert set(inv['_meta']['hostvars']['test_host']['departments']) == set(['paris'])" + +export ANSIBLE_CACHE_PLUGINS=cache_plugins/ +export ANSIBLE_CACHE_PLUGIN=none +ansible-inventory --list -i ./config_with_parameter.yml --export | \ + env python -c "import json, sys; inv = json.loads(sys.stdin.read()); \ + assert inv['_meta']['hostvars']['test_host']['given_timeout'] == inv['_meta']['hostvars']['test_host']['cache_timeout']" diff --git a/test/integration/targets/plugin_config_for_inventory/test_inventory.py b/test/integration/targets/plugin_config_for_inventory/test_inventory.py index 009caf75a13..6608e85d73e 100644 --- a/test/integration/targets/plugin_config_for_inventory/test_inventory.py +++ b/test/integration/targets/plugin_config_for_inventory/test_inventory.py @@ -18,6 +18,31 @@ DOCUMENTATION = ''' - seine-et-marne - haute-garonne required: False + cache: + description: cache + type: bool + default: false + required: False + cache_plugin: + description: cache plugin + type: str + default: none + required: False + cache_timeout: + description: test cache parameter + type: integer + default: 7 + required: False + cache_connection: + description: cache connection + type: str + default: /tmp/foo + required: False + cache_prefix: + description: cache prefix + type: str + default: prefix_ + required: False ''' EXAMPLES = ''' @@ -49,3 +74,10 @@ class InventoryModule(BaseInventoryPlugin): self.inventory.add_group(group) self.inventory.add_host(group=group, host=host) self.inventory.set_variable(host, 'departments', departments) + + # Ensure the timeout we're given gets sent to the cache plugin + if self.get_option('cache'): + given_timeout = self.get_option('cache_timeout') + cache_timeout = self._cache._plugin.get_option('_timeout') + self.inventory.set_variable(host, 'given_timeout', given_timeout) + self.inventory.set_variable(host, 'cache_timeout', cache_timeout)