#!/usr/bin/env bash set -euo pipefail umask 077 ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) env_file=${1:-"$ROOT/.env"} mode=${2:-} render_target=${3:-} if [[ "$env_file" != /* ]]; then env_file="$ROOT/$env_file" fi if [[ -n "$mode" && "$mode" != "--render-only" ]]; then echo "Usage: $0 [ENV_FILE] [--render-only OUTPUT_FILE]" >&2 exit 2 fi if [[ "$mode" == "--render-only" && -z "$render_target" ]]; then echo "Usage: $0 [ENV_FILE] [--render-only OUTPUT_FILE]" >&2 exit 2 fi [[ -f "$env_file" ]] || { echo "Development environment does not exist: $env_file" >&2 exit 2 } [[ "$(stat -c '%a' "$env_file")" == 600 ]] || { echo "Development environment must have mode 0600: $env_file" >&2 exit 2 } [[ "$(stat -c '%u' "$env_file")" == "$(id -u)" ]] || { echo "Development environment must be owned by the current user: $env_file" >&2 exit 2 } managed_keys=( ANDROID_APP_LINKS_PACKAGE_NAME ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS EMAIL_FROM_ADDRESS EMAIL_FROM_NAME FCM_PROJECT_ID FCM_SERVICE_ACCOUNT_JSON_BASE64 GITHUB_OAUTH_CLIENT_ID GITHUB_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_AUTHORIZED_PARTY_IDS GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET SUPPORT_INBOX_ADDRESS SUPPORT_INBOUND_RECIPIENT SUPPORT_INBOUND_WEBHOOK_TOKEN SUPPORT_OPERATOR_EMAIL_MODE WEB_PUSH_VAPID_PRIVATE_KEY WEB_PUSH_VAPID_PUBLIC_KEY WEB_PUSH_VAPID_SUBJECT ) runtime_dir=$(mktemp -d "${TMPDIR:-/tmp}/wnh-kind-runtime-secret.XXXXXX") cleanup() { status=$? trap - EXIT HUP INT TERM find "$runtime_dir" -xdev -depth -delete 2>/dev/null || true exit "$status" } trap cleanup EXIT HUP INT TERM keys_file="$runtime_dir/managed-keys" printf '%s\n' "${managed_keys[@]}" >"$keys_file" filtered_env="$runtime_dir/runtime.env" awk -F= ' NR == FNR { managed[$1] = 1 next } { key = $1 if (!(key in managed)) next seen[key]++ if (seen[key] > 1) { printf "Managed development key occurs more than once: %s\n", key > "/dev/stderr" invalid = 1 next } value = substr($0, length(key) + 2) if ((value ~ /^".*"$/) || (value ~ /^\047.*\047$/)) { value = substr(value, 2, length(value) - 2) } if (length(value) > 0) print key "=" value } END { if (invalid) exit 1 } ' "$keys_file" "$env_file" >"$filtered_env" chmod 600 "$filtered_env" if [[ "$mode" == "--render-only" ]]; then case "$render_target" in /*) ;; *) render_target="$ROOT/$render_target" ;; esac install -m 600 "$filtered_env" "$render_target" echo "Rendered managed development runtime keys without printing their values." exit 0 fi KUBECTL_BIN=${KUBECTL_BIN:-kubectl} KUBE_CONTEXT=${KUBE_CONTEXT:-kind-who-need-help} KUBE_NAMESPACE=${KUBE_NAMESPACE:-who-need-help} KUBE_SECRET_NAME=${KUBE_SECRET_NAME:-who-need-help-local} existing_json="$runtime_dir/existing.json" extra_json="$runtime_dir/extra.json" desired_json="$runtime_dir/desired.json" observed_json="$runtime_dir/observed.json" "$KUBECTL_BIN" --context "$KUBE_CONTEXT" --namespace "$KUBE_NAMESPACE" \ get secret "$KUBE_SECRET_NAME" --output json >"$existing_json" if [[ -s "$filtered_env" ]]; then "$KUBECTL_BIN" create secret generic "$KUBE_SECRET_NAME" \ --namespace "$KUBE_NAMESPACE" \ --from-env-file="$filtered_env" \ --dry-run=client \ --output json >"$extra_json" else printf '%s\n' '{"data":{}}' >"$extra_json" fi jq --slurpfile extra "$extra_json" --rawfile managed "$keys_file" ' ($managed | split("\n") | map(select(length > 0))) as $managed_keys | .data = ( ((.data // {}) | with_entries(select(.key as $key | ($managed_keys | index($key) | not)))) + ($extra[0].data // {}) ) | { apiVersion: "v1", kind: "Secret", metadata: { name: .metadata.name, namespace: .metadata.namespace, resourceVersion: .metadata.resourceVersion }, type: (.type // "Opaque"), data: .data } ' "$existing_json" >"$desired_json" "$KUBECTL_BIN" --context "$KUBE_CONTEXT" --namespace "$KUBE_NAMESPACE" \ replace --filename "$desired_json" >/dev/null "$KUBECTL_BIN" --context "$KUBE_CONTEXT" --namespace "$KUBE_NAMESPACE" \ get secret "$KUBE_SECRET_NAME" --output json >"$observed_json" jq --exit-status --slurpfile desired "$desired_json" \ '.data == $desired[0].data' "$observed_json" >/dev/null || { echo "Kubernetes Secret verification did not match the desired key set." >&2 exit 1 } synced_count=$(wc -l <"$filtered_env" | tr -d '[:space:]') echo "Synchronized $synced_count managed development runtime keys without printing their values."