From 174e3e0dc49d63bdb8706490778db664966b039e Mon Sep 17 00:00:00 2001 From: Max Lengdell Date: Mon, 1 Jun 2026 11:22:35 +0200 Subject: [PATCH] feat: support namespaced webhook configurations for multi-operator deployments Add config.namespacedWebhooks option that, when enabled: - Appends the operator namespace to webhook configuration names - Sets ENABLE_WEBHOOK_NAMESPACE_SUFFIX env var on the operator - Adds namespaceSelector to webhook entries to scope them to the operator's namespace This allows multiple CloudNativePG operators to run in single-namespace mode on the same cluster without webhook name collisions. Signed-off-by: Max Lengdell --- charts/cloudnative-pg/README.md | 1 + .../cloudnative-pg/templates/deployment.yaml | 4 +++ .../mutatingwebhookconfiguration.yaml | 22 ++++++++++++++- .../validatingwebhookconfiguration.yaml | 27 ++++++++++++++++++- charts/cloudnative-pg/values.yaml | 3 +++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/charts/cloudnative-pg/README.md b/charts/cloudnative-pg/README.md index 8d7033a0c3..c7cfc666e6 100644 --- a/charts/cloudnative-pg/README.md +++ b/charts/cloudnative-pg/README.md @@ -34,6 +34,7 @@ Kubernetes: `>=1.29.0-0` | commonAnnotations | object | `{}` | Annotations to be added to all other resources. | | config.clusterWide | bool | `true` | This option determines if the operator is responsible for observing events across the entire Kubernetes cluster or if its focus should be narrowed down to the specific namespace within which it has been deployed. | | config.create | bool | `true` | Specifies whether the secret should be created. | +| config.namespacedWebhooks | bool | `false` | When set to true, appends the operator namespace to webhook configuration names to avoid collisions when running multiple operators in namespaced mode. | | config.data | object | `{}` | The content of the configmap/secret, see https://cloudnative-pg.io/documentation/current/operator_conf/#available-options for all the available options. | | config.maxConcurrentReconciles | int | `10` | The maximum number of concurrent reconciles. Defaults to 10. | | config.name | string | `"cnpg-controller-manager-config"` | The name of the configmap/secret to use. | diff --git a/charts/cloudnative-pg/templates/deployment.yaml b/charts/cloudnative-pg/templates/deployment.yaml index c17e6a7493..1449cf7554 100644 --- a/charts/cloudnative-pg/templates/deployment.yaml +++ b/charts/cloudnative-pg/templates/deployment.yaml @@ -93,6 +93,10 @@ spec: - name: WATCH_NAMESPACE value: "{{ include "cloudnative-pg.namespace" . }}" {{- end }} + {{- if .Values.config.namespacedWebhooks }} + - name: ENABLE_WEBHOOK_NAMESPACE_SUFFIX + value: "true" + {{- end }} {{- if .Values.additionalEnv }} {{- tpl (.Values.additionalEnv | toYaml) . | nindent 8 }} {{- end }} diff --git a/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml b/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml index c58628a60e..cf1a2cf98f 100644 --- a/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml +++ b/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml @@ -21,7 +21,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - name: cnpg-mutating-webhook-configuration + name: cnpg-mutating-webhook-configuration{{- if .Values.config.namespacedWebhooks }}-{{ include "cloudnative-pg.namespace" . }}{{- end }} {{- with .Values.commonAnnotations }} annotations: {{- toYaml . | nindent 4 }} @@ -39,6 +39,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} name: mbackup.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -60,6 +65,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} name: mcluster.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -81,6 +91,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} name: mdatabase.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -102,6 +117,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} name: mscheduledbackup.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io diff --git a/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml b/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml index c171c911d8..dc6b5cffc7 100644 --- a/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml +++ b/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml @@ -21,7 +21,7 @@ apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - name: cnpg-validating-webhook-configuration + name: cnpg-validating-webhook-configuration{{- if .Values.config.namespacedWebhooks }}-{{ include "cloudnative-pg.namespace" . }}{{- end }} labels: {{- include "cloudnative-pg.labels" . | nindent 4 }} {{- with .Values.rbac.annotations }} @@ -39,6 +39,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.validating.failurePolicy }} name: vbackup.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -60,6 +65,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.validating.failurePolicy }} name: vcluster.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -81,6 +91,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.validating.failurePolicy }} name: vscheduledbackup.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -102,6 +117,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.validating.failurePolicy }} name: vdatabase.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io @@ -123,6 +143,11 @@ webhooks: port: {{ .Values.service.port }} failurePolicy: {{ .Values.webhook.validating.failurePolicy }} name: vpooler.cnpg.io + {{- if .Values.config.namespacedWebhooks }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "cloudnative-pg.namespace" . }} + {{- end }} rules: - apiGroups: - postgresql.cnpg.io diff --git a/charts/cloudnative-pg/values.yaml b/charts/cloudnative-pg/values.yaml index f70d2926c0..b107e6f4db 100644 --- a/charts/cloudnative-pg/values.yaml +++ b/charts/cloudnative-pg/values.yaml @@ -78,6 +78,9 @@ config: # events across the entire Kubernetes cluster or if its focus should be # narrowed down to the specific namespace within which it has been deployed. clusterWide: true + # -- When set to true, appends the operator namespace to webhook configuration + # names to avoid collisions when running multiple operators in namespaced mode. + namespacedWebhooks: false # -- The content of the configmap/secret, see # https://cloudnative-pg.io/documentation/current/operator_conf/#available-options # for all the available options.