163 lines
4.5 KiB
Bash
Executable File
163 lines
4.5 KiB
Bash
Executable File
#!/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."
|