# kube-prometheus-stack Helm values for OSDC.
#
# This chart is used ONLY as a CRD + exporter provider:
#   - Installs monitoring.coreos.com CRDs (ServiceMonitor, PodMonitor, etc.)
#   - Runs node-exporter and kube-state-metrics to expose system metrics
#   - Runs Prometheus Operator to manage CRD lifecycle
#
# Prometheus, Grafana, and AlertManager are DISABLED.
# Metrics collection and push is handled by Grafana Alloy (see alloy-values.yaml).

# --- Prometheus (DISABLED — Alloy handles scraping + push) ---
prometheus:
  enabled: false

# --- Control plane ServiceMonitors (DISABLED — we manage our own) ---
# kube-prometheus-stack creates ServiceMonitors for these by default.
# We disable them all and use custom monitors in kubernetes/monitors/
# for the components we actually want (apiserver, coredns).
# EKS does not expose controller-manager, scheduler, or etcd endpoints.
kubeApiServer:
  enabled: false
coreDns:
  enabled: false
kubeProxy:
  enabled: false
kubeControllerManager:
  enabled: false
kubeScheduler:
  enabled: false
kubeEtcd:
  enabled: false

# --- kubelet + cadvisor ServiceMonitor ---
# DISABLED on IPv6-only EKS. Prometheus Operator's kubelet endpoint
# controller picks node.status.addresses[0], which on dual-stack nodes
# is the IPv4 InternalIP — Alloy (IPv6-only pod) cannot reach it.
# See docs/observability.md ("Disabled scrapers (IPv6 migration)").
# TODO(ipv6): re-enable after shipping a custom IPv6-aware kubelet
# ServiceMonitor under kubernetes/monitors/servicemonitors/, then
# uncomment the serviceMonitor filter block below.
kubelet:
  enabled: false
  # serviceMonitor:
  #   interval: 60s
  #   # Disable /metrics/probes scraping — generates ~1440 high-cardinality
  #   # prober_probe_duration_seconds_bucket series with no alerting value
  #   probes: false
  #   # cadvisor: keep only pod-level memory metrics (per pod/container series)
  #   # - container_memory_working_set_bytes: active memory used by pod; K8s uses this for OOM kill decisions
  #   # - container_memory_rss: physical memory (no cache); useful for spotting memory leaks
  #   # NOTE: these generate one series per container, so high pod churn (e.g. runners) increases cardinality
  #   cAdvisorMetricRelabelings:
  #     - action: keep
  #       sourceLabels: [__name__]
  #       regex: "container_memory_working_set_bytes|container_memory_rss"
  #   # kubelet: keep only running pod/container counts
  #   metricRelabelings:
  #     - action: keep
  #       sourceLabels: [__name__]
  #       regex: "kubelet_running_(pods|containers)|kubelet_node_name"

# --- Grafana (DISABLED — use Grafana Cloud) ---
grafana:
  enabled: false

# --- AlertManager (DISABLED — use Grafana Cloud alerting) ---
alertmanager:
  enabled: false

# --- node-exporter (DaemonSet — runs on ALL nodes) ---
nodeExporter:
  tolerations:
    - operator: Exists  # tolerate ALL taints — must run on every node

