listing and secret name removal done

This commit is contained in:
brent s. 2020-04-14 14:33:33 -04:00
parent 36369b6ca8
commit 018384dfce
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
3 changed files with 44 additions and 29 deletions

View File

@ -232,7 +232,7 @@ class VaultPass(object):
lpath = path.split('/') lpath = path.split('/')
kname = lpath[-1] kname = lpath[-1]
path = '/'.join(lpath[0:-1]) path = '/'.join(lpath[0:-1])
self.removeSecretName(kname, path, mount, force = force, destroy = destroy) self.removeSecretName(kname, path, mount, destroy = destroy)
return(handler(**args)) return(handler(**args))


def editSecret(self, path, mount, editor_prog = constants.EDITOR, *args, **kwargs): def editSecret(self, path, mount, editor_prog = constants.EDITOR, *args, **kwargs):
@ -458,17 +458,43 @@ class VaultPass(object):
exists = self._pathExists(orig_path, mount, is_secret = True) exists = self._pathExists(orig_path, mount, is_secret = True)
data = {} data = {}
if exists: if exists:
if not force:
_logger.debug('Getting confirmation to update/replace {0} ({1}) on mount {2}'.format(path,
kname,
mount))
confirmation = self._getConfirm(('Secret name {0} at path {1} on mount {2} exists. '
'Overwrite/update? (y/N) ').format(kname, path, mount))
if not confirmation:
_logger.debug('Confirmation denied; skipping.')
return(None)
data = self.getSecret(path, mount, kname = kname) data = self.getSecret(path, mount, kname = kname)
data[kname] = secret data[kname] = secret
self.createSecret(data, path, mount, force = force) self.createSecret(data, path, mount, force = force)
return(None) return(None)


def listSecretNames(self, path, mount, output = None, indent = 4, *args, **kwargs): def listSecretNames(self, path, mount, output = None, indent = 4, *args, **kwargs):
pass # TODO exists = self._pathExists(path, mount)
is_secret = self._pathExists(path, mount, is_secret = True)
if not any((exists, is_secret)):
_logger.error('Invalid path')
_logger.debug('Path {0} on mount {1} is invalid/does not exist.'.format(path, mount))
raise ValueError('Invalid path')
self.mount.getSecretsTree(path = path, mounts = mount)
outstr = self.mount.printer(path = path, mounts = mount, output = output, indent = indent)
print(outstr)
return(None)


def removeSecretName(self, kname, path, mount, force = False, destroy = False, *args, **kwargs): def removeSecretName(self, kname, path, mount, destroy = False, *args, **kwargs):
# NOTE: this should edit a secret such that it removes a key from the dict at path. # NOTE: this should edit a secret such that it removes a key from the dict at path.
pass # TODO data = self.getSecret(path, mount)
if kname not in data:
_logger.error('Secret name does not exist')
_logger.debug('Secret name {0} does not exist in {1}:{2}.'.format(kname, mount, path))
raise ValueError('Secret name does not exist')
del(data[kname])
# TODO: handle destroy?
self.createSecret(data, path, mount, force = True)
return(data)


def searchSecrets(self, pattern, mount, *args, **kwargs): def searchSecrets(self, pattern, mount, *args, **kwargs):
pass # TODO pass # TODO

View File

@ -5,6 +5,7 @@ import string
NAME = 'VaultPass' NAME = 'VaultPass'
VERSION = '0.0.1' VERSION = '0.0.1'
SUPPORTED_ENGINES = ('kv1', 'kv2', 'cubbyhole') SUPPORTED_ENGINES = ('kv1', 'kv2', 'cubbyhole')
# SUPPORTED_OUTPUT_FORMATS = ('pretty', 'yaml', 'json', 'tree')
SUPPORTED_OUTPUT_FORMATS = ('pretty', 'yaml', 'json') SUPPORTED_OUTPUT_FORMATS = ('pretty', 'yaml', 'json')
ALPHA_LOWER_PASS_CHARS = string.ascii_lowercase ALPHA_LOWER_PASS_CHARS = string.ascii_lowercase
ALPHA_UPPER_PASS_CHARS = string.ascii_uppercase ALPHA_UPPER_PASS_CHARS = string.ascii_uppercase

