ansible/lookup/vault: use ansible variable

Signed-off-by: Alexis Pentori <alexis@status.im>
This commit is contained in:
Alexis Pentori 2024-09-26 11:51:33 +02:00
parent 5096a10bb9
commit 10457bfb7d
No known key found for this signature in database
GPG Key ID: 65250D2801E47A10
1 changed files with 48 additions and 31 deletions

View File

@ -5,15 +5,11 @@ import sys
import os import os
import hvac import hvac
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
try: display = Display()
from __main__ import display
except ImportError:
from ansible.utils.display import Display
display = Display()
DOCUMENTATION = """ DOCUMENTATION = """
@ -26,20 +22,45 @@ requirements:
- VAULT_TOKEN environment var - VAULT_TOKEN environment var
short_description: look up data from a Hashicorp vault short_description: look up data from a Hashicorp vault
decription: decription:
- Use the hvac library to grab one or more items stored in a Hashicorp Vault - Use the hvac library to grab one or more items stored in a Hashicorp Vault
- The plugin use the variable <env> and <stage> form ansible to determined the path to query
options: options:
path: path:
description: path of the secret in the Vault description: Path of the secret in the Vault, by default the Path will be prefixed by the <env>/<stage>/<path>
required: true required: true
field: field:
description: field to return from vault description: Field to return from vault
required: true required: true
stage:
description: Override the value of stage used in the path
required: false
env:
description: Override the value of the env used in the path
required: false
override:
description: Search only for the path specifed
required: false
""" """
Examples = """ Examples = """
- name: get 'username' from Vault entry 'test' - name: Get 'username' from Vault entry 'config' to fetch secret from 'example/test/config'
debug: debug:
msg: "{{ lookup('vault, 'test', field='username' ) }}" msg: "{{ lookup('vault, 'config', field='username' )}}"
vars:
env: 'example'
stage: 'test'
- name: Get 'username' from Vault entry 'config' to fetch secret from 'example-2/prod/config'
debug:
msg: "{{ lookup('vault, 'test', field='username', stage='prod', env='example-2' )}}"
vars:
env: 'example'
stage: 'test'
- name: Get 'username' from Vault entry 'config' to fetch secret from 'other/path/to/config'
debug:
msg: "{{ lookup('vault, 'other/path/to/config', field='username', override=True)}}"
vars:
env: 'example'
stage: 'test'
""" """
RETURN = """ RETURN = """
@ -47,39 +68,35 @@ RETURN = """
description: description:
- Items for Hashicorp Vault - Items for Hashicorp Vault
""" """
VAULT_CACERT = os.environ.get('VAULT_CACERT', './ansible/files/vault-ca.crt')
VAULT_CLIENT_CERT = os.environ.get('VAULT_CLIENT_CERT', './ansible/files/vault-client-user.crt')
VAULT_CLIENT_KEY = os.environ.get('VAULT_CLIENT_KEY', './ansible/files/vault-client-user.key')
class LookupModule(LookupBase): class LookupModule(LookupBase):
def run(self, terms, **kwargs): def run(self, terms, field: str, variables=None, override: str = False, **kwargs):
VAULT_CACERT = os.environ.get('VAULT_CACERT', './ansible/files/vault-ca.crt')
VAULT_CLIENT_CERT = os.environ.get('VAULT_CLIENT_CERT', './ansible/files/vault-client-user.crt')
VAULT_CLIENT_KEY = os.environ.get('VAULT_CLIENT_KEY', './ansible/files/vault-client-user.key')
self.vault = hvac.Client(cert=(VAULT_CLIENT_CERT, VAULT_CLIENT_KEY),verify=VAULT_CACERT) self.vault = hvac.Client(cert=(VAULT_CLIENT_CERT, VAULT_CLIENT_KEY),verify=VAULT_CACERT)
values = [] values = []
env = kwargs.get("env", variables["env"])
stage = kwargs.get("stage", variables["stage"])
prefix = ""
if override:
display.debug("Overriding the env/stage behavior and using only the path provided: %s" % terms)
else:
display.debug("Using the env : %s and the stage : %s" % (env, stage))
prefix=f"{env}/{stage}/"
for term in terms: for term in terms:
rval = self.lookup(term, kwargs) rval = self.lookup(f"{prefix}{term}", field=field)
if rval is None: if rval is None:
raise AnsibleError("No matching term, field found!") raise AnsibleError("No matching term, field not found!")
values.append(rval) values.append(rval)
return values return values
def lookup(self, term, kwargs): def lookup(self, term, **kwargs):
field = kwargs.get('field') field = kwargs.get('field')
display.v("Querying Vault field %s at path %s" % (field,term))
val = self.vault.secrets.kv.read_secret_version(term) val = self.vault.secrets.kv.read_secret_version(term)
if val: if val:
return str(val['data']['data'][field]) return str(val['data']['data'][field])
def main():
if len(sys.argv) < 3:
print("Usage: %s <path> <field>" % os.path.basename(__file__))
return -1
print(LookupModule().run(sys.argv[1], field=sys.argv[2]))
return 0
if __name__ == "__main__":
sys.exit(main())