diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 357be45..9c940b0 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -2,17 +2,24 @@ name: Release on: push: - branches: [ '*' ] - tags: [ 'v*' ] + tags: ['v*'] jobs: - create-release: + test: + uses: ./.github/workflows/test.yaml + secrets: inherit + release: + needs: [test] + permissions: + contents: write runs-on: ubuntu-latest steps: - id: version uses: orbit-online/image-version@v0.9.1 - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} - name: Set up buildx uses: docker/setup-buildx-action@v2 - name: Login to docker hub @@ -21,11 +28,15 @@ jobs: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN_RW }} - name: Build & push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: + context: "." file: k8s-secrets/Dockerfile tags: secoya/pkidb-k8s-secrets:${{ steps.version.outputs.version }} push: true build-args: | "BUILD_TOOL=github" "BUILT_BY=${{ github.actor }}" + - uses: orbit-online/upkg-release@v1 + with: + paths: bin common.sh LICENSE README.md diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..3031bd4 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,25 @@ +name: Test + +on: + push: + branches: ['*'] + tags: ['!v*'] + workflow_call: {} + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: orbit-online/upkg-install@v1 + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@master + env: + SHELLCHECK_OPTS: -x + with: + ignore_paths: .upkg + - name: Show --help menus + run: for cmd in bin/*; do ! grep -q docopt "$cmd" || "$cmd" --help; done + env: + PKIDBURL: "https://example.org" diff --git a/.gitignore b/.gitignore index 5bc9a2a..71f9c24 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/.upkg/ +/.upkg diff --git a/pkidb-browser.sh b/bin/pkidb-browser similarity index 73% rename from pkidb-browser.sh rename to bin/pkidb-browser index 24d30f6..32c9efe 100755 --- a/pkidb-browser.sh +++ b/bin/pkidb-browser @@ -1,32 +1,31 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_browser() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" source "$pkgroot/common.sh" DOC="pkidb-browser - Exclusively manage Browser CAs Usage: pkidb-browser FINGERPRINT... " -# docopt parser below, refresh this parser with `docopt.sh pkidb-browser.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:84}; usage=${DOC:47:37}; digest=a0056; shorts=(); longs=() -argcounts=(); node_0(){ value FINGERPRINT a true; }; node_1(){ oneormore 0; } -node_2(){ required 1; }; node_3(){ required 2; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:47:37}" >&2; exit 1 -}'; unset var_FINGERPRINT; parse 3 "$@"; local prefix=${DOCOPT_PREFIX:-''} -unset "${prefix}FINGERPRINT" -if declare -p var_FINGERPRINT >/dev/null 2>&1; then -eval "${prefix}"'FINGERPRINT=("${var_FINGERPRINT[@]}")'; else -eval "${prefix}"'FINGERPRINT=()'; fi; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-browser.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-browser` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e;trimmed_doc=${DOC:0:84} +usage=${DOC:47:37};digest=a0056;options=();node_0(){ value FINGERPRINT a true;} +node_1(){ repeatable 0;};cat <<<' docopt_exit() { [[ -n $1 ]] && printf "%s\n" \ +"$1" >&2;printf "%s\n" "${DOC:47:37}" >&2;exit 1;}';local \ +varnames=(FINGERPRINT) varname;for varname in "${varnames[@]}"; do unset \ +"var_$varname";done;parse 1 "$@";local p=${DOCOPT_PREFIX:-''};for varname in \ +"${varnames[@]}"; do unset "$p$varname";done;if declare -p var_FINGERPRINT \ +>/dev/null 2>&1; then eval $p'FINGERPRINT=("${var_FINGERPRINT[@]}")';else eval \ +$p'FINGERPRINT=()';fi;eval ;local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && \ +docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; \ +do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-browser` eval "$(docopt "$@")" check_all_deps @@ -76,7 +75,7 @@ declare -p "${prefix}FINGERPRINT"; done; } tmp_ca_path=$(mktemp) # shellcheck disable=2064 trap "rm '$tmp_ca_path'" EXIT - "$pkgroot/pkidb-ca.sh" "$fingerprint" > "$tmp_ca_path" + "$pkgroot/bin/pkidb-ca" "$fingerprint" > "$tmp_ca_path" certutil -d "$nssdbpath" -A -n "$fingerprint" -t "$expected_trust" -i "$tmp_ca_path" 2> >(LOGPROGRAM=certutil tee_verbose) changed=true rm "$tmp_ca_path" diff --git a/pkidb-ca.sh b/bin/pkidb-ca similarity index 64% rename from pkidb-ca.sh rename to bin/pkidb-ca index 6ac2e67..d4d39f6 100755 --- a/pkidb-ca.sh +++ b/bin/pkidb-ca @@ -1,32 +1,31 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_ca() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" source "$pkgroot/common.sh" DOC="pkidb-ca - Retrieve a CA certificate using the SHA-256 fingerprint Usage: pkidb-ca [--dest=CAPATH] FINGERPRINT " -# docopt parser below, refresh this parser with `docopt.sh pkidb-ca.sh` -# shellcheck disable=2016,1090,1091,2034 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:112}; usage=${DOC:67:45}; digest=ca1f7; shorts=('') -longs=(--dest); argcounts=(1); node_0(){ value __dest 0; }; node_1(){ -value FINGERPRINT a; }; node_2(){ optional 0; }; node_3(){ required 2 1; } -node_4(){ required 3; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:67:45}" >&2; exit 1 -}'; unset var___dest var_FINGERPRINT; parse 4 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__dest" \ -"${prefix}FINGERPRINT"; eval "${prefix}"'__dest=${var___dest:-}' -eval "${prefix}"'FINGERPRINT=${var_FINGERPRINT:-}'; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}__dest" "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-ca.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-ca` +# shellcheck disable=2016,2086,2317,1090,1091,2034 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:112};usage=${DOC:67:45};digest=ca1f7;options=(' --dest 1') +node_0(){ value __dest 0;};node_1(){ value FINGERPRINT a;};node_2(){ optional 0 +};node_3(){ sequence 2 1;};cat <<<' docopt_exit() { [[ -n $1 ]] && printf \ +"%s\n" "$1" >&2;printf "%s\n" "${DOC:67:45}" >&2;exit 1;}';local \ +varnames=(__dest FINGERPRINT) varname;for varname in "${varnames[@]}"; do +unset "var_$varname";done;parse 3 "$@";local p=${DOCOPT_PREFIX:-''};for \ +varname in "${varnames[@]}"; do unset "$p$varname";done;eval $p'__dest=${var__'\ +'_dest:-};'$p'FINGERPRINT=${var_FINGERPRINT:-};';local docopt_i=1;[[ \ +$BASH_VERSION =~ ^4.3 ]] && docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for \ +varname in "${varnames[@]}"; do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-ca` eval "$(docopt "$@")" check_all_deps diff --git a/pkidb-client-krl.sh b/bin/pkidb-client-krl similarity index 58% rename from pkidb-client-krl.sh rename to bin/pkidb-client-krl index 404595f..c0922a7 100755 --- a/pkidb-client-krl.sh +++ b/bin/pkidb-client-krl @@ -1,36 +1,33 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_client_krl() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" - source "$pkgroot/.upkg/orbit-online/collections.sh/collections.sh" source "$pkgroot/common.sh" DOC="pkidb-client-krl - Retrieve a CMS signed KRL and verify it against CAs Usage: pkidb-client-krl --dest=KRLPATH KRLNAME CAFILE... " -# docopt parser below, refresh this parser with `docopt.sh pkidb-client-krl.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:129}; usage=${DOC:71:58}; digest=67a0d; shorts=('') -longs=(--dest); argcounts=(1); node_0(){ value __dest 0; }; node_1(){ -value KRLNAME a; }; node_2(){ value CAFILE a true; }; node_3(){ oneormore 2; } -node_4(){ required 0 1 3; }; node_5(){ required 4; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:71:58}" >&2; exit 1 -}'; unset var___dest var_KRLNAME var_CAFILE; parse 5 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__dest" "${prefix}KRLNAME" \ -"${prefix}CAFILE"; eval "${prefix}"'__dest=${var___dest:-}' -eval "${prefix}"'KRLNAME=${var_KRLNAME:-}' -if declare -p var_CAFILE >/dev/null 2>&1; then -eval "${prefix}"'CAFILE=("${var_CAFILE[@]}")'; else eval "${prefix}"'CAFILE=()' -fi; local docopt_i=1; [[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2 -for ((;docopt_i>0;docopt_i--)); do declare -p "${prefix}__dest" \ -"${prefix}KRLNAME" "${prefix}CAFILE"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-client-krl.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-client-krl` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:129};usage=${DOC:71:58};digest=67a0d;options=(' --dest 1') +node_0(){ value __dest 0;};node_1(){ value KRLNAME a;};node_2(){ value CAFILE \ +a true;};node_3(){ repeatable 2;};node_4(){ sequence 0 1 3;};cat <<<' \ +docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:71:58}" >&2;exit 1;}';local varnames=(__dest KRLNAME CAFILE) varname +for varname in "${varnames[@]}"; do unset "var_$varname";done;parse 4 "$@" +local p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset \ +"$p$varname";done;if declare -p var_CAFILE >/dev/null 2>&1; then eval $p'CAFIL'\ +'E=("${var_CAFILE[@]}")';else eval $p'CAFILE=()';fi;eval $p'__dest=${var___des'\ +'t:-};'$p'KRLNAME=${var_KRLNAME:-};';local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 \ +]] && docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for varname in \ +"${varnames[@]}"; do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-client-krl` eval "$(docopt "$@")" check_all_deps @@ -39,7 +36,7 @@ for ((;docopt_i>0;docopt_i--)); do declare -p "${prefix}__dest" \ # e.g. "warning: command substitution: ignored null byte in input" # shellcheck disable=2154 - local pem pem_dest=${__dest}.pem + local pem_dest=${__dest}.pem # shellcheck disable=2153 if [[ -e $__dest ]] && ! check_krlcms "${CAFILE[@]}" <"$pem_dest"; then info 'Current KRL invalid, deleting' @@ -52,6 +49,7 @@ for ((;docopt_i>0;docopt_i--)); do declare -p "${prefix}__dest" \ # shellcheck disable=2154 has_changed "$url" "$pem_dest" || chg=$? + local pem krlb64 if [[ $chg = 0 ]]; then pem=$(download "$url") || fatal $? "Unable to fetch the KRL '%s'" "$KRLNAME" krlb64=$(check_krlcms "${CAFILE[@]}" <<<"$pem") @@ -74,6 +72,7 @@ check_krlcms() { debug "Verifying the KRL using CAs at '%s'" "$(join_by , "${capaths[@]}")" if out=$(openssl cms -verify -inform PEM -CAfile <(cat "${capaths[@]}") -certfile <(cat "${capaths[@]}") -binary | base64); then verbose 'The KRL is valid' + printf "%s" "$out" else ret=$? error "Unable to verify the KRL CMS signature with CAs at '%s'. Error was: %s" "$(join_by , "${capaths[@]}")" "$out" diff --git a/pkidb-crl.sh b/bin/pkidb-crl similarity index 54% rename from pkidb-crl.sh rename to bin/pkidb-crl index 94850fb..7eaff1d 100755 --- a/pkidb-crl.sh +++ b/bin/pkidb-crl @@ -1,36 +1,33 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_crl() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" - source "$pkgroot/.upkg/orbit-online/collections.sh/collections.sh" source "$pkgroot/common.sh" DOC="pkidb-crl - Retrieve a CRL and verify it against CAs Usage: pkidb-crl --dest=CRLPATH CRLNAME CAFILE... " -# docopt parser below, refresh this parser with `docopt.sh pkidb-crl.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:104}; usage=${DOC:53:51}; digest=8e2d5; shorts=('') -longs=(--dest); argcounts=(1); node_0(){ value __dest 0; }; node_1(){ -value CRLNAME a; }; node_2(){ value CAFILE a true; }; node_3(){ oneormore 2; } -node_4(){ required 0 1 3; }; node_5(){ required 4; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:53:51}" >&2; exit 1 -}'; unset var___dest var_CRLNAME var_CAFILE; parse 5 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__dest" "${prefix}CRLNAME" \ -"${prefix}CAFILE"; eval "${prefix}"'__dest=${var___dest:-}' -eval "${prefix}"'CRLNAME=${var_CRLNAME:-}' -if declare -p var_CAFILE >/dev/null 2>&1; then -eval "${prefix}"'CAFILE=("${var_CAFILE[@]}")'; else eval "${prefix}"'CAFILE=()' -fi; local docopt_i=1; [[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2 -for ((;docopt_i>0;docopt_i--)); do declare -p "${prefix}__dest" \ -"${prefix}CRLNAME" "${prefix}CAFILE"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-crl.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-crl` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:104};usage=${DOC:53:51};digest=8e2d5;options=(' --dest 1') +node_0(){ value __dest 0;};node_1(){ value CRLNAME a;};node_2(){ value CAFILE \ +a true;};node_3(){ repeatable 2;};node_4(){ sequence 0 1 3;};cat <<<' \ +docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:53:51}" >&2;exit 1;}';local varnames=(__dest CRLNAME CAFILE) varname +for varname in "${varnames[@]}"; do unset "var_$varname";done;parse 4 "$@" +local p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset \ +"$p$varname";done;if declare -p var_CAFILE >/dev/null 2>&1; then eval $p'CAFIL'\ +'E=("${var_CAFILE[@]}")';else eval $p'CAFILE=()';fi;eval $p'__dest=${var___des'\ +'t:-};'$p'CRLNAME=${var_CRLNAME:-};';local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 \ +]] && docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for varname in \ +"${varnames[@]}"; do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-crl` eval "$(docopt "$@")" check_all_deps diff --git a/bin/pkidb-k8s-secrets b/bin/pkidb-k8s-secrets new file mode 100755 index 0000000..d1f206c --- /dev/null +++ b/bin/pkidb-k8s-secrets @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# shellcheck source-path=.. + +pkidb_k8s_secrets() { + set -eo pipefail; shopt -s inherit_errexit + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") + PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") + source "$pkgroot/common.sh" + DOC="pkidb-k8s-secrets - Retrieve CAs via fingerprint and create k8s secrets from them +Usage: + pkidb-k8s-secrets [--namespace=NS] FINGERPRINT... + +Notes: +* Make sure to specify \$PKIDBURL +* The namespace can also be specified via \$POD_NAMESPACE +" +# docopt parser below, refresh this parser with `docopt.sh pkidb-k8s-secrets` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:238};usage=${DOC:82:58};digest=8eced;options=(' --namespac'\ +'e 1');node_0(){ value __namespace 0;};node_1(){ value FINGERPRINT a true;} +node_2(){ optional 0;};node_3(){ repeatable 1;};node_4(){ sequence 2 3;};cat \ +<<<' docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:82:58}" >&2;exit 1;}';local varnames=(__namespace FINGERPRINT) varname +for varname in "${varnames[@]}"; do unset "var_$varname";done;parse 4 "$@" +local p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset \ +"$p$varname";done;if declare -p var_FINGERPRINT >/dev/null 2>&1; then eval \ +$p'FINGERPRINT=("${var_FINGERPRINT[@]}")';else eval $p'FINGERPRINT=()';fi;eval \ +$p'__namespace=${var___namespace:-};';local docopt_i=1;[[ $BASH_VERSION =~ \ +^4.3 ]] && docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for varname in \ +"${varnames[@]}"; do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-k8s-secrets` + eval "$(docopt "$@")" + + # shellcheck disable=2154 + local fingerprint namespace=$__namespace cert secret_name + [[ -n $namespace ]] || namespace=${POD_NAMESPACE:?"Either --namespace or \$POD_NAMESPACE must be specified"} + # shellcheck disable=2153 + for fingerprint in "${FINGERPRINT[@]}"; do + secret_name=${fingerprint,,} + cert=$("$pkgroot/bin/pkidb-ca" "$fingerprint") + printf ' +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: %s + namespace: %s +data: + ca.crt: %s +' "$secret_name" "$namespace" "$(base64 -w0 <<<"$cert")" | kubectl apply -f - | LOGPROGRAM=kubectl tee_info + done +} + +pkidb_k8s_secrets "$@" diff --git a/pkidb-os.sh b/bin/pkidb-os similarity index 54% rename from pkidb-os.sh rename to bin/pkidb-os index 6dbe05a..d96ce4d 100755 --- a/pkidb-os.sh +++ b/bin/pkidb-os @@ -1,32 +1,31 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_os() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" source "$pkgroot/common.sh" DOC="pkidb-os - Exclusively manage OS local CAs (/usr/local/share-ca-certificates) Usage: pkidb-os FINGERPRINT... " -# docopt parser below, refresh this parser with `docopt.sh pkidb-os.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:110}; usage=${DOC:78:32}; digest=346da; shorts=(); longs=() -argcounts=(); node_0(){ value FINGERPRINT a true; }; node_1(){ oneormore 0; } -node_2(){ required 1; }; node_3(){ required 2; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:78:32}" >&2; exit 1 -}'; unset var_FINGERPRINT; parse 3 "$@"; local prefix=${DOCOPT_PREFIX:-''} -unset "${prefix}FINGERPRINT" -if declare -p var_FINGERPRINT >/dev/null 2>&1; then -eval "${prefix}"'FINGERPRINT=("${var_FINGERPRINT[@]}")'; else -eval "${prefix}"'FINGERPRINT=()'; fi; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-os.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-os` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:110};usage=${DOC:78:32};digest=346da;options=();node_0(){ +value FINGERPRINT a true;};node_1(){ repeatable 0;};cat <<<' docopt_exit() { +[[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" "${DOC:78:32}" >&2;exit 1;}' +local varnames=(FINGERPRINT) varname;for varname in "${varnames[@]}"; do unset \ +"var_$varname";done;parse 1 "$@";local p=${DOCOPT_PREFIX:-''};for varname in \ +"${varnames[@]}"; do unset "$p$varname";done;if declare -p var_FINGERPRINT \ +>/dev/null 2>&1; then eval $p'FINGERPRINT=("${var_FINGERPRINT[@]}")';else eval \ +$p'FINGERPRINT=()';fi;eval ;local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && \ +docopt_i=2;for ((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; \ +do declare -p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-os` eval "$(docopt "$@")" check_all_deps [[ $EUID = 0 ]] || fatal "You must be root" @@ -48,7 +47,7 @@ declare -p "${prefix}FINGERPRINT"; done; } done < <(find "$certs_path" -type f -print0) # Update specified CAs for fingerprint in "${FINGERPRINT[@]}"; do - "$pkgroot/pkidb-ca.sh" --dest "${certs_path}/${fingerprint}.crt" "$fingerprint" || ret=$? + "$pkgroot/bin/pkidb-ca" --dest "${certs_path}/${fingerprint}.crt" "$fingerprint" || ret=$? done /usr/sbin/update-ca-certificates 2>&1 | LOGPROGRAM=update-ca-certificates tee_verbose diff --git a/pkidb-pam.sh b/bin/pkidb-pam similarity index 64% rename from pkidb-pam.sh rename to bin/pkidb-pam index e6e7227..5d4bbae 100755 --- a/pkidb-pam.sh +++ b/bin/pkidb-pam @@ -1,36 +1,34 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_pam() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" - source "$pkgroot/.upkg/orbit-online/collections.sh/collections.sh" source "$pkgroot/common.sh" DOC="pkidb-pam - Exclusively manage PAM CAs and cache CRLs Usage: pkidb-pam --crl=CRLNAME... FINGERPRINT... " -# docopt parser below, refresh this parser with `docopt.sh pkidb-pam.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:104}; usage=${DOC:54:50}; digest=82e65; shorts=('') -longs=(--crl); argcounts=(1); node_0(){ value __crl 0 true; }; node_1(){ -value FINGERPRINT a true; }; node_2(){ oneormore 0; }; node_3(){ oneormore 1; } -node_4(){ required 2 3; }; node_5(){ required 4; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:54:50}" >&2; exit 1 -}'; unset var___crl var_FINGERPRINT; parse 5 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__crl" "${prefix}FINGERPRINT" -if declare -p var___crl >/dev/null 2>&1; then -eval "${prefix}"'__crl=("${var___crl[@]}")'; else eval "${prefix}"'__crl=()'; fi -if declare -p var_FINGERPRINT >/dev/null 2>&1; then -eval "${prefix}"'FINGERPRINT=("${var_FINGERPRINT[@]}")'; else -eval "${prefix}"'FINGERPRINT=()'; fi; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}__crl" "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-pam.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-pam` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:104};usage=${DOC:54:50};digest=82e65;options=(' --crl 1') +node_0(){ value __crl 0 true;};node_1(){ value FINGERPRINT a true;};node_2(){ +repeatable 0;};node_3(){ repeatable 1;};node_4(){ sequence 2 3;};cat <<<' \ +docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:54:50}" >&2;exit 1;}';local varnames=(__crl FINGERPRINT) varname;for \ +varname in "${varnames[@]}"; do unset "var_$varname";done;parse 4 "$@";local \ +p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset "$p$varname" +done;if declare -p var___crl >/dev/null 2>&1; then eval $p'__crl=("${var___crl'\ +'[@]}")';else eval $p'__crl=()';fi;if declare -p var_FINGERPRINT >/dev/null \ +2>&1; then eval $p'FINGERPRINT=("${var_FINGERPRINT[@]}")';else eval $p'FINGERP'\ +'RINT=()';fi;eval ;local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2 +for ((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; do declare \ +-p "$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-pam` eval "$(docopt "$@")" check_all_deps [[ $EUID = 0 ]] || fatal "You must be root" @@ -63,7 +61,7 @@ declare -p "${prefix}__crl" "${prefix}FINGERPRINT"; done; } local capaths=() for fingerprint in "${FINGERPRINT[@]}"; do capaths+=("${certs_path}/${fingerprint}.pem") - "$pkgroot/pkidb-ca.sh" --dest "${certs_path}/${fingerprint}.pem" "$fingerprint" || ret=$? + "$pkgroot/bin/pkidb-ca" --dest "${certs_path}/${fingerprint}.pem" "$fingerprint" || ret=$? done (cd "$certs_path" && pkcs11_make_hash_link) || ret=$? @@ -92,7 +90,7 @@ declare -p "${prefix}__crl" "${prefix}FINGERPRINT"; done; } # Update CRLs for the specified CAs for crl_name in "${__crl[@]}"; do - "$pkgroot/pkidb-crl.sh" --dest "${crls_path}/${crl_name}.pem" "$crl_name" "${capaths[@]}" || ret=$? + "$pkgroot/bin/pkidb-crl" --dest "${crls_path}/${crl_name}.pem" "$crl_name" "${capaths[@]}" || ret=$? done (cd "$crls_path" && pkcs11_make_hash_link) diff --git a/pkidb-sshd.sh b/bin/pkidb-sshd similarity index 56% rename from pkidb-sshd.sh rename to bin/pkidb-sshd index 367238e..0a2a94d 100755 --- a/pkidb-sshd.sh +++ b/bin/pkidb-sshd @@ -1,10 +1,10 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_sshd() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" source "$pkgroot/common.sh" DOC="pkidb-sshd - Manage client CAs for openssh-server and renew its hostkey @@ -19,36 +19,30 @@ Options: -k --key-algo ALGO Host cert key algorithms to consider for renewal [default: ecdsa ed25519 rsa] " -# docopt parser below, refresh this parser with `docopt.sh pkidb-sshd.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:544}; usage=${DOC:72:65}; digest=a830b; shorts=(-e -f -k) -longs=(--expiry-threshhold --step-root-fp --key-algo); argcounts=(1 1 1) -node_0(){ value __expiry_threshhold 0; }; node_1(){ value __step_root_fp 1; } -node_2(){ value __key_algo 2 true; }; node_3(){ value KRLNAME a; }; node_4(){ -value FINGERPRINT a true; }; node_5(){ optional 0 1; }; node_6(){ optional 5; } -node_7(){ oneormore 2; }; node_8(){ optional 7; }; node_9(){ oneormore 4; } -node_10(){ required 6 8 3 9; }; node_11(){ required 10; } -cat <<<' docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2 -printf "%s\n" "${DOC:72:65}" >&2; exit 1; }'; unset var___expiry_threshhold \ -var___step_root_fp var___key_algo var_KRLNAME var_FINGERPRINT; parse 11 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__expiry_threshhold" \ -"${prefix}__step_root_fp" "${prefix}__key_algo" "${prefix}KRLNAME" \ -"${prefix}FINGERPRINT" -eval "${prefix}"'__expiry_threshhold=${var___expiry_threshhold:-50%}' -eval "${prefix}"'__step_root_fp=${var___step_root_fp:-'"'"'$STEP_ROOT_FP'"'"'}' -if declare -p var___key_algo >/dev/null 2>&1; then -eval "${prefix}"'__key_algo=("${var___key_algo[@]}")'; else -eval "${prefix}"'__key_algo=(ecdsa ed25519 rsa)'; fi -eval "${prefix}"'KRLNAME=${var_KRLNAME:-}' -if declare -p var_FINGERPRINT >/dev/null 2>&1; then -eval "${prefix}"'FINGERPRINT=("${var_FINGERPRINT[@]}")'; else -eval "${prefix}"'FINGERPRINT=()'; fi; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}__expiry_threshhold" "${prefix}__step_root_fp" \ -"${prefix}__key_algo" "${prefix}KRLNAME" "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-sshd.sh` +# docopt parser below, refresh this parser with `docopt.sh pkidb-sshd` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:544};usage=${DOC:72:65};digest=a830b;options=('-f --step-r'\ +'oot-fp 1' '-e --expiry-threshhold 1' '-k --key-algo 1');node_0(){ value \ +__step_root_fp 0;};node_1(){ value __expiry_threshhold 1;};node_2(){ value \ +__key_algo 2 true;};node_3(){ value KRLNAME a;};node_4(){ value FINGERPRINT a \ +true;};node_5(){ optional 0 1;};node_6(){ optional 7;};node_7(){ repeatable 2;} +node_8(){ repeatable 4;};node_9(){ sequence 5 6 3 8;};cat <<<' docopt_exit() { +[[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" "${DOC:72:65}" >&2;exit 1;}' +local varnames=(__step_root_fp __expiry_threshhold __key_algo KRLNAME \ +FINGERPRINT) varname;for varname in "${varnames[@]}"; do unset "var_$varname" +done;parse 9 "$@";local p=${DOCOPT_PREFIX:-''};for varname in \ +"${varnames[@]}"; do unset "$p$varname";done;if declare -p var___key_algo \ +>/dev/null 2>&1; then eval $p'__key_algo=("${var___key_algo[@]}")';else eval \ +$p'__key_algo=(ecdsa ed25519 rsa)';fi;if declare -p var_FINGERPRINT >/dev/null \ +2>&1; then eval $p'FINGERPRINT=("${var_FINGERPRINT[@]}")';else eval $p'FINGERP'\ +'RINT=()';fi;eval $p'__step_root_fp=${var___step_root_fp:-'"'"'$STEP_ROOT_FP'"'\ +"'};'$p'__expiry_threshhold=${var___expiry_threshhold:-50%};'$p'KRLNAME=${var_'\ +'KRLNAME:-};';local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2;for \ +((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; do declare -p \ +"$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' pkidb-sshd` eval "$(docopt "$@")" check_all_deps [[ $EUID = 0 ]] || fatal "You must be root" @@ -72,14 +66,14 @@ declare -p "${prefix}__expiry_threshhold" "${prefix}__step_root_fp" \ done < <(find "$certs_path" -type f -print0) # Update specified CAs for fingerprint in "${FINGERPRINT[@]}"; do - "$pkgroot/pkidb-ca.sh" --dest "${certs_path}/${fingerprint}.pem" "$fingerprint" || { ret=$?; continue; } + "$pkgroot/bin/pkidb-ca" --dest "${certs_path}/${fingerprint}.pem" "$fingerprint" || { ret=$?; continue; } capaths+=("${certs_path}/${fingerprint}.pem") ssh_pubkey=$(ssh-keygen -i -m PKCS8 -f <(get_pubkey <"${certs_path}/${fingerprint}.pem")) || { ret=$?; continue; } key_lines+=("$ssh_pubkey") done umask 133 printf "%s\n" "${key_lines[@]}" >"$ca_keys_path" - "$pkgroot/pkidb-client-krl.sh" --dest "$krl_path" "$KRLNAME" "${capaths[@]}" || ret=$? + "$pkgroot/bin/pkidb-client-krl" --dest "$krl_path" "$KRLNAME" "${capaths[@]}" || ret=$? info "The client CA certs and the krl have been updated" # shellcheck disable=2154 @@ -89,7 +83,7 @@ declare -p "${prefix}__expiry_threshhold" "${prefix}__step_root_fp" \ fatal "\$STEP_ROOT_FP is not defined" fi export STEP_URL - STEP_URL=$(LOGLEVEL=warning "$pkgroot/pkidb-ca.sh" "$STEP_ROOT_FP" | get_subject_field "2.5.4.87" url) + STEP_URL=$(LOGLEVEL=warning "$pkgroot/bin/pkidb-ca" "$STEP_ROOT_FP" | get_subject_field "2.5.4.87" url) local algo ssh_host_key renewed=false # shellcheck disable=2154 diff --git a/pkidb-step.sh b/bin/pkidb-step similarity index 57% rename from pkidb-step.sh rename to bin/pkidb-step index 8279c14..871d1d5 100755 --- a/pkidb-step.sh +++ b/bin/pkidb-step @@ -1,16 +1,16 @@ #!/usr/bin/env bash +# shellcheck source-path=.. pkidb_step() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" source "$pkgroot/common.sh" check_all_deps [[ -n $STEP_ROOT_FP ]] || fatal "\$STEP_ROOT_FP is not defined" export STEP_URL - STEP_URL=$(LOGLEVEL=warning "$pkgroot/pkidb-ca.sh" "$STEP_ROOT_FP" | get_subject_field "2.5.4.87" url) + STEP_URL=$(LOGLEVEL=warning "$pkgroot/bin/pkidb-ca" "$STEP_ROOT_FP" | get_subject_field "2.5.4.87" url) exec step "$@" } diff --git a/sign-dev-tls-cert.sh b/bin/sign-dev-tls-cert similarity index 61% rename from sign-dev-tls-cert.sh rename to bin/sign-dev-tls-cert index a779faf..e887e70 100755 --- a/sign-dev-tls-cert.sh +++ b/bin/sign-dev-tls-cert @@ -1,10 +1,9 @@ #!/usr/bin/env bash +# shellcheck source-path=.. main() { set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" - source "$pkgroot/.upkg/orbit-online/collections.sh/collections.sh" + local pkgroot; pkgroot=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/..") source "$pkgroot/common.sh" DOC="sign-dev-tls-cert - Retrieve a TLS cert for .local domains @@ -19,28 +18,25 @@ Options: Notes: The certificate bundle and key will be output to ./bundle.pem and ./key.pem " -# docopt parser below, refresh this parser with `docopt.sh sign-dev-tls-cert.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:422}; usage=${DOC:59:57}; digest=77f05; shorts=(-f -C '') -longs=(--force-renewal --dir --san); argcounts=(0 1 1); node_0(){ -switch __force_renewal 0; }; node_1(){ value __dir 1; }; node_2(){ -value __san 2 true; }; node_3(){ value FQDN a; }; node_4(){ oneormore 2; } -node_5(){ optional 0 1 4; }; node_6(){ required 5 3; }; node_7(){ required 6; } -cat <<<' docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2 -printf "%s\n" "${DOC:59:57}" >&2; exit 1; }'; unset var___force_renewal \ -var___dir var___san var_FQDN; parse 7 "$@"; local prefix=${DOCOPT_PREFIX:-''} -unset "${prefix}__force_renewal" "${prefix}__dir" "${prefix}__san" \ -"${prefix}FQDN"; eval "${prefix}"'__force_renewal=${var___force_renewal:-false}' -eval "${prefix}"'__dir=${var___dir:-}' -if declare -p var___san >/dev/null 2>&1; then -eval "${prefix}"'__san=("${var___san[@]}")'; else eval "${prefix}"'__san=()'; fi -eval "${prefix}"'FQDN=${var_FQDN:-}'; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}__force_renewal" "${prefix}__dir" "${prefix}__san" \ -"${prefix}FQDN"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' sign-dev-tls-cert.sh` +# docopt parser below, refresh this parser with `docopt.sh sign-dev-tls-cert` +# shellcheck disable=2016,2086,2317,1090,1091,2034,2154 +docopt() { source "$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh" '2.0.0' || { +ret=$?;printf -- "exit %d\n" "$ret";exit "$ret";};set -e +trimmed_doc=${DOC:0:422};usage=${DOC:59:57};digest=77f05;options=('-f --force-'\ +'renewal 0' '-C --dir 1' ' --san 1');node_0(){ switch __force_renewal 0;} +node_1(){ value __dir 1;};node_2(){ value __san 2 true;};node_3(){ value FQDN a +};node_4(){ optional 0 1 5;};node_5(){ repeatable 2;};node_6(){ sequence 4 3;} +cat <<<' docopt_exit() { [[ -n $1 ]] && printf "%s\n" "$1" >&2;printf "%s\n" \ +"${DOC:59:57}" >&2;exit 1;}';local varnames=(__force_renewal __dir __san FQDN) \ +varname;for varname in "${varnames[@]}"; do unset "var_$varname";done;parse 6 \ +"$@";local p=${DOCOPT_PREFIX:-''};for varname in "${varnames[@]}"; do unset \ +"$p$varname";done;if declare -p var___san >/dev/null 2>&1; then eval $p'__san='\ +'("${var___san[@]}")';else eval $p'__san=()';fi;eval $p'__force_renewal=${var_'\ +'__force_renewal:-false};'$p'__dir=${var___dir:-};'$p'FQDN=${var_FQDN:-};' +local docopt_i=1;[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2;for \ +((;docopt_i>0;docopt_i--)); do for varname in "${varnames[@]}"; do declare -p \ +"$p$varname";done;done;} +# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/docopt-lib.sh/docopt-lib.sh"' sign-dev-tls-cert` eval "$(docopt "$@")" ( [[ $FQDN = *.local ]] || fatal "The FQDN '%s' must be a .local domain" "$FQDN" diff --git a/common.sh b/common.sh index 4eee30f..cf7b28b 100644 --- a/common.sh +++ b/common.sh @@ -1,5 +1,10 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 +source "${pkgroot:?}/.upkg/records.sh/records.sh" +# shellcheck disable=SC1091 +source "$pkgroot/.upkg/collections.sh/collections.sh" + [[ -n "$PKIDBURL" ]] || fatal "\$PKIDBURL is not set, unable to continue." check_all_deps() { diff --git a/k8s-secrets/.gitignore b/k8s-secrets/.gitignore index 5bc9a2a..71f9c24 100644 --- a/k8s-secrets/.gitignore +++ b/k8s-secrets/.gitignore @@ -1 +1 @@ -/.upkg/ +/.upkg diff --git a/k8s-secrets/Dockerfile b/k8s-secrets/Dockerfile index 696ec3d..0b2cd68 100644 --- a/k8s-secrets/Dockerfile +++ b/k8s-secrets/Dockerfile @@ -9,10 +9,11 @@ RUN wget -q "https://dl.k8s.io/release/v1.27.4/bin/linux/amd64/kubectl" && \ install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl WORKDIR /pkidb-tools -COPY common.sh k8s-secrets/upkg.json /pkidb-tools -COPY --chmod=0755 pkidb-k8s-secrets.sh pkidb-ca.sh /pkidb-tools -RUN bash -ec 'src=$(wget -qO- https://raw.githubusercontent.com/orbit-online/upkg/v0.14.0/upkg.sh); \ -shasum -a 256 -c <(printf "8312d0fa0e47ff22387086021c8b096b899ff9344ca8622d80cc0d1d579dccff -") <<<"$src"; \ -set - install; eval "$src"' +COPY common.sh k8s-secrets/upkg.json /pkidb-tools/ +COPY --chmod=0755 bin/pkidb-k8s-secrets bin/pkidb-ca /pkidb-tools/ +RUN bash -ec 'u=https://github.com/orbit-online/upkg/releases/download/v0.24.4/upkg-install.tar.gz;\ +t=$(mktemp); trap "rm \"$t\"" EXIT;wget -qO"$t" "$u" || curl -fsLo"$t" "$u";\ +shasum -a 256 -c <(echo "4398bebb91fbf9103b44ffb415e66bc3c7c99522cae27535b2050054869bfbb7 $t");\ +tar xzC /usr/local -f "$t"' -ENTRYPOINT ["/pkidb-tools/pkidb-k8s-secrets.sh"] +ENTRYPOINT ["/pkidb-tools/pkidb-k8s-secrets"] diff --git a/k8s-secrets/upkg.json b/k8s-secrets/upkg.json index e2d5d91..28ca278 100644 --- a/k8s-secrets/upkg.json +++ b/k8s-secrets/upkg.json @@ -1,8 +1,20 @@ { - "dependencies": { - "orbit-online/records.sh": "v0.9.5", - "orbit-online/checkdeps": "v1.0.2", - "andsens/docopt.sh": "v1.0.0-upkg", - "orbit-online/path-tools": "v0.2.1" - } + "dependencies": [ + { + "tar": "https://github.com/andsens/docopt.sh/releases/latest/download/docopt-lib.sh.tar.gz", + "sha256": "1d8b771418583cce2e6362c4c6b9a2cc506b241327424d5cc0b6fac8e8463806" + }, + { + "tar": "https://github.com/orbit-online/path-tools/releases/latest/download/path-tools.tar.gz", + "sha256": "2ae2a98714aa81e2142b749dac9ecdb61e050e66bf8bd33aef0fccb2ce66c84b" + }, + { + "tar": "https://github.com/orbit-online/records.sh/releases/latest/download/records.sh.tar.gz", + "sha256": "0469f15f5b689cb29b30f2a3b233c61856eb209fc50c74ef141120bbf70697f1" + }, + { + "tar": "https://github.com/orbit-online/checkdeps/releases/latest/download/checkdeps.tar.gz", + "sha256": "0b7ebb5e60163ccbd4966527f72c0e30f8cb183de6057ddad72b4e6b83ae1637" + } + ] } diff --git a/pkidb-k8s-secrets.sh b/pkidb-k8s-secrets.sh deleted file mode 100755 index f0dc9bc..0000000 --- a/pkidb-k8s-secrets.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -pkidb_k8s_secrets() { - set -eo pipefail; shopt -s inherit_errexit - local pkgroot; pkgroot=$(dirname "$(realpath "${BASH_SOURCE[0]}")") - PATH=$("$pkgroot/.upkg/.bin/path_prepend" "$pkgroot/.upkg/.bin") - source "$pkgroot/.upkg/orbit-online/records.sh/records.sh" - DOC="pkidb-k8s-secrets - Retrieve CAs via fingerprint and create k8s secrets from them -Usage: - pkidb-k8s-secrets [--namespace=NS] FINGERPRINT... - -Notes: -* Make sure to specify \$PKIDBURL -* The namespace can also be specified via \$POD_NAMESPACE -" -# docopt parser below, refresh this parser with `docopt.sh pkidb-k8s-secrets.sh` -# shellcheck disable=2016,1090,1091,2034,2154 -docopt() { source "$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh" '1.0.0' || { -ret=$?; printf -- "exit %d\n" "$ret"; exit "$ret"; }; set -e -trimmed_doc=${DOC:0:238}; usage=${DOC:82:58}; digest=8eced; shorts=('') -longs=(--namespace); argcounts=(1); node_0(){ value __namespace 0; }; node_1(){ -value FINGERPRINT a true; }; node_2(){ optional 0; }; node_3(){ oneormore 1; } -node_4(){ required 2 3; }; node_5(){ required 4; }; cat <<<' docopt_exit() { -[[ -n $1 ]] && printf "%s\n" "$1" >&2; printf "%s\n" "${DOC:82:58}" >&2; exit 1 -}'; unset var___namespace var_FINGERPRINT; parse 5 "$@" -local prefix=${DOCOPT_PREFIX:-''}; unset "${prefix}__namespace" \ -"${prefix}FINGERPRINT"; eval "${prefix}"'__namespace=${var___namespace:-}' -if declare -p var_FINGERPRINT >/dev/null 2>&1; then -eval "${prefix}"'FINGERPRINT=("${var_FINGERPRINT[@]}")'; else -eval "${prefix}"'FINGERPRINT=()'; fi; local docopt_i=1 -[[ $BASH_VERSION =~ ^4.3 ]] && docopt_i=2; for ((;docopt_i>0;docopt_i--)); do -declare -p "${prefix}__namespace" "${prefix}FINGERPRINT"; done; } -# docopt parser above, complete command for generating this parser is `docopt.sh --library='"$pkgroot/.upkg/andsens/docopt.sh/docopt-lib.sh"' pkidb-k8s-secrets.sh` - eval "$(docopt "$@")" - - # shellcheck disable=2154 - local fingerprint namespace=$__namespace cert secret_name - [[ -n $namespace ]] || namespace=${POD_NAMESPACE:?"Either --namespace or \$POD_NAMESPACE must be specified"} - # shellcheck disable=2153 - for fingerprint in "${FINGERPRINT[@]}"; do - secret_name=${fingerprint,,} - cert=$("$pkgroot/pkidb-ca.sh" "$fingerprint") - printf ' -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: %s - namespace: %s -data: - ca.crt: %s -' "$secret_name" "$namespace" "$(base64 -w0 <<<"$cert")" | kubectl apply -f - | LOGPROGRAM=kubectl tee_info - done -} - -pkidb_k8s_secrets "$@" diff --git a/upkg.json b/upkg.json index 0a9ec83..bcd9ffe 100644 --- a/upkg.json +++ b/upkg.json @@ -1,23 +1,29 @@ { - "dependencies": { - "orbit-online/checkdeps": "v1.0.2", - "orbit-online/records.sh": "v0.9.5", - "andsens/docopt.sh": "v1.0.0-upkg", - "orbit-online/smallstep-wrapper": "v2.0.3", - "orbit-online/collections.sh": "v0.0.1", - "orbit-online/path-tools": "v0.2.1" - }, - "assets": ["common.sh"], - "commands": { - "pkidb-k8s-secrets": "pkidb-k8s-secrets.sh", - "pkidb-ca": "pkidb-ca.sh", - "pkidb-client-krl": "pkidb-client-krl.sh", - "pkidb-crl": "pkidb-crl.sh", - "pkidb-browser": "pkidb-browser.sh", - "pkidb-pam": "pkidb-pam.sh", - "pkidb-os": "pkidb-os.sh", - "pkidb-sshd": "pkidb-sshd.sh", - "pkidb-step": "pkidb-step.sh", - "sign-dev-tls-cert": "sign-dev-tls-cert.sh" - } + "name": "pkidb-tools", + "dependencies": [ + { + "tar": "https://github.com/orbit-online/checkdeps/releases/latest/download/checkdeps.tar.gz", + "sha256": "0b7ebb5e60163ccbd4966527f72c0e30f8cb183de6057ddad72b4e6b83ae1637" + }, + { + "tar": "https://github.com/orbit-online/records.sh/releases/latest/download/records.sh.tar.gz", + "sha256": "0469f15f5b689cb29b30f2a3b233c61856eb209fc50c74ef141120bbf70697f1" + }, + { + "tar": "https://github.com/orbit-online/smallstep-wrapper/releases/latest/download/smallstep-wrapper.tar.gz", + "sha256": "c47a1a9438222498e531f56ff47bd8e694956c699fbd568d544e937f7bbf43c1" + }, + { + "tar": "https://github.com/orbit-online/collections.sh/releases/latest/download/collections.sh.tar.gz", + "sha256": "ca741323c2bd77f547fa9aea41050d85dfc5f1ce3ff42f73b7a12f7c90b9be2e" + }, + { + "tar": "https://github.com/orbit-online/path-tools/releases/latest/download/path-tools.tar.gz", + "sha256": "2ae2a98714aa81e2142b749dac9ecdb61e050e66bf8bd33aef0fccb2ce66c84b" + }, + { + "tar": "https://github.com/andsens/docopt.sh/releases/latest/download/docopt-lib.sh.tar.gz", + "sha256": "1d8b771418583cce2e6362c4c6b9a2cc506b241327424d5cc0b6fac8e8463806" + } + ] }