diff --git a/.deploy-to-homebrew b/.deploy-to-homebrew new file mode 100755 index 0000000..1fcb803 --- /dev/null +++ b/.deploy-to-homebrew @@ -0,0 +1,108 @@ +#!/bin/bash + +set -e + +if [ "$GITHUB_TOKEN" = "" ]; then echo "\$GITHUB_TOKEN isn't set"; exit 1; fi +if [ "$VERSION" = "" ]; then echo "\$VERSION isn't set"; exit 1; fi + +ARCHIVE=$(mktemp /tmp/branchout.XXXXXX) +CHECKOUT_DIR=$(mktemp -d /tmp/homebrew-branchout.XXXXXX) +cleanup() { + rm -r "${ARCHIVE}" + rm -r "${CHECKOUT_DIR}" +} +# trap cleanup EXIT + +curl -sSL https://github.com/Branchout/branchout/archive/$VERSION.tar.gz -o "$ARCHIVE" +if ! tar xOf "$ARCHIVE" > /dev/null 2>/dev/null; then echo "$ARCHIVE isn't a valid archive"; exit 1; fi + +HASH=$(shasum -a 256 "$ARCHIVE" | cut -d\ -f1) + +git clone https://${GITHUB_TOKEN}@github.com/Branchout/homebrew-branchout.git "$CHECKOUT_DIR" +echo "class Branchout < Formula + + desc \"Command-line git repository layout manage\" + homepage \"https://github.com/Branchout/branchout\" + url \"https://github.com/StickySource/branchout/archive/${VERSION}.tar.gz\" + sha256 \"${HASH}\" + version \"${VERSION:1}\" + + depends_on \"branchout/branchout/branchout-core\" + depends_on \"branchout/branchout/branchout-maven\" + depends_on \"branchout/branchout/branchout-secrets\" + + def test + system \"#{bin}/branchout version\" + end +end +" > "$CHECKOUT_DIR/branchout.rb" + +echo "class BranchoutCore < Formula + + desc \"Command-line git repository layout manage\" + homepage \"https://github.com/Branchout/branchout\" + url \"https://github.com/StickySource/branchout/archive/${VERSION}.tar.gz\" + sha256 \"${HASH}\" + version \"${VERSION:1}\" + + depends_on \"git\" + depends_on \"bash\" + + def install + bin.install \"branchout\" + bin.install \"branchout-project\" + bin.install \"branchout-group\" + bin.install \"branchout-init\" + bin.install \"branchout-environment\" + bin.install \"branchout-configuration\" + end + + def test + system \"#{bin}/branchout version\" + end +end +" > "$CHECKOUT_DIR/branchout-core.rb" + +echo "class BranchoutMaven < Formula + + desc \"Command-line git repository layout manager\" + homepage \"https://github.com/Branchout/branchout\" + url \"https://github.com/StickySource/branchout/archive/${VERSION}.tar.gz\" + sha256 \"${HASH}\" + version \"${VERSION:1}\" + + depends_on \"branchout/branchout/core\" + depends_on \"maven\" + + def install + bin.install \"branchout-maven\" + end + + def test + system \"#{bin}/branchout version\" + end +end +" > "$CHECKOUT_DIR/branchout-maven.rb" + +echo "class BranchoutSecrets < Formula + + desc \"Command-line git repository layout manager\" + homepage \"https://github.com/Branchout/branchout\" + url \"https://github.com/StickySource/branchout/archive/${VERSION}.tar.gz\" + sha256 \"${HASH}\" + version \"${VERSION:1}\" + + depends_on \"stickycode/kubesec/kubesec\" + depends_on \"gpg\" + + def install + bin.install \"branchout-secrets\" + end + + def test + system \"#{bin}/branchout version\" + end +end +" > "$CHECKOUT_DIR/branchout-secrets.rb" + +#(cd "$CHECKOUT_DIR" && git config user.email "michael@stickycode.net" && git config user.name "Michael McCallum" && git commit -a -m "$VERSION" && git tag -a -m"$VERSION" "$VERSION" && git push origin master --tags) diff --git a/bats/branchout-secrets.bats b/bats/branchout-secrets.bats index 141e31c..c49ed24 100644 --- a/bats/branchout-secrets.bats +++ b/bats/branchout-secrets.bats @@ -1,9 +1,17 @@ +#!/bin/bash + load helper teardown() { - test -d "${GNUPGHOME_TEMP}/.gpg.s" && GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.s" gpgconf --kill gpg-agent || true - test -d "${GNUPGHOME_TEMP}/.gpg.d" && GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.d" gpgconf --kill gpg-agent || true - test -d "${GNUPGHOME_TEMP}" && rm -rf "/tmp/$(basename ${GNUPGHOME_TEMP})" || true + if test -d "${GNUPGHOME_TEMP}/.gpg.s"; then + GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.s" gpgconf --kill gpg-agent || true + fi + if test -d "${GNUPGHOME_TEMP}/.gpg.d"; then + GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.d" gpgconf --kill gpg-agent || true + fi + if test -d "${GNUPGHOME_TEMP}"; then + rm -rf "/tmp/$(basename "${GNUPGHOME_TEMP}")" || true + fi } @test "secret - shellcheck compliant with no exceptions" { @@ -14,7 +22,7 @@ teardown() { @test "secret - invoking branchout secret usage" { secretExample secrets-usage run branchout-secrets --passphrase=test - assert_error "branchout secrets: a tool for managing kubebernetes secrets" + assert_error "branchout secrets: a tool for managing kubernetes secrets" } @test "secret - raw setup my key" { @@ -87,6 +95,12 @@ teardown() { assert_success_file secrets/create } +@test "secret - create secret when it there is no key" { + secretExample secrets-create-with-no-key + run branchout-secrets create missing-application/secret --passphrase=test <<< "" + assert_error "You need to run 'branchout secrets setup' to configure a key for signing" +} + @test "secret - fail to create secret when it exists" { secretExample secrets-create-already-exists run branchout set-config "EMAIL" "branchout@example.com" @@ -95,7 +109,7 @@ teardown() { assert_error "Secret already exists for example-application/secret" } -@test "secret - key" { +@test "secret - use key" { secretExample secrets-key run branchout secrets use-key "branchout@example.com" assert_success_file secrets/use-branchout @@ -103,7 +117,21 @@ teardown() { assert_success_file secrets/main-key } -@test "secret - register key" { +@test "secret - create secret when there is no setup" { + example secrets-no-setup + run branchout-secrets create missing-application/secret --passphrase=test <<< "" + assert_error "You need to run 'branchout secrets setup' to configure a key for signing" +} + +@test "secret - create secret when there is no setup for all" { + example secrets-no-setup-for-all + mkdir -p target/resources/kubernetes src/main/secrets/ + cp -r "${EXAMPLES}"/secret-templates/example-application target/resources/kubernetes/app-1 + run branchout-secrets create <<< "" + assert_error "You need to run 'branchout secrets setup' to configure a key for signing" +} + +@test "secret - register public key" { secretExample secrets-add-key run branchout secrets use-key "branchout@example.com" run branchout secrets register-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" @@ -112,34 +140,54 @@ teardown() { assert_success_file secrets/two-keys } -@test "secret - register key by id" { +@test "secret - register unknown public key fails" { + secretExample secrets-add-unknown-key + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + run branchout secrets register-key "pgp:EEEEEC480F6AE9341C8790965916E6EA295DF6B" + assert_error "Key EEEEEC480F6AE9341C8790965916E6EA295DF6B not found" +} + +@test "secret - register add encryption key with import" { + secretExample secrets-add-key-with-import + mkdir .keys + cp "${EXAMPLES}/gnupg/extra.pub" .keys/AB754D3EBB9F49880CB7BD2E68684CA661E85551.pub + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + run branchout secrets add-key "pgp:AB754D3EBB9F49880CB7BD2E68684CA661E85551" + assert_success_file secrets/keys-import + run branchout-secrets show-keys + assert_success_file secrets/keys-import +} + +@test "secret - add encryption key by id" { secretExample secrets-add-key-by-id run branchout secrets use-key "branchout@example.com" - run branchout secrets register-key "branchout2@example.com" + run branchout secrets add-key "branchout2@example.com" assert_success_file secrets/two-keys run branchout-secrets show-keys assert_success_file secrets/two-keys } -@test "secret - deregister key" { +@test "secret - remove encryption key by id" { secretExample secrets-remove-key run branchout secrets use-key "branchout@example.com" - run branchout secrets register-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" + run branchout secrets add-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" assert_success_file secrets/two-keys run branchout-secrets show-keys assert_success_file secrets/two-keys - run branchout secrets deregister-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" + run branchout secrets remove-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" assert_success_file secrets/main-key } -@test "secret - deregister key by id" { +@test "secret - remove encryption key by email" { secretExample secrets-remove-key-by-id run branchout secrets use-key "branchout@example.com" - run branchout secrets register-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" + run branchout secrets remove-key "pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B" assert_success_file secrets/two-keys run branchout-secrets show-keys assert_success_file secrets/two-keys - run branchout secrets deregister-key "branchout2@example.com" + run branchout secrets remove-key "branchout2@example.com" assert_success_file secrets/main-key } @@ -216,6 +264,7 @@ teardown() { run branchout-secrets update missing-application/secret --keyring=d --passphrase=test assert_error_file secrets/safe-from-outsiders } + @test "secret - add new key to all secrets fails on mismatch" { secretExample secrets-add-people-fails-on-mismatch run branchout secrets use-key "branchout2@example.com" @@ -243,6 +292,21 @@ teardown() { assert_success_file secrets/view-app-1 } +@test "secret - add new key to all secrets with import " { + secretSetup secrets-add-people-with-import + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + mkdir -p target/resources/kubernetes src/main/secrets/ + cp -r "${EXAMPLES}"/secret-templates/example-application target/resources/kubernetes/app-1 + cp -r "${EXAMPLES}"/secrets/example-application src/main/secrets/app-1 + mkdir .keys + cp "${EXAMPLES}/gnupg/extra.pub" .keys/AB754D3EBB9F49880CB7BD2E68684CA661E85551.pub + run branchout-secrets add-key pgp:AB754D3EBB9F49880CB7BD2E68684CA661E85551 --passphrase=test + assert_success_file secrets/add-people-with-import + run branchout-secrets view app-1/secret --passphrase=test + assert_success_file secrets/view-app-1 +} + @test "secret - remove key from secret" { secretSetup secrets-remove-people run branchout secrets use-key "branchout@example.com" @@ -267,7 +331,7 @@ teardown() { @test "secret - edit a secret" { skip "Not implemented" - EDITOR="cat" + export EDITOR="cat" run branchout-secrets edit some-secret --passphrase=test assert_success_file secrets/edit } diff --git a/bats/current.bats b/bats/current.bats new file mode 100644 index 0000000..9e5702d --- /dev/null +++ b/bats/current.bats @@ -0,0 +1,37 @@ +load helper + +teardown() { + test -d "${GNUPGHOME_TEMP}/.gpg.s" && GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.s" gpgconf --kill gpg-agent || true + test -d "${GNUPGHOME_TEMP}/.gpg.d" && GNUPGHOME="${GNUPGHOME_TEMP}/.gpg.d" gpgconf --kill gpg-agent || true + test -d "${GNUPGHOME_TEMP}" && rm -rf "/tmp/$(basename ${GNUPGHOME_TEMP})" || true +} + +@test "secret - register public key" { + secretExample secrets-register-key + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + run branchout secrets register-key "branchout2@example.com" + assert_success_file secrets/main-key + run branchout-secrets show-keys + assert_success_file secrets/main-key +} + +@test "secret - register public key twice" { + secretExample secrets-register-key-twice + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + run branchout secrets register-key "branchout2@example.com" + assert_success_file secrets/main-key + run branchout secrets register-key "branchout2@example.com" + assert_error "Key branchout2@example.com is already registered" +} + +@test "secret - register public key by file" { + secretExample secrets-register-key-by-file + run branchout secrets use-key "branchout@example.com" + assert_success_file secrets/use-branchout + run branchout secrets register-key "${EXAMPLES}/gnupg/branchout3.pub" + assert_success_file secrets/main-key + run branchout secrets users "branchout@example.com" + assert_error "Key branchout@example.com is already registered" +} \ No newline at end of file diff --git a/branchout-secrets b/branchout-secrets index 58dc20e..952fb1e 100755 --- a/branchout-secrets +++ b/branchout-secrets @@ -39,7 +39,7 @@ setupRsa4096() { else echo "Generating key for ${BRANCHOUT_CONFIG_EMAIL}" - runGpg --quick-gen-key "${BRANCHOUT_CONFIG_EMAIL}" rsa4096 + runGpg --quick-gen-key "${BRANCHOUT_CONFIG_EMAIL}" secretsUseKey "${BRANCHOUT_CONFIG_EMAIL}" fi } @@ -50,7 +50,7 @@ secretsUseKey() { branchout set-config "GPG_KEY" "${fingerPrint}" echo "default-key ${fingerPrint}" > "${BRANCHOUT_CONFIG_GPG_HOME}.${BRANCHOUT_CONFIG_GPG_KEYRING}/gpg.conf" echo "using key ${fingerPrint} for ${1}" - updateKeysAdd "pgp:${fingerPrint}" + addEncryptionKey "pgp:${fingerPrint}" } secretsSetupView() { @@ -65,22 +65,23 @@ secretsEdit() { secretsView() { # shellcheck disable=SC2086 - runKubesec decrypt -x "src/main/secrets/${1}.yaml" + runKubesec decrypt -x "src/main/secrets/${1}.kubesec" } ensureKeys() { - ensureConfigValue "Setup gpg key" "GPG_KEY" - updateKeysAdd "${BRANCHOUT_CONFIG_GPG_KEY}" + test -n "${BRANCHOUT_CONFIG_GPG_KEY}" || usage-secrets "You need to run 'branchout secrets setup' to configure a key for signing" + ensureConfigValue "you gpg key" "GPG_KEY" + addEncryptionKey "${BRANCHOUT_CONFIG_GPG_KEY}" } secretUpdate() { verify "${1}" # shellcheck disable=SC2086 - if runKubesec encrypt -i "${@:2}" "src/main/secrets/${1}.yaml"; then - displaySecretStatus "${1}" "BO_THEME_OK" "update ok" + if runKubesec encrypt -i "${@:2}" "src/main/secrets/${1}.kubesec"; then + displaySecretStatus "${1}" "BO_THEME_OK" "update" "ok" else - displaySecretStatus "${1}" "BO_THEME_ERROR" "update failed" + displaySecretStatus "${1}" "BO_THEME_ERROR" "update" "failed" return 1 fi } @@ -89,11 +90,11 @@ secretsUpdate() { ensureKeys test -d target/resources/kubernetes || usage-secrets "You need to build to get the templates" find target/resources/kubernetes -name 'secret*.template' | sort | sed -e 's,target/resources/kubernetes/\(.*\)/\(.*\).template,\1/\2,' | while read -r each; do - if test ! -f "src/main/secrets/${each}.yaml"; then - displaySecretStatus "${each}" "BO_THEME_HIGHLIGHT" "${1}missing" + if test ! -f "src/main/secrets/${each}.kubesec"; then + displaySecretStatus "${each}" "BO_THEME_HIGHLIGHT" "${1}" "missing" fi done - find src/main/secrets -name 'secret*.yaml' | sort | sed -e 's,src/main/secrets/\(.*\)/\(.*\).yaml,\1/\2,' | while read -r each; do + find src/main/secrets -name 'secret*.kubesec' | sort | sed -e 's,src/main/secrets/\(.*\)/\(.*\).kubesec,\1/\2,' | while read -r each; do secretUpdate "${each}" "${@:2}" done } @@ -101,32 +102,36 @@ secretsUpdate() { secretsCreate() { ensureKeys test -f "target/resources/kubernetes/${1}.template" || usage-secrets "Secret template not found for $1" - test -f "src/main/secrets/$1.yaml" && usage-secrets "Secret already exists for ${1}" + test -f "src/main/secrets/$1.kubesec" && usage-secrets "Secret already exists for ${1}" mkdir -p "src/main/secrets/$(dirname "$1")" # shellcheck disable=SC2046 - if runKubesec encrypt $(awk '{print "--key="$1}' KEYS) "target/resources/kubernetes/${1}.template" --output "src/main/secrets/${1}.yaml"; then - displaySecretStatus "${1}" "BO_THEME_OK" "create ok" + if runKubesec encrypt --cleartext $(awk '{print "--key="$1}' KEYS) "target/resources/kubernetes/${1}.template" --output "src/main/secrets/${1}.kubesec"; then + displaySecretStatus "${1}" "BO_THEME_OK" "create" "ok" else - displaySecretStatus "${1}" "BO_THEME_ERROR" "create failed" + displaySecretStatus "${1}" "BO_THEME_ERROR" "create" "failed" fi } displaySecretStatus() { - echo -e "${BO_THEME_RESET}${1%/*} ${1##*/}\\033[70D\\033[70C${!2}${3}${BO_THEME_RESET}" + if test -n "${BRANCHOUT_VERBOSE}"; then + echo -e "${BO_THEME_RESET}${3} src/main/secrets/${1%/*}/${1##*/}.kubesec\\033[70D\\033[70C${!2}${4}${BO_THEME_RESET}" + else + echo -e "${BO_THEME_RESET}${3} ${1%/*}/${1##*/}\\033[70D\\033[70C${!2}${4}${BO_THEME_RESET}" + fi } secretStatus() { if test ! -f "target/resources/kubernetes/${1}.template"; then - displaySecretStatus "${1}" "BO_THEME_WARNING" "${2}no-template" + displaySecretStatus "${1}" "BO_THEME_WARNING" "${2}" "no-template" return 0 else - if diff -u <(yq read "target/resources/kubernetes/${1}.template" data | sort | cut -d: -f1) <(yq read "src/main/secrets/${1}.yaml" data | sort | cut -d: -f1) >/dev/null; then - displaySecretStatus "${1}" "BO_THEME_OK" "${2}ok" + if diff -u <(yq read "target/resources/kubernetes/${1}.template" data | sort | cut -d: -f1) <(yq read "src/main/secrets/${1}.kubesec" data | sort | cut -d: -f1) >/dev/null; then + displaySecretStatus "${1}" "BO_THEME_OK" "${2}" "ok" return 0 else - displaySecretStatus "${1}" "BO_THEME_ERROR" "${2}mismatch" - test "${2}" = "verify " && diff -y <(yq read "target/resources/kubernetes/${1}.template" data | sort | cut -d: -f1) <(yq read "src/main/secrets/${1}.yaml" data | sort | cut -d: -f1) + displaySecretStatus "${1}" "BO_THEME_ERROR" "${2}" "mismatch" + test "${2}" = "verify" && diff -y <(yq read "target/resources/kubernetes/${1}.template" data | grep "^[^ :]*: " | sort | cut -d: -f1) <(yq read "src/main/secrets/${1}.kubesec" data | sort | cut -d: -f1) return 1 fi fi @@ -135,28 +140,28 @@ secretStatus() { secretsStatus() { test -d target/resources/kubernetes || usage-secrets "You need to build to get the templates" find target/resources/kubernetes -name 'secret*.template' | sort | sed -e 's,target/resources/kubernetes/\(.*\)/\(.*\).template,\1/\2,' | while read -r each; do - if test ! -f "src/main/secrets/${each}.yaml"; then - displaySecretStatus "${each}" "BO_THEME_HIGHLIGHT" "${1}missing" + if test ! -f "src/main/secrets/${each}.kubesec"; then + displaySecretStatus "${each}" "BO_THEME_HIGHLIGHT" "${1}" "missing" fi done - find src/main/secrets -name 'secret*.yaml' | sort | sed -e 's,src/main/secrets/\(.*\)/\(.*\).yaml,\1/\2,' | while read -r each; do - secretStatus "${each}" "${1}" || true + find src/main/secrets -name 'secret*.kubesec' | sort | sed -e 's,src/main/secrets/\(.*\)/\(.*\).kubesec,\1/\2,' | while read -r each; do + secretStatus "${each}" "${@:1}" || true done } verifyAll() { - secretsStatus "verify " + secretsStatus "verify" } verify() { - secretStatus "${1}" "verify " + secretStatus "${1}" "verify" } showKeys() { test ! -f "KEYS" || cat "KEYS" } -updateKeysRemove() { +removeEncryptionKey() { test -n "${1}" || usage-secrets "Provide a key to register" removedKey="${1}" case "${1}" in @@ -175,18 +180,19 @@ updateKeysRemove() { rm "KEYS.tmp" } -updateKeysAdd() { +addEncryptionKey() { test -n "${1}" || usage-secrets "Provide a key to register" newKey="${1}" case "${1}" in pgp:*) + runGpg --with-colons -q --list-keys "${1#*:}" >/dev/null 2>/dev/null || runGpg --import "${BRANCHOUT_DIRECTORY}/.keys/${1#*:}.pub" 2>/dev/null || usage-secrets "Key ${1#*:} not found" ;; kms:*) ;; aws:*) ;; *) - newKey="pgp:$(runGpg --with-colons --list-keys "${1}" | awk -F: '$1 == "fpr" {print $10; exit}')" || usage-secrets "Key type ${1#:*} unrecognised" + newKey="pgp:$(runGpg --with-colons --list-keys "${1}" | awk -F: '$1 == "fpr" {print $10; exit}')" || usage-secrets "Key type ${1#*:} unrecognised" ;; esac test -f "KEYS" && grep -v "^${newKey}$" "KEYS" > "KEYS.tmp" && true @@ -195,31 +201,51 @@ updateKeysAdd() { rm "KEYS.tmp" } +addPublicKey() { + test -d "${BRANCHOUT_DIRECTORY}/.keys/" || mkdir "${BRANCHOUT_DIRECTORY}/.keys/" + if test -f "${1}"; then + emailAddress="$(runGpg --with-colons --import-options show-only --import < "${1}" | awk -F: '$1 == "uid" {print $10; exit}' | sed -e 's,.*<\(.*\)>,\1,')" + echo "Importing $(basename "${1}") as ${emailAddress}" + runGpg --import < "${1}" + runGpg -a -o "${BRANCHOUT_DIRECTORY}/.keys/${emailAddress}.pub" --export "${emailAddress}" || usage-secrets "Key ${emailAddress} is not known" + else + test -f "${BRANCHOUT_DIRECTORY}/.keys/${1}.pub" && usage-secrets "Key ${1} is already registered" + runGpg -a -o "${BRANCHOUT_DIRECTORY}/.keys/${1}.pub" --export "${1}" || usage-secrets "Key ${1} is not known" + fi +} + +removePublicKey() { + test -f "${BRANCHOUT_DIRECTORY}/.keys/${1}.pub" || usage-secrets "Key ${1} is not known, as such it cannot be deregistered" + rm "${BRANCHOUT_DIRECTORY}/.keys/${1}.pub" +} + registerKey() { - updateKeysAdd "${1}" + addPublicKey "${1}" showKeys } deregisterKey() { - updateKeysRemove "${1}" + removePublicKey "${1}" showKeys } addKey() { - registerKey "${1}" + addEncryptionKey "${1}" + showKeys secretsUpdate "add-key" "--key=+${newKey#*:}" } removeKey() { - deregisterKey "${1}" - + removeEncryptionKey "${1}" + showKeys + secretsUpdate "remove-key" "--key=-${removedKey#*:}" } usage-secrets() { test -n "${1}" && echo "${1}" && echo - echo "branchout secrets: a tool for managing kubebernetes secrets + echo "branchout secrets: a tool for managing kubernetes secrets branchout secrets settings|edit|create|show [][--debug] @@ -227,14 +253,14 @@ usage-secrets() { edit - edit a secret file create - create a secret file view - show the contents of a secret file - setup - setup an rsa 4096 key - use-key - set the given email and its associated key as the encryption context - add-key - add a key for encryption to the list - remove-key - remove a key from encryption set + setup - setup an RSA key + use-key - set the given email and its associated key as the encryption for this branchout context + add-key - add a key for encryption to the list for this environment + remove-key - remove a key from encryption set for this environment show-keys - show the keys used for encryption + register-key - registers a key with the Branchout context kubesec - run a raw kubesec command with the correct keyring - gpg - run a raw gpg command with the correct keyring - setupEd25519 - setup an ed25519 key + gpg - run a raw gpg command with the correct keyring " exit 127 } @@ -259,6 +285,9 @@ main() { KUBESEC_SETTINGS="${KUBESEC_SETTINGS} --passphrase=${PASSPHRASE}" shift ;; + --verbose) + BRANCHOUT_VERBOSE=true + ;; --trace) GNUPG_SETTINGS="-v ${GNUPG_SETTINGS}" GNUPG_DEBUG="" @@ -308,7 +337,7 @@ main() { secretsView "$2" ;; status) - secretsStatus + secretsStatus "status" ;; use-key) secretsUseKey "${2}" "${3}" diff --git a/examples/gnupg/extra.pub b/examples/gnupg/extra.pub new file mode 100644 index 0000000..ce2309e --- /dev/null +++ b/examples/gnupg/extra.pub @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +KjVkDnw4wF5azjkp +=Mw1l +-----END PGP PUBLIC KEY BLOCK----- diff --git a/examples/secret-templates/example-application/secret.template b/examples/secret-templates/example-application/secret.template index d837b6d..1f5c79e 100644 --- a/examples/secret-templates/example-application/secret.template +++ b/examples/secret-templates/example-application/secret.template @@ -4,6 +4,6 @@ type: Opaque metadata: name: example-application data: - key1: dmFsdWU= - key2.yaml: dmFsdWU= - key3.json: dmFsdWU= \ No newline at end of file + key1: value + key2.yaml: value + key3.json: value diff --git a/examples/secret-templates/mismatch-application/secret.template b/examples/secret-templates/mismatch-application/secret.template index 3f4b86c..eac6a28 100644 --- a/examples/secret-templates/mismatch-application/secret.template +++ b/examples/secret-templates/mismatch-application/secret.template @@ -4,7 +4,9 @@ type: Opaque metadata: name: notemplate data: - key1: dmFsdWU= - key2.yaml: dmFsdWU= - key3.json: dmFsdWU= - key4.json: dmFsdWU= + key1: value + key2.yaml: | + some contents + for a file + key3.json: value + key4.json: value diff --git a/examples/secret-templates/missing-application/secret.template b/examples/secret-templates/missing-application/secret.template index d837b6d..1f5c79e 100644 --- a/examples/secret-templates/missing-application/secret.template +++ b/examples/secret-templates/missing-application/secret.template @@ -4,6 +4,6 @@ type: Opaque metadata: name: example-application data: - key1: dmFsdWU= - key2.yaml: dmFsdWU= - key3.json: dmFsdWU= \ No newline at end of file + key1: value + key2.yaml: value + key3.json: value diff --git a/examples/secrets/example-application/secret.yaml b/examples/secrets/example-application/secret.kubesec similarity index 100% rename from examples/secrets/example-application/secret.yaml rename to examples/secrets/example-application/secret.kubesec diff --git a/examples/secrets/mismatch-application/secret.yaml b/examples/secrets/mismatch-application/secret.kubesec similarity index 100% rename from examples/secrets/mismatch-application/secret.yaml rename to examples/secrets/mismatch-application/secret.kubesec diff --git a/examples/secrets/no-template-application/secret.yaml b/examples/secrets/no-template-application/secret.kubesec similarity index 100% rename from examples/secrets/no-template-application/secret.yaml rename to examples/secrets/no-template-application/secret.kubesec diff --git a/output/secrets/add-key-branchout3.txt b/output/secrets/add-key-branchout3.txt index 5f1fc2e..6b1aa8a 100644 --- a/output/secrets/add-key-branchout3.txt +++ b/output/secrets/add-key-branchout3.txt @@ -1,4 +1,4 @@ pgp:520D39C127DA4C77B1CA7BD04B59A79F662253BA pgp:BBCBD423E6536F1A1EDABF95AAA99B3A301F5178 -\033[0mapp-1 secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mapp-1 secret\033[70D\033[70C\033[0mupdate ok\033[0m +\033[0mverify app-1/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mupdate app-1/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/add-key-fails-with-mismatch.txt b/output/secrets/add-key-fails-with-mismatch.txt index ad4e8f3..14f1c36 100644 --- a/output/secrets/add-key-fails-with-mismatch.txt +++ b/output/secrets/add-key-fails-with-mismatch.txt @@ -1,8 +1,8 @@ pgp:BBCBD423E6536F1A1EDABF95AAA99B3A301F5178 pgp:DD4AC5C480F6AE9341C8790965916E6EA295DF6B -\033[0mexample-application secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mexample-application secret\033[70D\033[70C\033[0mupdate ok\033[0m -\033[0mmismatch-application secret\033[70D\033[70C\033[31mverify mismatch\033[0m +\033[0mverify example-application/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mupdate example-application/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mverify mismatch-application/secret\033[70D\033[70C\033[31mmismatch\033[0m key1\t\t\t\t\t\t\t\tkey1 key2.yaml\t\t\t\t\t\t\tkey2.yaml key3.json\t\t\t\t\t\t\tkey3.json diff --git a/output/secrets/add-people-with-import.txt b/output/secrets/add-people-with-import.txt new file mode 100644 index 0000000..a3f2bf7 --- /dev/null +++ b/output/secrets/add-people-with-import.txt @@ -0,0 +1,4 @@ +pgp:520D39C127DA4C77B1CA7BD04B59A79F662253BA +pgp:AB754D3EBB9F49880CB7BD2E68684CA661E85551 +\033[0mverify app-1/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mupdate app-1/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/add-people.txt b/output/secrets/add-people.txt index 5f1fc2e..6b1aa8a 100644 --- a/output/secrets/add-people.txt +++ b/output/secrets/add-people.txt @@ -1,4 +1,4 @@ pgp:520D39C127DA4C77B1CA7BD04B59A79F662253BA pgp:BBCBD423E6536F1A1EDABF95AAA99B3A301F5178 -\033[0mapp-1 secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mapp-1 secret\033[70D\033[70C\033[0mupdate ok\033[0m +\033[0mverify app-1/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mupdate app-1/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/create-app-1.txt b/output/secrets/create-app-1.txt index a7e91cc..4ea573b 100644 --- a/output/secrets/create-app-1.txt +++ b/output/secrets/create-app-1.txt @@ -1 +1 @@ -\033[0mapp-1 secret\033[70D\033[70C\033[0mcreate ok\033[0m +\033[0mcreate app-1/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/create-with-project-keys.txt b/output/secrets/create-with-project-keys.txt index aba20fd..9b27c04 100644 --- a/output/secrets/create-with-project-keys.txt +++ b/output/secrets/create-with-project-keys.txt @@ -1 +1 @@ -\033[0mmissing-application secret\033[70D\033[70C\033[0mcreate ok\033[0m +\033[0mcreate missing-application/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/create.txt b/output/secrets/create.txt index aba20fd..9b27c04 100644 --- a/output/secrets/create.txt +++ b/output/secrets/create.txt @@ -1 +1 @@ -\033[0mmissing-application secret\033[70D\033[70C\033[0mcreate ok\033[0m +\033[0mcreate missing-application/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/keys-import.txt b/output/secrets/keys-import.txt new file mode 100644 index 0000000..0818a42 --- /dev/null +++ b/output/secrets/keys-import.txt @@ -0,0 +1,2 @@ +pgp:520D39C127DA4C77B1CA7BD04B59A79F662253BA +pgp:AB754D3EBB9F49880CB7BD2E68684CA661E85551 diff --git a/output/secrets/mismatched-keys.txt b/output/secrets/mismatched-keys.txt index 7178382..b3fa3ac 100644 --- a/output/secrets/mismatched-keys.txt +++ b/output/secrets/mismatched-keys.txt @@ -1,4 +1,4 @@ -\033[0mmismatch-application secret\033[70D\033[70C\033[31mverify mismatch\033[0m +\033[0mverify mismatch-application/secret\033[70D\033[70C\033[31mmismatch\033[0m key1\t\t\t\t\t\t\t\tkey1 key2.yaml\t\t\t\t\t\t\tkey2.yaml key3.json\t\t\t\t\t\t\tkey3.json diff --git a/output/secrets/remove-branchout3.txt b/output/secrets/remove-branchout3.txt index a701bd6..3a4f446 100644 --- a/output/secrets/remove-branchout3.txt +++ b/output/secrets/remove-branchout3.txt @@ -1,3 +1,3 @@ pgp:520D39C127DA4C77B1CA7BD04B59A79F662253BA -\033[0mapp-1 secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mapp-1 secret\033[70D\033[70C\033[0mupdate ok\033[0m +\033[0mverify app-1/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mupdate app-1/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/safe-from-outsiders.txt b/output/secrets/safe-from-outsiders.txt index bf28195..8f696fa 100644 --- a/output/secrets/safe-from-outsiders.txt +++ b/output/secrets/safe-from-outsiders.txt @@ -1,3 +1,3 @@ -\033[0mmissing-application secret\033[70D\033[70C\033[0mverify ok\033[0m +\033[0mverify missing-application/secret\033[70D\033[70C\033[0mok\033[0m Unable to decrypt Data Encryption Key (DEK) (re-run with --debug flag to get more details) -\033[0mmissing-application secret\033[70D\033[70C\033[31mupdate failed\033[0m +\033[0mupdate missing-application/secret\033[70D\033[70C\033[31mfailed\033[0m diff --git a/output/secrets/status.txt b/output/secrets/status.txt index a1286e5..494a1a8 100644 --- a/output/secrets/status.txt +++ b/output/secrets/status.txt @@ -1,4 +1,4 @@ -\033[0mmissing-application secret\033[70D\033[70C\033[38;5;11mmissing\033[0m -\033[0mexample-application secret\033[70D\033[70C\033[0mok\033[0m -\033[0mmismatch-application secret\033[70D\033[70C\033[31mmismatch\033[0m -\033[0mno-template-application secret\033[70D\033[70C\033[38;5;202mno-template\033[0m +\033[0mstatus missing-application/secret\033[70D\033[70C\033[38;5;11mmissing\033[0m +\033[0mstatus example-application/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mstatus mismatch-application/secret\033[70D\033[70C\033[31mmismatch\033[0m +\033[0mstatus no-template-application/secret\033[70D\033[70C\033[38;5;202mno-template\033[0m diff --git a/output/secrets/verify-all-fails.txt b/output/secrets/verify-all-fails.txt index 8a13b8a..6d6f223 100644 --- a/output/secrets/verify-all-fails.txt +++ b/output/secrets/verify-all-fails.txt @@ -1,8 +1,8 @@ -\033[0mmissing-application secret\033[70D\033[70C\033[38;5;11mverify missing\033[0m -\033[0mexample-application secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mmismatch-application secret\033[70D\033[70C\033[31mverify mismatch\033[0m +\033[0mverify missing-application/secret\033[70D\033[70C\033[38;5;11mmissing\033[0m +\033[0mverify example-application/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mverify mismatch-application/secret\033[70D\033[70C\033[31mmismatch\033[0m key1\t\t\t\t\t\t\t\tkey1 key2.yaml\t\t\t\t\t\t\tkey2.yaml key3.json\t\t\t\t\t\t\tkey3.json key4.json\t\t\t\t\t\t < -\033[0mno-template-application secret\033[70D\033[70C\033[38;5;202mverify no-template\033[0m +\033[0mverify no-template-application/secret\033[70D\033[70C\033[38;5;202mno-template\033[0m diff --git a/output/secrets/verify-all-success.txt b/output/secrets/verify-all-success.txt index 0190481..52c16c9 100644 --- a/output/secrets/verify-all-success.txt +++ b/output/secrets/verify-all-success.txt @@ -1,3 +1,3 @@ -\033[0mapp-1 secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mapp-2 secret\033[70D\033[70C\033[0mverify ok\033[0m -\033[0mapp3 secret\033[70D\033[70C\033[0mverify ok\033[0m +\033[0mverify app-1/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mverify app-2/secret\033[70D\033[70C\033[0mok\033[0m +\033[0mverify app3/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/verify-one-success.txt b/output/secrets/verify-one-success.txt index 206b247..344d298 100644 --- a/output/secrets/verify-one-success.txt +++ b/output/secrets/verify-one-success.txt @@ -1 +1 @@ -\033[0mapp-2 secret\033[70D\033[70C\033[0mverify ok\033[0m +\033[0mverify app-2/secret\033[70D\033[70C\033[0mok\033[0m diff --git a/output/secrets/verify-success.txt b/output/secrets/verify-success.txt index 0901cf4..e7de5c7 100644 --- a/output/secrets/verify-success.txt +++ b/output/secrets/verify-success.txt @@ -1 +1 @@ -\033[0mexample-application secret\033[70D\033[70C\033[0mverify ok\033[0m +\033[0mverify example-application/secret\033[70D\033[70C\033[0mok\033[0m