data "aws_subnet" "vpc_subnets" {
  count = length(module.vpc.private_subnets)
  id    = module.vpc.private_subnets[count.index]
}

data "aws_availability_zones" "available" {
  state = "available"
}

locals {
  availability_zone_name_map = zipmap(
    data.aws_availability_zones.available.zone_ids,
    data.aws_availability_zones.available.names,
  )
  availability_zone_names = [
    for az in var.availability_zones : lookup(local.availability_zone_name_map, az, az)
  ]
  node_group_subnet_ids = [
    for subnet in data.aws_subnet.vpc_subnets : subnet.id
    if contains(local.availability_zone_names, subnet.availability_zone)
  ]
}

locals {
  admin_role_names = [
    "cicd-role",
    "argocd-oidc-role",
    "dbaas-central-role-${var.env}",
    local.jumpserver_role_name,
  ]
}

locals {
  eks_managed_node_group_defaults = {
    subnet_ids                 = local.node_group_subnet_ids
    create_iam_role            = true
    iam_role_attach_cni_policy = true
    iam_role_additional_policies = {
      AmazonEBSCSIDriverPolicy = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
    }
    metadata_options = {
      http_put_response_hop_limit = 2
    }
  }
}

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 21.0"

  name                        = local.name
  kubernetes_version          = var.eks.k8s_version
  endpoint_private_access     = true
  endpoint_public_access      = true
  enable_irsa                 = true
  create_cloudwatch_log_group = false
  enabled_log_types           = []
  encryption_config = {
    resources = ["secrets"]
  }
  endpoint_public_access_cidrs = local.public_access_cidrs
  access_entries = {
    for role_name in local.admin_role_names : role_name => {
      principal_arn = format("arn:aws:iam::%s:role/%s", local.seed_account, role_name)
      type          = "STANDARD"
      policy_associations = {
        admin = {
          policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
          access_scope = {
            type = "cluster"
          }
        }
      }
    }
  }

  create_iam_role      = true
  create_node_iam_role = true

  addons = {
    vpc-cni = {
      before_compute    = true
      resolve_conflicts = "OVERWRITE"
      most_recent       = true
      configuration_values = jsonencode({
        env = {
          ENABLE_PREFIX_DELEGATION = "true"
        }
      })
    }
    coredns = {
      most_recent = true
    }
    kube-proxy = {
      most_recent = true
    }
    aws-ebs-csi-driver = {
      most_recent = true
    }
    metrics-server = {
      most_recent = true
    }
  }

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  eks_managed_node_groups = {
    for k, v in var.eks.node_groups : k => merge(local.eks_managed_node_group_defaults, v)
  }
  enable_cluster_creator_admin_permissions = true

  node_security_group_additional_rules = {
    ingress_cluster_8080 = {
      description                   = "Allow control plane to node port 8080 (e.g. Kong webhook)"
      protocol                      = "tcp"
      from_port                     = 8080
      to_port                       = 8080
      type                          = "ingress"
      source_cluster_security_group = true
    }
  }

  tags = {
    environment = var.env
    usedby      = "dbaas-control-plane-seed"
    servicetype = "byoc"
    tenant      = "admin"
  }
}

locals {
  eks = {
    name                       = module.eks.cluster_name
    endpoint                   = module.eks.cluster_endpoint
    certificate_authority_data = module.eks.cluster_certificate_authority_data
    public_ips                 = module.vpc.nat_public_ips
    oidc_issuer_url            = module.eks.cluster_oidc_issuer_url
    kubeconfig = yamlencode({
      apiVersion = "v1"
      kind       = "Config"
      clusters = [{
        name = module.eks.cluster_name
        cluster = {
          server                     = module.eks.cluster_endpoint
          certificate-authority-data = module.eks.cluster_certificate_authority_data
        }
      }]
      contexts = [{
        name = module.eks.cluster_name
        context = {
          cluster = module.eks.cluster_name
          user    = module.eks.cluster_name
        }
      }]
      current-context = module.eks.cluster_name
      users = [{
        name = module.eks.cluster_name
        user = {
          exec = {
            apiVersion = "client.authentication.k8s.io/v1beta1"
            command    = "aws"
            args = [
              "eks",
              "get-token",
              "--region", var.aws_region,
              "--cluster-name", module.eks.cluster_name,
              "--profile", local.seed_account,
              "--output", "json"
            ]
          }
        }
      }]
    })
  }
}