apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "kubernetes-agent.fullname" . }}-deployment
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "kubernetes-agent.labels" . | nindent 4 }}
data:
  otel-collector-config.yaml: |
    extensions:
      health_check:
        endpoint: "0.0.0.0:13133"

    receivers:
      # Collect cluster-level metrics from the Kubernetes API
      k8s_cluster:
        collection_interval: {{ .Values.collectionInterval }}
        node_conditions_to_report:
          - Ready
          - MemoryPressure
          - DiskPressure
          - PIDPressure
          - NetworkUnavailable
        allocatable_types_to_report:
          - cpu
          - memory
          - storage

      # Watch Kubernetes events and ingest as logs
      k8sobjects:
        objects:
          - name: events
            mode: watch
            group: events.k8s.io
          {{- if .Values.resourceSpecs.enabled }}
          # Pull full resource specs for dashboard detail views
          - name: pods
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
          - name: nodes
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
          - name: namespaces
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
          - name: deployments
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: apps
          - name: statefulsets
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: apps
          - name: daemonsets
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: apps
          - name: jobs
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: batch
          - name: cronjobs
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: batch
          - name: persistentvolumeclaims
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
          - name: persistentvolumes
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
          - name: horizontalpodautoscalers
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: autoscaling
          {{- if .Values.resourceSpecs.vpa }}
          - name: verticalpodautoscalers
            mode: pull
            interval: {{ .Values.resourceSpecs.interval }}
            group: autoscaling.k8s.io
          {{- end }}
          {{- end }}

      {{- if or .Values.controlPlane.enabled .Values.serviceMesh.enabled }}
      # Scrape metrics via Prometheus endpoints (control plane and/or service mesh)
      prometheus:
        config:
          scrape_configs:
            {{- if .Values.controlPlane.enabled }}
            - job_name: etcd
              scheme: https
              tls_config:
                insecure_skip_verify: {{ .Values.controlPlane.etcd.insecureSkipVerify }}
              static_configs:
                {{- range .Values.controlPlane.etcd.endpoints }}
                - targets:
                    - {{ . | quote }}
                {{- end }}
            - job_name: kube-apiserver
              scheme: https
              tls_config:
                insecure_skip_verify: {{ .Values.controlPlane.apiServer.insecureSkipVerify }}
              bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
              static_configs:
                {{- range .Values.controlPlane.apiServer.endpoints }}
                - targets:
                    - {{ . | quote }}
                {{- end }}
            - job_name: kube-scheduler
              scheme: https
              tls_config:
                insecure_skip_verify: {{ .Values.controlPlane.scheduler.insecureSkipVerify }}
              bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
              static_configs:
                {{- range .Values.controlPlane.scheduler.endpoints }}
                - targets:
                    - {{ . | quote }}
                {{- end }}
            - job_name: kube-controller-manager
              scheme: https
              tls_config:
                insecure_skip_verify: {{ .Values.controlPlane.controllerManager.insecureSkipVerify }}
              bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
              static_configs:
                {{- range .Values.controlPlane.controllerManager.endpoints }}
                - targets:
                    - {{ . | quote }}
                {{- end }}
            {{- end }}
            {{- if and .Values.serviceMesh.enabled (eq .Values.serviceMesh.provider "istio") }}
            - job_name: envoy-stats
              metrics_path: /stats/prometheus
              scrape_interval: {{ .Values.serviceMesh.istio.scrapeInterval }}
              kubernetes_sd_configs:
                - role: pod
              relabel_configs:
                - source_labels: [__meta_kubernetes_pod_container_name]
                  action: keep
                  regex: istio-proxy
                - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip]
                  action: replace
                  regex: (\d+);((([0-9]+?)(\.|$)){4})
                  replacement: $2:15090
                  target_label: __address__
                - action: labelmap
                  regex: __meta_kubernetes_pod_label_(.+)
                - source_labels: [__meta_kubernetes_namespace]
                  action: replace
                  target_label: namespace
                - source_labels: [__meta_kubernetes_pod_name]
                  action: replace
                  target_label: pod_name
            {{- end }}
            {{- if and .Values.serviceMesh.enabled (eq .Values.serviceMesh.provider "linkerd") }}
            - job_name: linkerd-proxy
              metrics_path: /metrics
              scrape_interval: {{ .Values.serviceMesh.linkerd.scrapeInterval }}
              kubernetes_sd_configs:
                - role: pod
              relabel_configs:
                - source_labels: [__meta_kubernetes_pod_container_name]
                  action: keep
                  regex: linkerd-proxy
                - source_labels: [__meta_kubernetes_pod_container_port_name]
                  action: keep
                  regex: linkerd-admin
                - action: labelmap
                  regex: __meta_kubernetes_pod_label_(.+)
                - source_labels: [__meta_kubernetes_namespace]
                  action: replace
                  target_label: namespace
                - source_labels: [__meta_kubernetes_pod_name]
                  action: replace
                  target_label: pod_name
            {{- end }}
      {{- end }}

    processors:
      # Enrich all telemetry with Kubernetes metadata
      k8sattributes:
        auth_type: serviceAccount
        extract:
          metadata:
            - k8s.pod.name
            - k8s.pod.uid
            - k8s.namespace.name
            - k8s.node.name
            - k8s.deployment.name
            - k8s.replicaset.name
            - k8s.statefulset.name
            - k8s.daemonset.name
            - k8s.job.name
            - k8s.cronjob.name
            - k8s.container.name
          labels:
            - tag_name: k8s.pod.label.app
              key: app
              from: pod
            - tag_name: k8s.pod.label.app.kubernetes.io/name
              key: app.kubernetes.io/name
              from: pod
        pod_association:
          - sources:
              - from: resource_attribute
                name: k8s.pod.ip
          - sources:
              - from: resource_attribute
                name: k8s.pod.uid
          - sources:
              - from: connection

      # Stamp all telemetry with the cluster name and service name
      resource:
        attributes:
          - key: k8s.cluster.name
            value: {{ .Values.clusterName | quote }}
            action: upsert
          - key: service.name
            value: "kubernetes-agent-{{ .Values.clusterName }}"
            action: upsert

      # Batch telemetry for efficient export
      batch:
        send_batch_size: 100
        send_batch_max_size: 200
        timeout: 10s

      # Limit memory usage
      memory_limiter:
        check_interval: 5s
        limit_mib: 3000
        spike_limit_mib: 600

    exporters:
      otlphttp:
        endpoint: "{{ .Values.oneuptime.url }}/otlp"
        encoding: json
        headers:
          x-oneuptime-token: "${env:ONEUPTIME_API_KEY}"
        sending_queue:
          enabled: true
          num_consumers: 10
          queue_size: 5000
        retry_on_failure:
          enabled: true
          initial_interval: 5s
          max_interval: 60s
          max_elapsed_time: 300s

    service:
      extensions:
        - health_check
      pipelines:
        metrics:
          receivers:
            - k8s_cluster
            {{- if or .Values.controlPlane.enabled .Values.serviceMesh.enabled }}
            - prometheus
            {{- end }}
          processors:
            - memory_limiter
            - k8sattributes
            - resource
            - batch
          exporters:
            - otlphttp
        logs:
          receivers:
            - k8sobjects
          processors:
            - memory_limiter
            - k8sattributes
            - resource
            - batch
          exporters:
            - otlphttp
