Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kube-prometheus-stack] Grafana crd datasources #5240

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion charts/kube-prometheus-stack/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ sources:
- https://github.com/prometheus-community/helm-charts
- https://github.com/prometheus-operator/kube-prometheus
# in case of changes within CRDs, a major version bump is mandatory. See: https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#upgrading-chart
version: 68.3.2
version: 68.3.3
appVersion: v0.79.2
kubeVersion: ">=1.19.0-0"
home: https://github.com/prometheus-operator/kube-prometheus
Expand Down
98 changes: 98 additions & 0 deletions charts/kube-prometheus-stack/templates/grafana/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{{- define "kube-prometheus-stack.grafana.datasources" -}}
{{- $scrapeInterval := .Values.grafana.sidecar.datasources.defaultDatasourceScrapeInterval | default .Values.prometheus.prometheusSpec.scrapeInterval | default "30s" -}}
{{- $datasources := list -}}
{{- if .Values.grafana.sidecar.datasources.defaultDatasourceEnabled }}
{{/* Create jsonData dictionary first */}}
{{- $jsonData := dict
"httpMethod" .Values.grafana.sidecar.datasources.httpMethod
"timeInterval" $scrapeInterval
"timeout" .Values.grafana.sidecar.datasources.timeout -}}
{{/* Conditionally add exemplarTraceIdDestinations */}}
{{- if .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }}
{{- $_ := set $jsonData "exemplarTraceIdDestinations" (list (dict
"datasourceUid" .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid
"name" .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName)) -}}
{{- end }}
{{/* Create defaultDS with ordered fields */}}
{{- $defaultDS := dict -}}
{{- $_ := set $defaultDS "name" .Values.grafana.sidecar.datasources.name -}}
{{- $_ := set $defaultDS "type" "prometheus" -}}
{{- $_ := set $defaultDS "uid" .Values.grafana.sidecar.datasources.uid -}}
{{- $_ := set $defaultDS "url" (default (printf "http://%s-prometheus.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.prometheus.service.port
(trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix)
) .Values.grafana.sidecar.datasources.url) -}}
{{- $_ := set $defaultDS "access" "proxy" -}}
{{- $_ := set $defaultDS "isDefault" .Values.grafana.sidecar.datasources.isDefaultDatasource -}}
{{- $_ := set $defaultDS "jsonData" $jsonData -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a suggestion which can be considered as alternative. It's just an option to discuss about if possible and it's not indented as "please use this".

Suggested change
{{- $defaultDS := dict -}}
{{- $_ := set $defaultDS "name" .Values.grafana.sidecar.datasources.name -}}
{{- $_ := set $defaultDS "type" "prometheus" -}}
{{- $_ := set $defaultDS "uid" .Values.grafana.sidecar.datasources.uid -}}
{{- $_ := set $defaultDS "url" (default (printf "http://%s-prometheus.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.prometheus.service.port
(trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix)
) .Values.grafana.sidecar.datasources.url) -}}
{{- $_ := set $defaultDS "access" "proxy" -}}
{{- $_ := set $defaultDS "isDefault" .Values.grafana.sidecar.datasources.isDefaultDatasource -}}
{{- $_ := set $defaultDS "jsonData" $jsonData -}}
{{- $defaultDS := (dict
"name" .Values.grafana.sidecar.datasources.name
"type" "prometheus"
"uid" .Values.grafana.sidecar.datasources.uid
"url" (default (printf "http://%s-prometheus.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.prometheus.service.port
(trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix)
) .Values.grafana.sidecar.datasources.url)
"access" "proxy"
"isDefault" .Values.grafana.sidecar.datasources.isDefaultDatasource
"jsonData" $jsonData
) -}}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkroepke the main problem here, that if we take your approach we loose the possibility to add comments, because any comments between dict keys break the formatting. At the beginning I implemented it in a way you suggested but later I realized that I cannot make nice conditionals with comments, so I switched to this version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dzirg44 what the downside of just using plain templating instead put everything logic into the templating syntax?

I still feel not happy, it feel like an unnatural helm template.

Suggested change
{{- $defaultDS := dict -}}
{{- $_ := set $defaultDS "name" .Values.grafana.sidecar.datasources.name -}}
{{- $_ := set $defaultDS "type" "prometheus" -}}
{{- $_ := set $defaultDS "uid" .Values.grafana.sidecar.datasources.uid -}}
{{- $_ := set $defaultDS "url" (default (printf "http://%s-prometheus.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.prometheus.service.port
(trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix)
) .Values.grafana.sidecar.datasources.url) -}}
{{- $_ := set $defaultDS "access" "proxy" -}}
{{- $_ := set $defaultDS "isDefault" .Values.grafana.sidecar.datasources.isDefaultDatasource -}}
{{- $_ := set $defaultDS "jsonData" $jsonData -}}
name: {{ .Values.grafana.sidecar.datasources.name }}
type: prometheus
uid: {{ .Values.grafana.sidecar.datasources.uid }}
url: {{ (default (printf "http://%s-prometheus.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.prometheus.service.port
(trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix)
) .Values.grafana.sidecar.datasources.url) }}
access: proxy
isDefault: {{ .Values.grafana.sidecar.datasources.isDefaultDatasource }}
{{- with $jsonData }}
jsonData:
{{ . | nindent 2 }}
{{- end }}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkroepke Can you take a look at the refactored version?
In essence I:

created 3 functions

  • kube-prometheus-stack.grafana.datasourceUrl.defaultPrometheus
  • kube-prometheus-stack.grafana.datasourceUrl.replica
  • kube-prometheus-stack.grafana.datasourceUrl.alertmanager

Converted urlDisplayLabel in exemplarTraceIdDestinations

used coalesce instead of default (can be reverted back) in some cases

timeout - removed (i don't see this parameter in the values or in grafana prometheus datasource api)

Some potential issues:

  • exemplarTraceIdDestinations, if I am not mistaken this parameter cannot be omitted so probably the code can be unsafe.
  • this code is really weird
{{- $scrapeInterval := .Values.grafana.sidecar.datasources.defaultDatasourceScrapeInterval | default .Values.prometheus.prometheusSpec.scrapeInterval | default "30s" }}

would it be better to set scrapeInterval to 30s in values and remove default?

{{- $datasources = append $datasources $defaultDS -}}
{{- end }}

{{/* Same pattern for replica datasources */}}
{{- if .Values.grafana.sidecar.datasources.createPrometheusReplicasDatasources }}
{{- range until (int .Values.prometheus.prometheusSpec.replicas) }}
{{- $replicaDS := dict -}}
{{- $_ := set $replicaDS "name" (printf "%s-%d" $.Values.grafana.sidecar.datasources.name .) -}}
{{- $_ := set $replicaDS "type" "prometheus" -}}
{{- $_ := set $replicaDS "uid" (printf "%s-replica-%d" $.Values.grafana.sidecar.datasources.uid .) -}}
{{- $_ := set $replicaDS "url" (printf "http://prometheus-%s-%d.prometheus-operated:9090/%s"
(include "kube-prometheus-stack.prometheus.crname" $)
.
(trimPrefix "/" $.Values.prometheus.prometheusSpec.routePrefix)) -}}
{{- $_ := set $replicaDS "access" "proxy" -}}
{{- $_ := set $replicaDS "isDefault" false -}}
{{- $_ := set $replicaDS "jsonData" (dict "timeInterval" $scrapeInterval) -}}
{{- if $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }}
{{- $_ := set $replicaDS "jsonData" (dict
"timeInterval" $scrapeInterval
"exemplarTraceIdDestinations" (list (dict
"datasourceUid" $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid
"name" $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName))) -}}
{{- end }}
{{- $datasources = append $datasources $replicaDS -}}
{{- end }}
{{- end }}

{{/* And for alertmanager datasource */}}
{{- if .Values.grafana.sidecar.datasources.alertmanager.enabled }}
{{- $alertmanagerDS := dict -}}
{{- $_ := set $alertmanagerDS "name" .Values.grafana.sidecar.datasources.alertmanager.name -}}
{{- $_ := set $alertmanagerDS "type" "alertmanager" -}}
{{- $_ := set $alertmanagerDS "uid" .Values.grafana.sidecar.datasources.alertmanager.uid -}}
{{- $_ := set $alertmanagerDS "url" (default (printf "http://%s-alertmanager.%s:%v/%s"
(include "kube-prometheus-stack.fullname" .)
(include "kube-prometheus-stack.namespace" .)
.Values.alertmanager.service.port
(trimPrefix "/" .Values.alertmanager.alertmanagerSpec.routePrefix)
) .Values.grafana.sidecar.datasources.alertmanager.url) -}}
{{- $_ := set $alertmanagerDS "access" "proxy" -}}
{{- $_ := set $alertmanagerDS "isDefault" false -}}
{{- $_ := set $alertmanagerDS "jsonData" (dict
"handleGrafanaManagedAlerts" .Values.grafana.sidecar.datasources.alertmanager.handleGrafanaManagedAlerts
"implementation" .Values.grafana.sidecar.datasources.alertmanager.implementation) -}}
{{- $datasources = append $datasources $alertmanagerDS -}}
{{- end }}

{{- if .Values.grafana.additionalDataSources }}
{{- $datasources = concat $datasources .Values.grafana.additionalDataSources -}}
{{- end }}
{{- $result := dict "datasources" $datasources -}}
{{- $result | toYaml -}}
{{- end }}

{{/* Helper function to sanitize names */}}
{{- define "kube-prometheus-stack.grafana.sanitizeName" -}}
{{- $name := lower . -}}
{{- $name := regexReplaceAll "[^a-z0-9-]" $name "-" -}}
{{- $name := regexReplaceAll "^[^a-z]" $name "x" -}}
{{- $name := regexReplaceAll "-+$" $name "" -}}
{{- $name := regexReplaceAll "^-+" $name "" -}}
{{- $name := regexReplaceAll "-+'" $name "-" -}}
{{- if eq $name "" -}}
{{- "default" -}}
{{- else -}}
{{- $name -}}
{{- end -}}
{{- end -}}
Original file line number Diff line number Diff line change
@@ -1,84 +1,28 @@
{{- if or (and .Values.grafana.enabled .Values.grafana.sidecar.datasources.enabled) .Values.grafana.forceDeployDatasources }}
{{- if .Values.grafana.configMapDatasources }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "kube-prometheus-stack.fullname" . }}-grafana-datasource
namespace: {{ template "kube-prometheus-stack-grafana.namespace" . }}
{{- if .Values.grafana.sidecar.datasources.annotations }}
name: {{ include "kube-prometheus-stack.fullname" . }}-grafana-datasource
namespace: {{ include "kube-prometheus-stack-grafana.namespace" . }}
{{- with .Values.grafana.sidecar.datasources.annotations }}
annotations:
{{- toYaml .Values.grafana.sidecar.datasources.annotations | nindent 4 }}
{{- end }}
{{ toYaml . | nindent 4 }}
{{- end }}
labels:
{{ $.Values.grafana.sidecar.datasources.label }}: {{ $.Values.grafana.sidecar.datasources.labelValue | quote }}
app: {{ template "kube-prometheus-stack.name" $ }}-grafana
{{ include "kube-prometheus-stack.labels" $ | indent 4 }}
{{ .Values.grafana.sidecar.datasources.label }}: {{ .Values.grafana.sidecar.datasources.labelValue | quote }}
app: {{ include "kube-prometheus-stack.name" . }}-grafana
{{ include "kube-prometheus-stack.labels" . | nindent 4 }}
data:
datasource.yaml: |-
apiVersion: 1
{{- if .Values.grafana.deleteDatasources }}
{{- if .Values.grafana.deleteDatasources }}
deleteDatasources:
{{ tpl (toYaml .Values.grafana.deleteDatasources | indent 6) . }}
{{- end }}
{{- if .Values.grafana.prune }}
{{ tpl (toYaml .Values.grafana.deleteDatasources | indent 6) . | trim }}
{{- end }}
{{- if .Values.grafana.prune }}
prune: {{ .Values.grafana.prune }}
{{- end }}
datasources:
{{- $scrapeInterval := .Values.grafana.sidecar.datasources.defaultDatasourceScrapeInterval | default .Values.prometheus.prometheusSpec.scrapeInterval | default "30s" }}
{{- if .Values.grafana.sidecar.datasources.defaultDatasourceEnabled }}
- name: "{{ .Values.grafana.sidecar.datasources.name }}"
type: prometheus
uid: {{ .Values.grafana.sidecar.datasources.uid }}
{{- if .Values.grafana.sidecar.datasources.url }}
url: {{ .Values.grafana.sidecar.datasources.url }}
{{- else }}
url: http://{{ template "kube-prometheus-stack.fullname" . }}-prometheus.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.prometheus.service.port }}/{{ trimPrefix "/" .Values.prometheus.prometheusSpec.routePrefix }}
{{- end }}
access: proxy
isDefault: {{ .Values.grafana.sidecar.datasources.isDefaultDatasource }}
jsonData:
httpMethod: {{ .Values.grafana.sidecar.datasources.httpMethod }}
timeInterval: {{ $scrapeInterval }}
{{- if .Values.grafana.sidecar.datasources.timeout }}
timeout: {{ .Values.grafana.sidecar.datasources.timeout }}
{{- end }}
{{- if .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }}
exemplarTraceIdDestinations:
- datasourceUid: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }}
name: {{ .Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }}
{{- end }}
{{- if .Values.grafana.sidecar.datasources.createPrometheusReplicasDatasources }}
{{- range until (int .Values.prometheus.prometheusSpec.replicas) }}
- name: "{{ $.Values.grafana.sidecar.datasources.name }}-{{ . }}"
type: prometheus
uid: {{ $.Values.grafana.sidecar.datasources.uid }}-replica-{{ . }}
url: http://prometheus-{{ template "kube-prometheus-stack.prometheus.crname" $ }}-{{ . }}.prometheus-operated:9090/{{ trimPrefix "/" $.Values.prometheus.prometheusSpec.routePrefix }}
access: proxy
isDefault: false
jsonData:
timeInterval: {{ $scrapeInterval }}
{{- if $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations }}
exemplarTraceIdDestinations:
- datasourceUid: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.datasourceUid }}
name: {{ $.Values.grafana.sidecar.datasources.exemplarTraceIdDestinations.traceIdLabelName }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.grafana.sidecar.datasources.alertmanager.enabled }}
- name: "{{ .Values.grafana.sidecar.datasources.alertmanager.name }}"
type: alertmanager
uid: {{ .Values.grafana.sidecar.datasources.alertmanager.uid }}
{{- if .Values.grafana.sidecar.datasources.alertmanager.url }}
url: {{ .Values.grafana.sidecar.datasources.alertmanager.url }}
{{- else }}
url: http://{{ template "kube-prometheus-stack.fullname" . }}-alertmanager.{{ template "kube-prometheus-stack.namespace" . }}:{{ .Values.alertmanager.service.port }}/{{ trimPrefix "/" .Values.alertmanager.alertmanagerSpec.routePrefix }}
{{- end }}
access: proxy
jsonData:
handleGrafanaManagedAlerts: {{ .Values.grafana.sidecar.datasources.alertmanager.handleGrafanaManagedAlerts }}
implementation: {{ .Values.grafana.sidecar.datasources.alertmanager.implementation }}
{{- end }}
{{- end }}
{{- if .Values.grafana.additionalDataSources }}
{{ tpl (toYaml .Values.grafana.additionalDataSources | indent 4) . }}
{{- end }}
datasources: {{- (include "kube-prometheus-stack.grafana.datasources" . | fromYaml).datasources | toYaml | nindent 6 }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{- if or (and .Values.grafana.enabled .Values.grafana.sidecar.datasources.enabled) .Values.grafana.forceDeployDatasources }}
{{- if .Values.grafana.operatorDatasources }}
{{- $datasources := fromYaml (include "kube-prometheus-stack.grafana.datasources" .) }}
{{- range $ds := $datasources.datasources }}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: {{ include "kube-prometheus-stack.fullname" $ }}-{{ include "kube-prometheus-stack.grafana.sanitizeName" $ds.name }}
namespace: {{ template "kube-prometheus-stack-grafana.namespace" $ }}
labels:
app: {{ template "kube-prometheus-stack.name" $ }}-grafana
{{ include "kube-prometheus-stack.labels" $ | nindent 4 }}
spec:
instanceSelector:
matchLabels:
{{- if $.Values.grafana.operatorInstanceSelector }}
{{- toYaml $.Values.grafana.operatorInstanceSelector | nindent 6 }}
{{- else }}
app.kubernetes.io/instance: grafana
app.kubernetes.io/name: grafana-operator
{{- end }}
datasource:
{{- $ds | toYaml | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
16 changes: 16 additions & 0 deletions charts/kube-prometheus-stack/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,22 @@
##
forceDeployDatasources: false

## ConfigMapDatasources Create datasources as configmaps
##
configMapDatasources: true

## OperatorDatasources Create datasources as crds
##

Check failure on line 1022 in charts/kube-prometheus-stack/values.yaml

View workflow job for this annotation

GitHub Actions / lint-test

1022:1 [trailing-spaces] trailing spaces
operatorDatasources: false

## OperatorInstanceSelector Selects the instance of the operator to use for grafana operator
##

operatorInstanceSelector:

Check failure on line 1028 in charts/kube-prometheus-stack/values.yaml

View workflow job for this annotation

GitHub Actions / lint-test

1028:28 [trailing-spaces] trailing spaces
app.kubernetes.io/instance: grafana
app.kubernetes.io/name: grafana-operator

## ForceDeployDashboard Create dashboard configmap even if grafana deployment has been disabled
##
forceDeployDashboards: false
Expand Down
Loading