Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
191 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,38 @@ | ||
# Vaultutils | ||
# LSST Vault Utilities | ||
|
||
This package is a set of Vault utilities useful for the LSST use case. | ||
|
||
## Classes | ||
|
||
The package name is `lsstvaultutils`. Its functional classes are: | ||
|
||
1. `SecretCopier` -- this copies secrets between the current Kubernetes | ||
context and a Vault instance. | ||
|
||
2. `TokenAdmin` -- this highly LSST-specific class allows you to specify a | ||
path under the Vault secret store, and it will generate three tokens | ||
(read, write, and admin) for manipulating secrets under the path. It | ||
stores those under secret/delegated, so that an admin can find (and, | ||
if need be, revoke) them later. It also manages revoking those | ||
tokens and removing them from the secret/delegated path. | ||
|
||
3. `RecursiveDeleter` -- this adds a recursive deletion feature to Vault | ||
for removing a whole secret tree at a time. | ||
|
||
There is also a TimeFormatter class that exists only to add milliseconds | ||
to the debugging logs. | ||
|
||
## Programs | ||
|
||
The major functionality of these classes is also exposed as standalone | ||
programs. | ||
|
||
1. `copyk2v` -- copy a Kubernetes secret to a Vault secret path. | ||
|
||
2. `copyv2k` -- copy a set of Vault secrets at a specified path to a | ||
Kubernetes secret. | ||
|
||
3. `tokenadmin` -- Creating or revoke token sets for a given Vault secret | ||
path. | ||
|
||
4. `vaultrmrf` -- Remove a Vault secret path and everything underneath it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#!/usr/bin/env python | ||
"""RecursiveDeleter removes an entire secret tree from Vault. | ||
""" | ||
|
||
import logging | ||
import click | ||
import hvac | ||
from .timeformatter import TimeFormatter | ||
|
||
|
||
@click.command() | ||
@click.argument('vault_secret_path') | ||
@click.option('--url', envvar='VAULT_ADDR', | ||
help="URL of Vault endpoint.") | ||
@click.option('--token', envvar='VAULT_TOKEN', | ||
help="Vault token to use.") | ||
@click.option('--cacert', envvar='VAULT_CAPATH', | ||
help="Path to Vault CA certificate.") | ||
@click.option('--debug', envvar='DEBUG', is_flag=True, | ||
help="Enable debugging.") | ||
def standalone(vault_secret_path, url, token, cacert, debug): | ||
client = RecursiveDeleter(url, token, cacert, debug) | ||
client.recursive_delete(vault_secret_path) | ||
|
||
|
||
class RecursiveDeleter(object): | ||
"""Class to remove a whole secret tree from Vault. | ||
""" | ||
|
||
def __init__(self, url, token, cacert, debug): | ||
logger = logging.getLogger(__name__) | ||
if debug: | ||
logger.setLevel(logging.DEBUG) | ||
ch = logging.StreamHandler() | ||
if debug: | ||
ch.setLevel(logging.DEBUG) | ||
formatter = TimeFormatter( | ||
'%(asctime)s [%(levelname)s] %(name)s | %(message)s', | ||
datefmt='%Y-%m-%d %H:%M:%S.%F %Z(%z)') | ||
ch.setFormatter(formatter) | ||
logger.addHandler(ch) | ||
self.logger = logger | ||
if debug: | ||
self.logger.debug("Debug logging started.") | ||
if not url and token and cacert: | ||
raise ValueError("All of Vault URL, Vault Token, and Vault CA " + | ||
"path must be present, either in the " + | ||
"or as options.") | ||
self.vault_client = self.get_vault_client(url, token, cacert) | ||
|
||
def get_vault_client(self, url, token, cacert): | ||
"""Acquire a Vault client. | ||
""" | ||
self.logger.debug("Acquiring Vault client for '%s'." % url) | ||
client = hvac.Client(url=url, token=token, verify=cacert) | ||
assert client.is_authenticated() | ||
return client | ||
|
||
def recursive_delete(self, path): | ||
"""Delete path and everything under it. | ||
""" | ||
self.logger.debug("Removing '%s' recursively." % path) | ||
pkeys = [] | ||
resp = self.vault_client.list(path) | ||
if resp: | ||
self.logger.debug("Removing tree rooted at '%s'" % path) | ||
pkeys = resp["data"]["keys"] | ||
for item in [(path + "/" + x) for x in pkeys]: | ||
self.recursive_delete(item) | ||
else: | ||
self.logger.debug("Removing '%s' as leaf node." % path) | ||
self.vault_client.delete(path) | ||
|
||
|
||
if __name__ == '__main__': | ||
standalone() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import logging | ||
import time | ||
|
||
|
||
class TimeFormatter(logging.Formatter): | ||
"""Time formatter that does milliseconds. | ||
https://stackoverflow.com/questions/6290739/\ | ||
python-logging-use-milliseconds-in-time-format | ||
""" | ||
|
||
def formatTime(self, record, datefmt=None): | ||
ct = self.converter(record.created) | ||
if datefmt: | ||
if "%F" in datefmt: | ||
msec = "%03d" % record.msecs | ||
datefmt = datefmt.replace("%F", msec) | ||
s = time.strftime(datefmt, ct) | ||
else: | ||
t = time.strftime("%Y-%m-%d %H:%M:%S", ct) | ||
s = "%s,%03d" % (t, record.msecs) | ||
return s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters