listing and secret name removal done
This commit is contained in:
parent
36369b6ca8
commit
018384dfce
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
Reference in New Issue
Block a user