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:52:17 +02:00
parent 3f479e6827
commit b02a1025de
No known key found for this signature in database
GPG Key ID: 65250D2801E47A10

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())