#!/usr/bin/env bash
# scripts/dns-passthrough-outlier.sh — 작업D D-3: passthrough(TCP)에 outlier detection(49) 적용
# 전/후 dead-IP churn 실패율 비교.
#
# 예상: ejection이 죽은 host를 LB 후보에서 빼서 실패율을 낮추지만, 이 경로엔 route/L7 retry가
# 없으므로(48은 VS 자체가 없다) 0으로 수렴하지는 않을 것 — 그 잔여 실패가 D-3의 핵심 데이터.
#
# 전제: scripts/dns-passthrough-churn.sh 와 동일 전제 + scenarios/50-dns-resolution/
# 49-destinationrule-passthrough-outlier.yaml 존재(이 스크립트가 apply/delete를 직접 수행).
#
# 출처: docs/test-reports/2026-07-09_134250_dns-passthrough-tcp.md §6
#
# usage: bash scripts/dns-passthrough-outlier.sh
set -uo pipefail
CTX="${CTX:-homelab}"; NS="${NS:-dns-lab}"
DIR="$(cd "$(dirname "$0")/.." && pwd)"
SC="$DIR/scenarios/50-dns-resolution"
WORK="$DIR/tmp/dns-passthrough/d3"; mkdir -p "$WORK"

IP_A_SVC=$(kubectl --context="$CTX" -n "$NS" get svc backend-a -o jsonpath='{.spec.clusterIP}')
POD_A=$(kubectl --context="$CTX" -n "$NS" get pods -l app=backend-a -o jsonpath='{.items[0].status.podIP}')
POD_B=$(kubectl --context="$CTX" -n "$NS" get pods -l app=backend-b -o jsonpath='{.items[0].status.podIP}')
echo "IP_A_SVC=$IP_A_SVC POD_A=$POD_A POD_B=$POD_B"

loop_passthrough(){ # $1=sec $2=outfile
  kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -- sh -c '
    end=$(( $(date +%s) + '"$1"' ))
    n=0
    while [ $(date +%s) -lt $end ]; do
      n=$((n+1))
      out=$(curl -sk --connect-timeout 3 -m 10 -o /dev/null -w "%{exitcode} %{http_code} %{time_total}" https://gslb-pt.lab.internal/ 2>&1)
      printf "%s n=%d %s\n" "$(date +%H:%M:%S)" "$n" "$out"
    done' | tee "$2"
}

statsnap(){ # $1 = label
  echo "=== $1 stats (gslb-pt) @ $(date +%H:%M:%S) ==="
  kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -c istio-proxy -- pilot-agent request GET "stats?filter=gslb-pt" 2>/dev/null \
    | grep -E 'upstream_cx_connect_fail|upstream_cx_connect_timeout|upstream_cx_total|ejections_enforced|ejections_active|outlier_detection'
  echo "-- clusters (health_flags) --"
  kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -c istio-proxy -- pilot-agent request GET clusters 2>/dev/null \
    | grep -E 'outbound\|443\|\|gslb-pt\.lab\.internal::' | grep -E 'health_flags|cx_active|cx_total'
  echo
}

summarize(){ # $1 = loopfile
  echo "총시도: $(wc -l < "$1")"
  echo "exitcode=0(성공) 건수: $(awk '{print $3}' "$1" | grep -c '^0$')"
  echo "exitcode!=0 분포:"; awk '{print $3}' "$1" | grep -v '^0$' | sort | uniq -c
}

{
echo "# D-3 passthrough + outlier(DR49) 전/후 dead-IP churn — $(date +%Y-%m-%d_%H%M%S)"
echo

echo "## 1. dead-IP 조건 구성 (gslb-pt만 대상 — HTTP 경로 불변)"
kubectl --context="$CTX" -n "$NS" exec deploy/lab-dns -c writer -- sh -c \
  "printf '%s gslb.lab.internal\n%s gslb-pt.lab.internal\n%s gslb-pt.lab.internal\n' '$IP_A_SVC' '$POD_A' '$POD_B' > /hosts/addn; cat /hosts/addn"
sleep 6
echo ">> KILL backend-a (scale 0) @ $(date +%H:%M:%S)"
kubectl --context="$CTX" -n "$NS" scale deploy/backend-a --replicas=0
sleep 4

echo
echo "## 2. STAGE A — outlier 없음 (베이스라인, gslb-pt엔 DR 자체가 없는 상태)"
statsnap "stageA_BEFORE"
loop_passthrough 40 "$WORK/stageA_loop.txt"
statsnap "stageA_AFTER"
echo "### stageA 집계"; summarize "$WORK/stageA_loop.txt"

echo
echo "## 3. STAGE B — outlier(DR49) 적용"
kubectl --context="$CTX" apply -f "$SC/49-destinationrule-passthrough-outlier.yaml"
sleep 3
statsnap "stageB_BEFORE"
loop_passthrough 40 "$WORK/stageB_loop.txt"
statsnap "stageB_AFTER"
echo "### stageB 집계"; summarize "$WORK/stageB_loop.txt"

echo
echo "## 4. 정리 (DR49 삭제 — D-3 전용, 랩엔 상시 존재하지 않음)"
kubectl --context="$CTX" delete -f "$SC/49-destinationrule-passthrough-outlier.yaml" --ignore-not-found
kubectl --context="$CTX" -n "$NS" scale deploy/backend-a --replicas=1
kubectl --context="$CTX" -n "$NS" rollout status deploy/backend-a --timeout=90s
sleep 3
NEW_POD_A=$(kubectl --context="$CTX" -n "$NS" get pods -l app=backend-a -o jsonpath='{.items[0].status.podIP}')
echo "new backend-a pod IP = $NEW_POD_A"
kubectl --context="$CTX" -n "$NS" exec deploy/lab-dns -c writer -- sh -c \
  "printf '%s gslb.lab.internal\n%s gslb-pt.lab.internal\n' '$IP_A_SVC' '$NEW_POD_A' > /hosts/addn; cat /hosts/addn"
sleep 6
echo "-- post-restore sanity --"
kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -- sh -c 'dig +short gslb.lab.internal; echo ---; dig +short gslb-pt.lab.internal'
kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -- curl -s -m 5 -w " [http_code=%{http_code}]\n" http://gslb.lab.internal/
kubectl --context="$CTX" -n "$NS" exec deploy/netshoot -- curl -sk -m 5 -w " [http_code=%{http_code}]\n" https://gslb-pt.lab.internal/
} 2>&1 | tee "$WORK/full_run.txt"

echo ">> D-3 raw log: $WORK/full_run.txt"
