104 lines
2.9 KiB
Python
104 lines
2.9 KiB
Python
import functools
|
|
import hashlib
|
|
|
|
from ansible.constants import config
|
|
from ansible.errors import AnsibleError
|
|
from ansible.plugins.loader import cache_loader, lookup_loader
|
|
from ansible.plugins.lookup import LookupBase, display
|
|
|
|
DOCUMENTATION = """
|
|
lookup: cache
|
|
author: Dustin C. Hatch <dustin@hatch.name>
|
|
options:
|
|
cache_plugin:
|
|
description:
|
|
- Cache plugin to use
|
|
type: str
|
|
required: false
|
|
default: memory
|
|
env:
|
|
- name: ANSIBLE_LOOKUP_CACHE_PLUGIN
|
|
ini:
|
|
- section: lookup
|
|
key: cache_plugin
|
|
cache_timeout:
|
|
description:
|
|
- Cache duration in seconds
|
|
default: 3600
|
|
type: int
|
|
env:
|
|
- name: ANSIBLE_LOOKUP_CACHE_TIMEOUT
|
|
ini:
|
|
- section: lookup
|
|
key: cache_timeout
|
|
cache_connection:
|
|
description:
|
|
- Cache connection data or path, read cache plugin documentation for specifics.
|
|
type: str
|
|
env:
|
|
- name: ANSIBLE_LOOKUP_CACHE_CONNECTION
|
|
ini:
|
|
- section: lookup
|
|
key: cache_connection
|
|
cache_prefix:
|
|
description:
|
|
- Prefix to use for cache plugin files/tables
|
|
default: ''
|
|
env:
|
|
- name: ANSIBLE_LOOKUP_CACHE_PREFIX
|
|
ini:
|
|
- section: lookup
|
|
key: cache_prefix
|
|
"""
|
|
|
|
|
|
def _get_option(key: str):
|
|
return config.get_config_value(
|
|
key, plugin_type='lookup', plugin_name='cache'
|
|
)
|
|
|
|
|
|
@functools.cache
|
|
def _get_cache():
|
|
cache_plugin = _get_option('cache_plugin')
|
|
cache_options = {}
|
|
if cache_connection := _get_option('cache_connection'):
|
|
cache_options['_uri'] = cache_connection
|
|
if cache_timeout := _get_option('cache_timeout'):
|
|
cache_options['_timeout'] = cache_timeout
|
|
if cache_prefix := _get_option('cache_prefix'):
|
|
cache_options['_prefix'] = cache_prefix
|
|
return cache_loader.get(cache_plugin, **cache_options)
|
|
|
|
|
|
class LookupModule(LookupBase):
|
|
def run(self, terms, variables=None, **kwargs):
|
|
cache = _get_cache()
|
|
display.v(f'lookup cache: using cache plugin {cache.plugin_name}')
|
|
h = hashlib.sha1()
|
|
h.update(str((terms, kwargs)).encode('utf-8'))
|
|
key = h.hexdigest()
|
|
try:
|
|
result = cache.get(key)
|
|
except KeyError:
|
|
result = None
|
|
if result is None:
|
|
lookup_name, terms = terms[0], terms[1:]
|
|
lookup = lookup_loader.get(
|
|
lookup_name, loader=self._loader, templar=self._templar
|
|
)
|
|
if lookup is None:
|
|
raise AnsibleError(
|
|
f'Could not find lookup plugin {lookup_name!r}'
|
|
)
|
|
result = lookup.run(terms, variables=variables, **kwargs)
|
|
cache.set(key, result)
|
|
else:
|
|
str_terms = ', '.join(repr(t) for t in terms)
|
|
str_kwargs = ', '.join(f'{k}={v!r}' for k, v in kwargs.items())
|
|
display.v(
|
|
'lookup cache: found cached value for'
|
|
f' lookup({str_terms}, {str_kwargs})'
|
|
)
|
|
return result
|