hscloud/tools/secretstore.py
Sergiusz Bazanski 73cef11c85 *: rejigger tls certs and more
This pretty large change does the following:

 - moves nix from bootstrap.hswaw.net to nix/
 - changes clustercfg to use cfssl and moves it to cluster/clustercfg
 - changes clustercfg to source information about target location of
   certs from nix
 - changes clustercfg to push nix config
 - changes tls certs to have more than one CA
 - recalculates all TLS certs
   (it keeps the old serviceaccoutns key, otherwise we end up with
   invalid serviceaccounts - the cert doesn't match, but who cares,
   it's not used anyway)
2019-04-07 00:06:23 +02:00

82 lines
2.2 KiB
Python

#!/usr/bin/env python3
# A little tool to encrypt/decrypt git secrets. Kinda like password-store, but more purpose specific and portable.
import logging
import os
import sys
import subprocess
keys = [
"63DFE737F078657CC8A51C00C29ADD73B3563D82", # q3k
"482FF104C29294AD1CAF827BA43890A3DE74ECC7", # inf
"F07205946C07EEB2041A72FBC60C64879534F768", # cz2
#"0879F9FCA1C836677BB808C870FD60197E195C26", # implr (expired 2019-02-09)
]
logger = logging.getLogger(__name__)
def encrypt(src, dst):
cmd = ['gpg' , '--encrypt', '--armor', '--batch', '--yes', '--output', dst]
for k in keys:
cmd.append('--recipient')
cmd.append(k)
cmd.append(src)
subprocess.check_call(cmd)
def decrypt(src, dst):
cmd = ['gpg', '--decrypt', '--output', dst, src]
subprocess.check_call(cmd)
class SecretStoreMissing(Exception):
pass
class SecretStore(object):
def __init__(self, plain_root, cipher_root):
self.proot = plain_root
self.croot = cipher_root
def exists(self, suffix):
p = os.path.join(self.proot, suffix)
c = os.path.join(self.croot, suffix)
return os.path.exists(c) or os.path.exists(p)
def plaintext(self, suffix):
return os.path.join(self.proot, suffix)
def open(self, suffix, mode, *a, **kw):
p = os.path.join(self.proot, suffix)
c = os.path.join(self.croot, suffix)
if 'w' in mode:
return open(p, mode, *a, *kw)
if not self.exists(suffix):
raise SecretStoreMissing("Secret {} does not exist".format(suffix))
if not os.path.exists(p) or os.path.getctime(p) < os.path.getctime(c):
logger.info("Decrypting {} ({})...".format(suffix, c))
decrypt(c, p)
return open(p, mode, *a, **kw)
def main():
if len(sys.argv) < 3 or sys.argv[1] not in ('encrypt', 'decrypt'):
sys.stderr.write("Usage: {} encrypt/decrypt file\n".format(sys.argv[0]))
sys.stderr.flush()
return 1
action = sys.argv[1]
src = sys.argv[2]
if action == 'encrypt':
encrypt(src, '-')
else:
decrypt(src, '-')
if __name__ == '__main__':
sys.exit(main() or 0)