Skip to content

Commit

Permalink
Upgrade Vault hvac and update Vault modules (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanDinu authored Jul 19, 2019
1 parent 8708bc5 commit 76e5603
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 25 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ msrestazure==0.6.0
Jinja2==2.10.1
hashmerge
python-consul
hvac==0.8.2
hvac==0.9.3
passgen
inflection==0.3.1
kubernetes==9.0.0
25 changes: 20 additions & 5 deletions src/ops/ansible/filter_plugins/commonfilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,27 @@ def flatten_tree(d, parent_key='', sep='/'):
items.append((new_key, v))
return dict(items)

def read_vault(secret_path, key='value', fetch_all=False, vault_user=None,vault_url=None, token=None, auto_prompt=True):
def read_vault(
secret_path, key='value', fetch_all=False, vault_user=None, vault_url=None,
token=None, namespace=None, mount_point=None, auto_prompt=True):

from ops.simplevault import SimpleVault
sv = SimpleVault(vault_user=vault_user, vault_addr=vault_url, vault_token=token,auto_prompt=auto_prompt)
sv = SimpleVault(
vault_user=vault_user, vault_addr=vault_url, vault_token=token,
namespace=namespace, mount_point=mount_point, auto_prompt=auto_prompt)
return sv.get(path=secret_path, key=key, fetch_all=fetch_all)

def write_vault(secret_path, key='value', data="", vault_user=None, vault_url=None, token=None, auto_prompt=True):
def write_vault(
secret_path, key='value', data="", vault_user=None, vault_url=None,
namespace=None, mount_point=None, token=None, auto_prompt=True):

from ops.simplevault import SimpleVault
sv = SimpleVault(vault_user=vault_user, vault_addr=vault_url, vault_token=token, auto_prompt=auto_prompt)
sv = SimpleVault(
vault_user=vault_user, vault_addr=vault_url, vault_token=token,
namespace=None, mount_point=None, auto_prompt=auto_prompt)
new_data = {}
if isinstance(data, dict):
for k,v in new_data.iteritems():
for k,v in data.iteritems():
new_data[k] = str(v)
elif key:
new_data[key] = str(data)
Expand All @@ -92,6 +102,8 @@ def managed_vault_secret(secret_path,key='value',
vault_user=None,
vault_addr=None,
vault_token=None,
namespace=None,
mount_point=None,
auto_prompt=True):
from ops.simplevault import ManagedVaultSecret
ms = ManagedVaultSecret(path=secret_path,
Expand All @@ -100,6 +112,8 @@ def managed_vault_secret(secret_path,key='value',
vault_user=vault_user,
vault_addr=vault_addr,
vault_token=vault_token,
namespace=namespace,
mount_point=mount_point,
auto_prompt=auto_prompt)
return ms.get()

Expand All @@ -112,6 +126,7 @@ def escape_json(input):
return escaped

class FilterModule(object):

def filters(self):
return {
'escape_new_lines': escape_new_lines,
Expand Down
51 changes: 32 additions & 19 deletions src/ops/simplevault.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
MAX_LDAP_ATTEMPTS = 3
class SimpleVault(object):
p_vault_conn = None
# persistent vault connection
def __init__(self, vault_user=None, vault_addr=None, vault_token=None, persistent_session=True, auto_prompt=True):
# persistent vault connection
def __init__(
self, vault_user=None, vault_addr=None, vault_token=None, namespace=None,
mount_point=None, persistent_session=True, auto_prompt=True):
def try_reading_token_file():
ret = None
try:
Expand All @@ -49,13 +51,15 @@ def write_token(token=None):
#with vault running on the provisioner's machine ?
self.vault_token = vault_token or os.getenv('VAULT_TOKEN',None) or try_reading_token_file()
self.vault_user = vault_user or os.getenv('VAULT_USER', None) or getpass.getuser()
self.mount_point = mount_point
self.namespace = namespace
self.ldap_attempts = 0

if persistent_session:
if SimpleVault.p_vault_conn:
self.vault_conn = SimpleVault.p_vault_conn
else:
self.vault_conn = hvac.Client(url=self.vault_addr, token=self.vault_token)
self.vault_conn = hvac.Client(url=self.vault_addr, namespace=self.namespace, token=self.vault_token)

while not self.vault_conn.is_authenticated() and auto_prompt:
display("VAULT-LIB: Not authenticated to vault '%s'" % self.vault_addr, stderr=True, color='red')
Expand All @@ -65,7 +69,7 @@ def write_token(token=None):
try:
self.ldap_attempts +=1
ldap_password = getpass.getpass(prompt='LDAP password for %s for server %s: ' % (self.vault_user, self.vault_addr))
auth_response = self.vault_conn.auth_ldap(self.vault_user, ldap_password)
auth_response = self.vault_conn.auth.ldap.login(username=self.vault_user, password=ldap_password)
self.vault_conn.is_authenticated()
self.vault_token = auth_response['auth']['client_token']
write_token(self.vault_token)
Expand All @@ -81,25 +85,27 @@ def get(self, path, key='value', wrap_ttl=None, default=None, fetch_all=False, r
if fetch_all:
key=None
try:
raw_data = self.vault_conn.read(path, wrap_ttl=wrap_ttl) or {}
data = raw_data.get('data') or {}
raw_data = self.vault_conn.secrets.kv.v2.read_secret_version(
path=path, mount_point=self.mount_point)
# move this check earlier, and, if true, return immediately
if raw:
return raw_data
data = raw_data.get('data')
if isinstance(data, dict):
if not fetch_all:
if key:
return data.get(key, default)
# the actual secret k v pairs are nested under another dictionary key "data"
return data.get("data").get(key, default)
else:
raise('VAULT-LIB: either key or fetch_all should be set!')

except Exception as e:
if raise_exceptions:
raise e
else:
data = default
if raw:
return raw_data
else:
return data
def put(self,path,value,lease=None,wrap_ttl=None):
return data

def put(self, path, value, lease=None, wrap_ttl=None):
payload = {}
if isinstance(value, (basestring, int, float, bool)):
payload['value'] = str(value)
Expand All @@ -108,15 +114,20 @@ def put(self,path,value,lease=None,wrap_ttl=None):
payload[k] = str(v)
else:
raise Exception('Unsupported data type for secret payload')
self.vault_conn.write(path, wrap_ttl,**payload)
self.vault_conn.secrets.kv.v2.create_or_update_secret(
path=path, secret=payload, mount_point=self.mount_point)

def is_authenticated(self):
return self.vault_conn.is_authenticated()


class ManagedVaultSecret(object):
p_sv = None
# Persistent SimpleVault accessory object
def __init__(self, path, key='value', policy={}, vault_user=None, vault_addr=None, vault_token=None, auto_prompt=True):
# Persistent SimpleVault accessory object
def __init__(
self, path, key='value', policy={}, vault_user=None, vault_addr=None,
vault_token=None, namespace=None, mount_point=None, auto_prompt=True):

self.__DEFAULT_POLICY__ = {
'engine': 'passgen',
'length': 24
Expand All @@ -125,6 +136,8 @@ def __init__(self, path, key='value', policy={}, vault_user=None, vault_addr=Non
self.already_initialized = False
self.actual_policy = self.__DEFAULT_POLICY__.copy()
self.key = key
self.mount_point = mount_point
self.namespace = namespace
if isinstance(policy,int):
self.actual_policy.update({'length': policy})
elif isinstance(policy,dict):
Expand All @@ -140,7 +153,9 @@ def __init__(self, path, key='value', policy={}, vault_user=None, vault_addr=Non
self.sv = ManagedVaultSecret.p_sv
else:
try:
self.sv = SimpleVault(vault_user=None, vault_addr=None, vault_token=None, auto_prompt=True)
self.sv = SimpleVault(
vault_user=None, vault_addr=None, vault_token=None, auto_prompt=True,
namespace=self.namespace, mount_point=self.mount_point)
ManagedVaultSecret.p_sv = self.sv
except Exception as e:
display('MANAGED-SECRET: could not obtain a proper Vault connection.\n{}'.format(e.message))
Expand All @@ -166,8 +181,6 @@ def __init__(self, path, key='value', policy={}, vault_user=None, vault_addr=Non
raise e
try:
#generating and storing the new secret


self.new_data = self.current_data.copy()
self.new_data[key] = passgen.passgen(**generator_args)
self.sv.put(path, self.new_data)
Expand Down

0 comments on commit 76e5603

Please sign in to comment.