diff --git a/.gitignore b/.gitignore index fec1873..518dd43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.inventory-cache +/.lookup-cache /.vault-secret.gpg .fact-cache /secure.yaml diff --git a/ansible.cfg b/ansible.cfg index 5cb5a56..70074cd 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -5,6 +5,7 @@ inventory = hosts, hosts.pyrocufflink.yml callback_plugins = plugins/callback inventory_plugins = plugins/inventory +lookup_plugins = plugins/lookup gathering = smart fact_caching = jsonfile @@ -20,3 +21,7 @@ server = https://ntfy.pyrocufflink.blue [ara] api_client = http api_server = https://ara.ansible.pyrocufflink.blue + +[lookup] +cache_plugin = jsonfile +cache_connection = .lookup-cache diff --git a/group_vars/wildcard-cert.yml b/group_vars/wildcard-cert.yml index abc2167..5ab8d20 100644 --- a/group_vars/wildcard-cert.yml +++ b/group_vars/wildcard-cert.yml @@ -1,21 +1,17 @@ -apache_ssl_certificate_data: >- - {{ - query( +pyrocufflink_wildcard_cert_secret: >- + {{ lookup( + "cache", "kubernetes.core.k8s", kind="Secret", namespace="default", resource_name="pyrocufflink-cert" - )[0].data["tls.crt"] - | b64decode - }} + ) }} -apache_ssl_certificate_key_data: >- - {{ - query( - "kubernetes.core.k8s", - kind="Secret", - namespace="default", - resource_name="pyrocufflink-cert" - )[0].data["tls.key"] - | b64decode - }} +pyrocufflink_wildcard_cert: >- + {{ pyrocufflink_wildcard_cert_secret.data["tls.crt"] | b64decode }} + +pyrocufflink_wildcard_key: >- + {{ pyrocufflink_wildcard_cert_secret.data["tls.key"] | b64decode }} + +apache_ssl_certificate_data: "{{ pyrocufflink_wildcard_cert }}" +apache_ssl_certificate_key_data: "{{ pyrocufflink_wildcard_key }}" diff --git a/plugins/lookup/cache.py b/plugins/lookup/cache.py new file mode 100644 index 0000000..133fd01 --- /dev/null +++ b/plugins/lookup/cache.py @@ -0,0 +1,103 @@ +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 +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