locals {
  # alb_clients access the SH
  alb_clients = toset(concat(
    var.cidr_map["vpc-access"], # VPN users
    var.cidr_map["vpc-system-services"], # Salt master, etc
    var.cidr_map["vpc-private-services"], # fm-shared search, qcompliance, phantom
  ))
}

resource "aws_lb" "searchhead-alb" {
  name               = var.alb_name != "" ? "${local.alb_name}-alb" : "${var.prefix}-searchhead-alb"
  internal           = true
  load_balancer_type = "application"
  # Not supported for NLB
  security_groups    = [aws_security_group.searchhead-alb-sg.id]
  # Note, changing subnets results in recreation of the resource
  subnets            = var.subnets
  enable_cross_zone_load_balancing = true

  access_logs {
    bucket  = "xdr-elb-${ var.environment }"
    enabled = true
  }

  tags = merge(var.standard_tags, var.tags)
}

#########################
# Listeners
resource "aws_lb_listener" "searchhead-alb-listener-https" {
  load_balancer_arn = aws_lb.searchhead-alb.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-FS-1-2-Res-2019-08" # PFS, TLS1.2, most "restrictive" policy (took awhile to find that)
  certificate_arn   = aws_acm_certificate.cert.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.searchhead-alb-target-8000.arn
  }
}

resource "aws_lb_listener" "searchhead-alb-listener-8000" {
  load_balancer_arn = aws_lb.searchhead-alb.arn
  port              = "8000"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-FS-1-2-Res-2019-08" # PFS, TLS1.2, most "restrictive" policy (took awhile to find that)
  certificate_arn   = aws_acm_certificate.cert.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.searchhead-alb-target-8000.arn
  }
}

# Only alb's can redirect
resource "aws_lb_listener" "searchhead-alb-listener-http" {
  load_balancer_arn = aws_lb.searchhead-alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

resource "aws_lb_listener" "searchhead-alb-listener-api" {
  load_balancer_arn = aws_lb.searchhead-alb.arn
  port              = "8089"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-FS-1-2-Res-2019-08" # PFS, TLS1.2, most "restrictive" policy (took awhile to find that)
  certificate_arn   = aws_acm_certificate.cert.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.searchhead-alb-target-api.arn
  }
}


#########################
# Targets
resource "aws_lb_target_group" "searchhead-alb-target-8000" {
  name     = var.alb_name != "" ? "${local.alb_name}-alb-target-8000" : "${var.prefix}-sh-alb-target-8000"
  port     = 8000
  protocol = "HTTPS"
  target_type = "instance"
  vpc_id   = var.vpc_id
  tags = merge(var.standard_tags, var.tags)

  health_check {
    enabled = true
    path = "/en-US/account/login?return_to=%2Fen-US%2F"
    port = 8000
    protocol = "HTTPS"
  }

  # Stickiness is not needed here, but we'll need it if we add SHs
  stickiness {
    type = "lb_cookie"
    cookie_duration = 86400 # 1 day
    enabled = true
  }
}

resource "aws_lb_target_group_attachment" "searchhead-alb-target-8000-instance" {
  target_group_arn = aws_lb_target_group.searchhead-alb-target-8000.arn
  target_id        = aws_instance.instance.id
  port             = 8000
}

resource "aws_lb_target_group" "searchhead-alb-target-api" {
  name     = var.alb_name != "" ? "${local.alb_name}-target-api" : "${var.prefix}-sh-alb-target-api"
  port     = 8089
  protocol = "HTTPS"
  target_type = "instance"
  vpc_id   = var.vpc_id
  tags = merge(var.standard_tags, var.tags)

  health_check {
    enabled = true
    #path = "/services/server/health/splunkd" # reportedly works, but doesn't
    path = "/"
    port = 8089
    protocol = "HTTPS"
  }

}

resource "aws_lb_target_group_attachment" "searchhead-alb-target-api-instance" {
  target_group_arn = aws_lb_target_group.searchhead-alb-target-api.arn
  target_id        = aws_instance.instance.id
  port             = 8089
}


#########################
# Security Group for ALB
resource "aws_security_group" "searchhead-alb-sg" {
  name = var.alb_name != "" ? "${local.alb_name}-alb-sh" : "${var.prefix}-sh-alb-sg"
  description = "Security Group for the Searchhead ALB"
  vpc_id = var.vpc_id
  tags = merge(var.standard_tags, var.tags)
}

resource "aws_security_group_rule" "searchhead-alb-api-in" {
  type              = "ingress"
  from_port         = 8089
  to_port           = 8089
  protocol          = "tcp"
  cidr_blocks       = local.alb_clients
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

resource "aws_security_group_rule" "searchhead-alb-https-in" {
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = local.alb_clients
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

resource "aws_security_group_rule" "searchhead-alb-8000-in" {
  type              = "ingress"
  from_port         = 8000
  to_port           = 8000
  protocol          = "tcp"
  cidr_blocks       = local.alb_clients
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

resource "aws_security_group_rule" "searchhead-http-in" {
  # Port 80 is open as a redirect to 443
  type              = "ingress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  cidr_blocks       = local.alb_clients
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

resource "aws_security_group_rule" "searchhead-alb-8000-out" {
  type              = "egress"
  from_port         = 8000
  to_port           = 8000
  protocol          = "tcp"
  # Maybe should limit to the local vpc, but I don't readily have that cidr available
  cidr_blocks       = [ "10.0.0.0/8" ]
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

resource "aws_security_group_rule" "searchhead-alb-api-out" {
  type              = "egress"
  from_port         = 8089
  to_port           = 8089
  protocol          = "tcp"
  # Maybe should limit to the local vpc, but I don't readily have that cidr available
  cidr_blocks       = [ "10.0.0.0/8" ]
  security_group_id = aws_security_group.searchhead-alb-sg.id
}

#########################
# DNS Entry
resource "aws_route53_record" "searchhead_internal" {
  zone_id = var.dns_info["private"]["zone_id"]
  name    = local.alb_name
  type    = "CNAME"
  records = [aws_lb.searchhead-alb.dns_name]
  ttl = "60"
  provider = aws.c2
}
