| Matthias Andreas Benkard | 3cf43e3 | 2026-11-05 22:28:28 +0100 | [diff] [blame] | 1 | #! /bin/bash |
| 2 | # Edits mailcow.conf in the mailcow-secrets secret with $EDITOR. |
| 3 | # |
| 4 | # Usage: edit-mailcow-conf [namespace] [secret] [key] |
| 5 | set -euo pipefail |
| 6 | |
| 7 | namespace=${1:-mulk} |
| 8 | secret=${2:-mailcow-secrets} |
| 9 | key=${3:-mailcow.conf} |
| 10 | |
| 11 | editor=${VISUAL:-${EDITOR:-vi}} |
| 12 | |
| 13 | # Keep the plaintext on tmpfs and readable only by us. |
| 14 | umask 077 |
| 15 | workdir=$(mktemp -d "${XDG_RUNTIME_DIR:-/tmp}/edit-secret.XXXXXX") |
| 16 | trap 'rm -rf "$workdir"' EXIT |
| 17 | |
| 18 | json=$(kubectl -n "$namespace" get secret "$secret" -o json) |
| 19 | resource_version=$(jq -r '.metadata.resourceVersion' <<<"$json") |
| 20 | jq -r --arg key "$key" '.data[$key] // error("key \($key) not found")' <<<"$json" \ |
| 21 | | base64 -d >"$workdir/original" |
| 22 | cp "$workdir/original" "$workdir/$key" |
| 23 | |
| 24 | while :; do |
| 25 | $editor "$workdir/$key" |
| 26 | |
| 27 | if cmp -s "$workdir/original" "$workdir/$key"; then |
| 28 | echo "No changes." |
| 29 | exit 0 |
| 30 | fi |
| 31 | |
| 32 | diff -u --label "$key (cluster)" --label "$key (edited)" \ |
| 33 | "$workdir/original" "$workdir/$key" || : |
| 34 | |
| 35 | read -r -p "Apply to secret $namespace/$secret? [y]es/[e]dit again/[n]o: " answer |
| 36 | case $answer in |
| 37 | y|Y|yes) break ;; |
| 38 | e|E|edit) continue ;; |
| 39 | *) echo "Aborted."; exit 1 ;; |
| 40 | esac |
| 41 | done |
| 42 | |
| 43 | # Including resourceVersion makes the patch fail if someone else changed |
| 44 | # the secret in the meantime. |
| 45 | jq -n \ |
| 46 | --arg key "$key" \ |
| 47 | --arg rv "$resource_version" \ |
| 48 | --arg data "$(base64 -w0 <"$workdir/$key")" \ |
| 49 | '{metadata: {resourceVersion: $rv}, data: {($key): $data}}' \ |
| 50 | >"$workdir/patch.json" |
| 51 | |
| 52 | kubectl -n "$namespace" patch secret "$secret" --type merge --patch-file "$workdir/patch.json" |