77 lines
4.7 KiB
Bash
77 lines
4.7 KiB
Bash
#!/bin/sh
|
|
set -eu
|
|
set -o pipefail
|
|
# Shell syntax and static analysis cover the actual container shell scripts.
|
|
shellcheck -s ash -x -S warning infra/local/scripts/dispatch.sh infra/local/scripts/test.sh
|
|
shellcheck -x -S warning infra/local/tools.sh infra/local/scripts/start-service.sh infra/local/mongo/start.sh infra/local/nats/start.sh infra/local/vault/start.sh
|
|
. infra/local/scripts/common.sh
|
|
. infra/local/scripts/images.sh
|
|
. infra/local/scripts/bootstrap.sh
|
|
# Offline fixtures exercise stable selection, reject prereleases, and preserve pins.
|
|
get() {
|
|
case "$1" in
|
|
*/tags/latest) printf '{"digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}';;
|
|
*page_size*) cat <<'JSON'
|
|
{"results":[{"name":"2.1.0","digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},{"name":"2.2.0-rc1","digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}]}
|
|
JSON
|
|
;;
|
|
*) return 1;;
|
|
esac
|
|
}
|
|
[ "$(image hashicorp/vault latest)" = 'hashicorp/vault:2.1.0@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ] || fail 'Stable release selection failed'
|
|
get() { printf '{"digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","results":[{"name":"3.0.0-rc1","digest":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}]}'; }
|
|
if image hashicorp/vault latest >/dev/null 2>&1; then fail 'Prerelease accepted'; fi
|
|
# Isolate state from the developer stack during failure tests.
|
|
STATE="$WORK/state"; mkdir "$STATE"; printf 'previous build' > "$STATE/images.env"
|
|
get() { return 1; }
|
|
if images >/dev/null 2>&1; then fail 'Offline resolution succeeded'; fi
|
|
[ "$(cat "$STATE/images.env")" = 'previous build' ] || fail 'Failed resolution replaced pins'
|
|
if printf '{"api_key":"","sender_address":"notifications@localhost.test"}' | email_valid; then fail 'Empty email accepted'; fi
|
|
printf '{"api_key":"fixture-only","sender_address":"sender@example.test"}' | email_valid
|
|
# Initialized Vault without matching local keys must fail without initializing it again.
|
|
vault() { printf '{"initialized":true}'; }
|
|
if (initialize) > "$WORK/initialize-error" 2>&1; then fail 'Missing local keys accepted'; fi
|
|
grep -q 'Missing .local' "$WORK/initialize-error"
|
|
for service in bff notifications; do
|
|
if grep -Eq 'database/creds/|SXCHNGE_MONGO_URI' "infra/local/vault/$service.hcl"; then fail 'Database credentials trigger Agent restart'; fi
|
|
done
|
|
echo 'PASS: shell analysis, stable selection, failed-resolution preservation, email validation, missing-key protection and Agent contract'
|
|
if command -v python >/dev/null 2>&1 || command -v python3 >/dev/null 2>&1; then fail 'Tool image unexpectedly contains Python'; fi
|
|
# Migration never overwrites an independently provisioned destination.
|
|
. infra/local/scripts/secrets.sh
|
|
secret_moves() { echo 'email services/notifications/email/resend'; }
|
|
archive_secret() { :; }
|
|
kv() {
|
|
case "$1" in
|
|
email) printf '{"api_key":"existing-fixture"}';;
|
|
*) cat "$WORK/destination";;
|
|
esac
|
|
}
|
|
vault() {
|
|
[ "$1" = kv/data/services/notifications/email/resend ] || fail 'Unexpected migration mutation'
|
|
jq -e '.options.cas==0' >/dev/null
|
|
printf '{"api_key":"existing-fixture"}' > "$WORK/destination"
|
|
}
|
|
printf 'null' > "$WORK/destination"
|
|
migrate_secrets
|
|
migrate_secrets
|
|
printf '{"api_key":"different-fixture"}' > "$WORK/destination"
|
|
if (migrate_secrets) >/dev/null 2>&1; then fail 'Migration overwrote conflicting destination'; fi
|
|
jq -e '.api_key=="different-fixture"' "$WORK/destination" >/dev/null
|
|
echo 'PASS: secret migration is repeatable and refuses conflicting destination values'
|
|
# Removing non-secret fields retains the key and checks the current KV version.
|
|
vault() {
|
|
if [ "${2:-GET}" = GET ]; then cat "$WORK/email-fixture"; else
|
|
jq -e '.options.cas==42 and .data=={api_key:"preserved-fixture-key"}' > /dev/null || return 1
|
|
printf '{"data":{"metadata":{"version":43},"data":{"api_key":"preserved-fixture-key"}}}' > "$WORK/email-fixture"
|
|
fi
|
|
}
|
|
printf '{"data":{"metadata":{"version":42},"data":{"api_key":"preserved-fixture-key","driver":"resend","sender_address":"sender@example.test","sender_name":"Fixture"}}}' > "$WORK/email-fixture"
|
|
normalize_email_secret
|
|
normalize_email_secret
|
|
jq -e '.data.data=={api_key:"preserved-fixture-key"}' "$WORK/email-fixture" >/dev/null
|
|
printf '{"data":{"metadata":{"version":43},"data":{"api_key":"preserved-fixture-key","unexpected":"must-not-drop"}}}' > "$WORK/email-fixture"
|
|
if (normalize_email_secret) >/dev/null 2>&1; then fail 'Unknown secret field was silently dropped'; fi
|
|
if grep -q EMAIL_CONFIG infra/local/vault/notifications.hcl infra/local/scripts/start-service.sh; then fail 'Email configuration is still rendered from Vault'; fi
|
|
echo 'PASS: email migration preserves API key, removes configuration fields and rejects unknown fields'
|