|
|
|
@ -39,6 +39,12 @@ import os
|
|
|
|
|
from ansible.errors import AnsibleError
|
|
|
|
|
from ansible.plugins.lookup import LookupBase
|
|
|
|
|
|
|
|
|
|
HAS_HVAC = False
|
|
|
|
|
try:
|
|
|
|
|
import hvac
|
|
|
|
|
HAS_HVAC = True
|
|
|
|
|
except ImportError:
|
|
|
|
|
HAS_HVAC = False
|
|
|
|
|
|
|
|
|
|
ANSIBLE_HASHI_VAULT_ADDR = 'http://127.0.0.1:8200'
|
|
|
|
|
|
|
|
|
@ -48,17 +54,17 @@ if os.getenv('VAULT_ADDR') is not None:
|
|
|
|
|
|
|
|
|
|
class HashiVault:
|
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
|
try:
|
|
|
|
|
import hvac
|
|
|
|
|
except ImportError:
|
|
|
|
|
raise AnsibleError("Please pip install hvac to use this module")
|
|
|
|
|
|
|
|
|
|
self.url = kwargs.get('url', ANSIBLE_HASHI_VAULT_ADDR)
|
|
|
|
|
|
|
|
|
|
self.token = kwargs.get('token')
|
|
|
|
|
if self.token is None:
|
|
|
|
|
raise AnsibleError("No Hashicorp Vault Token specified for hash_vault lookup")
|
|
|
|
|
|
|
|
|
|
# split secret arg, which has format 'secret/hello:value' into secret='secret/hello' and secret_field='value'
|
|
|
|
|
s = kwargs.get('secret')
|
|
|
|
|
if s is None:
|
|
|
|
|
raise AnsibleError("No secret specified")
|
|
|
|
|
raise AnsibleError("No secret specified for hashi_vault lookup")
|
|
|
|
|
|
|
|
|
|
s_f = s.split(':')
|
|
|
|
|
self.secret = s_f[0]
|
|
|
|
@ -97,22 +103,20 @@ class HashiVault:
|
|
|
|
|
|
|
|
|
|
self.client = hvac.Client(url=self.url, token=self.token)
|
|
|
|
|
|
|
|
|
|
if self.client.is_authenticated():
|
|
|
|
|
pass
|
|
|
|
|
else:
|
|
|
|
|
raise AnsibleError("Invalid authentication credentials specified")
|
|
|
|
|
if not self.client.is_authenticated():
|
|
|
|
|
raise AnsibleError("Invalid Hashicorp Vault Token Specified for hashi_vault lookup")
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
|
data = self.client.read(self.secret)
|
|
|
|
|
|
|
|
|
|
if data is None:
|
|
|
|
|
raise AnsibleError("The secret %s doesn't seem to exist" % self.secret)
|
|
|
|
|
raise AnsibleError("The secret %s doesn't seem to exist for hashi_vault lookup" % self.secret)
|
|
|
|
|
|
|
|
|
|
if self.secret_field == '': # secret was specified with trailing ':'
|
|
|
|
|
return data['data']
|
|
|
|
|
|
|
|
|
|
if self.secret_field not in data['data']:
|
|
|
|
|
raise AnsibleError("The secret %s does not contain the field '%s'. " % (self.secret, self.secret_field))
|
|
|
|
|
raise AnsibleError("The secret %s does not contain the field '%s'. for hashi_vault lookup" % (self.secret, self.secret_field))
|
|
|
|
|
|
|
|
|
|
return data['data'][self.secret_field]
|
|
|
|
|
|
|
|
|
@ -134,6 +138,9 @@ class HashiVault:
|
|
|
|
|
|
|
|
|
|
class LookupModule(LookupBase):
|
|
|
|
|
def run(self, terms, variables, **kwargs):
|
|
|
|
|
if not HAS_HVAC:
|
|
|
|
|
raise AnsibleError("Please pip install hvac to use the hashi_vault lookup module.")
|
|
|
|
|
|
|
|
|
|
vault_args = terms[0].split(' ')
|
|
|
|
|
vault_dict = {}
|
|
|
|
|
ret = []
|
|
|
|
@ -141,8 +148,8 @@ class LookupModule(LookupBase):
|
|
|
|
|
for param in vault_args:
|
|
|
|
|
try:
|
|
|
|
|
key, value = param.split('=')
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
raise AnsibleError("hashi_vault plugin needs key=value pairs, but received %s" % terms)
|
|
|
|
|
except ValueError:
|
|
|
|
|
raise AnsibleError("hashi_vault lookup plugin needs key=value pairs, but received %s" % terms)
|
|
|
|
|
vault_dict[key] = value
|
|
|
|
|
|
|
|
|
|
vault_conn = HashiVault(**vault_dict)
|
|
|
|
|