From df837e3ffa01c5b8ee40f34a69c4c0a01520c7a5 Mon Sep 17 00:00:00 2001 From: Richard Tief Date: Wed, 18 Dec 2024 11:13:10 +0100 Subject: [PATCH] feat(alerts): improved ca cert generation fixes: #546, #550 --- alerts/README.md | 17 +++++++ alerts/charts/Chart.yaml | 2 +- alerts/charts/templates/_helper.tpl | 35 +++++++++++++- .../templates/ca-secret-issuer-cert.yaml | 46 +++++++++++-------- alerts/charts/values.yaml | 26 +++++++++++ alerts/plugindefinition.yaml | 35 +++++++++----- 6 files changed, 126 insertions(+), 35 deletions(-) diff --git a/alerts/README.md b/alerts/README.md index 2fcb17ec..e540b1c4 100644 --- a/alerts/README.md +++ b/alerts/README.md @@ -76,6 +76,15 @@ Greenhouse regularly performs integration tests that are bundled with **alerts** | `alerts.alertmanager.alertmanagerConfig.webhook.routes[].name` | Name of the webhook route. | `""` | | `alerts.alertmanager.alertmanagerConfig.webhook.routes[].url` | Webhook url to post alerts to. | `""` | | `alerts.alertmanager.alertmanagerConfig.webhook.routes[].matchers` | List of matchers that the alert's label should match. matchType , name , regex , value | `[]` | + +| `alerts.auth.secretName` | Use custom secret for Alertmanager authentication | `""` | +| `alerts.auth.autoGenerateCert.enabled` | TLS Certificate Option 1: Use Helm to automatically generate self-signed certificate. | `true` | +| `alerts.auth.autoGenerateCert.recreate` | If set to true, new key/certificate is generated on Helm upgrade. | `false` | +| `alerts.auth.autoGenerateCert.certPeriodDays` | Cert period time in days. The default is 365 days. | `365` | +| `alerts.auth.certFile` | Path to your own PEM-encoded certificate. | `""` | +| `alerts.auth.keyFile` | Path to your own PEM-encoded private key. | `""` | +| `alerts.auth.caFile` | Path to CA cert. | `""` | + | `alerts.defaultRules.create` | Creates community Alertmanager alert rules. | `true` | | `alerts.defaultRules.labels` | kube-monitoring `plugin: ` to evaluate Alertmanager rules. | `{}` | | `alerts.alertmanager.alertmanagerSpec.alertmanagerConfiguration` | AlermanagerConfig to be used as top level configuration | `false` | @@ -205,6 +214,14 @@ alertmanagerConfiguration: name: global-alertmanager-configuration ``` +## TLS Certificate Requirement + +In order for Prometheus installations in onboarded Greenhouse clusters to communicate with the Alertmanager component, the Ingress requires a TLS certificate for which Prometheus is configured as trusted. There are various ways in which you can generate/configure the required TLS certificate. + + - You can use an automatically generated self-signed certificate by setting `alerts.auth.autoGenerateCert.enabled` to `true`. Helm will create a self-signed cert and a secret for you. + - You can use your own generated self-signed certificate by setting both `alerts.auth.autoGenerateCert.enabled` to `false`. You should provide the necessary values to `alerts.auth.certFile`, `alerts.auth.keyFile`, and `alerts.auth.caFile`. + - You can also sideload custom certificate by disabling `alerts.auth.autoGenerateCert.enabled` to `false` while setting your custom cert secret name in `alerts.auth.secretName` + ## Examples ### Deploy alerts with Alertmanager diff --git a/alerts/charts/Chart.yaml b/alerts/charts/Chart.yaml index 8fcb77e1..6b7202ef 100644 --- a/alerts/charts/Chart.yaml +++ b/alerts/charts/Chart.yaml @@ -8,7 +8,7 @@ maintainers: name: alerts sources: - https://github.com/cloudoperators/greenhouse-extensions -version: 0.15.5 +version: 0.16.0 keywords: - prometheus-alertmanager dependencies: diff --git a/alerts/charts/templates/_helper.tpl b/alerts/charts/templates/_helper.tpl index c4b20052..be36810d 100644 --- a/alerts/charts/templates/_helper.tpl +++ b/alerts/charts/templates/_helper.tpl @@ -1,5 +1,3 @@ -{{/* vim: set filetype=mustache: */}} - {{- define "kube-prometheus-stack.name" -}} {{- printf "%s" $.Release.Name | trunc 50 | trimSuffix "-" -}} {{- end }} @@ -49,3 +47,36 @@ plugin: {{ $root.Release.Name }} {{- end }} {{- end }} {{- end }} + +{{/* +Return certificate and CA for Prometheus to push alerts. +It handles variants when a cert has to be generated by Helm, +a cert is loaded from an existing secret or is provided via `.Values` +*/}} +{{- define "alerts.generateCert" -}} +{{- $caCertEnc := "" }} +{{- $certCrtEnc := "" }} +{{- $certKeyEnc := "" }} +{{- if .Values.alerts.auth.autoGenerateCert.enabled }} +{{- $prevSecret := (lookup "v1" "Secret" .Release.Namespace (default (printf "%s-monitoring-ca" .Release.Namespace) .Values.alerts.auth.secretName )) }} +{{- if and (not .Values.alerts.auth.autoGenerateCert.recreate) $prevSecret }} +{{- $certCrtEnc = index $prevSecret "data" "tls.crt" }} +{{- $certKeyEnc = index $prevSecret "data" "tls.key" }} +{{- $caCertEnc = index $prevSecret "data" "ca.crt" }} +{{- else }} +{{- $altNames := list ( printf "%s-alertmanager.%s" .Release.Name .Release.Namespace ) ( printf "%s-alertmanager.%s.svc" .Release.Name .Release.Namespace ) -}} +{{- $tmpperioddays := int .Values.alerts.auth.autoGenerateCert.certPeriodDays | default 365 }} +{{- $ca := genCA "greenhouse-monitoring-ca" $tmpperioddays }} +{{- $cert := genSignedCert .Release.Name nil $altNames $tmpperioddays $ca }} +{{- $certCrtEnc = b64enc $cert.Cert }} +{{- $certKeyEnc = b64enc $cert.Key }} +{{- $caCertEnc = b64enc $ca.Cert }} +{{- end }} +{{- else }} +{{- $certCrtEnc = .Files.Get .Values.alerts.auth.certFile | b64enc }} +{{- $certKeyEnc = .Files.Get .Values.alerts.auth.keyFile | b64enc }} +{{- $caCertEnc = .Files.Get .Values.alerts.auth.caFile | b64enc }} +{{- end }} +{{- $result := dict "crt" $certCrtEnc "key" $certKeyEnc "ca" $caCertEnc }} +{{- $result | toYaml }} +{{- end }} diff --git a/alerts/charts/templates/ca-secret-issuer-cert.yaml b/alerts/charts/templates/ca-secret-issuer-cert.yaml index c261ccd9..4b78bb7e 100644 --- a/alerts/charts/templates/ca-secret-issuer-cert.yaml +++ b/alerts/charts/templates/ca-secret-issuer-cert.yaml @@ -1,31 +1,35 @@ {{- if and .Values.alerts.alertmanager.enabled .Values.alerts.alertmanager.ingress.enabled }} -{{- $caSecret := (lookup "v1" "Secret" $.Release.Namespace (printf "%s-%s" $.Release.Namespace "monitoring-ca")) }} -{{- if not $caSecret }} -{{- $ca := genCA (printf "%s-%s" $.Release.Name "custom-ca") 3650 }} +{{- $cert := fromYaml (include "alerts.generateCert" .) }} +{{- $caCertEnc := $cert.ca }} +{{- $certCrtEnc := $cert.crt }} +{{- $certKeyEnc := $cert.key }} apiVersion: v1 kind: Secret -type: Opaque - +type: kubernetes.io/tls metadata: - name: {{ $.Release.Namespace }}-monitoring-ca - labels: -{{- include "kube-prometheus-stack.labels" . | indent 4 }} annotations: - "helm.sh/hook": pre-install + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" + labels: +{{- include "kube-prometheus-stack.labels" . | nindent 4 }} + name: {{ $.Release.Namespace }}-monitoring-ca + namespace: {{ .Release.Namespace }} data: - tls.crt: {{ $ca.Cert | b64enc | quote }} - tls.key: {{ $ca.Key | b64enc | quote }} ---- -{{- end }} + tls.crt: {{ $certCrtEnc }} + tls.key: {{ $certKeyEnc }} + ca.crt: {{ $caCertEnc }} {{- if .Capabilities.APIVersions.Has "cert-manager.io/v1" }} +--- apiVersion: cert-manager.io/v1 kind: Issuer metadata: - name: {{ $.Release.Namespace }}-monitoring-issuer + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" labels: {{- include "kube-prometheus-stack.labels" . | indent 4 }} - annotations: - "helm.sh/hook": pre-install + name: {{ $.Release.Namespace }}-monitoring-issuer + namespace: {{ $.Release.Namespace }} spec: ca: secretName: {{ $.Release.Namespace }}-monitoring-ca @@ -33,14 +37,16 @@ spec: apiVersion: cert-manager.io/v1 kind: Certificate metadata: - name: {{ $.Release.Namespace }}-prometheus-auth + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" labels: {{- include "kube-prometheus-stack.labels" . | indent 4 }} - annotations: - "helm.sh/hook": pre-install + name: {{ $.Release.Namespace }}-prometheus-auth + namespace: {{ $.Release.Namespace }} spec: dnsNames: - - "*.cloud.sap" + - {{ .Values.global.greenhouse.baseDomain | default "greenhouse.io" }} issuerRef: group: cert-manager.io kind: Issuer diff --git a/alerts/charts/values.yaml b/alerts/charts/values.yaml index 35266b61..0dc2b8cb 100644 --- a/alerts/charts/values.yaml +++ b/alerts/charts/values.yaml @@ -6,6 +6,32 @@ global: # kube-prometheus-stack configuration scoped to alerts alerts: + ## Authentication configuration for Alertmanager + ## + auth: + + ## Use existing secret for Alertmanager authentication + secretName: "" + + ## TLS Certificate Option 1: Use Helm to automatically generate self-signed certificate. + autoGenerateCert: + enabled: true + # If set to true, new key/certificate is generated on helm upgrade. + recreate: false + # Cert period time in days. The default is 365 days. + certPeriodDays: 365 + + ## TLS Certificate Option 2: Use your own self-signed certificate. + ## The chart reads the contents of the file paths with the helm .Files.Get function. + ## Refer to this doc https://helm.sh/docs/chart_template_guide/accessing_files/ to understand + ## limitations of file paths accessible to the chart. + ## Path to your own PEM-encoded certificate. + certFile: "" + ## Path to your own PEM-encoded private key. + keyFile: "" + ## Path to the CA cert. + caFile: "" + ## Create default rules for monitoring the cluster ## defaultRules: diff --git a/alerts/plugindefinition.yaml b/alerts/plugindefinition.yaml index 7a2eb762..13413457 100644 --- a/alerts/plugindefinition.yaml +++ b/alerts/plugindefinition.yaml @@ -6,7 +6,7 @@ kind: PluginDefinition metadata: name: alerts spec: - version: 2.3.5 + version: 2.4.0 weight: 0 displayName: Alerts description: The Alerts Plugin consists of both Prometheus Alertmanager and Supernova, the holistic alert management UI @@ -15,7 +15,7 @@ spec: helmChart: name: alerts repository: oci://ghcr.io/cloudoperators/greenhouse-extensions/charts - version: 0.15.5 + version: 0.16.0 uiApplication: name: supernova version: "latest" @@ -41,7 +41,7 @@ spec: description: "PredefinedFilters are filters applied through TabNavigation in the UI to differentiate between contexts such as Production, QA, and others. They are loaded by default when the application is loaded. The format is a list of objects including name, display name and matchers (map containing matchers as name and expression pairs)" required: false type: list - + # prometheus-operator options - name: alerts.prometheusOperator.enabled description: Deploy Prometheus Operator if kube-monitoring has not already installed it once. required: false @@ -53,19 +53,36 @@ spec: default: false type: bool # alertmanager options - - name: alerts.alertmanager.enabled - description: Deploy Alertmanager. Deactivate if you bring your own Alertmanager. - required: true + - name: alerts.auth.secretName + description: Use custom secret for Alertmanager authentication + required: false + type: string + - name: alerts.auth.autoGenerateCert.enabled + description: TLS Certificate Option 1 - Use Helm to automatically generate self-signed certificate. + required: false type: bool + - name: alerts.auth.autoGenerateCert.certPeriodDays + description: Cert period time in days. The default is 365 days. + default: 365 - name: alerts.defaultRules.create description: Additional labels for Alertmanager PrometheusRule alerts. Name of the kube-monitoring Plugin to evaluate Alertmanager alerts. default: true required: false type: bool + - name: alerts.defaultRules.labels + description: Create default rules for monitoring Alertmanager. Deactivate if you bring your own Alertmanager. + default: + plugin: kube-monitoring + required: false + type: map - name: alerts.dashboard.create description: Whether to install the default dashboards for self-monitoring Prometheus Alertmanger. default: true type: bool + - name: alerts.alertmanager.enabled + description: Deploy Alertmanager. Deactivate if you bring your own Alertmanager. + required: true + type: bool - name: alerts.alertmanager.ingress.enabled description: Enable Alertmanager Ingress. default: true @@ -81,12 +98,6 @@ spec: plugin: kube-monitoring required: false type: map - - name: alerts.defaultRules.labels - description: Create default rules for monitoring Alertmanager. Deactivate if you bring your own Alertmanager. - default: - plugin: kube-monitoring - required: false - type: map - name: alerts.alertmanagerConfig.slack.routes description: List of Slack routes containing name, channel, matchers and webhookURL. required: false