#! /bin/bash
# Edits mailcow.conf in the mailcow-secrets secret with $EDITOR.
#
# Usage: edit-mailcow-conf [namespace] [secret] [key]
set -euo pipefail

namespace=${1:-mulk}
secret=${2:-mailcow-secrets}
key=${3:-mailcow.conf}

editor=${VISUAL:-${EDITOR:-vi}}

# Keep the plaintext on tmpfs and readable only by us.
umask 077
workdir=$(mktemp -d "${XDG_RUNTIME_DIR:-/tmp}/edit-secret.XXXXXX")
trap 'rm -rf "$workdir"' EXIT

json=$(kubectl -n "$namespace" get secret "$secret" -o json)
resource_version=$(jq -r '.metadata.resourceVersion' <<<"$json")
jq -r --arg key "$key" '.data[$key] // error("key \($key) not found")' <<<"$json" \
    | base64 -d >"$workdir/original"
cp "$workdir/original" "$workdir/$key"

while :; do
    $editor "$workdir/$key"

    if cmp -s "$workdir/original" "$workdir/$key"; then
        echo "No changes."
        exit 0
    fi

    diff -u --label "$key (cluster)" --label "$key (edited)" \
        "$workdir/original" "$workdir/$key" || :

    read -r -p "Apply to secret $namespace/$secret? [y]es/[e]dit again/[n]o: " answer
    case $answer in
        y|Y|yes) break ;;
        e|E|edit) continue ;;
        *) echo "Aborted."; exit 1 ;;
    esac
done

# Including resourceVersion makes the patch fail if someone else changed
# the secret in the meantime.
jq -n \
    --arg key "$key" \
    --arg rv "$resource_version" \
    --arg data "$(base64 -w0 <"$workdir/$key")" \
    '{metadata: {resourceVersion: $rv}, data: {($key): $data}}' \
    >"$workdir/patch.json"

kubectl -n "$namespace" patch secret "$secret" --type merge --patch-file "$workdir/patch.json"
