Description
Which component:
kubeseal
Is your feature request related to a problem? Please describe.
Updating an existing secret is a kind of convoluted, 2-step process, which involes a lot of boilerplate, compared to the actual input required to change or add a new keypair to the yaml file:
Describe the solution you'd like
A single subcommand, something like
kubeseal set KEY VALUE sealed-secrets.yaml
Describe alternatives you've considered
Creating a python script on the side, but there's pushback on adding it to our FluxCD repo, as it seems kind of out of scope (our repo consists entirely of yaml files that represent our cluster's state, whereas this would be a script)
Additional context
I'd be happy to contribute a PR if maintainers are willing to accept this feature
The python script i'm referring to looks a little something like this:
add-to-sealed-secrets.py
#!/usr/bin/env python
import argparse
import subprocess
import os
def get_namespace(sealed_secrets_file):
try:
import yaml
except ImportError:
print("PyYAML is required to determine namespace from namespace.yaml. Install it using 'pip install pyyaml', or specify the namespace explicitly with -n")
exit(1)
# Extract directory path and filename
directory = os.path.dirname(sealed_secrets_file)
namespace_file = os.path.join(directory, 'namespace.yaml')
if os.path.exists(namespace_file):
# Read the namespace from namespace.yaml using PyYAML
with open(namespace_file, 'r') as file:
data = yaml.safe_load(file)
if 'metadata' in data and 'name' in data['metadata']:
return data['metadata']['name']
return None
def add_to_sealed_secret(sealed_secrets_file, key, value, namespace):
try:
# If namespace is not provided, try to get it from namespace.yaml
if not namespace:
namespace = get_namespace(sealed_secrets_file)
if namespace is None:
print("Namespace not provided and unable to determine from namespace.yaml.")
exit(1)
# Execute kubectl command to create secret
kubectl_cmd = ['kubectl', 'create', 'secret', 'generic', 'xxx', '--dry-run=client',
'--from-file=' + key + '=/dev/stdin', '-o', 'json', '-n', namespace]
kubectl_process = subprocess.Popen(kubectl_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
secret_json, _ = kubectl_process.communicate(input=value.encode())
# Execute kubeseal command to seal the secret and append it to the sealed-secrets.yaml file
kubeseal_cmd = ['kubeseal', '--controller-namespace=kube-system', '--controller-name=sealed-secrets-controller',
'--format', 'yaml', '--merge-into', sealed_secrets_file]
subprocess.run(kubeseal_cmd, input=secret_json)
print("Secret sealed and added to", sealed_secrets_file)
except subprocess.CalledProcessError as e:
print(f"Error: {e}")
exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Add or modify a key in a sealed secret')
parser.add_argument('sealed_secrets_file', help='Path to the sealed secrets YAML file')
parser.add_argument('key', help='Key of the secret')
parser.add_argument('value', help='Value of the secret')
parser.add_argument('-n', '--namespace', help='Namespace for the secret (detected from the namespace.yaml next to the sealed secrets file if not specified)')
args = parser.parse_args()
add_to_sealed_secret(args.sealed_secrets_file, args.key, args.value, args.namespace)