diff --git a/secrets.sh b/secrets.sh index da3981c..9cc5856 100755 --- a/secrets.sh +++ b/secrets.sh @@ -1,4 +1,30 @@ #!/usr/bin/env bash +# shellcheck disable=SC1003 + +# Parts of this project are MIT Licensed, they will be denoted below. + +# MIT License + +# Original work Copyright (c) 2017 Jonathan Peres +# Modified work Copyright (c) 2019 Just_Insane + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. # The suffix to use for decrypted files. The default can be overridden using # the HELM_SECRETS_DEC_SUFFIX environment variable. @@ -7,6 +33,27 @@ DEC_SUFFIX="${HELM_SECRETS_DEC_SUFFIX:-.yaml.dec}" # Make sure HELM_BIN is set (normally by the helm command) HELM_BIN="${HELM_BIN:-helm}" +# The secret store to use to store values +# Defaults to "secret/helm" +if [[ -z "${VAULT_PATH}" ]] +then + default=secret/helm + read -p "Enter a Vault KV Store path [$default]: " VAULT_PATH + VAULT_PATH=${VAULT_PATH:-$default} + unset default +fi + +# The plaintext deliminator used to specify which values need to be stored in Vault +# Defaults to "changme" +if [[ -z "${secret_deliminator}" ]] +then + default=changeme + read -p "Enter a secret deliminator [$default]: " secret_deliminator + secret_deliminator=${secret_deliminator:-$default} + echo "Secret Deliminator is $secret_deliminator" + unset default +fi + getopt --test > /dev/null if [[ $? -ne 4 ]] then @@ -57,6 +104,18 @@ This allows you to first decrypt the file, edit it, then encrypt it again. You can use plain sops to encrypt - https://github.com/mozilla/sops +Vault secrets + +If VAULT_TOKEN env variable is set, automatically store values in Vault. +Secret values must be entered into the helm chart as a specific vaule, in this case "changme", for example + + db: + name: nextcloud + user: nextcloud + password: changeme + +would prompt to enter a value for the db password. + Example: $ ${HELM_BIN} secrets enc $ git add @@ -75,6 +134,18 @@ Produces ${DEC_SUFFIX} file. You can use plain sops to decrypt specific files - https://github.com/mozilla/sops +Vault secrets + +If VAULT_TOKEN env variable is set, automatically pull values from Vault in a plaintext file. +Values must be pulled in order to update or install via Helm. + +For example: + + db: + name: nextcloud + user: nextcloud + password: + Example: $ ${HELM_BIN} secrets dec @@ -208,6 +279,129 @@ is_help() { esac } +# Parses yaml document +# Based on https://github.com/jasperes/bash-yaml +parse_yaml() { + local yaml_file=$1 + local s + local w + local fs + + s='[[:space:]]*' + w='[a-zA-Z0-9_.-]*' + fs="$(echo @|tr @ '\034')" + + ( + sed -e '/- [^\“]'"[^\']"'.*: /s|\([ ]*\)- \([[:space:]]*\)|\1-\'$'\n'' \1\2|g' | + + sed -ne '/^--/s|--||g; s|\"|\\\"|g; s/[[:space:]]*$//g;' \ + -e "/#.*[\"\']/!s| #.*||g; /^#/s|#.*||g;" \ + -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ + -e "s|^\($s\)\($w\)${s}[:-]$s\(.*\)$s\$|\1$fs\2$fs\3|p" | + + awk -F"$fs" '{ + indent = length($1)/2; + if (length($2) == 0) { conj[indent]="+";} else {conj[indent]="";} + vname[indent] = $2; + for (i in vname) {if (i > indent) {delete vname[i]}} + if (length($3) > 0) { + vn=""; for (i=0; i "$yml" + echo "Encrypted $ymldec to $yml" + fi else - sops --encrypt --input-type yaml --output-type yaml "$ymldec" > "$yml" - echo "Encrypted $ymldec to $yml" + get_path + create_variables $yml + set_secrets fi } @@ -265,27 +466,35 @@ decrypt_helper() { __dec=0 [[ -e "$yml" ]] || { echo "File does not exist: $yml"; exit 1; } - if [[ $(grep -C10000 'sops:' "$yml" | grep -c 'version:') -eq 0 ]] - then - echo "Not encrypted: $yml" - __ymldec="$yml" - else - __ymldec=$(sed -e "s/\\.yaml$/${DEC_SUFFIX}/" <<<"$yml") - if [[ -e $__ymldec && $__ymldec -nt $yml ]] - then - echo "$__ymldec is newer than $yml" - else - sops --decrypt --input-type yaml --output-type yaml "$yml" > "$__ymldec" || { rm "$__ymldec"; exit 1; } - __dec=1 - fi - fi - if [[ ${BASH_VERSINFO[0]} -lt 4 ]] + if [[ -z "${VAULT_TOKEN}" ]] then - [[ $__ymldec_var ]] && eval $__ymldec_var="'$__ymldec'" - [[ $__dec_var ]] && eval $__dec_var="'$__dec'" + if [[ $(grep -C10000 'sops:' "$yml" | grep -c 'version:') -eq 0 ]] + then + echo "Not encrypted: $yml" + __ymldec="$yml" + else + __ymldec=$(sed -e "s/\\.yaml$/${DEC_SUFFIX}/" <<<"$yml") + if [[ -e $__ymldec && $__ymldec -nt $yml ]] + then + echo "$__ymldec is newer than $yml" + else + sops --decrypt --input-type yaml --output-type yaml "$yml" > "$__ymldec" || { rm "$__ymldec"; exit 1; } + __dec=1 + fi + fi + + if [[ ${BASH_VERSINFO[0]} -lt 4 ]] + then + [[ $__ymldec_var ]] && eval $__ymldec_var="'$__ymldec'" + [[ $__dec_var ]] && eval $__dec_var="'$__dec'" + fi + true # just so that decrypt_helper will exit with a true status on no error + else + get_path + create_variables $yml + get_secrets fi - true # just so that decrypt_helper will exit with a true status on no error } @@ -495,4 +704,4 @@ case "${1:-help}" in ;; esac -exit 0 +exit 0 \ No newline at end of file