resource "kubernetes_namespace" "rustdesk" {
  metadata {
    name = "rustdesk"
  }
}

resource "kubernetes_service_account" "rustdesk" {

  metadata {
    name      = "rustdesk-app-sa"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
  }

  automount_service_account_token = false
}

resource "kubernetes_config_map" "rustdesk_config" {
  metadata {
    name      = "rustdesk-config"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
  }

  data = {
    RELAY          = local.rustdesk_fqdn
    ENCRYPTED_ONLY = "1"
  }
}

resource "kubernetes_secret" "rustdesk_keys" {
  metadata {
    name      = "rustdesk-keys"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
  }

  data = {
    "id_ed25519"     = var.private_key
    "id_ed25519.pub" = var.public_key
  }
}

resource "kubernetes_deployment" "rustdesk_deploy" {
  metadata {
    name      = "rustdesk"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
    labels = {
      app = "rustdesk-app"
    }
  }

  spec {
    replicas = 1

    selector {
      match_labels = {
        app = "rustdesk-app"
      }
    }

    strategy {
      type = "Recreate"
    }

    template {
      metadata {
        labels = {
          app = "rustdesk-app"
        }
      }

      spec {
        service_account_name            = kubernetes_service_account.rustdesk.metadata[0].name
        automount_service_account_token = false

        container {
          name  = "rustdesk-container"
          image = "rustdesk/rustdesk-server-s6:${local.rustdesk_version}"

          env_from {
            config_map_ref {
              name = kubernetes_config_map.rustdesk_config.metadata[0].name
            }
          }

          security_context {
            allow_privilege_escalation = false
          }

          port {
            name           = "tcp-port-1"
            container_port = 21115
            host_port      = 21115
            protocol       = "TCP"
          }

          port {
            name           = "tcp-port-2"
            container_port = 21116
            host_port      = 21116
            protocol       = "TCP"
          }

          port {
            name           = "udp-port-1"
            container_port = 21116
            host_port      = 21116
            protocol       = "UDP"
          }

          port {
            name           = "tcp-port-3"
            container_port = 21117
            host_port      = 21117
            protocol       = "TCP"
          }

          volume_mount {
            name       = "rustdesk-data"
            mount_path = "/data"
          }

          volume_mount {
            name       = "rust-keys"
            mount_path = "/data/id_ed25519"
            sub_path   = "id_ed25519"
            read_only  = true
          }

          volume_mount {
            name       = "rust-keys"
            mount_path = "/data/id_ed25519.pub"
            sub_path   = "id_ed25519.pub"
            read_only  = true
          }
        }

        volume {
          name = "rustdesk-data"
          host_path {
            path = local.rustdesk_path
          }
        }

        volume {
          name = "rust-keys"
          secret {
            secret_name = kubernetes_secret.rustdesk_keys.metadata[0].name
          }
        }
      }
    }
  }
}

resource "kubernetes_service" "rustdesk_tcp_ports" {
  metadata {
    name      = "rustdesk-tcp-ports"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
  }

  spec {
    selector = {
      app = "rustdesk-app"
    }

    port {
      name        = "tcp-port-1"
      port        = 21115
      target_port = 21115
    }

    port {
      name        = "tcp-port-2"
      port        = 21116
      target_port = 21116
    }

    port {
      name        = "tcp-port-3"
      port        = 21117
      target_port = 21117
    }

    type = "LoadBalancer"
  }

  lifecycle {
    ignore_changes = [
      metadata[0].annotations
    ]
  }

}

resource "kubernetes_service" "rustdesk_udp_ports" {
  metadata {
    name      = "rustdesk-udp-ports"
    namespace = kubernetes_namespace.rustdesk.metadata[0].name
  }

  spec {
    selector = {
      app = "rustdesk-app"
    }

    port {
      name        = "udp-port-1"
      port        = 21116
      target_port = 21116
      protocol    = "UDP"
    }

    type = "LoadBalancer"
  }

  lifecycle {
    ignore_changes = [
      metadata[0].annotations
    ]
  }
}
