chore: mirror k8s-monitoring-2.0.12

upstream_repo:
This commit is contained in:
Nikolai Rodionov
2025-02-21 09:42:13 +01:00
commit 57712751f1
440 changed files with 101268 additions and 0 deletions

View File

@ -0,0 +1,25 @@
Grafana {{.Chart.Name}} Helm chart deployed!
This chart will install the following components:
{{- range $feature := (include "features.list.enabled" .) | fromYamlArray }}
{{- include (printf "feature.%s.notes.deployments" $feature) (dict "Values" (index $.Values $feature)) | indent 0 }}
{{- end }}
{{- include "collectors.notes.deployments" . }}
It will:
{{- range $feature := (include "features.list.enabled" .) | fromYamlArray }}
{{- if ne $feature "selfReporting" }}
{{- $task := include (printf "feature.%s.notes.task" $feature) (dict "Values" (index $.Values $feature)) | trim }}
{{- $destinations := include (printf "features.%s.destinations" $feature) $ | fromYamlArray }}
* {{ $task }} and send data to {{ include "english_list" $destinations }}.
{{- end }}
{{- end }}
{{- range $feature := (include "features.list.enabled" .) | fromYamlArray }}
{{- $collectorName := (index $.Values $feature).collector }}
{{- $Collector := dict "Namespace" $.Release.Namespace }}
{{- if $collectorName }}
{{- $Collector = merge $Collector (dict "ServiceName" (include "alloy.fullname" (index $.Subcharts $collectorName))) }}
{{- end }}
{{ include (printf "feature.%s.notes.actions" $feature) (dict "Values" (index $.Values $feature) "Collector" $Collector) | indent 0 }}
{{- end }}

View File

@ -0,0 +1,54 @@
{{ define "helper.k8s_name" }}
{{- . | lower | replace " " "-" -}}
{{ end }}
{{ define "helper.alloy_name" }}
{{- . | lower | replace " " "-" | replace "-" "_" -}}
{{ end }}
{{- define "helper.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" | lower }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride | lower }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" | lower }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" | lower }}
{{- end }}
{{- end }}
{{- end }}
{{- define "english_list" }}
{{- if eq (len .) 0 }}
{{- else if eq (len .) 1 }}
{{- index . 0 }}
{{- else if eq (len .) 2 }}
{{- index . 0 }} and {{ index . 1 }}
{{- else }}
{{- $last := index . (sub (len .) 1) }}
{{- $rest := slice . 0 (sub (len .) 1) }}
{{- join ", " $rest }}, and {{ $last }}
{{- end }}
{{- end }}
{{- define "english_list_or" }}
{{- if eq (len .) 0 }}
{{- else if eq (len .) 1 }}
{{- index . 0 }}
{{- else if eq (len .) 2 }}
{{- index . 0 }} and {{ index . 1 }}
{{- else }}
{{- $last := index . (sub (len .) 1) }}
{{- $rest := slice . 0 (sub (len .) 1) }}
{{- join ", " $rest }}, or {{ $last }}
{{- end }}
{{- end }}
{{- define "label_list" }}
{{- $labels := list }}
{{- range $key, $value := . }}
{{- $labels = append $labels (printf "%s=\"%s\"" $key $value) }}
{{- end }}
{{- printf "{%s}" ($labels | join ", ") }}
{{- end }}

View File