View File

@ -133,21 +133,6 @@ class MountHandler(object):
obj = dpath.util.get(self.paths, fullpath, None) obj = dpath.util.get(self.paths, fullpath, None)
return(obj) return(obj)


def getSecret(self, path, mount, version = None):
if not self.mounts:
self.getSysMounts()
mtype = self.getMountType(mount)
args = {}
handler = None
if mtype == 'cubbyhole':
handler = self.cubbyhandler.read_secret
elif mtype == 'kv1':
handler = self.client.secrets.kv.v1.read_secret
if mtype == 'kv2':
args['version'] = version
data = self.client.secrets
# TODO

def getSecretNames(self, path, mount, version = None): def getSecretNames(self, path, mount, version = None):
reader = None reader = None
mtype = self.getMountType(mount) mtype = self.getMountType(mount)
@ -267,7 +252,7 @@ class MountHandler(object):
_logger.debug('Added mountpoint {0} to mounts list with type {1}'.format(mount, mtype)) _logger.debug('Added mountpoint {0} to mounts list with type {1}'.format(mount, mtype))
return(None) return(None)


def printer(self, output = None, indent = 4): def printer(self, path = '/', mounts = None, output = None, indent = 4):
# def treePrint(obj, s = 'Password Store\n', level = 0): # def treePrint(obj, s = 'Password Store\n', level = 0):
# prefix = '├──' # prefix = '├──'
# leading_prefix = '│' # leading_prefix = '│'
@ -276,12 +261,10 @@ class MountHandler(object):
# return(s) # return(s)
if output: if output:
output = output.lower() output = output.lower()
if output and output not in ('pretty', 'yaml', 'json'): if output and output not in constants.SUPPORTED_OUTPUT_FORMATS:
# if output and output not in ('pretty', 'yaml', 'json', 'tree'):
_logger.error('Invalid output format') _logger.error('Invalid output format')
_logger.debug('The output parameter ("{0}") must be one of: pretty, yaml, json, or None'.format(output)) _logger.debug(('The output parameter ("{0}") must be one of: '
# _logger.debug(('The output parameter ("{0}") must be one of: ' '{0}, or None').format(output, ', '.join(constants.SUPPORTED_OUTPUT_FORMATS)))
# 'pretty, yaml, json, tree, or None').format(output))
raise ValueError('Invalid output format') raise ValueError('Invalid output format')
if output in ('pretty', 'yaml', 'json'): if output in ('pretty', 'yaml', 'json'):
if not any(((indent is None), isinstance(indent, int))): if not any(((indent is None), isinstance(indent, int))):
@ -290,20 +273,25 @@ class MountHandler(object):
raise ValueError('indent parameter must be an integer or None') raise ValueError('indent parameter must be an integer or None')
if not self.paths: if not self.paths:
self.getSecretsTree() self.getSecretsTree()
_paths = {}
if not mounts:
mounts = self.mounts.keys()
for m in mounts:
_paths[m] = self.getPath(path, m)
if output == 'json': if output == 'json':
import json import json
return(json.dumps(self.paths, indent = indent)) return(json.dumps(_paths, indent = indent))
elif output == 'yaml': elif output == 'yaml':
import yaml # https://pypi.org/project/PyYAML/ import yaml # https://pypi.org/project/PyYAML/
# import pyaml # https://pypi.python.org/pypi/pyaml # import pyaml # https://pypi.python.org/pypi/pyaml
return(yaml.dump(self.paths, indent = indent)) return(yaml.dump(_paths, indent = indent))
elif output == 'pretty': elif output == 'pretty':
import pprint import pprint
if indent is None: if indent is None:
indent = 1 indent = 1
return(pprint.pformat(self.paths, indent = indent, width = shutil.get_terminal_size((80, 20)).columns)) return(pprint.pformat(_paths, indent = indent, width = shutil.get_terminal_size((80, 20)).columns))
# elif output == 'tree': # elif output == 'tree':
# import tree # TODO? Wayyy later. # import tree # TODO? Wayyy later.
elif not output: elif not output:
return(str(self.paths)) return(str(_paths))
return(None) return(None)