# Veris On-Prem Cluster Setup — EKS
#
# This Terraform module creates everything needed to register an existing
# EKS cluster with Veris for customer-hosted simulations:
#
#   1. veris namespace
#   2. ServiceAccount with RBAC for job management
#   3. Long-lived bearer token (Secret-bound)
#   4. ECR repository for agent images
#
# Usage:
#   terraform init
#   terraform apply
#   terraform output -json veris_cluster_registration
#
# Then register with Veris:
#   terraform output -raw veris_cluster_registration | \
#     curl -X POST https://api.veris.ai/v1/clusters \
#       -H "Authorization: Bearer $VERIS_API_KEY" \
#       -H "Content-Type: application/json" \
#       -d @-

terraform {
  required_version = ">= 1.5"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = ">= 2.20"
    }
  }
}

# ---------------------------------------------------------------------------
# Variables
# ---------------------------------------------------------------------------

variable "cluster_name" {
  description = "Name of the existing EKS cluster"
  type        = string
}

variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "namespace" {
  description = "Kubernetes namespace for Veris jobs"
  type        = string
  default     = "veris"
}

variable "veris_organization_id" {
  description = "Your Veris organization ID (org_xxx)"
  type        = string
}

variable "ecr_repository_name" {
  description = "ECR repository name for agent images"
  type        = string
  default     = "veris-simulation-images"
}

variable "cluster_display_name" {
  description = "Display name for the cluster in Veris"
  type        = string
  default     = ""
}

# ---------------------------------------------------------------------------
# Data sources
# ---------------------------------------------------------------------------

provider "aws" {
  region = var.region
}

data "aws_eks_cluster" "this" {
  name = var.cluster_name
}

data "aws_eks_cluster_auth" "this" {
  name = var.cluster_name
}

provider "kubernetes" {
  host                   = data.aws_eks_cluster.this.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data)
  token                  = data.aws_eks_cluster_auth.this.token
}

data "aws_caller_identity" "current" {}

# ---------------------------------------------------------------------------
# Namespace
# ---------------------------------------------------------------------------

resource "kubernetes_namespace_v1" "veris" {
  metadata {
    name = var.namespace
  }
}

# ---------------------------------------------------------------------------
# Service Account + RBAC
# ---------------------------------------------------------------------------

resource "kubernetes_service_account_v1" "veris" {
  metadata {
    name      = "veris-sa"
    namespace = kubernetes_namespace_v1.veris.metadata[0].name
  }
}

resource "kubernetes_role_v1" "veris_job_manager" {
  metadata {
    name      = "veris-job-manager"
    namespace = kubernetes_namespace_v1.veris.metadata[0].name
  }

  rule {
    api_groups = ["batch"]
    resources  = ["jobs"]
    verbs      = ["create", "get", "list", "delete", "watch"]
  }

  rule {
    api_groups = [""]
    resources  = ["pods", "pods/log"]
    verbs      = ["get", "list", "watch"]
  }

  rule {
    api_groups = [""]
    resources  = ["secrets", "configmaps"]
    verbs      = ["create", "get", "delete", "list"]
  }

  rule {
    api_groups = [""]
    resources  = ["namespaces"]
    verbs      = ["get"]
  }
}

resource "kubernetes_role_binding_v1" "veris" {
  metadata {
    name      = "veris-sa-binding"
    namespace = kubernetes_namespace_v1.veris.metadata[0].name
  }

  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = kubernetes_role_v1.veris_job_manager.metadata[0].name
  }

  subject {
    kind      = "ServiceAccount"
    name      = kubernetes_service_account_v1.veris.metadata[0].name
    namespace = kubernetes_namespace_v1.veris.metadata[0].name
  }
}

# ---------------------------------------------------------------------------
# Long-lived bearer token (Secret-bound, does not expire)
# ---------------------------------------------------------------------------

resource "kubernetes_secret_v1" "veris_token" {
  metadata {
    name      = "veris-sa-token"
    namespace = kubernetes_namespace_v1.veris.metadata[0].name
    annotations = {
      "kubernetes.io/service-account.name" = kubernetes_service_account_v1.veris.metadata[0].name
    }
  }

  type                           = "kubernetes.io/service-account-token"
  wait_for_service_account_token = true
}

# ---------------------------------------------------------------------------
# ECR Repository
# ---------------------------------------------------------------------------

resource "aws_ecr_repository" "veris" {
  name                 = var.ecr_repository_name
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
    scan_on_push = true
  }

  tags = {
    ManagedBy = "veris-terraform"
    Purpose   = "veris-simulation-images"
  }
}

# ---------------------------------------------------------------------------
# Outputs — use these to register with Veris
# ---------------------------------------------------------------------------

locals {
  display_name = var.cluster_display_name != "" ? var.cluster_display_name : var.cluster_name
  ca_cert      = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data)
  token        = kubernetes_secret_v1.veris_token.data["token"]
}

output "veris_cluster_registration" {
  description = "JSON payload for POST /v1/clusters — register this cluster with Veris"
  sensitive   = true
  value = jsonencode({
    organization_id    = var.veris_organization_id
    name               = local.display_name
    provider           = "eks"
    api_server_url     = data.aws_eks_cluster.this.endpoint
    ca_certificate     = local.ca_cert
    namespace          = var.namespace
    auth_type          = "token"
    credentials        = { token = local.token }
    image_registry_url = aws_ecr_repository.veris.repository_url
  })
}

output "cluster_endpoint" {
  description = "EKS API server endpoint"
  value       = data.aws_eks_cluster.this.endpoint
}

output "ecr_repository_url" {
  description = "ECR repository URL for agent images"
  value       = aws_ecr_repository.veris.repository_url
}

output "namespace" {
  description = "Kubernetes namespace for Veris jobs"
  value       = var.namespace
}

output "registration_command" {
  description = "Run this command to register the cluster with Veris"
  value       = "terraform output -raw veris_cluster_registration | curl -X POST https://api.veris.ai/v1/clusters -H 'Authorization: Bearer $VERIS_API_KEY' -H 'Content-Type: application/json' -d @-"
}