@ -0,0 +1,53 @@
{{/* Checks if a V1 values file was used */}}
{{- define "validations.checkForV1" }}
{{- if (index .Values "externalServices") }}
{{- $msg := list "" "The Helm chart values appears to be from version 1.x of the k8s-monitoring Helm chart." }}
{{- $msg = append $msg "To continue using version 1.x, add this to your helm command:" }}
{{- $msg = append $msg " --version ^1" }}
{{- $msg = append $msg "" }}
{{- $msg = append $msg "If you'd like to migrate to version 2.0, see the Migration guide:" }}
{{- $msg = append $msg " https://github.com/grafana/k8s-monitoring-helm/blob/main/charts/k8s-monitoring/docs/Migration.md" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{/* Checks that the cluster name is defined */}}
{{- define "validations.cluster_name" }}
{{- if or (not .Values.cluster) (not .Values.cluster.name) }}
{{- $msg := list "" "A Cluster name is required!" }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "cluster:" }}
{{- $msg = append $msg " name: my-cluster-name" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{/* Checks that at least one feature is enabled */}}
{{- define "validations.features_enabled" }}
{{ $aFeatureIsEnabled := false }}
{{- range $feature := ((include "features.list" .) | fromYamlArray ) }}
{{- $aFeatureIsEnabled = or $aFeatureIsEnabled (eq (include (printf "features.%s.enabled" $feature) $) "true") }}
{{- end }}
{{- range $collector := ((include "collectors.list" .) | fromYamlArray ) }}
{{- $aFeatureIsEnabled = or $aFeatureIsEnabled ((index $.Values $collector).remoteConfig.enabled) }}
{{- $aFeatureIsEnabled = or $aFeatureIsEnabled ((index $.Values $collector).extraConfig) }}
{{- end }}
{{- if not $aFeatureIsEnabled }}
{{- $msg := list "" "No features are enabled. Please choose a feature to start monitoring. For example:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " enabled: true" }}
{{- $msg = append $msg "" }}
{{- $msg = append $msg "See https://github.com/grafana/k8s-monitoring-helm/blob/main/charts/k8s-monitoring/docs/Features.md for the list of available features." }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{/* Checks for platform settings */}}
{{- define "validations.platform" }}
{{- if and (not (eq .Values.global.platform "openshift")) (.Capabilities.APIVersions.Has "security.openshift.io/v1/SecurityContextConstraints") }}
{{- $msg := list "" "This Kubernetes cluster appears to be OpenShift. Please set the platform to enable compatibility:" }}
{{- $msg = append $msg "global:" }}
{{- $msg = append $msg " platform: openshift" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,42 @@
{{- range $collector := include "collectors.list.enabled" . | fromYamlArray }}
{{- $selfReportingEnabled := false }}
{{- $destinations := list }}
{{- range $feature := include "features.list" $ | fromYamlArray }}
{{- if has $collector (include (printf "features.%s.collectors" $feature) $ | fromYamlArray ) }}
{{- if eq $feature "selfReporting" }}
{{- $selfReportingEnabled = true }}
{{- end }}
{{- $destinations = concat $destinations ((include (printf "features.%s.destinations" $feature) $) | fromYamlArray) }}
{{- end }}
{{- end }}
{{/* Save the top level object and add the collector name */}}
{{- $values := deepCopy $ | merge (dict "collectorName" $collector) }}
{{- $alloyConfig := "" }}
{{- $alloyConfig = cat $alloyConfig (include "destinations.alloy.config" (deepCopy $ | merge (dict "names" $destinations)) | trim | nindent 0) }}
{{- range $feature := include "features.list" . | fromYamlArray }}
{{- if has $collector (include (printf "features.%s.collectors" $feature) $ | fromYamlArray ) }}
{{ $alloyConfig = cat $alloyConfig (include (printf "features.%s.include" $feature) $values | trim | nindent 0) }}
{{- end }}
{{- end }}
{{- $alloyConfig = cat $alloyConfig (include "collectors.logging.alloy" $values | trim | nindent 0) }}
{{- $alloyConfig = cat $alloyConfig (include "collectors.liveDebugging.alloy" $values | trim | nindent 0) }}
{{- $alloyConfig = cat $alloyConfig (include "collectors.remoteConfig.alloy" $values | trim | nindent 0) }}
{{- $alloyConfig = cat $alloyConfig (include "collectors.extraConfig.alloy" $values | trim | nindent 0) }}
{{/* Remove all trailing whitespace */}}
{{- $alloyConfig = regexReplaceAll `[ \t]+(\r?\n)` $alloyConfig "\n" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "alloy.fullname" (index $.Subcharts $collector) }}
namespace: {{ $.Release.Namespace }}
data:
config.alloy: |-
{{- $alloyConfig | trim | nindent 4 }}
{{ if $selfReportingEnabled }}
self-reporting-metric.prom: |
{{- include "features.selfReporting.metrics" $values | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,29 @@
{{- if eq .Values.global.alloyModules.source "configMap" }}
{{- $configMaps := dict }}
{{- $modules := list }}
{{- range $feature := (include "features.list.enabled" .) | fromYamlArray }}
{{- $modules = $modules | concat (include (printf "feature.%s.alloyModules" $feature) (dict "Values" (index $.Values $feature)) | fromYamlArray) }}
{{- end }}
{{- range $module := uniq $modules }}
{{- $pathParts := regexSplit "/" $module -1 }}
{{- $configMapName := printf "%s-alloy-module-%s" $.Release.Name (index $pathParts 1) }}
{{- if not (hasKey $configMaps $configMapName) }}
{{- $configMaps = $configMaps | merge (dict $configMapName (list $module)) }}
{{- else }}
{{- $configMaps = $configMaps | merge (dict $configMapName (append (index $configMaps $configMapName) $module)) }}
{{- end }}
{{- end }}
{{- range $configMapName := (keys $configMaps | sortAlpha) }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ $configMapName }}
data:
{{- range $path := (index $configMaps $configMapName) }}
{{- $pathParts := regexSplit "/" $path -1 }}
{{- $moduleFile := (slice $pathParts 2) | join "_" }}
{{ $moduleFile }}: |{{ $.Files.Get (printf "alloyModules/%s" $path) | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,41 @@
{{- if .Values.autoInstrumentation.enabled }}
{{- $config := .Values.autoInstrumentation.beyla.config.data }}
{{- $attributes := dict "kubernetes" (dict "enable" true "cluster_name" .Values.cluster.name) }}
{{- $internalMetrics := dict "prometheus" (dict "port" .Values.autoInstrumentation.beyla.service.targetPort) }}
{{- $prometheusExport := dict "port" .Values.autoInstrumentation.beyla.service.targetPort }}
{{- $overrides := dict "attributes" $attributes "internal_metrics" $internalMetrics "prometheus_export" $prometheusExport }}
{{- if and (eq .Values.autoInstrumentation.beyla.preset "network") (not .Values.autoInstrumentation.beyla.config.data.network) }}
{{- $network := dict "enable" true }}
{{- $overrides = merge $overrides (dict "network" $network) }}
{{- end }}
{{- if and (eq .Values.autoInstrumentation.beyla.preset "application") (not .Values.autoInstrumentation.beyla.config.data.discovery) }}
{{- $services := list (dict "k8s_namespace" ".") }}
{{- $excludeServices := list (dict "exe_path" ".*alloy.*|.*otelcol.*|.*beyla.*") }}
{{- $discovery := dict "services" $services "exclude_services" $excludeServices }}
{{- $overrides = merge $overrides (dict "discovery" $discovery) }}
{{- end }}
{{- $grpcReceiverEndpoint := include "features.applicationObservability.receiver.grpc" . | trim }}
{{- $httpReceiverEndpoint := include "features.applicationObservability.receiver.http" . | trim }}
{{- if or $grpcReceiverEndpoint $httpReceiverEndpoint }}
{{- $otelTracesExport := dict "endpoint" ($grpcReceiverEndpoint | default $httpReceiverEndpoint) }}
{{- $overrides = merge $overrides (dict "otel_traces_export" $otelTracesExport) }}
{{- end }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "beyla.fullname" .Subcharts.autoInstrumentation.Subcharts.beyla }}
namespace: {{ include "beyla.namespace" .Subcharts.autoInstrumentation.Subcharts.beyla }}
labels:
{{- include "beyla.labels" .Subcharts.autoInstrumentation.Subcharts.beyla | nindent 4 }}
app.kubernetes.io/component: config
{{- with .Values.autoInstrumentation.beyla.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
beyla-config.yml: |-
{{- (merge $config $overrides) | toYaml | nindent 4 }}
{{- end }}

View File

@ -0,0 +1,24 @@
{{/* Define the logging component.*/}}
{{/* Inputs: collectorName (string), Values */}}
{{- define "collectors.logging.alloy" }}
{{- with (index .Values .collectorName).logging }}
{{- if or (ne .level "info" ) (ne .format "logfmt") }}
logging {
level = "{{ .level }}"
format = "{{ .format }}"
}
{{- end }}
{{- end }}
{{- end }}
{{/* Define the livedebugging component.*/}}
{{/* Inputs: collectorName (string), Values */}}
{{- define "collectors.liveDebugging.alloy" }}
{{- with (index .Values .collectorName).liveDebugging }}
{{- if .enabled }}
livedebugging {
enabled = {{ .enabled }}
}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,5 @@
{{- define "collectors.extraConfig.alloy" -}}
{{- if (index .Values .collectorName).extraConfig }}
{{ (index .Values .collectorName).extraConfig | trim }}
{{- end }}
{{- end -}}

View File

@ -0,0 +1,52 @@
{{- define "collectors.list" -}}
- alloy-metrics
- alloy-singleton
- alloy-logs
- alloy-receiver
- alloy-profiles
{{- end }}
{{- define "collectors.list.enabled" -}}
{{- range $collector := ((include "collectors.list" .) | fromYamlArray ) }}
{{- if (index $.Values $collector).enabled }}
- {{ $collector }}
{{- end }}
{{- end }}
{{- end }}
{{/* Inputs: Values (all values), name (collector name), feature (feature name) */}}
{{- define "collectors.require_collector" -}}
{{- if not (index .Values .name).enabled }}
{{- $msg := list "" }}
{{- $msg = append $msg (printf "The %s feature requires the use of the %s collector." .feature .name ) }}
{{- $msg = append $msg "" }}
{{- $msg = append $msg "Please enable it by setting:" }}
{{- $msg = append $msg (printf "%s:" .name) }}
{{- $msg = append $msg " enabled: true" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{/* Inputs: Values (all values), name (collector name), feature (feature name), portNumber, portName, portProtocol */}}
{{- define "collectors.require_extra_port" -}}
{{- $found := false -}}
{{- range (index .Values .name).alloy.extraPorts -}}
{{- if eq (int .targetPort) (int $.portNumber) }}
{{- $found = true -}}
{{- end }}
{{- end }}
{{- if not $found }}
{{- $msg := list "" }}
{{- $msg = append $msg (printf "The %s feature requires that port %d to be open on the %s collector." .feature (.portNumber | int) .name ) }}
{{- $msg = append $msg "" }}
{{- $msg = append $msg "Please enable it by setting:" }}
{{- $msg = append $msg (printf "%s:" .name) }}
{{- $msg = append $msg " alloy:" }}
{{- $msg = append $msg " extraPorts:" }}
{{- $msg = append $msg (printf " - name: %s" .portName) }}
{{- $msg = append $msg (printf " port: %d" (.portNumber | int)) }}
{{- $msg = append $msg (printf " targetPort: %d" (.portNumber | int)) }}
{{- $msg = append $msg (printf " protocol: %s" .portProtocol) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- define "collectors.notes.deployments" }}
{{- range $collector := include "collectors.list.enabled" . | fromYamlArray }}
{{- $type := (index $.Values $collector).controller.type }}
{{- $replicas := (index $.Values $collector).controller.replicas | default 1 | int }}
{{- if ne $type "daemonset" }}
{{- $type = printf "%s, %d replica" $type $replicas }}
{{- if gt $replicas 1 }}{{- $type = printf "%ss" $type }}{{- end }}
{{- end }}
* Grafana Alloy "{{ $collector }}" ({{ $type }})
{{- end }}
{{- end }}

View File

@ -0,0 +1,81 @@
{{- define "collectors.remoteConfig.alloy" -}}
{{- $remoteConfigValues := (index .Values .collectorName).remoteConfig }}
{{- with merge $remoteConfigValues (dict "type" "remoteConfig" "name" (printf "%s-remote-cfg" .collectorName)) }}
{{- if .enabled }}
{{- if eq (include "secrets.usesKubernetesSecret" .) "true" }}
{{- include "secret.alloy" (deepCopy $ | merge (dict "object" .)) | nindent 0 }}
{{- end }}
remotecfg {
id = sys.env("GCLOUD_FM_COLLECTOR_ID")
url = {{ .url | quote }}
{{- if eq (include "secrets.authType" .) "basic" }}
basic_auth {
username = {{ include "secrets.read" (dict "object" . "key" "auth.username" "nonsensitive" true) }}
password = {{ include "secrets.read" (dict "object" . "key" "auth.password") }}
}
{{- end }}
poll_frequency = {{ .pollFrequency | quote }}
attributes = {
"platform" = "kubernetes",
"source" = "{{ $.Chart.Name }}",
"sourceVersion" = "{{ $.Chart.Version }}",
"release" = "{{ $.Release.Name }}",
"cluster" = {{ $.Values.cluster.name | quote }},
"namespace" = {{ $.Release.Namespace | quote }},
"workloadType" = {{ (index $.Values $.collectorName).controller.type | quote }},
{{- range $key, $value := .extraAttributes }}
{{ $key | quote }} = {{ $value | quote }},
{{- end }}
}
}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "collectors.validate.remoteConfig" }}
{{- if (index .Values .collectorName).enabled }}
{{- if (index .Values .collectorName).remoteConfig.enabled }}
{{- if not (has (index .Values .collectorName).alloy.stabilityLevel (list "public-preview" "experimental")) }}
{{- $msg := list "" "The remote configuration feature requires Alloy to use the \"public-preview\" stability level. Please set:" }}
{{- $msg = append $msg (printf "%s:" .collectorName ) }}
{{- $msg = append $msg " alloy:" }}
{{- $msg = append $msg " stabilityLevel: public-preview" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $hasCollectorIdEnv := false }}
{{- $hasAPIKey := false }}
{{- range $env := (index .Values .collectorName).alloy.extraEnv }}
{{- if eq $env.name "GCLOUD_FM_COLLECTOR_ID" }}{{ $hasCollectorIdEnv = true }}{{- end }}
{{- if eq $env.name "GCLOUD_RW_API_KEY" }}{{ $hasAPIKey = true }}{{- end }}
{{- end }}
{{- if not $hasCollectorIdEnv }}
{{- $msg := list "" "The remote configuration feature requires the environment variable GCLOUD_FM_COLLECTOR_ID to be set. Please set:" }}
{{- $msg = append $msg (printf "%s:" .collectorName ) }}
{{- $msg = append $msg " alloy:" }}
{{- $msg = append $msg " extraEnv:" }}
{{- $msg = append $msg " - name: GCLOUD_FM_COLLECTOR_ID" }}
{{- $msg = append $msg " value: " }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- if not $hasAPIKey }}
{{- $msg := list "" "The remote configuration feature requires the environment variable GCLOUD_RW_API_KEY to be set. Please set:" }}
{{- $msg = append $msg (printf "%s:" .collectorName ) }}
{{- $msg = append $msg " alloy:" }}
{{- $msg = append $msg " extraEnv:" }}
{{- $msg = append $msg " - name: GCLOUD_RW_API_KEY" }}
{{- $msg = append $msg " value: <Grafana Cloud Access Policy Token" }}
{{- $msg = append $msg "OR" }}
{{- $msg = append $msg " valueFrom:" }}
{{- $msg = append $msg " secretKeyRef:" }}
{{- $msg = append $msg " name: <secret name>" }}
{{- $msg = append $msg " key: <secret key>" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- define "secrets.list.remoteConfig" -}}
- auth.username
- auth.password
{{- end -}}

View File

@ -0,0 +1,34 @@
{{- define "collectors.validate.featuresEnabled" }}
{{- $msg := list "" "The %s collector is enabled, but there are no enabled features that will use it. Please disable the collector by setting:" }}
{{- $msg = append $msg "%s:" }}
{{- $msg = append $msg " enabled: false" }}
{{- $errorMessage := join "\n" $msg }}
{{- $collectorsUtilized := list }}
{{- range $feature := include "features.list.enabled" . | fromYamlArray }}
{{- $collectorsUtilized = concat $collectorsUtilized (include (printf "features.%s.collectors" $feature) $ | fromYamlArray) }}
{{- end }}
{{- range $collector := include "collectors.list.enabled" . | fromYamlArray }}
{{- $usedByAFeature := has $collector $collectorsUtilized }}
{{- $extraConfigDefined := not (not (index $.Values $collector).extraConfig) }}
{{- $remoteConfigEnabled := (index $.Values $collector).remoteConfig.enabled }}
{{- if not (or $usedByAFeature $extraConfigDefined $remoteConfigEnabled) }}
{{- fail (printf $errorMessage $collector $collector) }}
{{- end }}
{{- end }}
{{- end }}
{{- define "collectors.validate.liveDebugging" }}
{{- if (index .Values .collectorName).enabled }}
{{- if (index .Values .collectorName).liveDebugging.enabled }}
{{- if not (eq (index .Values .collectorName).alloy.stabilityLevel "experimental") }}
{{- $msg := list "" "The live debugging feature requires Alloy to use the \"experimental\" stability level. Please set:" }}
{{- $msg = append $msg (printf "%s:" .collectorName ) }}
{{- $msg = append $msg " alloy:" }}
{{- $msg = append $msg " stabilityLevel: experimental" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,19 @@
{{- range $destination := $.Values.destinations }}
{{- if eq (include "secrets.shouldCreateKubernetesSecret" $destination ) "true" }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "secrets.kubernetesSecretName" (deepCopy $ | merge (dict "object" $destination)) | quote }}
namespace: {{ include "secrets.kubernetesSecretNamespace" (deepCopy $ | merge (dict "object" $destination)) | quote }}
type: Opaque
data:
{{- $secrets := include (printf "secrets.list.%s" $destination.type) . | fromYamlArray }}
{{- range $secret := $secrets }}
{{- $value := include "secrets.getSecretValue" (dict "object" $destination "key" $secret) -}}
{{- if $value }}
{{ include "secrets.getSecretKey" (dict "object" $destination "key" $secret) }}: {{ $value | b64enc | quote }}
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,26 @@
{{/* Returns an alloy-formatted array of destination targets given the name */}}
{{/* Inputs: destinations (array of destination definition), names ([]string), type (string) ecosystem (string) */}}
{{- define "destinations.alloy.targets" -}}
{{- range $destination := .destinations }}
{{- if (has $destination.name $.names ) }}
{{- if eq (include (printf "destinations.%s.supports_%s" $destination.type $.type) $destination) "true" }}
{{ include (printf "destinations.%s.alloy.%s.%s.target" $destination.type $.ecosystem $.type) $destination | trim }},
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{/* Adds the Alloy components for destinations */}}
{{/*Inputs: destinations (array of destination definition), names([]string) clusterName (string), Release (Release object) Chart (Chart object) Files (Files object) */}}
{{- define "destinations.alloy.config" }}
{{- range $destination := .Values.destinations }}
{{- if (has $destination.name $.names ) }}
// Destination: {{ $destination.name }} ({{ $destination.type }})
{{- include (printf "destinations.%s.alloy" $destination.type) (deepCopy $ | merge (dict "destination" $destination)) | indent 0 }}
{{- if eq (include "secrets.usesKubernetesSecret" $destination) "true" }}
{{- include "secret.alloy" (deepCopy $ | merge (dict "object" $destination)) | nindent 0 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,40 @@
{{/* Inputs: destinations (array of destination names), type (string), feature (string) */}}
{{- define "destinations.validate_destination_list" -}}
{{- if empty .destinations }}
{{- $msg := list "" (printf "No destinations found that can accept %s from %s" .type .feature) }}
{{- $msg = append $msg (printf "Please add a destination with %s support." .type) }}
{{- $msg = append $msg "See https://github.com/grafana/k8s-monitoring-helm/blob/main/charts/k8s-monitoring/docs/destinations/README.md for more details." }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{/* Inputs: destinations (array of destination definition), type (string), ecosystem (string), filter (list of destination names) */}}
{{- define "destinations.get" -}}
{{- $destinations := list }}
{{- $backupDestinations := list }}
{{- range $destination := .destinations }}
{{- /* Does this destination support the telemetry data type? */}}
{{- if eq (include (printf "destinations.%s.supports_%s" $destination.type $.type) $destination) "true" }}
{{- if empty $.filter }}
{{- /* Is this destination in the ecosystem? */}}
{{- if eq $.ecosystem (include (printf "destinations.%s.ecosystem" $destination.type) .) }}
{{- $destinations = append $destinations $destination.name }}
{{- else }}
{{- $backupDestinations = append $backupDestinations $destination.name }}
{{- end }}
{{- /* Did the data source choose this destination? */}}
{{- else if has $destination.name $.filter }}
{{- $destinations = append $destinations $destination.name }}
{{- end }}
{{- end }}
{{- end }}
{{- if not (empty $destinations) }}
{{- $destinations | toYaml | indent 0 }}
{{- end }}
{{- /* Output non-ecosystem matching destinations if no ecosystem destinations are found */}}
{{- if and (empty $destinations) (not (empty $backupDestinations)) }}
{{- $backupDestinations | toYaml | indent 0 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,148 @@
{{- define "destinations.loki.alloy" }}
{{- $defaultValues := "destinations/loki-values.yaml" | .Files.Get | fromYaml }}
{{- with merge .destination $defaultValues }}
otelcol.exporter.loki {{ include "helper.alloy_name" .name | quote }} {
forward_to = [{{ include "destinations.loki.alloy.loki.logs.target" . }}]
}
{{- if .logProcessingStages }}
loki.process {{ include "helper.alloy_name" .name | quote }} {
{{ .logProcessingStages | indent 2 }}
forward_to = [loki.write.{{ include "helper.alloy_name" .name }}.receiver]
}
{{- end }}
loki.write {{ include "helper.alloy_name" .name | quote }} {
endpoint {
{{- if .urlFrom }}
url = {{ .urlFrom }}
{{- else }}
url = {{ .url | quote }}
{{- end }}
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "tenantId")) "true" }}
tenant_id = {{ include "secrets.read" (dict "object" . "key" "tenantId" "nonsensitive" true) }}
{{- end }}
{{- if or .extraHeaders .extraHeadersFrom }}
headers = {
{{- range $key, $value := .extraHeaders }}
{{ $key | quote }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraHeadersFrom }}
{{ $key | quote }} = {{ $value }},
{{- end }}
}
{{- end }}
{{- if .proxyURL }}
proxy_url = {{ .proxyURL | quote }}
{{- end }}
{{- if eq (include "secrets.authType" .) "basic" }}
basic_auth {
username = {{ include "secrets.read" (dict "object" . "key" "auth.username" "nonsensitive" true) }}
password = {{ include "secrets.read" (dict "object" . "key" "auth.password") }}
}
{{- else if eq (include "secrets.authType" .) "bearerToken" }}
{{- if .auth.bearerTokenFile }}
bearer_token_file = {{ .auth.bearerTokenFile | quote }}
{{- else }}
bearer_token = {{ include "secrets.read" (dict "object" . "key" "auth.bearerToken") }}
{{- end }}
{{- else if eq (include "secrets.authType" .) "oauth2" }}
oauth2 {
client_id = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientId" "nonsensitive" true) }}
{{- if eq .auth.oauth2.clientSecretFile "" }}
client_secret = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientSecret") }}
{{- else }}
client_secret_file = {{ .auth.oauth2.clientSecretFile | quote }}
{{- end }}
{{- if .auth.oauth2.endpointParams }}
endpoint_params = {
{{- range $k, $v := .auth.oauth2.endpointParams }}
{{ $k }} = {{ $v | toJson }},
{{- end }}
}
{{- end }}
{{- if .auth.oauth2.proxyURL }}
proxy_url = {{ .auth.oauth2.proxyURL | quote }}
{{- end }}
{{- if .auth.oauth2.noProxy }}
no_proxy = {{ .auth.oauth2.noProxy | quote }}
{{- end }}
{{- if .auth.oauth2.proxyFromEnvironment }}
proxyFromEnvironment = {{ .auth.oauth2.proxyFromEnvironment }}
{{- end }}
{{- if .auth.oauth2.proxyConnectHeader }}
proxy_connect_header = {{ .auth.oauth2.proxyConnectHeader | toJson }}
{{- end }}
{{- if .auth.oauth2.scopes }}
scopes = {{ .auth.oauth2.scopes | toJson }}
{{- end }}
{{- if .auth.oauth2.tokenURL }}
token_url = {{ .auth.oauth2.tokenURL | quote }}
{{- end }}
}
{{- end }}
{{- if .tls }}
tls_config {
insecure_skip_verify = {{ .tls.insecureSkipVerify | default false }}
{{- if .tls.caFile }}
ca_file = {{ .tls.caFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.ca")) "true" }}
ca_pem = {{ include "secrets.read" (dict "object" . "key" "tls.ca" "nonsensitive" true) }}
{{- end }}
{{- if .tls.certFile }}
cert_file = {{ .tls.certFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.cert")) "true" }}
cert_pem = {{ include "secrets.read" (dict "object" . "key" "tls.cert" "nonsensitive" true) }}
{{- end }}
{{- if .tls.keyFile }}
key_file = {{ .tls.keyFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.key")) "true" }}
key_pem = {{ include "secrets.read" (dict "object" . "key" "tls.key") }}
{{- end }}
}
{{- end }}
}
external_labels = {
cluster = {{ $.Values.cluster.name | quote }},
"k8s_cluster_name" = {{ $.Values.cluster.name | quote }},
{{- if .extraLabels }}
{{- range $k, $v := .extraLabels }}
{{ $k }} = {{ $v | quote }},
{{- end }}
{{- end }}
{{- if .extraLabelsFrom }}
{{- range $k, $v := .extraLabelsFrom }}
{{ $k }} = {{ $v }},
{{- end }}
{{- end }}
}
}
{{- end }}
{{- end }}
{{- define "secrets.list.loki" -}}
- tenantId
- auth.username
- auth.password
- auth.bearerToken
- auth.oauth2.clientId
- auth.oauth2.clientSecret
- tls.ca
- tls.cert
- tls.key
{{- end -}}
{{- define "destinations.loki.alloy.loki.logs.target" }}
{{- if .logProcessingStages -}}
loki.process.{{ include "helper.alloy_name" .name }}.receiver
{{- else -}}
loki.write.{{ include "helper.alloy_name" .name }}.receiver
{{- end -}}
{{- end -}}
{{- define "destinations.loki.alloy.otlp.logs.target" }}otelcol.exporter.loki.{{ include "helper.alloy_name" .name }}.input{{ end -}}
{{- define "destinations.loki.supports_metrics" }}false{{ end -}}
{{- define "destinations.loki.supports_logs" }}true{{ end -}}
{{- define "destinations.loki.supports_traces" }}false{{ end -}}
{{- define "destinations.loki.supports_profiles" }}false{{ end -}}
{{- define "destinations.loki.ecosystem" }}loki{{ end -}}

View File

@ -0,0 +1,422 @@
{{- define "destinations.otlp.alloy" }}
{{- $defaultValues := "destinations/otlp-values.yaml" | .Files.Get | fromYaml }}
{{- with merge .destination $defaultValues }}
{{- if eq (include "destinations.otlp.supports_metrics" .) "true" }}
otelcol.receiver.prometheus {{ include "helper.alloy_name" .name | quote }} {
output {
metrics = [{{ include "destinations.otlp.alloy.otlp.metrics.target" . | trim }}]
}
}
{{- end }}
{{- if eq (include "destinations.otlp.supports_logs" .) "true" }}
otelcol.receiver.loki {{ include "helper.alloy_name" .name | quote }} {
output {
logs = [{{ include "destinations.otlp.alloy.otlp.logs.target" . | trim }}]
}
}
{{- end }}
{{- if eq (include "secrets.authType" .) "basic" }}
otelcol.auth.basic {{ include "helper.alloy_name" .name | quote }} {
username = {{ include "secrets.read" (dict "object" . "key" "auth.username" "nonsensitive" true) }}
password = {{ include "secrets.read" (dict "object" . "key" "auth.password") }}
}
{{- else if eq (include "secrets.authType" .) "bearerToken" }}
{{- if .auth.bearerTokenFile }}
local.file {{ include "helper.alloy_name" .name | quote }} {
filename = {{ .auth.bearerTokenFile | quote }}
}
otelcol.auth.bearer {{ include "helper.alloy_name" .name | quote }} {
token = local.file.{{ include "helper.alloy_name" .name }}.content
}
{{- else }}
otelcol.auth.bearer {{ include "helper.alloy_name" .name | quote }} {
token = {{ include "secrets.read" (dict "object" . "key" "auth.bearerToken") }}
}
{{- end }}
{{- else if eq (include "secrets.authType" .) "oauth2" }}
otelcol.auth.oauth2 {{ include "helper.alloy_name" .name | quote }} {
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "auth.oauth2.clientId")) "true" }}
client_id = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientId" "nonsensitive" true) }}
{{- end }}
{{- if .auth.oauth2.clientSecretFile }}
client_secret_file = {{ .auth.oauth2.clientSecretFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "auth.oauth2.clientSecret")) "true" }}
client_secret = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientSecret") }}
{{- end }}
{{- if .auth.oauth2.endpointParams }}
endpoint_params = {
{{- range $k, $v := .auth.oauth2.endpointParams }}
{{ $k }} = {{ $v | toJson }},
{{- end }}
}
{{- end }}
{{- if .auth.oauth2.scopes }}
scopes = {{ .auth.oauth2.scopes | toJson }}
{{- end }}
{{- if .auth.oauth2.tokenURL }}
token_url = {{ .auth.oauth2.tokenURL | quote }}
{{- end }}
}
{{- end }}
otelcol.processor.attributes {{ include "helper.alloy_name" .name | quote }} {
{{- range $action := .processors.attributes.actions }}
action {
key = {{ $action.key | quote }}
action = {{ $action.action | quote }}
{{- if $action.value }}
value = {{ $action.value | quote }}
{{- else if $action.valueFrom }}
value = {{ $action.valueFrom }}
{{- end }}
{{- if $action.pattern }}
pattern = {{ $action.pattern | quote }}
{{- end }}
{{- if $action.fromAttribute }}
from_attribute = {{ $action.fromAttribute | quote }}
{{- end }}
{{- if $action.fromContext }}
from_context = {{ $action.fromContext | quote }}
{{- end }}
{{- if $action.convertedType }}
converted_type = {{ $action.convertedType | quote }}
{{- end }}
}
{{- end }}
output {
metrics = [otelcol.processor.transform.{{ include "helper.alloy_name" .name }}.input]
logs = [otelcol.processor.transform.{{ include "helper.alloy_name" .name }}.input]
traces = [otelcol.processor.transform.{{ include "helper.alloy_name" .name }}.input]
}
}
otelcol.processor.transform {{ include "helper.alloy_name" .name | quote }} {
error_mode = "ignore"
{{- if ne .metrics.enabled false }}
metric_statements {
context = "resource"
statements = [
`set(attributes["cluster"], {{ $.Values.cluster.name | quote }})`,
`set(attributes["k8s.cluster.name"], {{ $.Values.cluster.name | quote }})`,
{{- if .processors.transform.metrics.resource }}
{{- range $transform := .processors.transform.metrics.resource }}
{{ $transform | quote | indent 6 }},
{{- end }}
{{- end }}
]
}
{{- if .processors.transform.metrics.metric }}
metric_statements {
context = "metric"
statements = [
{{- range $transform := .processors.transform.metrics.metric }}
{{ $transform | quote | indent 6 }},
{{- end }}
]
}
{{- end }}
metric_statements {
context = "datapoint"
statements = [
`set(attributes["cluster"], {{ $.Values.cluster.name | quote }})`,
`set(attributes["k8s.cluster.name"], {{ $.Values.cluster.name | quote }})`,
{{- if .processors.transform.metrics.datapoint }}
{{- range $transform := .processors.transform.metrics.datapoint }}
{{ $transform | quote | indent 6 }},
{{- end }}
{{- end }}
]
}
{{- end }}
{{- if ne .logs.enabled false }}
log_statements {
context = "resource"
statements = [
`set(attributes["cluster"], {{ $.Values.cluster.name | quote }})`,
`set(attributes["k8s.cluster.name"], {{ $.Values.cluster.name | quote }})`,
{{- if .processors.transform.logs.resource }}
{{- range $transform := .processors.transform.logs.resource }}
{{ $transform | quote | indent 6 }},
{{- end }}
{{- end }}
]
}
log_statements {
context = "log"
statements = [
`delete_key(attributes, "loki.attribute.labels")`,
`set(resource.attributes["service.name"], attributes["service_name"]) where resource.attributes["service.name"] == nil and attributes["service_name"] != nil`,
`delete_key(attributes, "service_name") where attributes["service_name"] != nil`,
`set(resource.attributes["service.namespace"], attributes["service_namespace"] ) where resource.attributes["service.namespace"] == nil and attributes["service_namespace"] != nil`,
`delete_key(attributes, "service_namespace") where attributes["service_namespace"] != nil`,
`set(resource.attributes["deployment.environment.name"], attributes["deployment_environment_name"] ) where resource.attributes["deployment.environment.name"] == nil and attributes["deployment_environment_name"] != nil`,
`delete_key(attributes, "deployment_environment_name") where attributes["deployment_environment_name"] != nil`,
`set(resource.attributes["deployment.environment"], attributes["deployment_environment"] ) where resource.attributes["deployment.environment"] == nil and attributes["deployment_environment"] != nil`,
`delete_key(attributes, "deployment_environment") where attributes["deployment_environment"] != nil`,
{{- if .processors.transform.logs.log }}
{{- range $transform := .processors.transform.logs.log }}
{{ $transform | quote | indent 6 }},
{{- end }}
{{- end }}
]
}
{{- if .processors.transform.logs.scope }}
log_statements {
context = "scope"
statements = [
{{- range $transform := .processors.transform.logs.scope }}
{{ $transform | quote | indent 6 }},
{{- end }}
]
}
{{- end }}
{{- end }}
{{- if ne .traces.enabled false }}
trace_statements {
context = "resource"
statements = [
`set(attributes["cluster"], {{ $.Values.cluster.name | quote }})`,
`set(attributes["k8s.cluster.name"], {{ $.Values.cluster.name | quote }})`,
{{- if .processors.transform.traces.resource }}
{{- range $transform := .processors.transform.traces.resource }}
{{ $transform | quote | indent 6 }},
{{- end }}
{{- end }}
]
}
{{- if .processors.transform.traces.span }}
trace_statements {
context = "span"
statements = [
{{- range $transform := .processors.transform.traces.span }}
{{ $transform | quote | indent 6 }},
{{- end }}
]
}
{{- end }}
{{- if .processors.transform.traces.spanevent }}
trace_statements {
context = "spanevent"
statements = [
{{- range $transform := .processors.transform.traces.spanevent }}
{{ $transform | quote | indent 6 }},
{{- end }}
]
}
{{- end }}
{{- end }}
{{- if .processors.filters.enabled }}
output {
{{- if ne .metrics.enabled false }}
metrics = [otelcol.processor.filter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .logs.enabled false }}
logs = [otelcol.processor.filter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .traces.enabled false }}
traces = [otelcol.processor.filter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
}
}
otelcol.processor.filter {{ include "helper.alloy_name" .name | quote }} {
{{- if and .metrics.enabled (or .processors.filters.metrics.metric .processors.filters.metrics.datapoint) }}
metrics {
{{- if .processors.filters.metrics.metric }}
metric = [
{{- range $filter := .processors.filters.metrics.metric }}
{{ $filter | quote | indent 6 }},
{{- end }}
]
{{- end }}
{{- if .processors.filters.metrics.datapoint }}
datapoint = [
{{- range $filter := .processors.filters.metrics.datapoint }}
{{ $filter | quote | indent 6 }},
{{- end }}
]
{{- end }}
}
{{- end }}
{{- if and .logs.enabled .processors.filters.logs.log_record }}
logs {
log_record = [
{{- range $filter := .processors.filters.logs.log_record }}
{{ $filter | quote | indent 6 }},
{{- end }}
]
}
{{- end }}
{{- if and .traces.enabled (or .processors.filters.traces.span .processors.filters.traces.spanevent) }}
traces {
{{- if .processors.filters.traces.span }}
span = [
{{- range $filter := .processors.filters.traces.span }}
{{ $filter | quote | indent 6 }},
{{- end }}
]
{{- end }}
{{- if .processors.filters.traces.spanevent }}
spanevent = [
{{- range $filter := .processors.filters.traces.spanevent }}
{{ $filter | quote | indent 6 }},
{{- end }}
]
{{- end }}
}
{{- end }}
{{- end }}
{{- if .processors.batch.enabled }}
output {
{{- if ne .metrics.enabled false }}
metrics = [otelcol.processor.batch.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .logs.enabled false }}
logs = [otelcol.processor.batch.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .traces.enabled false }}
traces = [otelcol.processor.batch.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
}
}
otelcol.processor.batch {{ include "helper.alloy_name" .name | quote }} {
timeout = {{ .processors.batch.timeout | quote }}
send_batch_size = {{ .processors.batch.size | int }}
send_batch_max_size = {{ .processors.batch.maxSize | int }}
{{- end }}
{{- if .processors.memoryLimiter.enabled }}
output {
{{- if ne .metrics.enabled false }}
metrics = [otelcol.processor.memory_limiter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .logs.enabled false }}
logs = [otelcol.processor.memory_limiter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
{{- if ne .traces.enabled false }}
traces = [otelcol.processor.memory_limiter.{{ include "helper.alloy_name" .name }}.input]
{{- end }}
}
}
otelcol.processor.memory_limiter {{ include "helper.alloy_name" .name | quote }} {
check_interval = {{ .processors.memoryLimiter.checkInterval | quote }}
limit = {{ .processors.memoryLimiter.limit | quote }}
{{- end }}
output {
{{- $target := "" }}
{{- if eq .protocol "grpc" }}
{{- $target = printf "otelcol.exporter.otlp.%s.input" (include "helper.alloy_name" .name) }}
{{- else if eq .protocol "http" }}
{{- $target = printf "otelcol.exporter.otlphttp.%s.input" (include "helper.alloy_name" .name) }}
{{- end }}
{{- if ne .metrics.enabled false }}
metrics = [{{ $target }}]
{{- end }}
{{- if ne .logs.enabled false }}
logs = [{{ $target }}]
{{- end }}
{{- if ne .traces.enabled false }}
traces = [{{ $target }}]
{{- end }}
}
}
{{- if eq .protocol "grpc" }}
otelcol.exporter.otlp {{ include "helper.alloy_name" .name | quote }} {
{{- else if eq .protocol "http" }}
otelcol.exporter.otlphttp {{ include "helper.alloy_name" .name | quote }} {
{{- end }}
client {
{{- if .urlFrom }}
endpoint = {{ .urlFrom }}
{{- else }}
endpoint = {{ .url | quote }}
{{- end }}
{{- if eq .auth.type "basic" }}
auth = otelcol.auth.basic.{{ include "helper.alloy_name" .name }}.handler
{{- else if eq .auth.type "bearerToken" }}
auth = otelcol.auth.bearer.{{ include "helper.alloy_name" .name }}.handler
{{- else if eq .auth.type "oauth2" }}
auth = otelcol.auth.oauth2.{{ include "helper.alloy_name" .name }}.handler
{{- end }}
{{- if or (eq (include "secrets.usesSecret" (dict "object" . "key" "tenantId")) "true") .extraHeaders .extraHeadersFrom }}
headers = {
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "tenantId")) "true" }}
"X-Scope-OrgID" = {{ include "secrets.read" (dict "object" . "key" "tenantId" "nonsensitive" true) }},
{{- end }}
{{- range $key, $value := .extraHeaders }}
{{ $key | quote }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraHeadersFrom }}
{{ $key | quote }} = {{ $value }},
{{- end }}
}
{{- end }}
{{- if .readBufferSize }}
read_buffer_size = {{ .readBufferSize | quote }}
{{- end }}
{{- if .writeBufferSize }}
write_buffer_size = {{ .writeBufferSize | quote }}
{{- end }}
{{- if .tls }}
tls {
insecure = {{ .tls.insecure | default false }}
insecure_skip_verify = {{ .tls.insecureSkipVerify | default false }}
{{- if .tls.caFile }}
ca_file = {{ .tls.caFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.ca")) "true" }}
ca_pem = {{ include "secrets.read" (dict "object" . "key" "tls.ca" "nonsensitive" true) }}
{{- end }}
{{- if .tls.certFile }}
cert_file = {{ .tls.certFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.cert")) "true" }}
cert_pem = {{ include "secrets.read" (dict "object" . "key" "tls.cert" "nonsensitive" true) }}
{{- end }}
{{- if .tls.keyFile }}
key_file = {{ .tls.keyFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.key")) "true" }}
key_pem = {{ include "secrets.read" (dict "object" . "key" "tls.key") }}
{{- end }}
}
{{- end }}
}
}
{{- end }}
{{- end }}
{{- define "secrets.list.otlp" -}}
- tenantId
- auth.username
- auth.password
- auth.bearerToken
- auth.oauth2.clientId
- auth.oauth2.clientSecret
- tls.ca
- tls.cert
- tls.key
{{- end -}}
{{- define "destinations.otlp.alloy.prometheus.metrics.target" }}otelcol.receiver.prometheus.{{ include "helper.alloy_name" .name }}.receiver{{ end }}
{{- define "destinations.otlp.alloy.loki.logs.target" }}otelcol.receiver.loki.{{ include "helper.alloy_name" .name }}.receiver{{ end }}
{{- define "destinations.otlp.alloy.otlp.target" }}otelcol.processor.attributes.{{ include "helper.alloy_name" .name }}.input{{ end }}
{{- define "destinations.otlp.alloy.otlp.metrics.target" }}{{ include "destinations.otlp.alloy.otlp.target" . }}{{- end }}
{{- define "destinations.otlp.alloy.otlp.logs.target" }}{{ include "destinations.otlp.alloy.otlp.target" . }}{{- end }}
{{- define "destinations.otlp.alloy.otlp.traces.target" }}{{ include "destinations.otlp.alloy.otlp.target" . }}{{- end }}
{{- define "destinations.otlp.supports_metrics" }}{{ dig "metrics" "enabled" "false" . }}{{ end -}}
{{- define "destinations.otlp.supports_logs" }}{{ dig "logs" "enabled" "false" . }}{{ end -}}
{{- define "destinations.otlp.supports_traces" }}{{ dig "traces" "enabled" "true" . }}{{ end -}}
{{- define "destinations.otlp.supports_profiles" }}false{{ end -}}
{{- define "destinations.otlp.ecosystem" }}otlp{{ end -}}

View File

@ -0,0 +1,188 @@
{{- define "destinations.prometheus.alloy" }}
{{- $defaultValues := "destinations/prometheus-values.yaml" | .Files.Get | fromYaml }}
{{- with merge .destination $defaultValues }}
otelcol.exporter.prometheus {{ include "helper.alloy_name" .name | quote }} {
add_metric_suffixes = {{ .openTelemetryConversion.addMetricSuffixes }}
forward_to = [prometheus.remote_write.{{ include "helper.alloy_name" .name }}.receiver]
}
prometheus.remote_write {{ include "helper.alloy_name" .name | quote }} {
endpoint {
{{- if .urlFrom }}
url = {{ .urlFrom }}
{{- else }}
url = {{ .url | quote }}
{{- end }}
headers = {
{{- if ne (include "secrets.authType" .) "sigv4" }}
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "tenantId")) "true" }}
"X-Scope-OrgID" = {{ include "secrets.read" (dict "object" . "key" "tenantId" "nonsensitive" true) }},
{{- end }}
{{- end }}
{{- range $key, $value := .extraHeaders }}
{{ $key | quote }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraHeadersFrom }}
{{ $key | quote }} = {{ $value }},
{{- end }}
}
{{- if .proxyURL }}
proxy_url = {{ .proxyURL | quote }}
{{- end }}
{{- if eq (include "secrets.authType" .) "basic" }}
basic_auth {
username = {{ include "secrets.read" (dict "object" . "key" "auth.username" "nonsensitive" true) }}
password = {{ include "secrets.read" (dict "object" . "key" "auth.password") }}
}
{{- else if eq (include "secrets.authType" .) "bearerToken" }}
{{- if .auth.bearerTokenFile }}
bearer_token_file = {{ .auth.bearerTokenFile | quote }}
{{- else }}
bearer_token = {{ include "secrets.read" (dict "object" . "key" "auth.bearerToken") }}
{{- end }}
{{- else if eq (include "secrets.authType" .) "oauth2" }}
oauth2 {
client_id = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientId" "nonsensitive" true) }}
{{- if eq .auth.oauth2.clientSecretFile "" }}
client_secret = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientSecret") }}
{{- else }}
client_secret_file = {{ .auth.oauth2.clientSecretFile | quote }}
{{- end }}
{{- if .auth.oauth2.endpointParams }}
endpoint_params = {
{{- range $k, $v := .auth.oauth2.endpointParams }}
{{ $k }} = {{ $v | toJson }},
{{- end }}
}
{{- end }}
{{- if .auth.oauth2.proxyURL }}
proxy_url = {{ .auth.oauth2.proxyURL | quote }}
{{- end }}
{{- if .auth.oauth2.noProxy }}
no_proxy = {{ .auth.oauth2.noProxy | quote }}
{{- end }}
{{- if .auth.oauth2.proxyFromEnvironment }}
proxyFromEnvironment = {{ .auth.oauth2.proxyFromEnvironment }}
{{- end }}
{{- if .auth.oauth2.proxyConnectHeader }}
proxy_connect_header = {{ .auth.oauth2.proxyConnectHeader | toJson }}
{{- end }}
{{- if .auth.oauth2.scopes }}
scopes = {{ .auth.oauth2.scopes | toJson }}
{{- end }}
{{- if .auth.oauth2.tokenURL }}
token_url = {{ .auth.oauth2.tokenURL | quote }}
{{- end }}
}
{{- else if eq (include "secrets.authType" .) "sigv4" }}
sigv4 {
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "auth.sigv4.accessKey")) "true" }}
access_key = {{ include "secrets.read" (dict "object" . "key" "auth.sigv4.accessKey" "nonsensitive" true) }}
{{- end }}
{{- if .auth.sigv4.profile }}
profile = {{ .auth.sigv4.profile | quote }}
{{- end }}
{{- if .auth.sigv4.region }}
region = {{ .auth.sigv4.region | quote }}
{{- end }}
{{- if .auth.sigv4.roleArn }}
role_arn = {{ .auth.sigv4.roleArn | quote }}
{{- end }}
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "auth.sigv4.secretKey")) "true" }}
secret_key = {{ include "secrets.read" (dict "object" . "key" "auth.sigv4.secretKey") }}
{{- end }}
}
{{- end }}
{{- if .tls }}
tls_config {
insecure_skip_verify = {{ .tls.insecureSkipVerify | default false }}
{{- if .tls.caFile }}
ca_file = {{ .tls.caFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.ca")) "true" }}
ca_pem = {{ include "secrets.read" (dict "object" . "key" "tls.ca" "nonsensitive" true) }}
{{- end }}
{{- if .tls.certFile }}
cert_file = {{ .tls.certFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.cert")) "true" }}
cert_pem = {{ include "secrets.read" (dict "object" . "key" "tls.cert" "nonsensitive" true) }}
{{- end }}
{{- if .tls.keyFile }}
key_file = {{ .tls.keyFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.key")) "true" }}
key_pem = {{ include "secrets.read" (dict "object" . "key" "tls.key") }}
{{- end }}
}
{{- end }}
send_native_histograms = {{ .sendNativeHistograms | default false }}
queue_config {
capacity = {{ .queueConfig.capacity | default 10000}}
min_shards = {{ .queueConfig.minShards | default 1 }}
max_shards = {{ .queueConfig.maxShards | default 50 }}
max_samples_per_send = {{ .queueConfig.maxSamplesPerSend | default 2000 }}
batch_send_deadline = {{ .queueConfig.batchSendDeadline | default "5s" | quote }}
min_backoff = {{ .queueConfig.minBackoff | default "30ms" | quote }}
max_backoff = {{ .queueConfig.maxBackoff | default "5s" | quote }}
retry_on_http_429 = {{ .queueConfig.retryOnHttp429 | default true }}
sample_age_limit = {{ .queueConfig.sampleAgeLimit | default "0s" | quote }}
}
write_relabel_config {
source_labels = ["cluster"]
regex = ""
replacement = {{ $.Values.cluster.name | quote }}
target_label = "cluster"
}
write_relabel_config {
source_labels = ["k8s.cluster.name"]
regex = ""
replacement = {{ $.Values.cluster.name | quote }}
target_label = "cluster"
}
{{- if .metricProcessingRules }}
{{ .metricProcessingRules | indent 4 }}
{{- end }}
}
wal {
truncate_frequency = {{ .writeAheadLog.truncateFrequency | quote }}
min_keepalive_time = {{ .writeAheadLog.minKeepaliveTime | quote }}
max_keepalive_time = {{ .writeAheadLog.maxKeepaliveTime | quote }}
}
{{- if or .extraLabels .extraLabelsFrom }}
external_labels = {
{{- range $key, $value := .extraLabels }}
{{ $key }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraLabelsFrom }}
{{ $key }} = {{ $value }},
{{- end }}
}
{{- end }}
}
{{- end }}
{{- end }}
{{- define "secrets.list.prometheus" -}}
- tenantId
- auth.username
- auth.password
- auth.bearerToken
- auth.oauth2.clientId
- auth.oauth2.clientSecret
- auth.sigv4.accessKey
- auth.sigv4.secretKey
- tls.ca
- tls.cert
- tls.key
{{- end -}}
{{- define "destinations.prometheus.alloy.prometheus.metrics.target" }}prometheus.remote_write.{{ include "helper.alloy_name" .name }}.receiver{{ end -}}
{{- define "destinations.prometheus.alloy.otlp.metrics.target" }}otelcol.exporter.prometheus.{{ include "helper.alloy_name" .name }}.input{{ end -}}
{{- define "destinations.prometheus.supports_metrics" }}true{{ end -}}
{{- define "destinations.prometheus.supports_logs" }}false{{ end -}}
{{- define "destinations.prometheus.supports_traces" }}false{{ end -}}
{{- define "destinations.prometheus.supports_profiles" }}false{{ end -}}
{{- define "destinations.prometheus.ecosystem" }}prometheus{{ end -}}

View File

@ -0,0 +1,120 @@
{{- define "destinations.pyroscope.alloy" }}
{{- $defaultValues := "destinations/pyroscope-values.yaml" | .Files.Get | fromYaml }}
{{- with merge .destination $defaultValues }}
pyroscope.write {{ include "helper.alloy_name" .name | quote }} {
endpoint {
{{- if .urlFrom }}
url = {{ .urlFrom }}
{{- else }}
url = {{ .url | quote }}
{{- end }}
headers = {
{{- if eq (include "secrets.usesSecret" (dict "object" . "key" "tenantId")) "true" }}
"X-Scope-OrgID" = {{ include "secrets.read" (dict "object" . "key" "tenantId" "nonsensitive" true) }},
{{- end }}
{{- range $key, $value := .extraHeaders }}
{{ $key | quote }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraHeadersFrom }}
{{ $key | quote }} = {{ $value }},
{{- end }}
}
{{- if eq (include "secrets.authType" .) "basic" }}
basic_auth {
username = {{ include "secrets.read" (dict "object" . "key" "auth.username" "nonsensitive" true) }}
password = {{ include "secrets.read" (dict "object" . "key" "auth.password") }}
}
{{- else if eq (include "secrets.authType" .) "bearerToken" }}
bearer_token = {{ include "secrets.read" (dict "object" . "key" "auth.bearerToken") }}
{{- else if eq (include "secrets.authType" .) "oauth2" }}
oauth2 {
client_id = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientId" "nonsensitive" true) }}
{{- if eq .auth.oauth2.clientSecretFile "" }}
client_secret = {{ include "secrets.read" (dict "object" . "key" "auth.oauth2.clientSecret") }}
{{- else }}
client_secret_file = {{ .auth.oauth2.clientSecretFile | quote }}
{{- end }}
{{- if .auth.oauth2.endpointParams }}
endpoint_params = {
{{- range $k, $v := .auth.oauth2.endpointParams }}
{{ $k }} = {{ $v | toJson }},
{{- end }}
}
{{- end }}
{{- if .auth.oauth2.proxyURL }}
proxy_url = {{ .auth.oauth2.proxyURL | quote }}
{{- end }}
{{- if .auth.oauth2.noProxy }}
no_proxy = {{ .auth.oauth2.noProxy | quote }}
{{- end }}
{{- if .auth.oauth2.proxyFromEnvironment }}
proxyFromEnvironment = {{ .auth.oauth2.proxyFromEnvironment }}
{{- end }}
{{- if .auth.oauth2.proxyConnectHeader }}
proxy_connect_header = {{ .auth.oauth2.proxyConnectHeader | toJson }}
{{- end }}
{{- if .auth.oauth2.scopes }}
scopes = {{ .auth.oauth2.scopes | toJson }}
{{- end }}
{{- if .auth.oauth2.tokenURL }}
token_url = {{ .auth.oauth2.tokenURL | quote }}
{{- end }}
}
{{- end }}
{{- if .tls }}
tls_config {
insecure_skip_verify = {{ .tls.insecureSkipVerify | default false }}
{{- if .tls.caFile }}
ca_file = {{ .tls.caFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.ca")) "true" }}
ca_pem = {{ include "secrets.read" (dict "object" . "key" "tls.ca" "nonsensitive" true) }}
{{- end }}
{{- if .tls.certFile }}
cert_file = {{ .tls.certFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.cert")) "true" }}
cert_pem = {{ include "secrets.read" (dict "object" . "key" "tls.cert" "nonsensitive" true) }}
{{- end }}
{{- if .tls.keyFile }}
key_file = {{ .tls.keyFile | quote }}
{{- else if eq (include "secrets.usesSecret" (dict "object" . "key" "tls.key")) "true" }}
key_pem = {{ include "secrets.read" (dict "object" . "key" "tls.key") }}
{{- end }}
}
{{- end }}
}
external_labels = {
cluster = {{ $.Values.cluster.name | quote }},
k8s_cluster_name = {{ $.Values.cluster.name | quote }},
{{- range $key, $value := .extraLabels }}
{{ $key }} = {{ $value | quote }},
{{- end }}
{{- range $key, $value := .extraLabelsFrom }}
{{ $key }} = {{ $value }},
{{- end }}
}
}
{{- end }}
{{- end }}
{{- define "secrets.list.pyroscope" -}}
- tenantId
- auth.username
- auth.password
- auth.bearerToken
- auth.oauth2.clientId
- auth.oauth2.clientSecret
- tls.ca
- tls.cert
- tls.key
{{- end -}}
{{- define "destinations.pyroscope.alloy.pyroscope.profiles.target" }}pyroscope.write.{{ include "helper.alloy_name" .name }}.receiver{{ end -}}
{{- define "destinations.pyroscope.supports_metrics" }}false{{ end -}}
{{- define "destinations.pyroscope.supports_logs" }}false{{ end -}}
{{- define "destinations.pyroscope.supports_traces" }}false{{ end -}}
{{- define "destinations.pyroscope.supports_profiles" }}true{{ end -}}
{{- define "destinations.pyroscope.ecosystem" }}pyroscope{{ end -}}

View File

@ -0,0 +1,7 @@
{{/* Do not edit this file. It is generated by the Makefile */}}
{{- define "destinations.types" -}}
- loki
- otlp
- prometheus
- pyroscope
{{- end -}}

View File

@ -0,0 +1,69 @@
{{/* Does some basic destination validation */}}
{{/* Inputs: . (Values) */}}
{{- define "destinations.validate" }}
{{- range $i, $destination := .Values.destinations }}
{{- if not $destination.name }}
{{- $msg := list "" (printf "Destination #%d does not have a name." $i) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "destinations:" }}
{{- $msg = append $msg " - name: my-destination-name" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- if (regexFind "[^-_ a-zA-Z0-9]" $destination.name) }}
{{- $msg := list "" (printf "Destination #%d (%s) invalid characters in its name." $i $destination.name) }}
{{- $msg = append $msg "Please only use alphanumeric, underscores, dashes, or spaces." }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $types := (include "destinations.types" . ) | fromYamlArray }}
{{- if not $destination.type }}
{{ fail (printf "\nDestination #%d (%s) does not have a type.\nPlease set:\ndestinations:\n - name: %s\n type: %s" $i $destination.name $destination.name (include "english_list_or" $types)) }}
{{- end }}
{{- if not (has $destination.type $types) }}
{{ fail (printf "\nDestination #%d (%s) is using an unknown type (%s).\nPlease set:\ndestinations:\n - name: %s\n type: \"[%s]\"" $i $destination.name $destination.type $destination.name (include "english_list_or" $types)) }}
{{- end }}
{{- if and (eq $destination.type "otlp") (not (has ($destination.protocol | default "grpc") (list "grpc" "http"))) }}
{{- $msg := list "" (printf "Destination #%d (%s) has an unsupported protocol: %s." $i $destination.name $destination.protocol) }}
{{- $msg = append $msg "The protocol must be either \"grpc\" or \"http\"" }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "destinations:" }}
{{- $msg = append $msg (printf " - name: %s" $destination.name) }}
{{- $msg = append $msg " type: otlp" }}
{{- $msg = append $msg " protocol: otlp / http" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{/* Check if OTLP destination using Grafana Cloud OTLP gateway has protocol set */}}
{{- if and (eq $destination.type "otlp") (ne $destination.protocol "http") (regexMatch "otlp-gateway-.+grafana\\.net" $destination.url) }}
{{ fail (printf "\nDestination #%d (%s) is using Grafana Cloud OTLP gateway but has incorrect protocol '%s'. The gateway requires 'http'.\nPlease set:\ndestinations:\n - name: %s\n type: otlp\n url: %s\n protocol: http" $i $destination.name ($destination.protocol | default "grpc (default)") $destination.name $destination.url) }}
{{- end }}
{{/* Check if OTLP destination using Grafana Cloud Tempo checks */}}
{{- if and (eq $destination.type "otlp") (regexMatch "tempo-.+grafana\\.net" $destination.url) }}
{{- if ne $destination.protocol "grpc" }}
{{ fail (printf "\nDestination #%d (%s) is using Grafana Cloud Traces but has incorrect protocol '%s'. Grafana Cloud Traces requires 'grpc'.\nPlease set:\ndestinations:\n - name: %s\n type: otlp\n url: %s\n protocol: grpc" $i $destination.name ($destination.protocol | default "grpc (default)") $destination.name $destination.url) }}
{{- end }}
{{- if eq (dig "metrics" "enabled" true $destination) true }}
{{ fail (printf "\nDestination #%d (%s) is using Grafana Cloud Traces but has metrics enabled. Tempo only supports traces.\nPlease set:\ndestinations:\n - name: %s\n type: otlp\n url: %s\n metrics:\n enabled: false" $i $destination.name $destination.name $destination.url) }}
{{- end }}
{{- if eq (dig "logs" "enabled" true $destination) true }}
{{ fail (printf "\nDestination #%d (%s) is using Grafana Cloud Traces but has logs enabled. Tempo only supports traces.\nPlease set:\ndestinations:\n - name: %s\n type: otlp\n url: %s\n logs:\n enabled: false" $i $destination.name $destination.name $destination.url) }}
{{- end }}
{{- if eq (dig "traces" "enabled" true $destination) false }}
{{ fail (printf "\nDestination #%d (%s) is using Grafana Cloud Traces but has traces disabled.\nPlease set:\ndestinations:\n - name: %s\n type: otlp\n url: %s\n traces:\n enabled: true" $i $destination.name $destination.name $destination.url) }}
{{- end }}
{{- end }}
{{- if eq (include "secrets.authType" $destination) "basic" }}
{{- if eq (include "secrets.usesSecret" (dict "object" $destination "key" "auth.username")) "false" }}
{{ fail (printf "\nDestination #%d (%s) is using basic auth but does not have a username.\nPlease set:\ndestinations:\n - name: %s\n auth:\n type: basic\n username: my-username\n password: my-password" $i $destination.name $destination.name) }}
{{- end }}
{{- if eq (include "secrets.usesSecret" (dict "object" $destination "key" "auth.password")) "false" }}
{{ fail (printf "\nDestination #%d (%s) is using basic auth but does not have a password.\nPlease set:\ndestinations:\n - name: %s\n auth:\n type: basic\n username: my-username\n password: my-password" $i $destination.name $destination.name) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,4 @@
{{ range .Values.extraObjects }}
---
{{ tpl (toYaml .) $ }}
{{ end }}

View File

@ -0,0 +1,37 @@
{{- define "features.annotationAutodiscovery.enabled" }}{{ .Values.annotationAutodiscovery.enabled }}{{- end }}
{{- define "features.annotationAutodiscovery.collectors" }}
{{- if .Values.annotationAutodiscovery.enabled -}}
- {{ .Values.annotationAutodiscovery.collector }}
{{- end }}
{{- end }}
{{- define "features.annotationAutodiscovery.include" }}
{{- if .Values.annotationAutodiscovery.enabled -}}
{{- $destinations := include "features.annotationAutodiscovery.destinations" . | fromYamlArray }}
// Feature: Annotation Autodiscovery
{{- include "feature.annotationAutodiscovery.module" .Subcharts.annotationAutodiscovery }}
annotation_autodiscovery "feature" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.annotationAutodiscovery.destinations" }}
{{- if .Values.annotationAutodiscovery.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.annotationAutodiscovery.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.annotationAutodiscovery.validate" }}
{{- if .Values.annotationAutodiscovery.enabled -}}
{{- $featureName := "Annotation Autodiscovery" }}
{{- $destinations := include "features.annotationAutodiscovery.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "metrics" "ecosystem" "prometheus" "feature" $featureName) }}
{{- range $collector := include "features.annotationAutodiscovery.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,93 @@
{{- define "features.applicationObservability.enabled" }}{{ .Values.applicationObservability.enabled }}{{- end }}
{{- define "features.applicationObservability.collectors" }}
{{- if .Values.applicationObservability.enabled -}}
- {{ .Values.applicationObservability.collector }}
{{- end }}
{{- end }}
{{- define "features.applicationObservability.include" }}
{{- if .Values.applicationObservability.enabled -}}
{{- $destinations := include "features.applicationObservability.destinations" . | fromYamlArray }}
// Feature: Application Observability
{{- include "feature.applicationObservability.module" (dict "Values" $.Values.applicationObservability "Files" $.Subcharts.applicationObservability.Files) }}
application_observability "feature" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "otlp") | indent 4 | trim }}
]
logs_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "logs" "ecosystem" "otlp") | indent 4 | trim }}
]
traces_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "traces" "ecosystem" "otlp") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.applicationObservability.destinations" }}
{{- if .Values.applicationObservability.enabled -}}
{{- $metricsDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "otlp" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- $logDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "logs" "ecosystem" "otlp" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- $traceDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "traces" "ecosystem" "otlp" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- concat $metricsDestinations $logDestinations $traceDestinations | toYaml }}
{{- end -}}
{{- end -}}
{{- define "features.applicationObservability.validate" }}
{{- if .Values.applicationObservability.enabled -}}
{{- $featureName := "Application Observability" }}
{{- if .Values.applicationObservability.metrics.enabled -}}
{{- $metricDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "otlp" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- include "destinations.validate_destination_list" (dict "destinations" $metricDestinations "type" "metrics" "ecosystem" "otlp" "feature" $featureName) }}
{{- end -}}
{{- if .Values.applicationObservability.logs.enabled -}}
{{- $logDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "logs" "ecosystem" "loki" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- include "destinations.validate_destination_list" (dict "destinations" $logDestinations "type" "logs" "ecosystem" "loki" "feature" $featureName) }}
{{- end -}}
{{- if .Values.applicationObservability.traces.enabled -}}
{{- $traceDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "traces" "ecosystem" "otlp" "filter" $.Values.applicationObservability.destinations) | fromYamlArray -}}
{{- include "destinations.validate_destination_list" (dict "destinations" $traceDestinations "type" "traces" "ecosystem" "otlp" "feature" $featureName) }}
{{- end -}}
{{- range $collector := include "features.applicationObservability.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- if $.Values.applicationObservability.receivers.otlp.grpc.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.otlp.grpc.port "portName" "otlp-grpc" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.otlp.http.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.otlp.http.port "portName" "otlp-http" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.zipkin.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.zipkin.port "portName" "zipkin" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.jaeger.grpc.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.jaeger.grpc.port "portName" "jaeger-grpc" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.jaeger.thriftBinary.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.jaeger.thriftBinary.port "portName" "jaeger-binary" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.jaeger.thriftCompact.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.jaeger.thriftCompact.port "portName" "jaeger-compact" "portProtocol" "TCP") }}
{{- end -}}
{{- if $.Values.applicationObservability.receivers.jaeger.thriftHttp.enabled }}
{{- include "collectors.require_extra_port" (dict "Values" $.Values "name" $collector "feature" $featureName "portNumber" $.Values.applicationObservability.receivers.jaeger.thriftHttp.port "portName" "jaeger-http" "portProtocol" "TCP") }}
{{- end -}}
{{- include "feature.applicationObservability.validate" (dict "Values" $.Values.applicationObservability) }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "features.applicationObservability.receiver.grpc" }}
{{- if and .Values.applicationObservability.enabled .Values.applicationObservability.receivers.otlp.grpc.enabled }}
http://{{ include "alloy.fullname" (index .Subcharts .Values.applicationObservability.collector) }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.applicationObservability.receivers.otlp.grpc.port }}
{{- end }}
{{- end }}
{{- define "features.applicationObservability.receiver.http" }}
{{- if and .Values.applicationObservability.enabled .Values.applicationObservability.receivers.otlp.http.enabled }}
http://{{ include "alloy.fullname" (index .Subcharts .Values.applicationObservability.collector) }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.applicationObservability.receivers.otlp.http.port }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,37 @@
{{- define "features.autoInstrumentation.enabled" }}{{ .Values.autoInstrumentation.enabled }}{{- end }}
{{- define "features.autoInstrumentation.collectors" }}
{{- if .Values.autoInstrumentation.enabled -}}
- {{ .Values.autoInstrumentation.collector }}
{{- end }}
{{- end }}
{{- define "features.autoInstrumentation.include" }}
{{- if .Values.autoInstrumentation.enabled -}}
{{- $destinations := include "features.autoInstrumentation.destinations" . | fromYamlArray }}
// Feature: Auto-Instrumentation
{{- include "feature.autoInstrumentation.module" (dict "Values" $.Values.autoInstrumentation "Files" $.Subcharts.autoInstrumentation.Files) }}
auto_instrumentation "feature" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.autoInstrumentation.destinations" }}
{{- if .Values.autoInstrumentation.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.autoInstrumentation.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.autoInstrumentation.validate" }}
{{- if .Values.autoInstrumentation.enabled -}}
{{- $featureName := "Auto-Instrumentation" }}
{{- $destinations := include "features.autoInstrumentation.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "metrics" "ecosystem" "prometheus" "feature" $featureName) }}
{{- range $collector := include "features.autoInstrumentation.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,37 @@
{{- define "features.clusterEvents.enabled" }}{{ .Values.clusterEvents.enabled }}{{- end }}
{{- define "features.clusterEvents.collectors" }}
{{- if .Values.clusterEvents.enabled -}}
- {{ .Values.clusterEvents.collector }}
{{- end }}
{{- end }}
{{- define "features.clusterEvents.include" }}
{{- if .Values.clusterEvents.enabled -}}
{{- $destinations := include "features.clusterEvents.destinations" . | fromYamlArray }}
// Feature: Cluster Events
{{- include "feature.clusterEvents.module" (dict "Values" $.Values.clusterEvents "Files" $.Subcharts.clusterEvents.Files) }}
cluster_events "feature" {
logs_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "logs" "ecosystem" "loki") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.clusterEvents.destinations" }}
{{- if .Values.clusterEvents.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "logs" "ecosystem" "loki" "filter" $.Values.clusterEvents.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.clusterEvents.validate" }}
{{- if .Values.clusterEvents.enabled -}}
{{- $featureName := "Kubernetes Cluster events" }}
{{- $destinations := include "features.clusterEvents.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "logs" "ecosystem" "loki" "feature" $featureName) }}
{{- range $collector := include "features.clusterEvents.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,183 @@
{{- define "features.clusterMetrics.enabled" }}{{ .Values.clusterMetrics.enabled }}{{- end }}
{{- define "features.clusterMetrics.collectors" }}
{{- if .Values.clusterMetrics.enabled -}}
- {{ .Values.clusterMetrics.collector }}
{{- end }}
{{- end }}
{{- define "features.clusterMetrics.include" }}
{{- if .Values.clusterMetrics.enabled -}}
{{- $destinations := include "features.clusterMetrics.destinations" . | fromYamlArray }}
// Feature: Cluster Metrics
{{- include "feature.clusterMetrics.module" (dict "Values" $.Values.clusterMetrics "Files" $.Subcharts.clusterMetrics.Files "Release" $.Release) }}
cluster_metrics "feature" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.clusterMetrics.destinations" }}
{{- if .Values.clusterMetrics.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.clusterMetrics.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.clusterMetrics.validate" }}
{{- if .Values.clusterMetrics.enabled -}}
{{- $featureName := "Kubernetes Cluster metrics" }}
{{- $destinations := include "features.clusterMetrics.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "metrics" "ecosystem" "prometheus" "feature" $featureName) }}
{{- range $collector := include "features.clusterMetrics.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- if .Values.clusterMetrics.opencost.enabled}}
{{- if ne .Values.cluster.name .Values.clusterMetrics.opencost.opencost.exporter.defaultClusterId }}
{{- $msg := list "" "The OpenCost default cluster id should match the cluster name." }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " exporter:" }}
{{- $msg = append $msg (printf " defaultClusterId: %s" .Values.cluster.name) }}
{{- fail (join "\n" $msg) }}
{{- end -}}
{{- if ne .Values.clusterMetrics.opencost.metricsSource "custom" }}
{{- if eq .Values.clusterMetrics.opencost.metricsSource "" }}
{{- $msg := list "" "OpenCost requires linking to a Prometheus data source." }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- if eq (len $destinations) 1 }}
{{- $msg = append $msg (printf " metricsSource: %s" (first $destinations)) }}
{{- else }}
{{- $msg = append $msg " metricsSource: <metrics destination name>" }}
{{- $msg = append $msg (printf "Where <metrics destination name> is one of %s" (include "english_list_or" $destinations)) }}
{{- end }}
{{- fail (join "\n" $msg) }}
{{- end -}}
{{- $destinationFound := false }}
{{- range $index, $destinationName := $destinations }}
{{- if eq $destinationName $.Values.clusterMetrics.opencost.metricsSource }}
{{- $destinationFound = true }}
{{- $destination := index $.Values.destinations $index }}
{{- $openCostMetricsUrl := (printf "<Query URL for destination \"%s\">" $destinationName) }}
{{- if $destination.url }}
{{- if regexMatch "/api/prom/push" $destination.url }}
{{- $openCostMetricsUrl = (regexReplaceAll "^(.*)/api/prom/push$" $destination.url "${1}/api/prom") }}
{{- else if regexMatch "/api/v1/push" $destination.url }}
{{- $openCostMetricsUrl = (regexReplaceAll "^(.*)/api/v1/push$" $destination.url "${1}/api/v1/query") }}
{{- else if regexMatch "/api/v1/write" $destination.url }}
{{- $openCostMetricsUrl = (regexReplaceAll "^(.*)/api/v1/write$" $destination.url "${1}/api/v1/query") }}
{{- end }}
{{- end }}
{{- if eq $.Values.clusterMetrics.opencost.opencost.prometheus.external.url ""}}
{{- $msg := list "" "OpenCost requires a url to a Prometheus data source." }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg " external:" }}
{{- $msg = append $msg (printf " url: %s" $openCostMetricsUrl) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $authType := include "secrets.authType" $destination }}
{{- $secretType := include "secrets.secretType" $destination }}
{{- if eq $authType "basic" }}
{{- if eq $secretType "embedded" }}
{{- $destinationUsername := include "secrets.getSecretValue" (dict "object" $destination "key" ".auth.username") }}
{{- if ne $.Values.clusterMetrics.opencost.opencost.prometheus.username $destinationUsername}}
{{- $msg := list "" (printf "The username for %s and OpenCost do not match." $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg (printf " username: %s" $destinationUsername) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $destinationPassword := include "secrets.getSecretValue" (dict "object" $destination "key" ".auth.password") }}
{{- if ne $.Values.clusterMetrics.opencost.opencost.prometheus.password_key $destinationPassword}}
{{- $msg := list "" (printf "The password for %s and OpenCost do not match." $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg (printf " password: %s" $destinationPassword) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- else }}
{{- $destinationSecret := include "secrets.kubernetesSecretName" (dict "Values" $.Values "Chart" $.Chart "Release" $.Release "object" $destination) }}
{{- if ne $.Values.clusterMetrics.opencost.opencost.prometheus.existingSecretName $destinationSecret}}
{{- $msg := list "" (printf "OpenCost requires the secret for %s to be set." $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg (printf " existingSecretName: %s" $destinationSecret) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $destinationUsernameKey := include "secrets.getSecretKey" (dict "object" $destination "key" ".auth.username") }}
{{- if ne $.Values.clusterMetrics.opencost.opencost.prometheus.username_key $destinationUsernameKey}}
{{- $msg := list "" (printf "The username secret key for %s and OpenCost do not match." $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg (printf " username_key: %s" $destinationUsernameKey) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- $destinationPasswordKey := include "secrets.getSecretKey" (dict "object" $destination "key" ".auth.password") }}
{{- if ne $.Values.clusterMetrics.opencost.opencost.prometheus.password_key $destinationPasswordKey}}
{{- $msg := list "" (printf "The password secret key for %s and OpenCost do not match." $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " prometheus:" }}
{{- $msg = append $msg (printf " password_key: %s" $destinationPasswordKey) }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{- else if ne $authType "none" }}
{{- $msg := list "" (printf "Unable to provide guidance for configuring OpenCost to use %s authentication for %s." $authType $destinationName) }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " metricsSource: custom" }}
{{- $msg = append $msg ("And configure %s authentication for %s using guidance from the OpenCost Helm chart.") }}
{{- $msg = append $msg "Documentation: https://github.com/opencost/opencost-helm-chart/tree/main/charts/opencost" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- end }}
{{- end -}}
{{- if eq $destinationFound false }}
{{- $msg := list "" (printf "The destination \"%s\" is not a Prometheus data source." $.Values.clusterMetrics.opencost.metricsSource) }}
{{- $msg = append $msg "OpenCost requires a Prometheus database to query where cluster metrics are stored." }}
{{- $msg = append $msg "" }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "clusterMetrics:" }}
{{- $msg = append $msg " opencost:" }}
{{- $msg = append $msg " metricsSource: <metrics destination name>" }}
{{- $msg = append $msg (printf "Where <metrics destination name> is one of %s" (include "english_list_or" $destinations)) }}
{{- fail (join "\n" $msg) }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,21 @@
{{- define "features.list" }}
- annotationAutodiscovery
- applicationObservability
- autoInstrumentation
- clusterMetrics
- clusterEvents
- nodeLogs
- podLogs
- profiling
- prometheusOperatorObjects
- integrations
- selfReporting
{{- end }}
{{- define "features.list.enabled" }}
{{- range $feature := ((include "features.list" .) | fromYamlArray ) }}
{{- if eq (include (printf "features.%s.enabled" $feature) $) "true" }}
- {{ $feature }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,80 @@
{{- define "features.integrations.enabled" }}
{{- $metricIntegrations := include "feature.integrations.configured.metrics" (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) | fromYamlArray }}
{{- $logIntegrations := include "feature.integrations.configured.logs" (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) | fromYamlArray }}
{{- if or $metricIntegrations $logIntegrations }}true{{ else }}false{{ end }}
{{- end }}
{{- define "features.integrations.collectors" }}
{{- $metricIntegrations := include "feature.integrations.configured.metrics" (dict "Values" .Values.integrations) | fromYamlArray }}
{{- if (not (empty $metricIntegrations)) }}
- {{ .Values.integrations.collector }}
{{- end }}
{{- end }}
{{- define "features.integrations.metrics.include" }}
{{- $values := dict "Chart" $.Subcharts.integrations.Chart "Values" .Values.integrations "Files" $.Subcharts.integrations.Files "Release" $.Release }}
{{- $destinations := include "features.integrations.destinations" . | fromYamlArray }}
{{- $integrations := include "feature.integrations.configured.metrics" $values | fromYamlArray }}
{{- range $integrationType := $integrations }}
{{- include (printf "integrations.%s.module.metrics" $integrationType) $values | indent 0 }}
{{ include "helper.alloy_name" $integrationType }}_integration "integration" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end }}
{{- end }}
{{- define "features.integrations.include" }}
{{- if eq .collectorName .Values.integrations.collector }}
{{ include "features.integrations.metrics.include" . | indent 0 }}
{{- end }}
{{- end }}
{{- define "features.integrations.destinations" }}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.integrations.destinations) -}}
{{- end }}
{{- define "features.integrations.logs.discoveryRules" }}
{{- $values := (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) }}
{{- $extraDiscoveryRules := list }}
{{- $logIntegrations := include "feature.integrations.configured.logs" $values | fromYamlArray }}
{{- range $integration := $logIntegrations }}
{{- $extraDiscoveryRules = append $extraDiscoveryRules ((include (printf "integrations.%s.logs.discoveryRules" $integration) $values) | indent 0) }}
{{- end }}
{{ $extraDiscoveryRules | join "\n" }}
{{- end }}
{{- define "features.integrations.logs.logProcessingStages" }}
{{- $values := (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) }}
{{- $extraLogProcessingStages := "" }}
{{- $logIntegrations := include "feature.integrations.configured.logs" $values | fromYamlArray }}
{{- range $integration := $logIntegrations }}
{{- $extraLogProcessingStages = cat $extraLogProcessingStages "\n" (include (printf "integrations.%s.logs.processingStage" $integration) $values) | indent 0 }}
{{- end }}
{{ $extraLogProcessingStages }}
{{- end }}
{{- define "features.integrations.validate" }}
{{- if eq (include "features.integrations.enabled" .) "true" }}
{{- $featureName := "Service Integrations" }}
{{- $metricIntegrations := include "feature.integrations.configured.metrics" (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) | fromYamlArray }}
{{- if $metricIntegrations }}
{{- $metricDestinations := include "features.integrations.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $metricDestinations "type" "metrics" "ecosystem" "prometheus" "feature" $featureName) }}
{{- end }}
{{- $podLogsEnabled := include "features.podLogs.enabled" $ }}
{{- $logIntegrations := include "feature.integrations.configured.logs" (dict "Values" .Values.integrations "Files" $.Subcharts.integrations.Files) | fromYamlArray }}
{{- if and $logIntegrations (ne $podLogsEnabled "true") }}
{{- $msg := list "" "Service integrations that include logs requires enabling the Pod Logs feature." }}
{{- $msg = append $msg "Please set:" }}
{{- $msg = append $msg "podLogs:" }}
{{- $msg = append $msg " enabled: true" }}
{{- fail (join "\n" $msg) }}
{{- end }}
{{- include "feature.integrations.validate" (dict "Values" $.Values.integrations) }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,40 @@
{{- define "features.nodeLogs.enabled" }}{{ .Values.nodeLogs.enabled }}{{- end }}
{{- define "features.nodeLogs.collectors" }}
{{- if .Values.nodeLogs.enabled -}}
- {{ .Values.nodeLogs.collector }}
{{- end }}
{{- end }}
{{- define "features.nodeLogs.include" }}
{{- if .Values.nodeLogs.enabled -}}
{{- $destinations := include "features.nodeLogs.destinations" . | fromYamlArray }}
// Feature: Node Logs
{{- include "feature.nodeLogs.module" (dict "Values" .Values.nodeLogs "Files" $.Subcharts.nodeLogs.Files) }}
node_logs "feature" {
logs_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "logs" "ecosystem" "loki") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.nodeLogs.destinations" }}
{{- if .Values.nodeLogs.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "logs" "ecosystem" "loki" "filter" $.Values.nodeLogs.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.nodeLogs.validate" }}
{{- if .Values.nodeLogs.enabled -}}
{{- $featureName := "Kubernetes Node logs" }}
{{- $destinations := include "features.nodeLogs.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "logs" "ecosystem" "loki" "feature" $featureName) }}
{{- range $collector := include "features.nodeLogs.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- include "feature.nodeLogs.collector.validate" (dict "Values" $.Values.nodeLogs "Collector" (index $.Values $collector) "CollectorName" $collector) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,43 @@
{{- define "features.podLogs.enabled" }}{{ .Values.podLogs.enabled }}{{- end }}
{{- define "features.podLogs.collectors" }}
{{- if .Values.podLogs.enabled -}}
- {{ .Values.podLogs.collector }}
{{- end }}
{{- end }}
{{- define "features.podLogs.include" }}
{{- if .Values.podLogs.enabled -}}
{{- $extraDiscoveryRules := cat (include "features.integrations.logs.discoveryRules" .) "\n" .Values.podLogs.extraDiscoveryRules | trim }}
{{- $extraLogProcessingStages := cat (include "features.integrations.logs.logProcessingStages" .) "\n" .Values.podLogs.extraLogProcessingStages | trim }}
{{- $values := mergeOverwrite .Values.podLogs (dict "extraDiscoveryRules" $extraDiscoveryRules "extraLogProcessingStages" $extraLogProcessingStages) }}
{{- $destinations := include "features.podLogs.destinations" . | fromYamlArray }}
// Feature: Pod Logs
{{- include "feature.podLogs.module" (dict "Values" $values "Files" $.Subcharts.podLogs.Files) }}
pod_logs "feature" {
logs_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "logs" "ecosystem" "loki") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.podLogs.destinations" }}
{{- if .Values.podLogs.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "logs" "ecosystem" "loki" "filter" $.Values.podLogs.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.podLogs.validate" }}
{{- if .Values.podLogs.enabled -}}
{{- $featureName := "Kubernetes Pod logs" }}
{{- $destinations := include "features.podLogs.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "logs" "ecosystem" "loki" "feature" $featureName) }}
{{- range $collector := include "features.podLogs.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- include "feature.podLogs.collector.validate" (dict "Values" $.Values.podLogs "Collector" (index $.Values $collector) "CollectorName" $collector) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,37 @@
{{- define "features.profiling.enabled" }}{{ .Values.profiling.enabled }}{{- end }}
{{- define "features.profiling.collectors" }}
{{- if .Values.profiling.enabled -}}
- {{ .Values.profiling.collector }}
{{- end }}
{{- end }}
{{- define "features.profiling.include" }}
{{- if .Values.profiling.enabled -}}
{{- $destinations := include "features.profiling.destinations" . | fromYamlArray }}
// Feature: Profiling
{{- include "feature.profiling.module" (dict "Values" $.Values.profiling "Files" $.Subcharts.profiling.Files) }}
profiling "feature" {
profiles_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "profiles" "ecosystem" "pyroscope") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.profiling.destinations" }}
{{- if .Values.profiling.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "profiles" "ecosystem" "pyroscope" "filter" $.Values.profiling.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.profiling.validate" }}
{{- if .Values.profiling.enabled -}}
{{- $featureName := "Profiling" }}
{{- $destinations := include "features.profiling.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "profiles" "ecosystem" "pyroscope" "feature" $featureName) }}
{{- range $collector := include "features.profiling.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,38 @@
{{- define "features.prometheusOperatorObjects.enabled" }}{{ .Values.prometheusOperatorObjects.enabled }}{{- end }}
{{- define "features.prometheusOperatorObjects.collectors" }}
{{- if .Values.prometheusOperatorObjects.enabled -}}
- {{ .Values.prometheusOperatorObjects.collector }}
{{- end }}
{{- end }}
{{- define "features.prometheusOperatorObjects.include" }}
{{- if .Values.prometheusOperatorObjects.enabled -}}
{{- $destinations := include "features.prometheusOperatorObjects.destinations" . | fromYamlArray }}
// Feature: Prometheus Operator Objects
{{- include "feature.prometheusOperatorObjects.module" (dict "Values" $.Values.prometheusOperatorObjects "Files" $.Subcharts.prometheusOperatorObjects.Files) }}
prometheus_operator_objects "feature" {
metrics_destinations = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end -}}
{{- end -}}
{{- define "features.prometheusOperatorObjects.destinations" }}
{{- if .Values.prometheusOperatorObjects.enabled -}}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.prometheusOperatorObjects.destinations) -}}
{{- end -}}
{{- end -}}
{{- define "features.prometheusOperatorObjects.validate" }}
{{- if .Values.prometheusOperatorObjects.enabled -}}
{{- $featureName := "Prometheus Operator Objects" }}
{{- $destinations := include "features.prometheusOperatorObjects.destinations" . | fromYamlArray }}
{{- include "destinations.validate_destination_list" (dict "destinations" $destinations "type" "metrics" "ecosystem" "prometheus" "feature" $featureName) }}
{{- range $collector := include "features.prometheusOperatorObjects.collectors" . | fromYamlArray }}
{{- include "collectors.require_collector" (dict "Values" $.Values "name" $collector "feature" $featureName) }}
{{- end -}}
{{- include "feature.prometheusOperatorObjects.validate" (dict "Values" $.Values.prometheusOperatorObjects) }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,92 @@
{{- define "features.selfReporting.enabled" -}}
{{- $metricsDestinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.selfReporting.destinations) | fromYamlArray -}}
{{ and .Values.selfReporting.enabled (not (empty $metricsDestinations)) }}
{{- end -}}
{{- define "features.selfReporting.collectors" -}}
{{- if eq (include "features.selfReporting.enabled" .) "true" }}
{{- $collectorsByIncreasingPreference := list "alloy-receiver" "alloy-metrics" "alloy-singleton" }}
{{- $chosenCollector := "" }}
{{- range $collector := $collectorsByIncreasingPreference }}
{{- if (index $.Values $collector).enabled }}{{- $chosenCollector = $collector }}{{- end -}}
{{- end -}}
- {{ $chosenCollector }}
{{- end -}}
{{- end }}
{{- define "features.selfReporting.destinations" }}
{{- if eq (include "features.selfReporting.enabled" .) "true" }}
{{- include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.selfReporting.destinations) -}}
{{- end }}
{{- end }}
{{- define "features.selfReporting.validate" }}{{ end }}
{{- define "features.selfReporting.include" }}
{{- if eq (include "features.selfReporting.enabled" .) "true" }}
{{- $destinations := include "destinations.get" (dict "destinations" $.Values.destinations "type" "metrics" "ecosystem" "prometheus" "filter" $.Values.selfReporting.destinations) | fromYamlArray -}}
// Self Reporting
prometheus.exporter.unix "kubernetes_monitoring_telemetry" {
set_collectors = ["textfile"]
textfile {
directory = "/etc/alloy"
}
}
discovery.relabel "kubernetes_monitoring_telemetry" {
targets = prometheus.exporter.unix.kubernetes_monitoring_telemetry.targets
rule {
target_label = "instance"
action = "replace"
replacement = "{{ .Release.Name }}"
}
rule {
target_label = "job"
action = "replace"
replacement = "integrations/kubernetes/kubernetes_monitoring_telemetry"
}
}
prometheus.scrape "kubernetes_monitoring_telemetry" {
job_name = "integrations/kubernetes/kubernetes_monitoring_telemetry"
targets = discovery.relabel.kubernetes_monitoring_telemetry.output
scrape_interval = {{ .Values.selfReporting.scrapeInterval | default .Values.global.scrapeInterval | quote}}
clustering {
enabled = true
}
forward_to = [prometheus.relabel.kubernetes_monitoring_telemetry.receiver]
}
prometheus.relabel "kubernetes_monitoring_telemetry" {
rule {
source_labels = ["__name__"]
regex = "grafana_kubernetes_monitoring_.*"
action = "keep"
}
forward_to = [
{{ include "destinations.alloy.targets" (dict "destinations" $.Values.destinations "names" $destinations "type" "metrics" "ecosystem" "prometheus") | indent 4 | trim }}
]
}
{{- end }}
{{- end }}
{{- define "features.selfReporting.metrics" }}
{{- if eq (include "features.selfReporting.enabled" .) "true" }}
# HELP grafana_kubernetes_monitoring_build_info A metric to report the version of the Kubernetes Monitoring Helm chart
# TYPE grafana_kubernetes_monitoring_build_info gauge
grafana_kubernetes_monitoring_build_info{version="{{ .Chart.Version }}", namespace="{{ .Release.Namespace }}"{{- if .Values.global.platform }}, platform="{{ .Values.global.platform }}"{{ end }}} 1
# HELP grafana_kubernetes_monitoring_feature_info A metric to report the enabled features of the Kubernetes Monitoring Helm chart
# TYPE grafana_kubernetes_monitoring_feature_info gauge
{{- range $feature := include "features.list.enabled" . | fromYamlArray }}
{{- if ne $feature "selfReporting" }}
{{- $featureSummary := include (printf "feature.%s.summary" $feature) (dict "Chart" (index $.Subcharts $feature).Chart "Values" (index $.Values $feature)) | fromYaml }}
grafana_kubernetes_monitoring_feature_info{{ include "label_list" (merge $featureSummary (dict "feature" $feature)) }} 1
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- define "feature.selfReporting.alloyModules" }}{{ end }}
{{- define "feature.selfReporting.notes.deployments" }}{{ end }}
{{- define "feature.selfReporting.notes.task" }}{{ end }}
{{- define "feature.selfReporting.notes.actions" }}{{ end }}

View File

@ -0,0 +1,84 @@
{{- if and (index .Values "alloy-logs").enabled (eq .Values.global.platform "openshift") }}
{{- $usesHostPathVolumes := (index .Values "alloy-logs").alloy.mounts.varlog }}
---
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}
allowHostDirVolumePlugin: {{ $usesHostPathVolumes }}
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- SETGID
- SETUID
- SETPCAP
- NET_BIND_SERVICE
- NET_RAW
- SYS_CHROOT
- MKNOD
- AUDIT_WRITE
- SETFCAP
defaultAddCapabilities: null
defaultAllowPrivilegeEscalation: false
forbiddenSysctls:
- '*'
fsGroup:
type: RunAsAny
groups: []
priority: null
readOnlyRootFilesystem: false # Set because Grafana Alloy needs to write to /tmp/alloy
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- runtime/default
supplementalGroups:
type: RunAsAny
users: []
volumes:
{{- if $usesHostPathVolumes }}
- hostPath
{{- end }}
- configMap
- emptyDir
- projected
- secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}-scc
rules:
- verbs:
- use
apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}-scc
subjects:
- kind: ServiceAccount
name: {{ include "alloy.fullname" (index .Subcharts "alloy-logs") }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,80 @@
{{- if and (index .Values "alloy-metrics").enabled (eq .Values.global.platform "openshift") }}
---
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- SETGID
- SETUID
- SETPCAP
- NET_BIND_SERVICE
- NET_RAW
- SYS_CHROOT
- MKNOD
- AUDIT_WRITE
- SETFCAP
defaultAddCapabilities: null
defaultAllowPrivilegeEscalation: false
forbiddenSysctls:
- '*'
fsGroup:
type: RunAsAny
groups: []
priority: null
readOnlyRootFilesystem: false # Set because Grafana Alloy needs to write to /tmp/alloy
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- runtime/default
supplementalGroups:
type: RunAsAny
users: []
volumes:
- configMap
- emptyDir
- projected
- secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}-scc
rules:
- verbs:
- use
apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}-scc
subjects:
- kind: ServiceAccount
name: {{ include "alloy.fullname" (index .Subcharts "alloy-metrics") }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,80 @@
{{- if and (index .Values "alloy-profiles").enabled (eq .Values.global.platform "openshift") }}
---
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: true
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- SETGID
- SETUID
- SETPCAP
- NET_BIND_SERVICE
- NET_RAW
- SYS_CHROOT
- MKNOD
- AUDIT_WRITE
- SETFCAP
defaultAddCapabilities: null
defaultAllowPrivilegeEscalation: false
forbiddenSysctls:
- '*'
fsGroup:
type: RunAsAny
groups: []
priority: null
readOnlyRootFilesystem: false # Set because Grafana Alloy needs to write to /tmp/alloy
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- runtime/default
supplementalGroups:
type: RunAsAny
users: []
volumes:
- configMap
- emptyDir
- projected
- secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}-scc
rules:
- verbs:
- use
apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}-scc
subjects:
- kind: ServiceAccount
name: {{ include "alloy.fullname" (index .Subcharts "alloy-profiles") }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,80 @@
{{- if and (index .Values "alloy-receiver").enabled (eq .Values.global.platform "openshift") }}
---
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- SETGID
- SETUID
- SETPCAP
- NET_BIND_SERVICE
- NET_RAW
- SYS_CHROOT
- MKNOD
- AUDIT_WRITE
- SETFCAP
defaultAddCapabilities: null
defaultAllowPrivilegeEscalation: false
forbiddenSysctls:
- '*'
fsGroup:
type: RunAsAny
groups: []
priority: null
readOnlyRootFilesystem: false # Set because Grafana Alloy needs to write to /tmp/alloy
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- runtime/default
supplementalGroups:
type: RunAsAny
users: []
volumes:
- configMap
- emptyDir
- projected
- secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}-scc
rules:
- verbs:
- use
apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}-scc
subjects:
- kind: ServiceAccount
name: {{ include "alloy.fullname" (index .Subcharts "alloy-receiver") }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,80 @@
{{- if and (index .Values "alloy-singleton").enabled (eq .Values.global.platform "openshift") }}
---
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
allowedCapabilities:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- FSETID
- KILL
- SETGID
- SETUID
- SETPCAP
- NET_BIND_SERVICE
- NET_RAW
- SYS_CHROOT
- MKNOD
- AUDIT_WRITE
- SETFCAP
defaultAddCapabilities: null
defaultAllowPrivilegeEscalation: false
forbiddenSysctls:
- '*'
fsGroup:
type: RunAsAny
groups: []
priority: null
readOnlyRootFilesystem: false # Set because Grafana Alloy needs to write to /tmp/alloy
requiredDropCapabilities: null
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- runtime/default
supplementalGroups:
type: RunAsAny
users: []
volumes:
- configMap
- emptyDir
- projected
- secret
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}-scc
rules:
- verbs:
- use
apiGroups:
- security.openshift.io
resources:
- securitycontextconstraints
resourceNames:
- {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}-scc
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}-scc
subjects:
- kind: ServiceAccount
name: {{ include "alloy.fullname" (index .Subcharts "alloy-singleton") }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,42 @@
{{- if and (index .Values "alloy-receiver").enabled (index .Values "alloy-receiver").extraService.enabled -}}
{{- $name := printf "%s-%s" .Release.Name (index .Values "alloy-receiver").extraService.name | trunc 63 | trimSuffix "-" }}
{{- if (index .Values "alloy-receiver").extraService.fullname }}
{{- $name = (index .Values "alloy-receiver").extraService.fullname }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ $name }}
labels:
{{- include "alloy.labels" (index .Subcharts "alloy-receiver") | nindent 4 }}
app.kubernetes.io/component: networking
{{- with (index .Values "alloy-receiver").service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ (index .Values "alloy-receiver").service.type }}
{{- if (index .Values "alloy-receiver").service.clusterIP }}
clusterIP: {{ (index .Values "alloy-receiver").service.clusterIP }}
{{- end }}
selector:
{{- include "alloy.selectorLabels" (index .Subcharts "alloy-receiver") | nindent 4 }}
{{- if semverCompare ">=1.26-0" .Capabilities.KubeVersion.Version }}
internalTrafficPolicy: {{ (index .Values "alloy-receiver").service.internalTrafficPolicy}}
{{- end }}
ports:
- name: http-metrics
{{- if eq (index .Values "alloy-receiver").service.type "NodePort" }}
nodePort: {{ (index .Values "alloy-receiver").service.nodePort }}
{{- end }}
port: {{ (index .Values "alloy-receiver").alloy.listenPort }}
targetPort: {{ (index .Values "alloy-receiver").alloy.listenPort }}
protocol: "TCP"
{{- range $portMap := (index .Values "alloy-receiver").alloy.extraPorts }}
- name: {{ $portMap.name }}
port: {{ $portMap.port }}
targetPort: {{ $portMap.targetPort }}
protocol: {{ coalesce $portMap.protocol "TCP" }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,25 @@
{{- range $collector := (include "collectors.list.enabled" .) | fromYamlArray }}
{{- $remoteConfigValues := merge ((index $.Values $collector).remoteConfig) (dict "type" "remoteConfig" "name" (printf "%s-remote-cfg" $collector)) }}
{{- with $remoteConfigValues }}
{{- if .enabled }}
# create: {{ (include "secrets.shouldCreateKubernetesSecret" . ) }}
{{- if eq (include "secrets.shouldCreateKubernetesSecret" . ) "true" }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "secrets.kubernetesSecretName" (deepCopy $ | merge (dict "object" .)) | quote }}
namespace: {{ include "secrets.kubernetesSecretNamespace" (deepCopy $ | merge (dict "object" .)) | quote }}
type: Opaque
data:
{{- $secrets := include "secrets.list.remoteConfig" . | fromYamlArray }}
{{- range $secret := $secrets }}
{{- $value := include "secrets.getSecretValue" (dict "object" $remoteConfigValues "key" $secret) -}}
{{- if $value }}
{{ include "secrets.getSecretKey" (dict "object" $remoteConfigValues "key" $secret) }}: {{ $value | b64enc | quote }}
{{- end }}
{{- end }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,172 @@
{{/* Helper function to return the auth type, defaulting to none */}}
{{/* Inputs: . (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.authType" }}
{{- if hasKey . "auth" }}{{ .auth.type | default "none" }}{{ else }}none{{ end }}
{{- end }}
{{/* Helper function to determine the secret type */}}
{{/* Inputs: . (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.secretType" }}
{{- if hasKey . "secret" }}
{{- if eq .secret.embed true -}}embedded
{{- else if eq .secret.create false -}}external
{{- else }}create
{{- end }}
{{- else -}}
create
{{- end }}
{{- end }}
{{/* Determine if a ___From field has been defined for a secret value */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value) */}}
{{- define "secrets.getSecretFromRef" -}}
{{- $value := .object -}}
{{- range $pathPart := (regexSplit "\\." (printf "%sFrom" .key) -1) -}} {{/* "path.to.auth.password" --> ["path", "to", "auth" "passwordFrom"] */}}
{{- if $pathPart -}}
{{- if and (not (kindIs "string" $value)) (hasKey $value $pathPart) -}}
{{- $value = (index $value $pathPart) -}}
{{- else -}}
{{- $value = "" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $value -}}
{{- end -}}
{{/* Determine the key to access a secret value within a secret component */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value) */}}
{{- define "secrets.getSecretKey" -}}
{{- $value := .object -}}
{{- $defaultKey := (( regexSplit "\\." .key -1) | last) -}} {{/* "path.to.auth.password" --> "password" */}}
{{- range $pathPart := (regexSplit "\\." (printf "%sKey" .key) -1) -}} {{/* "path.to.auth.password" --> ["path", "to", "auth" "passwordKey"] */}}
{{- if $pathPart -}}
{{- if and (not (kindIs "string" $value)) (hasKey $value $pathPart) -}}
{{- $value = (index $value $pathPart) -}}
{{- else -}}
{{- $value = $defaultKey -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $value -}}
{{- end -}}
{{/* Determine if a key was defined by the user */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value) */}}
{{- define "secrets.isSecretKeyDefined" -}}
{{- $found := true}}
{{- $value := .object -}}
{{- range $pathPart := (regexSplit "\\." (printf "%sKey" .key) -1) -}} {{/* "path.to.auth.password" --> ["path", "to", "auth" "passwordKey"] */}}
{{- if $pathPart -}}
{{- if and (not (kindIs "string" $value)) (hasKey $value $pathPart) -}}
{{- $value = (index $value $pathPart) -}}
{{- else -}}
{{- $found = false -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $found -}}
{{- end -}}
{{/*Determine the path to the secret value*/}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value) */}}
{{- define "secrets.getSecretValue" }}
{{- $value := .object -}}
{{- range $pathPart := (regexSplit "\\." .key -1) -}} {{/* "path.to.auth.password" --> ["path", "to", "auth" "password"] */}}
{{- if $pathPart -}}
{{- if and (not (kindIs "string" $value)) (hasKey $value $pathPart) -}}
{{- $value = (index $value $pathPart) -}}
{{- else -}}
{{- $value = "" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $value -}}
{{- end }}
{{/* Build the alloy command to read a secret value */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value), nonsensitive */}}
{{- define "secrets.read" }}
{{- $credRef := include "secrets.getSecretFromRef" . -}}
{{- if $credRef -}}
{{ $credRef }}
{{- else if eq (include "secrets.secretType" .object) "embedded" -}}
{{ include "secrets.getSecretValue" (dict "object" .object "key" .key) | quote }}
{{- else if eq (include "secrets.usesKubernetesSecret" .object) "true" -}}
{{- $credKey := include "secrets.getSecretKey" (dict "object" .object "key" .key) -}}
{{- if .nonsensitive -}}
nonsensitive(remote.kubernetes.secret.{{ include "helper.alloy_name" .object.name }}.data[{{ $credKey | quote }}])
{{- else -}}
remote.kubernetes.secret.{{ include "helper.alloy_name" .object.name }}.data[{{ $credKey | quote }}]
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Determines if the object will reference a secret value */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth), key (path to secret value), nonsensitive */}}
{{- define "secrets.usesSecret" -}}
{{- $secretType := (include "secrets.secretType" .object) }}
{{- $ref := include "secrets.getSecretFromRef" . -}}
{{- $value := include "secrets.getSecretValue" . -}}
{{- if (not (eq $ref "")) }}true
{{- else if (eq $secretType "external") }}true
{{- else if (eq $value "") }}false
{{- else -}}true{{- end -}}
{{- end -}}
{{/* Determines if the object will reference a Kubernetes secret */}}
{{/* Inputs: . (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.usesKubernetesSecret" -}}
{{- $secretType := (include "secrets.secretType" .) }}
{{- if eq $secretType "embedded" -}}false
{{- else -}}
{{- $usesK8sSecret := false }}
{{- range $secret := include (printf "secrets.list.%s" .type) . | fromYamlArray }}
{{- $ref := include "secrets.getSecretFromRef" (dict "object" $ "key" $secret) -}}
{{- $keyDefined := include "secrets.isSecretKeyDefined" (dict "object" $ "key" $secret) -}}
{{- $value := include "secrets.getSecretValue" (dict "object" $ "key" $secret) -}}
{{- if (eq $secretType "external") }}
{{- if eq $keyDefined "true" }}{{- $usesK8sSecret = true }}{{- end }}
{{- else }}
{{- if and $value (not $ref) }}{{- $usesK8sSecret = true }}{{- end }}
{{- end }}
{{- end }}
{{- $usesK8sSecret -}}
{{- end -}}
{{- end -}}
{{/* Determines if the object will need to create a Kubernetes secret. NOTE that this object should be before merging with default values */}}
{{/* Inputs: object (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.shouldCreateKubernetesSecret" -}}
{{- if eq (include "secrets.usesKubernetesSecret" .) "false" }}false
{{- else if and (hasKey . "secret") (hasKey .secret "create") -}}
{{ .secret.create }}
{{- else -}}
true
{{- end -}}
{{- end -}}
{{/* This returns the Kubernetes Secret name for this destination */}}
{{/* Inputs: $ (top level helm data) object (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.kubernetesSecretName" -}}
{{- if and (hasKey .object "secret") (hasKey .object.secret "name") (not (empty .object.secret.name)) -}}
{{ .object.secret.name }}
{{- else -}}
{{- if contains .Chart.Name .Release.Name }}
{{- printf "%s-%s" .object.name .Release.Name | trunc 63 | trimSuffix "-" | lower -}}
{{- else }}
{{- printf "%s-%s-%s" .object.name .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" | lower -}}
{{- end }}
{{- end }}
{{- end }}
{{/* This returns the Kubernetes Secret namespace for this destination */}}
{{/* Inputs: $ (top level helm data) object (user of the secret, needs name, secret, auth) */}}
{{- define "secrets.kubernetesSecretNamespace" -}}
{{- if and (hasKey .object "secret") (hasKey .object.secret "namespace") (not (empty .object.secret.namespace)) -}}
{{- .object.secret.namespace -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end }}
{{- end }}

View File

@ -0,0 +1,8 @@
{{/* This builds the remote.kubernetes.secret component for this destination */}}
{{/* Inputs: $ (top level object) object (user of the secret, needs name, secret, auth) */}}
{{ define "secret.alloy" }}
remote.kubernetes.secret {{ include "helper.alloy_name" .object.name | quote }} {
name = {{ include "secrets.kubernetesSecretName" . | quote }}
namespace = {{ include "secrets.kubernetesSecretNamespace" . | quote }}
}
{{ end }}

View File

@ -0,0 +1,105 @@
{{- define "secrets.list.unittest.secrets" }}
- auth.username
- auth.password
{{- end }}
{{- if eq (((index .Values "testing") | default false) | toString) "true" }}
{{- $noAuth := dict "type" "unittest.secrets"}}
{{- $usernameAndPassword := dict "type" "unittest.secrets" "auth" (dict "username" "my-username" "password" "my-password") }}
{{- $embeddedSecret := deepCopy $usernameAndPassword | merge (dict "secret" (dict "embed" true)) }}
{{- $allSecretsHaveRefs := dict "type" "unittest.secrets" "auth" (dict "usernameFrom" "env('USER')" "passwordFrom" "env('PASS')") }}
{{- $oneSecretHasRef := dict "type" "unittest.secrets" "auth" (dict "username" "my-username" "passwordFrom" "env('PASS')") }}
{{- $externalNoKeys := dict "type" "unittest.secrets" "secret" (dict "create" false) "auth" dict }}
{{- $externalOneKey := deepCopy $externalNoKeys | merge (dict "auth" (dict "usernameKey" "user")) }}
{{- $externalBothKeys := deepCopy $externalNoKeys | merge (dict "auth" (dict "usernameKey" "user" "passwordKey" "pass")) }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-authType
data:
testEmpty: {{ include "secrets.authType" $noAuth | quote }}
testEmptyAuth: {{ include "secrets.authType" (dict "auth" (dict)) | quote }}
testEmptyType: {{ include "secrets.authType" (dict "auth" (dict "type" "")) | quote }}
testAuthTypeBasic: {{ include "secrets.authType" (dict "auth" (dict "type" "basic")) | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-secretType
data:
testEmpty: {{ include "secrets.secretType" $noAuth | quote }}
testEmptySecret: {{ include "secrets.secretType" (dict "secret" (dict)) | quote }}
testEmbeddedTrue: {{ include "secrets.secretType" (dict "secret" (dict "embed" true)) | quote }}
testEmbeddedFalse: {{ include "secrets.secretType" (dict "secret" (dict "embed" false)) | quote }}
testCreateTrue: {{ include "secrets.secretType" (dict "secret" (dict "create" true)) | quote }}
testCreateFalse: {{ include "secrets.secretType" (dict "secret" (dict "create" false)) | quote }}
testBothTrue: {{ include "secrets.secretType" (dict "secret" (dict "create" true "embed" true)) | quote }}
testBothFalse: {{ include "secrets.secretType" (dict "secret" (dict "create" false "embed" false)) | quote }}
testCreateTrueEmbedFalse: {{ include "secrets.secretType" (dict "secret" (dict "create" true "embed" false)) | quote }}
testCreateFalseEmbedTrue: {{ include "secrets.secretType" (dict "secret" (dict "create" false "embed" true)) | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-getSecretFromRef
data:
testNoPath: {{ include "secrets.getSecretFromRef" (dict "object" dict "key" "auth.password") | quote }}
testNoReference: {{ include "secrets.getSecretFromRef" (dict "object" (dict "auth" dict) "key" "auth.password") | quote }}
testHasElementNoReference: {{ include "secrets.getSecretFromRef" (dict "object" (dict "auth" (dict "password" "test")) "key" "auth.password") | quote }}
testHasReference: {{ include "secrets.getSecretFromRef" (dict "object" (dict "auth" (dict "passwordFrom" "test")) "key" "auth.password") | quote }}
testHasReferenceAndElement: {{ include "secrets.getSecretFromRef" (dict "object" (dict "auth" (dict "password" "a-secret" "passwordFrom" "test")) "key" "auth.password") | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-getSecretKey
data:
testNoPath: {{ include "secrets.getSecretKey" (dict "object" dict "key" "auth.password") | quote }}
testNoKey: {{ include "secrets.getSecretKey" (dict "object" (dict "auth" dict) "key" "auth.password") | quote }}
testHasElementNoKey: {{ include "secrets.getSecretKey" (dict "object" (dict "auth" (dict "password" "test")) "key" "auth.password") | quote }}
testHasKey: {{ include "secrets.getSecretKey" (dict "object" (dict "auth" (dict "passwordKey" "test")) "key" "auth.password") | quote }}
testHasKeyAndElement: {{ include "secrets.getSecretKey" (dict "object" (dict "auth" (dict "password" "a-secret" "passwordKey" "test")) "key" "auth.password") | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-isSecretKeyDefined
data:
testNoPath: {{ include "secrets.isSecretKeyDefined" (dict "object" dict "key" "auth.password") | quote }}
testNoKey: {{ include "secrets.isSecretKeyDefined" (dict "object" $externalNoKeys "key" "auth.password") | quote }}
testHasElementNoKey: {{ include "secrets.isSecretKeyDefined" (dict "object" (dict "auth" (dict "password" "test")) "key" "auth.password") | quote }}
testHasKey: {{ include "secrets.isSecretKeyDefined" (dict "object" $externalOneKey "key" "auth.username") | quote }}
testHasKeyAndElement: {{ include "secrets.isSecretKeyDefined" (dict "object" (dict "auth" (dict "password" "a-secret" "passwordKey" "test")) "key" "auth.password") | quote }}
externalNoKeys: {{ include "secrets.isSecretKeyDefined" (dict "object" $externalNoKeys "key" "auth.username") | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-getSecretValue
data:
testNoPath: {{ include "secrets.getSecretValue" (dict "object" dict "key" "auth.password") | quote }}
testNoPassword: {{ include "secrets.getSecretValue" (dict "object" (dict "auth" dict) "key" "auth.password") | quote }}
testHasPassword: {{ include "secrets.getSecretValue" (dict "object" (dict "auth" (dict "password" "password")) "key" "auth.password") | quote }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-secrets-usesKubernetesSecret
data:
noAuth: {{ include "secrets.usesKubernetesSecret" $noAuth | quote }}
usernameAndPassword: {{ include "secrets.usesKubernetesSecret" $usernameAndPassword | quote }}
embeddedSecret: {{ include "secrets.usesKubernetesSecret" $embeddedSecret | quote }}
allSecretsHaveRefs: {{ include "secrets.usesKubernetesSecret" $allSecretsHaveRefs | quote }}
oneSecretHasRef: {{ include "secrets.usesKubernetesSecret" $oneSecretHasRef | quote }}
externalNoKeys: {{ include "secrets.usesKubernetesSecret" $externalNoKeys | quote }}
externalOneKey: {{ include "secrets.usesKubernetesSecret" $externalOneKey | quote }}
externalBothKeys: {{ include "secrets.usesKubernetesSecret" $externalBothKeys | quote }}
{{- end }}

View File

@ -0,0 +1,18 @@
{{- include "validations.checkForV1" . }}
{{- include "validations.cluster_name" . }}
{{- include "validations.platform" . }}
{{- include "destinations.validate" . -}}
{{- /* Feature Validations*/}}
{{- include "validations.features_enabled" . }}
{{- range $feature := ((include "features.list" .) | fromYamlArray) }}
{{- include (printf "features.%s.validate" $feature) $ }}
{{- end }}
{{- include "collectors.validate.featuresEnabled" . }}
{{- range $collectorName := ((include "collectors.list.enabled" .) | fromYamlArray) }}
{{- include "collectors.validate.liveDebugging" (dict "collectorName" $collectorName "Values" $.Values) }}
{{- include "collectors.validate.remoteConfig" (dict "collectorName" $collectorName "Values" $.Values) }}
{{- end }}
---