---
# Source: sumologic/templates/setup/setup-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name:  RELEASE-NAME-sumologic-setup
  annotations:
    helm.sh/hook: pre-install,pre-upgrade
    helm.sh/hook-weight: "2"
    helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
  labels:
    app: RELEASE-NAME-sumologic
    chart: "sumologic-%CURRENT_CHART_VERSION%"
    release: "RELEASE-NAME"
    heritage: "Helm"
data:
  custom.sh: |
    #!/bin/bash
    #
    # This script copies files from /customer-scripts to /scripts/<dirname> basing on the filename
    #
    # Example file structure:
    #
    # /customer-scripts
    # ├── dir1_main.tf
    # ├── dir1_setup.sh
    # ├── dir2_list.txt
    # └── dir2_setup.sh
    #
    # Expected structure:
    #
    # /scripts
    # ├── dir1
    # │   ├── main.tf
    # │   └── setup.sh
    # └── dir2
    #     ├── list.txt
    #     └── setup.sh
    #
    # shellcheck disable=SC2010
    # extract target directory names from the file names using _ as separator
    err_report() {
        echo "Custom script error on line $1"
        exit 1
    }
    trap 'err_report $LINENO' ERR
  
    for dir in $(ls -1 /customer-scripts | grep _ | grep -oE '^.*?_' | sed 's/_//g' | sort | uniq); do
      target="/scripts/${dir}"
      mkdir "${target}"
      # shellcheck disable=SC2010
      # Get files for given directory and take only filename part (after first _)
      for file in $(ls -1 "/customer-scripts/${dir}_"* | grep -oE '_.*' | sed 's/_//g'); do
        cp "/customer-scripts/${dir}_${file}" "${target}/${file}"
      done
  
      if [[ ! -f setup.sh ]]; then
        echo "You're missing setup.sh script in custom scripts directory: '${dir}'"
        continue
      fi
  
      cd "${target}" && bash setup.sh
    done
  fields.tf: |
    resource "sumologic_field" "cluster" {
      count = var.create_fields ? 1 : 0
  
      field_name = "cluster"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "container" {
      count = var.create_fields ? 1 : 0
  
      field_name = "container"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "deployment" {
      count = var.create_fields ? 1 : 0
  
      field_name = "deployment"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "host" {
      count = var.create_fields ? 1 : 0
  
      field_name = "host"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "namespace" {
      count = var.create_fields ? 1 : 0
  
      field_name = "namespace"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "node" {
      count = var.create_fields ? 1 : 0
  
      field_name = "node"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "pod" {
      count = var.create_fields ? 1 : 0
  
      field_name = "pod"
      data_type = "String"
      state = "Enabled"
    }
    resource "sumologic_field" "service" {
      count = var.create_fields ? 1 : 0
  
      field_name = "service"
      data_type = "String"
      state = "Enabled"
    }
  locals.tf: |
    locals {
      default_events_source                       = "events"
      default_logs_source                         = "logs"
      apiserver_metrics_source                    = "apiserver-metrics"
      control_plane_metrics_source                = "control-plane-metrics"
      controller_metrics_source                   = "kube-controller-manager-metrics"
      default_metrics_source                      = "(default-metrics)"
      kubelet_metrics_source                      = "kubelet-metrics"
      node_metrics_source                         = "node-exporter-metrics"
      scheduler_metrics_source                    = "kube-scheduler-metrics"
      state_metrics_source                        = "kube-state-metrics"
    }
  main.tf: |
    terraform {
      required_providers {
        sumologic = {
          source  = "sumologic/sumologic"
          version = "~> 2.6"
        }
        kubernetes = {
          source  = "hashicorp/kubernetes"
          version = "~> 1.13"
        }
      }
    }
  providers.tf: |-
    provider "sumologic" {}
  
    provider "kubernetes" {
    
        cluster_ca_certificate    = file("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
        host                      = "https://kubernetes.default.svc"
        load_config_file          = "false"
        token                     = file("/var/run/secrets/kubernetes.io/serviceaccount/token")
    }
  resources.tf: |
    resource "sumologic_collector" "collector" {
        name  = var.collector_name
        fields  = {
          cluster = var.cluster_name
        }
    }
    
    resource "sumologic_http_source" "default_events_source" {
        name         = local.default_events_source
        collector_id = sumologic_collector.collector.id
        category     = "${var.cluster_name}/${local.default_events_source}"
    }
    
    resource "sumologic_http_source" "default_logs_source" {
        name         = local.default_logs_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "apiserver_metrics_source" {
        name         = local.apiserver_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "control_plane_metrics_source" {
        name         = local.control_plane_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "controller_metrics_source" {
        name         = local.controller_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "default_metrics_source" {
        name         = local.default_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "kubelet_metrics_source" {
        name         = local.kubelet_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "node_metrics_source" {
        name         = local.node_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "scheduler_metrics_source" {
        name         = local.scheduler_metrics_source
        collector_id = sumologic_collector.collector.id
    }
    
    resource "sumologic_http_source" "state_metrics_source" {
        name         = local.state_metrics_source
        collector_id = sumologic_collector.collector.id
    }
  
    resource "kubernetes_secret" "sumologic_collection_secret" {
      metadata {
        name = "sumologic"
        namespace = var.namespace_name
      }
  
      data = {
        endpoint-events                           = sumologic_http_source.default_events_source.url
        endpoint-logs                             = sumologic_http_source.default_logs_source.url
        endpoint-metrics-apiserver                = sumologic_http_source.apiserver_metrics_source.url
        endpoint-control_plane_metrics_source     = sumologic_http_source.control_plane_metrics_source.url
        endpoint-metrics-kube-controller-manager  = sumologic_http_source.controller_metrics_source.url
        endpoint-metrics                          = sumologic_http_source.default_metrics_source.url
        endpoint-metrics-kubelet                  = sumologic_http_source.kubelet_metrics_source.url
        endpoint-metrics-node-exporter            = sumologic_http_source.node_metrics_source.url
        endpoint-metrics-kube-scheduler           = sumologic_http_source.scheduler_metrics_source.url
        endpoint-metrics-kube-state               = sumologic_http_source.state_metrics_source.url
      }
  
      type = "Opaque"
    }
  setup.sh: |
    #!/bin/bash
  
    # Fix URL to remove "v1" or "v1/"
    export SUMOLOGIC_BASE_URL=${SUMOLOGIC_BASE_URL%v1*}
    # Support proxy for Terraform
    export HTTP_PROXY=${HTTP_PROXY:=""}
    export HTTPS_PROXY=${HTTPS_PROXY:=""}
    export NO_PROXY=${NO_PROXY:=""}
  
    function remaining_fields() {
        local RESPONSE="$(curl -XGET -s \
            -u "${SUMOLOGIC_ACCESSID}:${SUMOLOGIC_ACCESSKEY}" \
            "${SUMOLOGIC_BASE_URL}"v1/fields/quota)"
  
        echo "${RESPONSE}" | jq '.remaining'
    }
  
    # Check if we'd have at least 10 fields remaining after additional fields
    # would be created for the collection
    function should_create_fields() {
        local REMAINING=$(remaining_fields)
        if [[ $(( REMAINING - 8 )) -ge 10 ]] ; then
            return 0
        else
            return 1
        fi
    }
  
    cp /etc/terraform/{locals,main,providers,resources,variables,fields}.tf /terraform/
    cd /terraform || exit 1
  
    terraform init
  
    # Sumo Logic fields
    if should_create_fields ; then
        readonly CREATE_FIELDS=1
        readonly FIELDS_RESPONSE="$(curl -XGET -s \
            -u "${SUMOLOGIC_ACCESSID}:${SUMOLOGIC_ACCESSKEY}" \
            "${SUMOLOGIC_BASE_URL}"v1/fields | jq '.data[]' )"
  
        declare -ra FIELDS=("cluster" "container" "deployment" "host" "namespace" "node" "pod" "service")
        for FIELD in "${FIELDS[@]}" ; do
            FIELD_ID=$( echo "${FIELDS_RESPONSE}" | jq -r "select(.fieldName == \"${FIELD}\") | .fieldId" )
            # Don't try to import non existing fields
            if [[ -z "${FIELD_ID}" ]]; then
                continue
            fi
  
            terraform import \
                -var="create_fields=1" \
                sumologic_field."${FIELD}" "${FIELD_ID}"
        done
    else
        readonly CREATE_FIELDS=0
        echo "Couldn't automatically create fields"
        echo "You do not have enough field capacity to create the required fields automatically."
        echo "Please refer to https://help.sumologic.com/Manage/Fields to manually create the fields after you have removed unused fields to free up capacity."
    fi
  
    readonly COLLECTOR_NAME="kubernetes"
  
    # Sumo Logic Collector and HTTP sources
    # Only import sources when collector exists.
    if terraform import sumologic_collector.collector "${COLLECTOR_NAME}"; then
    terraform import sumologic_http_source.default_events_source "${COLLECTOR_NAME}/events"
    terraform import sumologic_http_source.default_logs_source "${COLLECTOR_NAME}/logs"
    terraform import sumologic_http_source.apiserver_metrics_source "${COLLECTOR_NAME}/apiserver-metrics"
    terraform import sumologic_http_source.control_plane_metrics_source "${COLLECTOR_NAME}/control-plane-metrics"
    terraform import sumologic_http_source.controller_metrics_source "${COLLECTOR_NAME}/kube-controller-manager-metrics"
    terraform import sumologic_http_source.default_metrics_source "${COLLECTOR_NAME}/(default-metrics)"
    terraform import sumologic_http_source.kubelet_metrics_source "${COLLECTOR_NAME}/kubelet-metrics"
    terraform import sumologic_http_source.node_metrics_source "${COLLECTOR_NAME}/node-exporter-metrics"
    terraform import sumologic_http_source.scheduler_metrics_source "${COLLECTOR_NAME}/kube-scheduler-metrics"
    terraform import sumologic_http_source.state_metrics_source "${COLLECTOR_NAME}/kube-state-metrics"
    fi
  
    # Kubernetes Secret
    terraform import kubernetes_secret.sumologic_collection_secret sumologic/sumologic
  
    # Apply planned changes
    terraform apply -auto-approve \
        -var="create_fields=${CREATE_FIELDS}" \
        || { echo "Error during applying Terraform changes"; exit 1; }
  
    # Cleanup env variables
    export SUMOLOGIC_BASE_URL=
    export SUMOLOGIC_ACCESSKEY=
    export SUMOLOGIC_ACCESSID=
  
    bash /etc/terraform/custom.sh
  variables.tf: |
    variable "cluster_name" {
      type  = string
      default = "kubernetes"
    }
  
    variable "collector_name" {
      type  = string
      default = "kubernetes"
    }
  
    variable "namespace_name" {
      type  = string
      default = "sumologic"
    }
  
    variable "create_fields" {
      description = "If set, Terraform will attempt to create fields at Sumo Logic"
      type        = bool
      default     = true
    }
