2024-05-01 17:11:36 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
# Edit a single attribute of a sops json file
|
|
|
|
# Helps working with multiline strings in json
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
2024-05-12 14:34:00 +02:00
|
|
|
print_help() {
|
|
|
|
cat << EOF
|
|
|
|
clerie-sops-edit <secrets_file> <action> <key>
|
|
|
|
|
|
|
|
This script allows editing single secrets in a secrets file by key.
|
|
|
|
|
|
|
|
<secrets_file> is a sops secrets file
|
|
|
|
<action> is one of "edit", "read", "set" and "append"
|
|
|
|
<key> is the key of the secret in the secrets file to modify
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
if [[ $# != 3 ]]; then
|
|
|
|
print_help
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2024-05-01 17:11:36 +02:00
|
|
|
SECRETS_FILE="$1"
|
2024-05-12 14:34:00 +02:00
|
|
|
|
|
|
|
if [[ ! -f "${SECRETS_FILE}" ]]; then
|
|
|
|
echo "File \"${SECRETS_FILE}\" does not exist"
|
|
|
|
echo
|
|
|
|
print_help
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
ACTION="$2"
|
|
|
|
|
|
|
|
if ! echo "edit read set append" | grep -wq "${ACTION}"; then
|
|
|
|
echo "Action \"${ACTION}\" not supported"
|
|
|
|
echo
|
|
|
|
print_help
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
KEY="$3"
|
2024-05-02 12:39:12 +02:00
|
|
|
KEY_SELECTOR="$(jq -Rsc '[.]' <(echo -n "${KEY}"))"
|
2024-05-01 17:11:36 +02:00
|
|
|
|
|
|
|
if [[ -n $EDITOR ]]; then
|
|
|
|
EDITOR=vim
|
|
|
|
fi
|
|
|
|
|
|
|
|
TMP_FILE="$(mktemp)"
|
2024-05-12 14:34:00 +02:00
|
|
|
DECRYPT_ERROR_FILE="$(mktemp)"
|
2024-05-01 17:11:36 +02:00
|
|
|
|
2024-05-12 14:34:00 +02:00
|
|
|
if ! clerie-sops --decrypt --extract "${KEY_SELECTOR}" "${SECRETS_FILE}" > "${TMP_FILE}" 2> "${DECRYPT_ERROR_FILE}"; then
|
|
|
|
# Ignore that the key does not exist, but fail for all other errors
|
2024-05-12 14:42:55 +02:00
|
|
|
if ! grep -q "component .* not found" "${DECRYPT_ERROR_FILE}"; then
|
2024-05-12 14:34:00 +02:00
|
|
|
cat "${DECRYPT_ERROR_FILE}"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
2024-05-01 17:11:36 +02:00
|
|
|
|
2024-05-02 12:28:22 +02:00
|
|
|
TMP_FILE_HASH_BEFORE="$(sha256sum "${TMP_FILE}")"
|
|
|
|
|
2024-05-12 14:34:00 +02:00
|
|
|
case "${ACTION}" in
|
|
|
|
edit)
|
|
|
|
"${EDITOR}" "${TMP_FILE}"
|
|
|
|
;;
|
|
|
|
read)
|
|
|
|
cat "${TMP_FILE}"
|
|
|
|
;;
|
|
|
|
set)
|
|
|
|
cat > "${TMP_FILE}"
|
|
|
|
;;
|
|
|
|
append)
|
|
|
|
cat >> "${TMP_FILE}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "Unsupported action"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
2024-05-01 17:11:36 +02:00
|
|
|
|
2024-05-02 12:28:22 +02:00
|
|
|
TMP_FILE_HASH_AFTER="$(sha256sum "${TMP_FILE}")"
|
|
|
|
|
|
|
|
# Don't write value back when it hasn't changed
|
|
|
|
if [[ "${TMP_FILE_HASH_BEFORE}" == "${TMP_FILE_HASH_AFTER}" ]]; then
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2024-05-02 12:39:12 +02:00
|
|
|
JSON_QUOTED_SECRET="$(jq -Rsc '.' "${TMP_FILE}")"
|
2024-05-01 17:11:36 +02:00
|
|
|
|
|
|
|
rm "${TMP_FILE}"
|
|
|
|
|
2024-05-02 12:39:12 +02:00
|
|
|
clerie-sops --set "${KEY_SELECTOR} ${JSON_QUOTED_SECRET}" "${SECRETS_FILE}"
|