#!/bin/bash
set -e
# Make kubectl/helm work regardless of cloud-init's HOME state (root's ~/.kube/config may not be auto-discovered).
export KUBECONFIG=/etc/kubernetes/admin.conf
echo ">>>> K8S Final config Start <<<<"

# Sanity check: efs.txt must be present and non-empty (UserData creates it BEFORE master.sh runs)
if [ ! -s /root/efs.txt ]; then
  echo "ERROR: /root/efs.txt is missing or empty. Aborting NFS provisioner install." >&2
  exit 1
fi
EFS_DNS=$(cat /root/efs.txt)
echo "Using EFS DNS: $EFS_DNS"

# Wait for API server to be ready (kubeadm init just finished — endpoint may need a moment)
echo "[Pre] Waiting for API server readiness"
for i in $(seq 1 60); do
  if kubectl get --raw /readyz >/dev/null 2>&1; then
    echo "API server ready"
    break
  fi
  echo "Waiting for API server... ($i/60)"
  sleep 5
done

echo "[TASK 1] Install Flannel CNI (Pod CIDR 172.16.0.0/16)"
aws s3 cp s3://my-k8s-scripts/kube-flannel.yml /root/kube-flannel.yml
sed -i 's/\r$//' /root/kube-flannel.yml
kubectl apply -f /root/kube-flannel.yml
sleep 3

echo "[TASK 2] Rename context to HomeLab"
kubectl config rename-context "kubernetes-admin@kubernetes" "HomeLab" || true

echo "[TASK 3] Install Metrics server"
kubectl apply -f https://raw.githubusercontent.com/gasida/DOIK/main/vanilla/metrics-server.yaml

echo "[TASK 4] Local-path StorageClass (NOT default — for non-PG ephemeral use only)"
kubectl apply -f https://raw.githubusercontent.com/gasida/DOIK/main/vanilla/local-path-storage.yaml

echo "[TASK 5] NFS External Provisioner on AWS EFS"
helm repo add nfs-subdir-external-provisioner \
  https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner 2>/dev/null || true
helm repo update nfs-subdir-external-provisioner >/dev/null
printf 'tolerations: [{key: node-role.kubernetes.io/master, operator: Exists, effect: NoSchedule}]\n' | \
  helm upgrade --install nfs-provisioner -n kube-system \
    nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
    --set nfs.server="$EFS_DNS" \
    --set nfs.path=/ \
    --set nodeSelector."kubernetes\.io/hostname"=k8s-m \
    --values /dev/stdin

echo "[TASK 6] Untaint master + label as master role"
kubectl taint node k8s-m node-role.kubernetes.io/control-plane- >/dev/null 2>&1 || true
kubectl label nodes k8s-m node-role.kubernetes.io/master= --overwrite >/dev/null 2>&1 || true

echo "[TASK 7] AWS EBS CSI Driver install (production-grade per-PVC IOPS/Throughput)"
helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
helm repo update aws-ebs-csi-driver
helm upgrade --install aws-ebs-csi-driver aws-ebs-csi-driver/aws-ebs-csi-driver \
  -n kube-system \
  --set controller.serviceAccount.create=true \
  --set node.serviceAccount.create=true \
  --set controller.tolerations[0].key=node-role.kubernetes.io/master \
  --set controller.tolerations[0].effect=NoSchedule \
  --set controller.tolerations[0].operator=Exists
kubectl -n kube-system rollout status deploy/ebs-csi-controller --timeout=180s

echo "[TASK 8] StorageClass: ebs-gp3 (default for PG data + WAL)"
cat <<'YAML' | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "6000"
  throughput: "250"
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# WAL 전용 — 필요 시 iops/throughput 만 다르게 튜닝 가능
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3-wal
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "6000"
  throughput: "250"
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
YAML

echo "[TASK 9] Remove local-path default flag (production PG should not land there)"
kubectl patch storageclass local-path \
  -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' \
  >/dev/null 2>&1 || true

echo ">>>> K8S Final Config End <<<<"
