feat: add update-keys script
This commit is contained in:
170
scripts/update-secrets-keys
Executable file
170
scripts/update-secrets-keys
Executable file
@@ -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 <<EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Updates sops encryption keys for all secrets.yaml files in the project.
|
||||
Uses .sops.yaml configuration to determine which keys to use.
|
||||
|
||||
OPTIONS:
|
||||
-k, --age-key-file PATH Path to age key file for decryption (default: uses SOPS_AGE_KEY_FILE env var)
|
||||
-n, --dry-run Show which files would be updated without making changes
|
||||
-v, --verbose Show detailed output
|
||||
-h, --help Show this help message
|
||||
|
||||
EXAMPLES:
|
||||
# Update all secrets using default age key
|
||||
$0
|
||||
|
||||
# Use specific age key file
|
||||
$0 --age-key-file ~/.config/sops/age/keys.txt
|
||||
|
||||
# Dry run to see which files would be updated
|
||||
$0 --dry-run --verbose
|
||||
|
||||
ENVIRONMENT:
|
||||
SOPS_AGE_KEY_FILE Default age key file location (if -k not specified)
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unknown option: $1" >&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
|
||||
Reference in New Issue
Block a user