#!/usr/bin/env bash
# scripts/checks/d011-03-vip-tenant.sh -- D-011 item 3: API reachability from a tenant
# VM (Option B), via the D-035 pod-egress proof.
#
# Runs an ephemeral agnhost pod IN a tenant k8s cluster and has it TCP-connect to the
# keystone public VIP. This is the exact test the dual-homed D-033 node FAILED and the
# single-homed D-035 topology must PASS -- it proves a tenant workload egresses through
# its router SNAT to the provider API VIP.
#
# Dynamic values (never hardcoded): the keystone VIP:port is derived from the tenant
# cred's auth_url; the kubeconfig is the one tenant-acceptance leaves at
# ~/tenant-<client>/kube/config, or fetched via `coe cluster config` AS THE TENANT.
#
# Mutation note: creates ONE short-lived agnhost pod and deletes it (even on failure).
# Additive + self-cleaning, not destructive -> NOT --disruptive-gated (a post-restart
# confidence run legitimately exercises tenant egress).
#
# Exit: 0 PASS (pod connected to the VIP) | 1 FAIL (egress blocked: timeout/refused)
#       | 2 HOLD (no kubectl/creds/kubeconfig/VIP derivable).
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/lib-validate.sh
. "$HERE/../lib-validate.sh"
ID=d011-03-vip-tenant; vr_begin "$ID"
CLIENT="${VR_TENANT:-beta}"
AGNHOST="${VR_AGNHOST:-registry.k8s.io/e2e-test-images/agnhost:2.47}"

vr_need kubectl awk || { emit "$ID" "$VR_HOLD" "missing tool"; exit "$VR_HOLD"; }

# --- derive keystone VIP:port from the tenant cred auth_url (dynamic) ---
CF=""
for c in "$HOME/tenant-${CLIENT}/${CLIENT}-cluster-cred.txt" \
         "$HOME/tenant-${CLIENT}/${CLIENT}-svc-cred.txt"; do
  [ -s "$c" ] && grep -qE '^auth_url=' "$c" && { CF="$c"; break; }
done
[ -n "$CF" ] || { emit "$ID" "$VR_HOLD" "no tenant cred for '$CLIENT' (auth_url source)"; exit "$VR_HOLD"; }
AUTHURL="$(awk -F= '/^auth_url=/{print $2}' "$CF")"
VIP="$(python3 -c '
import sys
from urllib.parse import urlparse
p=urlparse(sys.argv[1])
port=p.port or (443 if p.scheme=="https" else 80)
print("%s %d" % (p.hostname or "", port))' "$AUTHURL" 2>/dev/null)"
VHOST="${VIP%% *}"; VPORT="${VIP##* }"
vr_is_ipv4 "$VHOST" 2>/dev/null || [ -n "$VHOST" ] || { emit "$ID" "$VR_HOLD" "could not derive keystone VIP from auth_url"; exit "$VR_HOLD"; }
[ -n "$VPORT" ] || { emit "$ID" "$VR_HOLD" "could not derive keystone port"; exit "$VR_HOLD"; }
echo "  target keystone VIP: $VHOST:$VPORT (from $CLIENT auth_url)"

# --- obtain the tenant kubeconfig (reuse existing; else fetch as tenant) ---
KDIR="$HOME/tenant-${CLIENT}/kube"; KCFG="$KDIR/config"
if [ ! -s "$KCFG" ]; then
  echo "  no cached kubeconfig; fetching via coe cluster config (as tenant)"
  command -v openstack >/dev/null || { emit "$ID" "$VR_HOLD" "no cached kubeconfig and openstack absent"; exit "$VR_HOLD"; }
  mkdir -p "$KDIR"
  ( vr_tenant_env "$CF" || exit 2
    cd "$KDIR" && openstack coe cluster config "${CLIENT}-cluster" --dir "$KDIR" --force </dev/null 2>&1 ) | sed 's/^/    /'
  [ -s "$KCFG" ] || { emit "$ID" "$VR_HOLD" "kubeconfig fetch produced no config"; exit "$VR_HOLD"; }
  chmod 600 "$KCFG"
fi
export KUBECONFIG="$KCFG"
kubectl version --client >/dev/null 2>&1 || { emit "$ID" "$VR_HOLD" "kubectl not functional"; exit "$VR_HOLD"; }

# --- ephemeral agnhost pod: connect to the VIP; delete always ---
POD="vip-probe-$$-$RANDOM"
cleanup(){ kubectl delete pod "$POD" --ignore-not-found --now >/dev/null 2>&1 || true; }
trap cleanup EXIT
echo "  launching probe pod $POD -> $VHOST:$VPORT"
if ! run kubectl run "$POD" --image="$AGNHOST" --restart=Never --command -- \
        /agnhost connect "$VHOST:$VPORT" --timeout=8s; then
  emit "$ID" "$VR_HOLD" "could not create probe pod (image pull / RBAC?)"; exit "$VR_HOLD"
fi
# wait for terminal phase (Succeeded/Failed), up to ~60s
PHASE=""
for _ in $(seq 1 30); do
  PHASE="$(kubectl get pod "$POD" -o jsonpath='{.status.phase}' 2>/dev/null || true)"
  case "$PHASE" in Succeeded|Failed) break;; esac
  sleep 2
done
LOGS="$(kubectl logs "$POD" 2>/dev/null || true)"
printf '%s\n' "$LOGS" | sed 's/^/    /'
echo "  pod phase: ${PHASE:-<none>}"

if [ "$PHASE" = Succeeded ]; then
  emit "$ID" "$VR_PASS" "tenant pod egress reached keystone VIP $VHOST:$VPORT (Option B proven)"; exit "$VR_PASS"
fi
if printf '%s\n' "$LOGS" | grep -qiE 'TIMEOUT|REFUSED|no route|i/o timeout'; then
  emit "$ID" "$VR_FAIL" "tenant pod egress to $VHOST:$VPORT BLOCKED ($(printf '%s' "$LOGS" | tr -d '\n' | tail -c 40))"; exit "$VR_FAIL"
fi
if [ "$PHASE" = Failed ]; then
  emit "$ID" "$VR_FAIL" "tenant pod egress to $VHOST:$VPORT failed (phase Failed)"; exit "$VR_FAIL"
fi
emit "$ID" "$VR_HOLD" "probe pod did not reach terminal phase (phase=${PHASE:-none})"; exit "$VR_HOLD"
