From 5ea3bac57012fc8354e87aadf2864e8a62d5f73b Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Tue, 14 Oct 2025 20:02:42 +0200 Subject: [PATCH] feat: add update-keys script --- scripts/update-secrets-keys | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100755 scripts/update-secrets-keys diff --git a/scripts/update-secrets-keys b/scripts/update-secrets-keys new file mode 100755 index 0000000..c23d0b1 --- /dev/null +++ b/scripts/update-secrets-keys @@ -0,0 +1,170 @@ +#!/usr/bin/env bash +set -Euo pipefail + +# Script to update sops keys for all secrets.yaml files in the project +# Uses .sops.yaml configuration to determine encryption keys + +AGE_KEY_FILE="" +DRY_RUN=false +VERBOSE=false + +# Parse options +while [[ $# -gt 0 ]]; do + case $1 in + -k|--age-key-file) + AGE_KEY_FILE="$2" + shift 2 + ;; + -n|--dry-run) + DRY_RUN=true + shift + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + -h|--help) + cat <&2 + echo "Use --help for usage information." >&2 + exit 1 + ;; + esac +done + +# Check if 'sops' command is available +if ! command -v sops > /dev/null; then + echo "ERROR: 'sops' command not found. Please ensure it is installed and in your PATH." >&2 + echo "Install with: nix-shell -p sops" >&2 + exit 1 +fi + +# Determine the absolute directory where the script itself is located +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +PROJECT_ROOT=$(readlink -f "$SCRIPT_DIR/..") + +# Check if .sops.yaml exists +SOPS_CONFIG="$PROJECT_ROOT/.sops.yaml" +if [ ! -f "$SOPS_CONFIG" ]; then + echo "ERROR: .sops.yaml not found at '$SOPS_CONFIG'" >&2 + exit 1 +fi + +# Export age key file if provided +if [ -n "$AGE_KEY_FILE" ]; then + if [ ! -f "$AGE_KEY_FILE" ]; then + echo "ERROR: Age key file not found at '$AGE_KEY_FILE'" >&2 + exit 1 + fi + export SOPS_AGE_KEY_FILE="$AGE_KEY_FILE" + if [ "$VERBOSE" = true ]; then + echo "INFO: Using age key file: $AGE_KEY_FILE" + fi +elif [ -z "${SOPS_AGE_KEY_FILE:-}" ]; then + echo "WARNING: SOPS_AGE_KEY_FILE not set. You may not be able to decrypt secrets." >&2 + echo " Use --age-key-file to specify a key file, or set SOPS_AGE_KEY_FILE environment variable." >&2 +fi + +# Find all secrets.yaml files +echo "INFO: Searching for secrets.yaml files in $PROJECT_ROOT..." +mapfile -t SECRET_FILES < <(find "$PROJECT_ROOT" -name "secrets.yaml" -type f | sort) + +if [ ${#SECRET_FILES[@]} -eq 0 ]; then + echo "WARNING: No secrets.yaml files found in the project." >&2 + exit 0 +fi + +echo "INFO: Found ${#SECRET_FILES[@]} secrets.yaml file(s)" +if [ "$VERBOSE" = true ] || [ "$DRY_RUN" = true ]; then + for file in "${SECRET_FILES[@]}"; do + relative_path="${file#$PROJECT_ROOT/}" + echo " - $relative_path" + done +fi + +if [ "$DRY_RUN" = true ]; then + echo "INFO: Dry-run mode enabled. No files will be modified." + exit 0 +fi + +# Update keys for each file +UPDATED_COUNT=0 +FAILED_COUNT=0 +SKIPPED_COUNT=0 + +for file in "${SECRET_FILES[@]}"; do + relative_path="${file#$PROJECT_ROOT/}" + + if [ "$VERBOSE" = true ]; then + echo "INFO: Updating keys for: $relative_path" + else + echo -n "Updating $relative_path... " + fi + + # Check if file is encrypted with sops + if ! grep -q "^sops:" "$file" 2>/dev/null; then + echo "SKIP (not encrypted)" + ((SKIPPED_COUNT++)) + continue + fi + + # Run sops updatekeys + if sops updatekeys --yes "$file" 2>&1 | { + if [ "$VERBOSE" = true ]; then + cat + else + grep -v "^$" || true + fi + }; then + if [ "$VERBOSE" != true ]; then + echo "OK" + fi + ((UPDATED_COUNT++)) + else + EXIT_STATUS=$? + echo "FAILED (exit code: $EXIT_STATUS)" >&2 + ((FAILED_COUNT++)) + fi +done + +# Summary +echo "" +echo "===== Summary =====" +echo "Total files found: ${#SECRET_FILES[@]}" +echo "Successfully updated: $UPDATED_COUNT" +echo "Failed: $FAILED_COUNT" +echo "Skipped: $SKIPPED_COUNT" + +if [ $FAILED_COUNT -gt 0 ]; then + exit 1 +fi + +echo "INFO: All secrets.yaml files have been updated successfully." +exit 0