#!/usr/bin/env bash # scripts/smoke.sh — minimal post-deploy critical-path checks. Run from the # operator's workstation against the public URL, NOT from the deploy host. # # Usage: # BASE_URL=https://stage.admin.azaion.com SMOKE_ADMIN_EMAIL=... SMOKE_ADMIN_PASSWORD=... ./scripts/smoke.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "$SCRIPT_DIR/_lib.sh" usage() { cat <<'EOF' Usage: ./scripts/smoke.sh [--help] Required environment: BASE_URL public base URL of the deploy target SMOKE_ADMIN_EMAIL existing ApiAdmin user SMOKE_ADMIN_PASSWORD matching password EOF } [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { usage; exit 0; } require_env BASE_URL SMOKE_ADMIN_EMAIL SMOKE_ADMIN_PASSWORD require_cmd curl jq step() { log_info "smoke[$1] $2"; } fail() { log_error "smoke[$1] FAILED: $2"; exit 1; } # 1. Liveness (anonymous) step 1 "GET /health/live" curl --fail --silent --show-error --max-time 5 "$BASE_URL/health/live" >/dev/null \ || fail 1 "/health/live did not return 200" # 2. Readiness — public-facing nginx may not expose /health/ready (it's internal- # only by design). Skip if not 200; the deploy script already checked it inside # the host network. step 2 "GET /health/ready (best-effort, may be unreachable from public URL)" if curl --fail --silent --show-error --max-time 5 "$BASE_URL/health/ready" >/dev/null; then log_info "/health/ready returned 200 (exposed publicly — verify this is intentional)" fi # 3. Login → JWT step 3 "POST /login as $SMOKE_ADMIN_EMAIL" TOKEN_JSON="$(curl --fail --silent --show-error --max-time 10 \ -H 'Content-Type: application/json' \ -d "$(jq -n --arg e "$SMOKE_ADMIN_EMAIL" --arg p "$SMOKE_ADMIN_PASSWORD" '{email:$e, password:$p}')" \ "$BASE_URL/login")" \ || fail 3 "login request failed" TOKEN="$(echo "$TOKEN_JSON" | jq -r '.token // .Token // empty')" [[ -n "$TOKEN" ]] || fail 3 "login returned no token: $TOKEN_JSON" AUTH=(-H "Authorization: Bearer $TOKEN") # 4. Authenticated GET /users/current step 4 "GET /users/current" curl --fail --silent --show-error --max-time 5 "${AUTH[@]}" "$BASE_URL/users/current" >/dev/null \ || fail 4 "/users/current did not return 200" # 5. Authenticated GET /users step 5 "GET /users" USERS_JSON="$(curl --fail --silent --show-error --max-time 10 "${AUTH[@]}" "$BASE_URL/users")" \ || fail 5 "/users did not return 200" USER_COUNT="$(echo "$USERS_JSON" | jq 'length')" log_info "/users returned $USER_COUNT rows" # 6. Authenticated GET /resources/list (default folder) step 6 "GET /resources/list" curl --fail --silent --show-error --max-time 5 "${AUTH[@]}" "$BASE_URL/resources/list" >/dev/null \ || fail 6 "/resources/list did not return 200" log_info "smoke OK — 6 checks passed"