mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-27 15:11:23 -07:00
Fix inventory cache interface (#50446)
* Replace InventoryFileCacheModule with a better developer-interface Use new interface for inventory plugins with backwards compatibility Auto-update the backing cache-plugin if the cache has changed after parsing the inventory plugin * Update CacheModules to use the config system and add a deprecation warning if they are being imported directly rather than using cache_loader * Fix foreman inventory caching * Add tests * Add integration test to check that fact caching works normally with cache plugins using ansible.constants and inventory caching provides a helpful error for non-compatible cache plugins * Add some developer documentation for inventory and cache plugins * Add user documentation for inventory caching * Add deprecation docs * Apply suggestions from docs review * Add changelog
This commit is contained in:
parent
831f068f98
commit
9687879840
24 changed files with 831 additions and 86 deletions
|
@ -189,9 +189,90 @@ To facilitate this there are a few of helper functions used in the example below
|
|||
|
||||
The specifics will vary depending on API and structure returned. But one thing to keep in mind, if the inventory source or any other issue crops up you should ``raise AnsibleParserError`` to let Ansible know that the source was invalid or the process failed.
|
||||
|
||||
For examples on how to implement an inventory plug in, see the source code here:
|
||||
For examples on how to implement an inventory plugin, see the source code here:
|
||||
`lib/ansible/plugins/inventory <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/inventory>`_.
|
||||
|
||||
.. _inventory_plugin_caching:
|
||||
|
||||
inventory cache
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Extend the inventory plugin documentation with the inventory_cache documentation fragment and use the Cacheable base class to have the caching system at your disposal.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
extends_documentation_fragment:
|
||||
- inventory_cache
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
|
||||
NAME = 'myplugin'
|
||||
|
||||
Next, load the cache plugin specified by the user to read from and update the cache. If your inventory plugin uses YAML based configuration files and the ``_read_config_data`` method, the cache plugin is loaded within that method. If your inventory plugin does not use ``_read_config_data``, you must load the cache explicitly with ``load_cache_plugin``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
NAME = 'myplugin'
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
super(InventoryModule, self).parse(inventory, loader, path)
|
||||
|
||||
self.load_cache_plugin()
|
||||
|
||||
Before using the cache, retrieve a unique cache key using the ``get_cache_key`` method. This needs to be done by all inventory modules using the cache, so you don't use/overwrite other parts of the cache.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
super(InventoryModule, self).parse(inventory, loader, path)
|
||||
|
||||
self.load_cache_plugin()
|
||||
cache_key = self.get_cache_key(path)
|
||||
|
||||
Now that you've enabled caching, loaded the correct plugin, and retrieved a unique cache key, you can set up the flow of data between the cache and your inventory using the ``cache`` parameter of the ``parse`` method. This value comes from the inventory manager and indicates whether the inventory is being refreshed (such as via ``--flush-cache`` or the meta task ``refresh_inventory``). Although the cache shouldn't be used to populate the inventory when being refreshed, the cache should be updated with the new inventory if the user has enabled caching. You can use ``self._cache`` like a dictionary. The following pattern allows refreshing the inventory to work in conjunction with caching.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
super(InventoryModule, self).parse(inventory, loader, path)
|
||||
|
||||
self.load_cache_plugin()
|
||||
cache_key = self.get_cache_key(path)
|
||||
|
||||
# cache may be True or False at this point to indicate if the inventory is being refreshed
|
||||
# get the user's cache option too to see if we should save the cache if it is changing
|
||||
user_cache_setting = self.get_option('cache')
|
||||
|
||||
# read if the user has caching enabled and the cache isn't being refreshed
|
||||
attempt_to_read_cache = user_cache_setting and cache
|
||||
# update if the user has caching enabled and the cache is being refreshed; update this value to True if the cache has expired below
|
||||
cache_needs_update = user_cache_setting and not cache
|
||||
|
||||
# attempt to read the cache if inventory isn't being refreshed and the user has caching enabled
|
||||
if attempt_to_read_cache:
|
||||
try:
|
||||
results = self._cache[cache_key]
|
||||
except KeyError:
|
||||
# This occurs if the cache_key is not in the cache or if the cache_key expired, so the cache needs to be updated
|
||||
cache_needs_update = True
|
||||
|
||||
if cache_needs_updates:
|
||||
results = self.get_inventory()
|
||||
|
||||
# set the cache
|
||||
self._cache[cache_key] = results
|
||||
|
||||
self.populate(results)
|
||||
|
||||
After the ``parse`` method is complete, the contents of ``self._cache`` is used to set the cache plugin if the contents of the cache have changed.
|
||||
|
||||
You have three other cache methods available:
|
||||
- ``set_cache_plugin`` forces the cache plugin to be set with the contents of ``self._cache`` before the ``parse`` method completes
|
||||
- ``update_cache_if_changed`` sets the cache plugin only if ``self._cache`` has been modified before the ``parse`` method completes
|
||||
- ``clear_cache`` deletes the keys in ``self._cache`` from your cache plugin
|
||||
|
||||
.. _inventory_source_common_format:
|
||||
|
||||
Inventory source common format
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue