Harden production workflows and agent admission
This commit is contained in:
@@ -6,9 +6,22 @@ set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT="$(cd "$HERE/.." && pwd)"
|
||||
TOKEN="${MONLET_AUTH_TOKEN:-monlet-dev-token}"
|
||||
BASE="${MONLET_API_BASE_URL:-http://127.0.0.1:8000}"
|
||||
COMPOSE=(docker compose -f "$HERE/docker-compose.yml")
|
||||
TOKEN="${MONLET_AUTH_TOKEN:-monlet-ui-dev-token}"
|
||||
AGENT_KEY="${MONLET_AGENT_KEY:-monlet-agent-dev-key-0000000000000000}"
|
||||
POSTGRES_HOST_PORT="${MONLET_POSTGRES_HOST_PORT:-15432}"
|
||||
SERVER_HOST_PORT="${MONLET_SERVER_HOST_PORT:-18000}"
|
||||
WEB_HOST_PORT="${MONLET_WEB_HOST_PORT:-13000}"
|
||||
# Export so every `docker compose` call (up/exec/down) sees the UI token env,
|
||||
# including the cleanup trap.
|
||||
export MONLET_AUTH_TOKEN="$TOKEN"
|
||||
export MONLET_POSTGRES_HOST_PORT="$POSTGRES_HOST_PORT"
|
||||
export MONLET_SERVER_HOST_PORT="$SERVER_HOST_PORT"
|
||||
export MONLET_WEB_HOST_PORT="$WEB_HOST_PORT"
|
||||
BASE="${MONLET_API_BASE_URL:-http://127.0.0.1:$SERVER_HOST_PORT}"
|
||||
# PH-review: dedicated project name so smoke does not collide with the
|
||||
# showcase/dev stack (orphan containers, shared postgres volume with a stale
|
||||
# baseline schema, etc.).
|
||||
COMPOSE=(docker compose -p monlet-smoke -f "$HERE/docker-compose.yml")
|
||||
|
||||
log() { printf "\033[1;36m[smoke]\033[0m %s\n" "$*"; }
|
||||
fail() { printf "\033[1;31m[smoke]\033[0m %s\n" "$*" >&2; exit 1; }
|
||||
@@ -21,8 +34,11 @@ cleanup() {
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
log "starting stack"
|
||||
MONLET_AUTH_TOKEN="$TOKEN" "${COMPOSE[@]}" up -d --build postgres server web
|
||||
log "pre-clean previous smoke stack (if any)"
|
||||
"${COMPOSE[@]}" down -v --remove-orphans >/dev/null 2>&1 || true
|
||||
|
||||
log "starting stack (phase 1: postgres+server)"
|
||||
"${COMPOSE[@]}" up -d --build postgres server
|
||||
|
||||
log "waiting for /api/v1/ready"
|
||||
for i in $(seq 1 60); do
|
||||
@@ -37,33 +53,41 @@ curl -sf "$BASE/api/v1/health" | grep -q '"status":"ok"' || fail "health wrong b
|
||||
log "GET /metrics"
|
||||
curl -sf "$BASE/metrics" | grep -q '^monlet_server_' || fail "metrics missing"
|
||||
|
||||
AUTH=(-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json")
|
||||
log "starting web (phase 2)"
|
||||
"${COMPOSE[@]}" up -d --build web
|
||||
|
||||
AGENT_AUTH=(-H "Authorization: Bearer $AGENT_KEY" -H "Content-Type: application/json")
|
||||
UI_AUTH=(-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json")
|
||||
|
||||
log "POST heartbeat (examples/heartbeat.json)"
|
||||
curl -sf "${AUTH[@]}" -X POST "$BASE/api/v1/heartbeat" --data @"$ROOT/examples/heartbeat.json" \
|
||||
curl -sf "${AGENT_AUTH[@]}" -X POST "$BASE/api/v1/heartbeat" --data @"$ROOT/examples/heartbeat.json" \
|
||||
| grep -q '"accepted":true' || fail "heartbeat not accepted"
|
||||
|
||||
log "accept pending agent"
|
||||
curl -sf "${UI_AUTH[@]}" -X POST "$BASE/api/v1/agents/host-01.prod/accept" \
|
||||
| grep -q '"count":1' || fail "agent not accepted"
|
||||
|
||||
log "POST events (examples/event-batch.json)"
|
||||
curl -sf "${AUTH[@]}" -X POST "$BASE/api/v1/events" --data @"$ROOT/examples/event-batch.json" \
|
||||
curl -sf "${AGENT_AUTH[@]}" -X POST "$BASE/api/v1/events" --data @"$ROOT/examples/event-batch.json" \
|
||||
| grep -q '"accepted":' || fail "event batch not accepted"
|
||||
|
||||
log "GET /agents has host-01.prod"
|
||||
curl -sf "${AUTH[@]}" "$BASE/api/v1/agents" | grep -q '"agent_id":"host-01.prod"' \
|
||||
curl -sf "${UI_AUTH[@]}" "$BASE/api/v1/agents" | grep -q '"agent_id":"host-01.prod"' \
|
||||
|| fail "host-01.prod missing"
|
||||
|
||||
log "GET /checks not empty"
|
||||
curl -sf "${AUTH[@]}" "$BASE/api/v1/checks" | grep -q '"items":\[{' \
|
||||
curl -sf "${UI_AUTH[@]}" "$BASE/api/v1/checks" | grep -q '"items":\[{' \
|
||||
|| fail "checks empty"
|
||||
|
||||
log "GET /incidents not empty (event-batch.json contains a critical event)"
|
||||
curl -sf "${AUTH[@]}" "$BASE/api/v1/incidents?state=open" | grep -q '"items":\[{' \
|
||||
curl -sf "${UI_AUTH[@]}" "$BASE/api/v1/incidents?state=open" | grep -q '"items":\[{' \
|
||||
|| fail "no open incident"
|
||||
|
||||
log "GET /notifiers/outbox not empty"
|
||||
curl -sf "${AUTH[@]}" "$BASE/api/v1/notifiers/outbox" | grep -q '"items":\[{' \
|
||||
curl -sf "${UI_AUTH[@]}" "$BASE/api/v1/notifiers/outbox" | grep -q '"items":\[{' \
|
||||
|| fail "outbox empty"
|
||||
|
||||
WEB_BASE="${MONLET_WEB_BASE_URL:-http://127.0.0.1:3000}"
|
||||
WEB_BASE="${MONLET_WEB_BASE_URL:-http://127.0.0.1:$WEB_HOST_PORT}"
|
||||
log "waiting for web $WEB_BASE"
|
||||
for i in $(seq 1 60); do
|
||||
if curl -sf -o /dev/null "$WEB_BASE/"; then break; fi
|
||||
@@ -71,8 +95,8 @@ for i in $(seq 1 60); do
|
||||
[[ "$i" == "60" ]] && fail "web did not become ready"
|
||||
done
|
||||
|
||||
log "GET / (web overview)"
|
||||
curl -sf "$WEB_BASE/" | grep -q "Overview" || fail "web overview missing 'Overview'"
|
||||
log "GET / (web root follows redirect to /agents)"
|
||||
curl -sfL "$WEB_BASE/" | grep -q "host-01.prod" || fail "web root did not render agents list"
|
||||
|
||||
log "GET /agents (web list)"
|
||||
curl -sf "$WEB_BASE/agents" | grep -q "host-01.prod" || fail "web /agents missing host-01.prod"
|
||||
|
||||
Reference in New Issue
Block a user