Skip to content

[rollout-operator] - Add support for webhooks #3859

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

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5d83013
WIP
tcp13equals2 Aug 20, 2025
f410577
Table lint
tcp13equals2 Aug 20, 2025
f525e88
Move CRD into custom directory, make Failure policy explicit, add ZPD…
tcp13equals2 Aug 21, 2025
885f487
Merge branch 'main' into andrewhall/2365-add-rollout-operator-webhooks
tcp13equals2 Aug 21, 2025
b8f657e
Update role to have static CRD group name
tcp13equals2 Aug 21, 2025
c3a5a8c
Merge branch 'andrewhall/2365-add-rollout-operator-webhooks' of https…
tcp13equals2 Aug 21, 2025
f6aff8e
bump version
tcp13equals2 Aug 21, 2025
f09ad49
helm doc
tcp13equals2 Aug 21, 2025
ed61f60
helm version bump
tcp13equals2 Aug 21, 2025
23b854a
helm version bump space
tcp13equals2 Aug 21, 2025
0bbf9e8
helm version bump space
tcp13equals2 Aug 21, 2025
8d8a353
lint
tcp13equals2 Aug 21, 2025
7f1c21e
lint
tcp13equals2 Aug 21, 2025
cee571b
lint
tcp13equals2 Aug 21, 2025
6256cdb
lint
tcp13equals2 Aug 21, 2025
6e7824e
Still linting
tcp13equals2 Aug 21, 2025
060c2e5
Typo
tcp13equals2 Aug 21, 2025
935896c
Re-gen table
tcp13equals2 Aug 21, 2025
18f39ee
Address PR comments and add in replica template CRD
tcp13equals2 Aug 21, 2025
e42288a
Merge branch 'main' into andrewhall/2365-add-rollout-operator-webhooks
tcp13equals2 Aug 22, 2025
81f0877
Bump the appVersion to match what the rollout-operator will be
tcp13equals2 Aug 22, 2025
21edd58
Merge branch 'andrewhall/2365-add-rollout-operator-webhooks' of https…
tcp13equals2 Aug 22, 2025
08b81f0
Bump the appVersion to match what the rollout-operator will be
tcp13equals2 Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/rollout-operator/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: rollout-operator
description: "Grafana rollout-operator"
type: application
version: 0.31.0
version: 0.32.0
appVersion: v0.28.0
Copy link
Author

@tcp13equals2 tcp13equals2 Aug 21, 2025

Choose a reason for hiding this comment

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