# --- node-exporter subchart overrides ---
prometheus-node-exporter:
  # Bind to the node's primary IP via Downward API status.hostIP instead of
  # 0.0.0.0. On IPv6-only EKS the chart default (0.0.0.0:9100) is IPv4-only
  # and leaves Alloy (IPv6-only pod) unable to scrape — silently dropping
  # node_nf_conntrack_entries (which powers network-pressure-alerts) and
  # all node memory metrics.
  listenOnAllInterfaces: false
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 50
  extraArgs:
    - --no-collector.bcache
    - --no-collector.bonding
    - --no-collector.infiniband
    - --no-collector.nfs
    - --no-collector.nfsd
    - --no-collector.fibrechannel
    - --no-collector.ipvs
    - --no-collector.rapl
    - --no-collector.schedstat
    - --no-collector.interrupts
    - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker|var/lib/kubelet|run/containerd)($|/)
    - --collector.filesystem.fs-types-exclude=^(autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs|tmpfs)$
    - --collector.netdev.device-exclude=^(veth|cali|flannel|cni|docker|br-).*
  prometheus:
    monitor:
      interval: 60s
      metricRelabelings:
        # Keep memory + conntrack metrics; drop everything else (including per-core CPU).
        # Conntrack metrics power network-pressure-alerts (NodeConntrackHigh{Warn,Critical}) —
        # critical under IPv6-only EKS where pod-IPv4-internet egress goes through VPC CNI's
        # SNAT path, which is conntrack-heavy.
        - action: keep
          sourceLabels: [__name__]
          regex: "node_memory_MemAvailable_bytes|node_memory_MemTotal_bytes|node_nf_conntrack_entries|node_nf_conntrack_entries_limit"

# --- kube-state-metrics ---
kube-state-metrics:
  extraArgs:
    - --metric-allowlist=kube_(daemonset|deployment|pod|namespace|node|statefulset|persistentvolume|horizontalpodautoscaler|job)_.+
  prometheus:
    monitor:
      interval: 60s
      metricRelabelings:
        # Keep only the KSM metrics we actually use (single rule — multiple keeps are ANDed).
        # RE2 engine (no lookahead), so we use an explicit allowlist.
        #   daemonset: health status (desired/ready/available/unavailable)
        #   deployment: replica status + conditions + desired count
        #   namespace/node/statefulset/pv/hpa/job: all metrics (low cardinality)
        #   pod: info (node mapping), error indicators, restart count, status reasons
        - action: keep
          sourceLabels: [__name__]
          regex: "kube_daemonset_status_(desired_number_scheduled|number_ready|number_available|number_unavailable)|kube_deployment_status_(replicas_ready|replicas_available|replicas_unavailable|condition)|kube_deployment_spec_replicas|kube_(namespace|node|statefulset|persistentvolume|horizontalpodautoscaler|job)_.*|kube_pod_info|kube_pod_container_status_last_terminated_reason|kube_pod_container_status_terminated_reason|kube_pod_container_status_last_terminated_exitcode|kube_pod_container_status_restarts_total|kube_pod_status_reason"
        # Drop low-value node metrics
        - action: drop
          sourceLabels: [__name__]
          regex: "kube_node_status_addresses"
        # Drop successful terminations (only keep actual errors).
        # Both `_last_terminated_reason` (after restart) and `_terminated_reason`
        # (current state) are emitted by KSM — `last_` only fires for restarting
        # containers, so non-restarting pods (e.g. Job/CronJob with restartPolicy=Never)
        # need the non-`last` variant. Drop benign Completed reasons from both.
        - action: drop
          sourceLabels: [__name__, reason]
          regex: "kube_pod_container_status_(last_)?terminated_reason;Completed"
        - action: drop
          sourceLabels: [__name__, container_exit_code]
          regex: "kube_pod_container_status_last_terminated_exitcode;0"
        # Drop routine pod status reasons (spot reclaim, scheduling changes)
        # Keep only non-routine errors: Evicted, NodeLost, UnexpectedAdmissionError
        - action: drop
          sourceLabels: [__name__, reason]
          regex: "kube_pod_status_reason;(Shutdown|NodeAffinity)"
  tolerations:
    - key: CriticalAddonsOnly
      operator: Equal
      value: "true"
      effect: NoSchedule
  nodeSelector:
    role: base-infrastructure

# --- Prometheus Operator (manages CRD lifecycle) ---
prometheusOperator:
  tolerations:
    - key: CriticalAddonsOnly
      operator: Equal
      value: "true"
      effect: NoSchedule
  nodeSelector:
    role: base-infrastructure
  # Admission webhook (pre-install/pre-upgrade hook jobs)
  admissionWebhooks:
    patch:
      tolerations:
        - key: CriticalAddonsOnly
          operator: Equal
          value: "true"
          effect: NoSchedule
      nodeSelector:
        role: base-infrastructure
