#!/usr/bin/env python3 # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more # details. import argparse import base64 import sys import ruamel.yaml import ruamel.yaml.scalarstring def main(): argparser = argparse.ArgumentParser(description="Encode or decode Kubernetes Secrets.") argparser.add_argument("mode", help="Mode of operation, either encode or decode.", choices=["encode", "decode"]) argparser.add_argument("path", help="Path to the file to operate on. If set to -, STDIN will be used instead.", default="-", nargs="?") args = argparser.parse_args() yaml = ruamel.yaml.YAML() # Deduce whether to read from STDIN or open a file handle to a given path if args.path == "-": buffer = sys.stdin else: buffer = open(args.path) # Load the manifest manifest = yaml.load(buffer.read()) # Handle any known potential issues if not "kind" in manifest: print("No kind in manifest", file=sys.stderr) return 3 if manifest["kind"] != "Secret": print("Not a secret", file=sys.stderr) return 4 if not "data" in manifest: manifest["data"] = {} # Call appropriate function with the manifest manifest = globals()["secret_" + args.mode](manifest) # Write the processed manifest back as yaml yaml.dump(manifest, sys.stdout) return 0 def secret_decode(manifest): for key in manifest["data"].keys(): # Decode the data manifest["data"][key] = base64.b64decode(manifest["data"][key]).decode("utf-8") # Turn this element into a block quoted string if there are newlines if "\n" in manifest["data"][key]: manifest["data"][key] = ruamel.yaml.scalarstring.LiteralScalarString(manifest["data"][key]) return manifest def secret_encode(manifest): for key in manifest["data"].keys(): # Encode the data manifest["data"][key] = base64.b64encode(str(manifest["data"][key]).encode("utf-8")).decode("utf-8") return manifest if __name__ == '__main__': sys.exit(main())