Add deployment/setup-pve201.sh — one-shot Phase B host bootstrap
Idempotent: installs systemd tunnel unit, smoke-tests it, writes the nginx vhost + htpasswd, reloads nginx. Reads BASIC_AUTH_USER/PASS from env (use sudo -E).
This commit is contained in:
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
# setup-pve201.sh — one-shot Phase B host setup. Run on pve-201 from the repo root.
|
||||
#
|
||||
# Usage (run on pve-201, in the repo root, on branch chore/tim-tunnel-routing):
|
||||
# BASIC_AUTH_USER=front BASIC_AUTH_PASS=<pw> sudo -E bash deployment/setup-pve201.sh
|
||||
#
|
||||
# What it does (idempotent — safe to re-run):
|
||||
# 1. Installs flights-tim-tunnel.service systemd unit and brings it up.
|
||||
# 2. Smoke-tests the tunnel (curl to flights.test.aeroflot.ru via 127.0.0.1:8443).
|
||||
# 3. Installs the new ui-dashboard.gnerim.ru nginx vhost + htpasswd dir.
|
||||
# 4. Renders /etc/nginx/htpasswd/ui-dashboard from BASIC_AUTH_USER/PASS.
|
||||
# 5. Reloads nginx after `nginx -t` passes.
|
||||
#
|
||||
# Each step prints a heading and exits non-zero on failure. Re-running after a
|
||||
# fix continues where it failed (everything is overwrite-safe).
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "fatal: run as root (sudo -E bash $0)" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
step() { printf '\n=== %s ===\n' "$*"; }
|
||||
ok() { printf ' ok: %s\n' "$*"; }
|
||||
fail() { printf ' FAIL: %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
# ---------- 1. systemd unit ----------
|
||||
step "1. flights-tim-tunnel.service"
|
||||
|
||||
UNIT_SRC="$REPO_ROOT/deployment/systemd/flights-tim-tunnel.service"
|
||||
UNIT_DST="/etc/systemd/system/flights-tim-tunnel.service"
|
||||
[ -f "$UNIT_SRC" ] || fail "missing $UNIT_SRC — wrong branch?"
|
||||
|
||||
if [ -f "$UNIT_DST" ] && cmp -s "$UNIT_SRC" "$UNIT_DST"; then
|
||||
ok "$UNIT_DST already up-to-date"
|
||||
else
|
||||
cp "$UNIT_SRC" "$UNIT_DST"
|
||||
ok "installed $UNIT_DST"
|
||||
fi
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now flights-tim-tunnel.service
|
||||
sleep 2
|
||||
systemctl is-active flights-tim-tunnel.service >/dev/null \
|
||||
|| { systemctl status flights-tim-tunnel.service --no-pager; fail "tunnel unit not active"; }
|
||||
ok "unit active"
|
||||
|
||||
# ---------- 2. tunnel smoke test ----------
|
||||
step "2. tunnel smoke test"
|
||||
|
||||
ss -ltn | grep -qE '127\.0\.0\.1:8443\s' || fail "no listener on 127.0.0.1:8443"
|
||||
ok "listener present"
|
||||
|
||||
SWAGGER_RC=$(curl -sS -k --max-time 10 -o /dev/null -w "%{http_code}" \
|
||||
--resolve flights.test.aeroflot.ru:8443:127.0.0.1 \
|
||||
https://flights.test.aeroflot.ru:8443/swagger/index.html)
|
||||
if [ "$SWAGGER_RC" = "401" ]; then
|
||||
ok "swagger HTTP 401 (real backend, WAF passed)"
|
||||
elif [ "$SWAGGER_RC" = "200" ]; then
|
||||
fail "swagger HTTP 200 — likely WAF interstitial (tunnel bypassed)"
|
||||
else
|
||||
fail "swagger unexpected HTTP $SWAGGER_RC"
|
||||
fi
|
||||
|
||||
API_RC=$(curl -sS -k --max-time 10 -o /dev/null -w "%{http_code}" \
|
||||
--resolve flights.test.aeroflot.ru:8443:127.0.0.1 \
|
||||
https://flights.test.aeroflot.ru:8443/api/health)
|
||||
[ "$API_RC" = "200" ] && ok "api/health HTTP 200" || fail "api/health HTTP $API_RC"
|
||||
|
||||
# ---------- 3. nginx vhost ----------
|
||||
step "3. nginx vhost"
|
||||
|
||||
VHOST_SRC="$REPO_ROOT/deployment/nginx/ui-dashboard.gnerim.ru.conf"
|
||||
VHOST_DST="/etc/nginx/sites-available/ui-dashboard.gnerim.ru"
|
||||
[ -f "$VHOST_SRC" ] || fail "missing $VHOST_SRC"
|
||||
|
||||
if [ -f "$VHOST_DST" ] && cmp -s "$VHOST_SRC" "$VHOST_DST"; then
|
||||
ok "$VHOST_DST already up-to-date"
|
||||
else
|
||||
if [ -f "$VHOST_DST" ]; then
|
||||
BAK="${VHOST_DST}.bak.$(date +%Y%m%d-%H%M%S)"
|
||||
cp "$VHOST_DST" "$BAK"
|
||||
ok "backed up old vhost to $BAK"
|
||||
fi
|
||||
cp "$VHOST_SRC" "$VHOST_DST"
|
||||
ok "installed $VHOST_DST"
|
||||
fi
|
||||
|
||||
ENABLED="/etc/nginx/sites-enabled/ui-dashboard.gnerim.ru"
|
||||
if [ ! -L "$ENABLED" ]; then
|
||||
ln -sf "$VHOST_DST" "$ENABLED"
|
||||
ok "created sites-enabled symlink"
|
||||
else
|
||||
ok "sites-enabled symlink already present"
|
||||
fi
|
||||
|
||||
mkdir -p /etc/nginx/htpasswd
|
||||
ok "/etc/nginx/htpasswd ensured"
|
||||
|
||||
# ---------- 4. htpasswd ----------
|
||||
step "4. htpasswd"
|
||||
|
||||
: "${BASIC_AUTH_USER:?BASIC_AUTH_USER required (export it before sudo -E)}"
|
||||
: "${BASIC_AUTH_PASS:?BASIC_AUTH_PASS required (export it before sudo -E)}"
|
||||
|
||||
HASH=$(openssl passwd -apr1 "$BASIC_AUTH_PASS")
|
||||
HTPASSWD_PATH="/etc/nginx/htpasswd/ui-dashboard"
|
||||
echo "${BASIC_AUTH_USER}:${HASH}" > "$HTPASSWD_PATH"
|
||||
chmod 644 "$HTPASSWD_PATH"
|
||||
ok "wrote $HTPASSWD_PATH"
|
||||
|
||||
# ---------- 5. nginx reload ----------
|
||||
step "5. nginx -t + reload"
|
||||
|
||||
nginx -t
|
||||
systemctl reload nginx
|
||||
ok "nginx reloaded"
|
||||
|
||||
# ---------- summary ----------
|
||||
step "done"
|
||||
echo "Tunnel: $(systemctl is-active flights-tim-tunnel.service)"
|
||||
echo "Nginx: $(systemctl is-active nginx)"
|
||||
echo
|
||||
echo "Try:"
|
||||
echo " curl -u ${BASIC_AUTH_USER}:<pw> -I https://ui-dashboard.gnerim.ru/ # expect 502 until container is deployed (Workflow A)"
|
||||
echo " curl -u ${BASIC_AUTH_USER}:<pw> -I https://ui-dashboard.gnerim.ru/api/health # expect 200 from real upstream"
|
||||
Reference in New Issue
Block a user