This app version will need to be bumped once the new rollout-operator is merged/published (grafana/rollout-operator#253)

home: https://github.com/grafana/rollout-operator
kubeVersion: ^1.10.0-0
5 changes: 4 additions & 1 deletion charts/rollout-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Helm chart for deploying [Grafana rollout-operator](https://github.com/grafana/r

# rollout-operator

![Version: 0.31.0](https://img.shields.io/badge/Version-0.31.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.28.0](https://img.shields.io/badge/AppVersion-v0.28.0-informational?style=flat-square)
![Version: 0.32.0](https://img.shields.io/badge/Version-0.32.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.28.0](https://img.shields.io/badge/AppVersion-v0.28.0-informational?style=flat-square)

Grafana rollout-operator

Expand Down Expand Up @@ -72,3 +72,6 @@ It is not a highly available application and runs as a single pod.
| serviceMonitor.relabelings | list | `[]` | ServiceMonitor relabel configs to apply to samples before scraping https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig |
| serviceMonitor.scrapeTimeout | string | `nil` | ServiceMonitor scrape timeout in Go duration format (e.g. 15s) |
| tolerations | list | `[]` | |
| webhooks.enabled | bool | `false` | Enable the rollout-operator webhooks. See https://github.com/grafana/rollout-operator/#webhooks. Note that the webhooks require custom resource definitions. If upgrading, manually apply the files in the charts/rollout-operator/crds/ directory. |
| webhooks.failurePolicy | string | `"Fail"` | Validating and mutating webhook failure policy. `Ignore` or `Fail`. |
| webhooks.selfSignedCertSecretName | string | `"certificate"` | Secret resource name for the TLS certificate to be used with the webhooks |
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: replicatemplates.rollout-operator.grafana.com
spec:
group: rollout-operator.grafana.com
versions:
- name: v1
served: true
storage: true
additionalPrinterColumns:
- description: Status replicas
jsonPath: .status.replicas
name: StatusReplicas
type: string
- description: Spec replicas
jsonPath: .spec.replicas
name: SpecReplicas
type: string
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
default: 1
minimum: 0
labelSelector:
type: string
status:
type: object
properties:
replicas:
type: integer
subresources:
status: { }
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
labelSelectorPath: .spec.labelSelector
scope: Namespaced
names:
plural: replicatemplates
singular: replicatemplate
kind: ReplicaTemplate
categories:
# Include in "kubectl get all" output
- all
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
Copy link
Author

Choose a reason for hiding this comment

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

Note that this is in the crds directory so it can not be templated.

See https://helm.sh/docs/chart_best_practices/custom_resource_definitions/

metadata:
name: zoneawarepoddisruptionbudgets.rollout-operator.grafana.com
spec:
group: rollout-operator.grafana.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- selector
properties:
maxUnavailable:
type: integer
description: The number of pods that can be unavailable within a zone or partition.
minimum: 0
maxUnavailablePercentage:
type: integer
description: Calculate the maxUnavailable value as a percentage of the StatefulSet's spec.Replica count. This option is not supported when using podNamePartitionRegex.
minimum: 0
maximum: 100
selector:
type: object
description: A selector for finding pods and statefulsets that this ZoneAwarePodDisruptionBudget applies to.
required:
- matchLabels
properties:
matchLabels:
type: object
additionalProperties:
type: string
podNamePartitionRegex:
type: string
description: A regular expression for returning a partition name given a pod name. This field is optional and should only be used when the ZoneAwarePodDisruptionBudget is to be scoped to a partition, such as a multi-zone ingester deployment with ingest_storage_enabled. Enabling this changes the ZPDB functionality such that minAvailability is applied across ALL zones for a given partition. When not enabled, the minAvailability is applied to pods within the eviction zone assuming there are no disruptions in the other zones.
podNameRegexGroup:
type: integer
minimum: 1
description: The regular expression group number that contains the partition name. This field is only required when the podNamePartitionRegex field is set and has more then one subexpression grouping. The default value is 1.
subresources:
status: {}
scope: Namespaced
names:
kind: ZoneAwarePodDisruptionBudget
plural: zoneawarepoddisruptionbudgets
singular: zoneawarepoddisruptionbudget
shortNames:
- zdpb
6 changes: 5 additions & 1 deletion charts/rollout-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ spec:
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- -kubernetes.namespace={{ .Release.Namespace }}
{{- if .Values.webhooks.enabled }}
- -server-tls.enabled=true
- -server-tls.self-signed-cert.secret-name={{ .Values.webhooks.selfSignedCertSecretName }}
{{- end }}
{{- range .Values.extraArgs }}
- {{ . }}
{{- end }}
Expand All @@ -77,4 +81,4 @@ spec:
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
36 changes: 36 additions & 0 deletions charts/rollout-operator/templates/no-downscale-webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: no-downscale-{{ .Release.Namespace }}
labels:
grafana.com/inject-rollout-operator-ca: "true"
grafana.com/namespace: {{ .Release.Namespace | quote }}
{{- include "rollout-operator.labels" . | nindent 4 }}
webhooks:
- name: no-downscale-{{ .Release.Namespace }}.grafana.com
clientConfig:
service:
namespace: {{ .Release.Namespace | quote }}
name: {{ include "rollout-operator.fullname" . }}
path: /admission/no-downscale
port: 443
rules:
- operations:
- UPDATE
apiGroups:
- apps
apiVersions:
- v1
resources:
- statefulsets
- statefulsets/scale
scope: Namespaced
admissionReviewVersions:
- v1
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: {{ .Release.Namespace | quote }}
sideEffects: None
failurePolicy: {{.Values.webhooks.failurePolicy}}
{{- end -}}
35 changes: 35 additions & 0 deletions charts/rollout-operator/templates/pod-eviction-webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-eviction-{{ .Release.Namespace }}
labels:
grafana.com/inject-rollout-operator-ca: "true"
grafana.com/namespace: {{ .Release.Namespace | quote }}
{{- include "rollout-operator.labels" . | nindent 4 }}
webhooks:
- name: pod-eviction-{{ .Release.Namespace }}.grafana.com
clientConfig:
service:
namespace: {{ .Release.Namespace | quote }}
name: {{ include "rollout-operator.fullname" . }}
path: /admission/pod-eviction
port: 443
rules:
- operations:
- CREATE
apiGroups:
- ""
apiVersions:
- v1
resources:
- pods/eviction
scope: Namespaced
admissionReviewVersions:
- v1
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: {{ .Release.Namespace | quote }}
sideEffects: None
failurePolicy: {{.Values.webhooks.failurePolicy}}
{{- end -}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: prepare-downscale-{{ .Release.Namespace }}
labels:
grafana.com/inject-rollout-operator-ca: "true"
grafana.com/namespace: {{ .Release.Namespace | quote }}
{{- include "rollout-operator.labels" . | nindent 4 }}
webhooks:
- name: prepare-downscale-{{ .Release.Namespace }}.grafana.com
clientConfig:
service:
namespace: {{ .Release.Namespace | quote }}
name: {{ include "rollout-operator.fullname" . }}
path: /admission/prepare-downscale
port: 443
rules:
- operations:
- UPDATE
apiGroups:
- apps
apiVersions:
- v1
resources:
- statefulsets
- statefulsets/scale
scope: Namespaced
admissionReviewVersions:
- v1
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: {{ .Release.Namespace | quote }}
sideEffects: NoneOnDryRun
matchPolicy: Equivalent
timeoutSeconds: 10
failurePolicy: {{.Values.webhooks.failurePolicy}}
{{- end -}}
8 changes: 8 additions & 0 deletions charts/rollout-operator/templates/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ rules:
- statefulsets/status
verbs:
- update
- apiGroups:
- rollout-operator.grafana.com
Copy link
Author

Choose a reason for hiding this comment

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

Note that his group name is hard coded to match the CRD spec.group

resources:
- zoneawarepoddisruptionbudgets
verbs:
- get
- list
- watch
12 changes: 11 additions & 1 deletion charts/rollout-operator/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if .Values.serviceMonitor.enabled }}
{{- if or (eq .Values.serviceMonitor.enabled true) (eq .Values.webhooks.enabled true) }}
apiVersion: v1
kind: Service
metadata:
Expand All @@ -8,12 +8,22 @@ metadata:
{{- include "rollout-operator.labels" . | nindent 4 }}
spec:
type: ClusterIP
{{- if eq .Values.webhooks.enabled false }}
clusterIP: None
{{- end }}
ports:
{{- if .Values.serviceMonitor.enabled }}
- port: 8001
targetPort: http-metrics
protocol: TCP
name: http-metrics
{{- end }}
{{- if .Values.webhooks.enabled }}
- port: 443
protocol: TCP
targetPort: 8443
name: https
{{- end }}
selector:
{{- include "rollout-operator.selectorLabels" . | nindent 4 }}
{{- end -}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "rollout-operator.fullname" . }}-webhook-clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "rollout-operator.fullname" . }}-webhook-clusterrole
subjects:
- kind: ServiceAccount
name: {{ include "rollout-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
{{- end -}}
16 changes: 16 additions & 0 deletions charts/rollout-operator/templates/webhook-clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "rollout-operator.fullname" . }}-webhook-clusterrole
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
- mutatingwebhookconfigurations
verbs:
- list
- patch
- watch
{{- end -}}
15 changes: 15 additions & 0 deletions charts/rollout-operator/templates/webhook-role-binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "rollout-operator.fullname" . }}-webhook-rolebinding
namespace: {{ .Release.Namespace | quote }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "rollout-operator.fullname" . }}-webhook-role
subjects:
- kind: ServiceAccount
name: {{ include "rollout-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
{{- end -}}
23 changes: 23 additions & 0 deletions charts/rollout-operator/templates/webhook-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{- if .Values.webhooks.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "rollout-operator.fullname" . }}-webhook-role
namespace: {{ .Release.Namespace | quote }}
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- update
- get
resourceNames:
- {{ .Values.webhooks.selfSignedCertSecretName }}
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
{{- end -}}
Loading
Loading