resource "hcloud_ssh_key" "default" {
  name       = var.default_ssh_key.name
  public_key = var.default_ssh_key.public_key
}

data "template_file" "cloud_init" {
  template = file("./templates/cloud-init.yaml.tpl")

  vars = {
    tailscale_authkey = tailscale_tailnet_key.cloud_init_key.key
    default_ssh_key   = var.default_ssh_key.public_key
  }
}

resource "hcloud_placement_group" "default" {
  name = "serguzim.net"
  type = "spread"
}

resource "hcloud_primary_ip" "node_ipv4_addresses" {
  for_each      = local.hetzner_hosts
  name          = "primary_ipv4_${each.value.hostname}"
  datacenter    = each.value.datacenter
  type          = "ipv4"
  assignee_type = "server"
  auto_delete   = false
}

resource "hcloud_primary_ip" "node_ipv6_addresses" {
  for_each      = local.hetzner_hosts
  name          = "primary_ipv6_${each.value.hostname}"
  datacenter    = each.value.datacenter
  type          = "ipv6"
  assignee_type = "server"
  auto_delete   = false
}

# Create a server
resource "hcloud_server" "nodes" {
  for_each    = local.hetzner_hosts
  name        = each.value.hostname
  datacenter  = each.value.datacenter
  image       = each.value.image
  server_type = each.value.server_type
  ssh_keys    = [hcloud_ssh_key.default.id]
  user_data   = data.template_file.cloud_init.rendered
  placement_group_id = hcloud_placement_group.default.id
  public_net {
    ipv4 = hcloud_primary_ip.node_ipv4_addresses[each.key].id
    ipv6 = hcloud_primary_ip.node_ipv6_addresses[each.key].id
  }
  lifecycle {
    ignore_changes = [
      ssh_keys,
      user_data
    ]
    prevent_destroy = true
  }
}

resource "hcloud_rdns" "nodes_rdns_ipv4" {
  for_each   = local.hetzner_hosts
  server_id  = hcloud_server.nodes[each.key].id
  ip_address = hcloud_server.nodes[each.key].ipv4_address
  dns_ptr    = each.value.rdns
}

resource "hcloud_rdns" "nodes_rdns_ipv6" {
  for_each   = local.hetzner_hosts
  server_id  = hcloud_server.nodes[each.key].id
  ip_address = hcloud_server.nodes[each.key].ipv6_address
  dns_ptr    = each.value.rdns
}

locals {
  default_firewall_source_ips = [ "0.0.0.0/0", "::/0" ]
}

# Create firewalls
resource "hcloud_firewall" "nodes_services" {
  for_each = local.hetzner_hosts
  name = each.key
  apply_to {
    server = hcloud_server.nodes[each.key].id
  }

  rule {
    description = "ICMP"
    direction   = "in"
    protocol    = "icmp"
    source_ips  = local.default_firewall_source_ips
  }

  dynamic "rule" {
    for_each = flatten([ for k, v in var.services : v.ports if (v.ports != null && (v.host == each.key || v.host == "*")) ])
    content {
      description = rule.value.description
      direction   = "in"
      protocol    = rule.value.protocol
      port        = rule.value.port
      source_ips  = local.default_firewall_source_ips
    }
  }
}