#!/usr/bin/env bash
# T90 — double-mTLS egress guide verification (docs/istio/egress/double-mtls-gateway-connection)
# Istio 1.30.0 sidecar mode / k8s 1.30.6. Registry domain on this cluster: homelab.local
# (istiod --domain homelab.local since 2026-07-05; VERIFY with:
#  istioctl proxy-config cluster <pod> | head  — adapt DR/VS k8s-service hosts to what you see there)
set -euo pipefail
D=$(cd "$(dirname "$0")" && pwd)

# ---------- 1. PKI ----------
mkdir -p "$D/pki"; cd "$D/pki"
openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -subj "/CN=dmtls-test-ca" -days 30
openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/CN=api.partner.example"
printf 'subjectAltName = DNS:api.partner.example\nextendedKeyUsage = serverAuth\n' > server.ext
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 30 -extfile server.ext
openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/CN=egress-client"
printf 'extendedKeyUsage = clientAuth\n' > client.ext
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 30 -extfile client.ext

# ---------- 2. external partner (mTLS-requiring nginx, OUT of mesh) ----------
kubectl -n istio-verify-ext create configmap dmtls-partner \
  --from-file=nginx.conf="$D/pki/nginx.conf" --from-file=tls.crt=server.crt \
  --from-file=tls.key=server.key --from-file=ca.crt=ca.crt
kubectl apply -f "$D/partner.yaml"
kubectl -n istio-verify-ext rollout status deploy/dmtls-partner --timeout=120s

# ---------- 3. test ns / client / dedicated gateway ----------
kubectl apply -f <(head -6 "$D/ns-workloads.yaml")   # namespace first
kubectl -n istio-vt-t90 create secret generic dmtls-partner-client-cred \
  --from-file=tls.crt=client.crt --from-file=tls.key=client.key --from-file=ca.crt=ca.crt
# webhook was deactivated during the run -> kube-inject; with healthy webhook plain apply suffices
istioctl kube-inject -f "$D/client-pod.yaml" | kubectl apply -f -
istioctl kube-inject -f "$D/gw-deploy.yaml"  | kubectl apply -f -
kubectl apply -f "$D/ns-workloads.yaml"               # svc (pod/deploy already injected)
kubectl apply -f "$D/gw-sds-rbac.yaml"                # REQUIRED: SDS authz = SubjectAccessReview on gateway SA
kubectl -n istio-vt-t90 rollout status deploy/dmtls-egress --timeout=180s
kubectl -n istio-vt-t90 wait --for=condition=Ready pod/client --timeout=180s

# ---------- 4. wiring (SE / Gateway / DR-hop1 / DR-hop2 / VS) ----------
kubectl apply -f "$D/wiring.yaml"; sleep 8

CURL="kubectl -n istio-vt-t90 exec client -c curl -- curl -si --resolve api.partner.example:80:240.240.34.90 http://api.partner.example/ -w \n%{http_code}\n"
# (a) positive: expect 200 + x-client-verify: SUCCESS + dn=CN=egress-client
$CURL
# (b) path proof
kubectl -n istio-vt-t90 logs deploy/dmtls-egress --tail=2 | grep 'GET / HTTP'
istioctl proxy-config cluster client.istio-vt-t90 --fqdn dmtls-egress.istio-vt-t90.svc.homelab.local -o json | \
  jq '.[] | select(.name|contains("|partner|")) | {name, max:.circuitBreakers.thresholds[0].maxConnections, ka:.upstreamConnectionOptions.tcpKeepalive, sni:.transportSocket.typedConfig.sni}'
istioctl proxy-config cluster deploy/dmtls-egress -n istio-vt-t90 --fqdn api.partner.example -o json | \
  jq '.[] | select(.name=="outbound|443||api.partner.example") | {name, max:.circuitBreakers.thresholds[0].maxConnections, cert:[.transportSocket.typedConfig.commonTlsContext.tlsCertificateSdsSecretConfigs[]?.name]}'
# (c) negative 1: no client cert
kubectl -n istio-vt-t90 delete dr dmtls-partner-originate; sleep 6; $CURL   # plaintext->tls port: 400
kubectl apply -f "$D/dr-hop2-simple-ca.yaml"; sleep 6; $CURL                # SIMPLE+CA: 400 "No required SSL certificate"
kubectl -n istio-verify-ext logs deploy/dmtls-partner --tail=3
kubectl apply -f "$D/wiring.yaml"; sleep 6                                  # restore
# (d) negative 2: pitfall — VS mesh route removed under ALLOW_ANY
kubectl apply -f "$D/vs-no-mesh-route.yaml"; sleep 6; $CURL                 # 400, gateway log silent, nginx peer = CLIENT pod IP
kubectl -n istio-vt-t90 logs client -c istio-proxy --tail=1 | grep 'GET / HTTP'   # cluster = outbound|80||api.partner.example

# ---------- 5. cleanup ----------
# kubectl delete ns istio-vt-t90
# kubectl -n istio-verify-ext delete deploy/dmtls-partner svc/dmtls-partner cm/dmtls-partner
