diff --git a/README.md b/README.md index 1afad18..7180b65 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,15 @@ from the file `$HOME/.vault-token`, as documented at If any such parameter is set by both an environment variable and an alternative means, the environment variable takes precedence. +### Caching + +By default secrets fetched from Vault will be cached in memory, unless you specify + + export ANSIBLE_HASHICORP_VAULT_USE_CACHE=no + +Note that secrets will be fetched once per fork (defaults to 5). If you turn off +this feature by toggling above variable, all lookups will be done per node instead. + ### Usage ansible-vault works as any other lookup plugin. diff --git a/vault.py b/vault.py index 51415aa..edd1457 100644 --- a/vault.py +++ b/vault.py @@ -22,6 +22,8 @@ def __init__(self, basedir=None, runner=None, **kwargs): def get_basedir(self, variables): return self.basedir +_use_vault_cache = os.environ.get("ANSIBLE_HASHICORP_VAULT_USE_CACHE", "yes").lower() in ("yes", "1", "true") +_vault_cache = {} class LookupModule(LookupBase): @@ -81,6 +83,17 @@ def run(self, terms, inject=None, variables=None, **kwargs): cafile = os.getenv('VAULT_CACERT') or (variables or inject).get('vault_cacert') capath = os.getenv('VAULT_CAPATH') or (variables or inject).get('vault_capath') + + if _use_vault_cache and _vault_cache.has_key(key): + result = _vault_cache[key] + else: + result = self._fetch_remotely(cafile, capath, data, key, token, url) + if _use_vault_cache: + _vault_cache[key] = result + + return [result['data'][field]] if field is not None else [result['data']] + + def _fetch_remotely(self, cafile, capath, data, key, token, url): try: context = None if cafile or capath: @@ -106,7 +119,5 @@ def run(self, terms, inject=None, variables=None, **kwargs): raise AnsibleError('Unable to read %s from vault: %s' % (key, e)) except Exception as e: raise AnsibleError('Unable to read %s from vault: %s' % (key, e)) - result = json.loads(response.read()) - - return [result['data'][field]] if field is not None else [result['data']] + return result