diff --git a/.cruft.json b/.cruft.json index 09b8fbd..69a2ad5 100644 --- a/.cruft.json +++ b/.cruft.json @@ -14,7 +14,7 @@ "add_matrix": "y", "add_go_unit": "n", "automerge_patch": "y", - "automerge_patch_v0": "n", + "automerge_patch_v0": "y", "automerge_patch_regexp_blocklist": "", "automerge_patch_v0_regexp_allowlist": "", "automerge_minor_regexp_allowlist": "", diff --git a/.gitignore b/.gitignore index f6ff082..60e44bd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /helmcharts /manifests /vendor +/jsonnetfile.json /jsonnetfile.lock.json /crds /compiled diff --git a/class/defaults.yml b/class/defaults.yml index 69f8b87..169c5bf 100644 --- a/class/defaults.yml +++ b/class/defaults.yml @@ -2,4 +2,63 @@ parameters: rollout_operator: =_metadata: multi_tenant: true + namespace: syn-rollout-operator + + charts: + rollout-operator: + source: https://grafana.github.io/helm-charts + version: v0.47.0 + + images: + rolloutOperator: + registry: docker.io + repository: grafana/rollout-operator + + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + memory: 200Mi + + webhooks: + # Note that the webhooks installs rollout-operator CRDs. + enabled: true + timeoutSeconds: 10 + failurePolicy: 'Fail' + selfSignedCertSecretName: 'certificate' + objectSelector: {} + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' + # matchExpressions: + # - key: rollout-operator.syn.tools/allow + # operator: Exists + + monitoring: true + alerts: + rules: + 'alert:SYN_IncorrectWebhookConfigurationFailurePolicy': + expr: 'count by(type, webhook, namespace) (kube_validating_webhook_failure_policy{policy="Ignore", webhook=~"^(pod-eviction|zpdb-validation).+"} > 0)' + for: 5m + labels: + severity: warning + annotations: + summary: 'A validating or mutating rollout-operator webhook has an Ignore policy set. This should be set to Fail.' + 'alert:SYN_BadZoneAwarePodDisruptionBudgetConfiguration': + expr: 'sum by (job, namespace)(rate(rollout_operator_zpdb_configurations_observed_total{result="invalid"}[5m])) > 0' + for: 5m + labels: + severity: warning + annotations: + summary: 'An invalid zone aware pod disruption budget configuration has been observed.' + 'alert:SYN_HighNumberInflightZpdbRequests': + expr: 'avg_over_time(rollout_operator_zpdb_inflight_eviction_requests[5m]) > 10' + for: 5m + labels: + severity: warning + annotations: + summary: 'A sustained number of inflight ZPDB eviction requests has been observed.' + + helmValues: {} diff --git a/class/rollout-operator.yml b/class/rollout-operator.yml index 00de883..cf5a2b7 100644 --- a/class/rollout-operator.yml +++ b/class/rollout-operator.yml @@ -1,5 +1,12 @@ parameters: kapitan: + dependencies: + - type: helm + source: ${rollout_operator:charts:rollout-operator:source} + chart_name: rollout-operator + version: ${rollout_operator:charts:rollout-operator:version} + output_path: ${_base_directory}/helmcharts/rollout-operator/${rollout_operator:charts:rollout-operator:version} + compile: - input_paths: - ${_base_directory}/component/app.jsonnet @@ -9,3 +16,20 @@ parameters: - ${_base_directory}/component/main.jsonnet input_type: jsonnet output_path: rollout-operator/ + + # Helm chart + - input_type: jsonnet + input_paths: + - ${_base_directory}/component/helm.jsonnet + output_path: ${_base_directory}/helmcharts/rollout-operator/${rollout_operator:charts:rollout-operator:version}/ + - input_type: helm + output_type: yaml + input_paths: + - ${_base_directory}/helmcharts/rollout-operator/${rollout_operator:charts:rollout-operator:version} + output_path: ${_instance}/10_rollout_operator + helm_values_files: + - ${_base_directory}/helmcharts/rollout-operator/${rollout_operator:charts:rollout-operator:version}/values-component.yaml + - ${_base_directory}/helmcharts/rollout-operator/${rollout_operator:charts:rollout-operator:version}/values-overrides.yaml + helm_params: + name: rollout-operator + namespace: ${rollout_operator:namespace} diff --git a/component/app.jsonnet b/component/app.jsonnet index f08ba1d..e033378 100644 --- a/component/app.jsonnet +++ b/component/app.jsonnet @@ -3,7 +3,15 @@ local inv = kap.inventory(); local params = inv.parameters.rollout_operator; local argocd = import 'lib/argocd.libjsonnet'; -local app = argocd.App('rollout-operator', params.namespace); +local app = argocd.App('rollout-operator', params.namespace) { + spec+: { + syncPolicy+: { + syncOptions+: [ + 'ServerSideApply=true', + ], + }, + }, +}; local appPath = local project = std.get(std.get(app, 'spec', {}), 'project', 'syn'); diff --git a/component/helm.jsonnet b/component/helm.jsonnet new file mode 100644 index 0000000..8dae6a9 --- /dev/null +++ b/component/helm.jsonnet @@ -0,0 +1,52 @@ +local com = import 'lib/commodore.libjsonnet'; +local kap = import 'lib/kapitan.libjsonnet'; +local inv = kap.inventory(); + +// The hiera parameters for the component +local params = inv.parameters.rollout_operator; +local isOpenshift = std.member([ 'openshift4', 'oke' ], inv.parameters.facts.distribution); + +local values = { + global: { + commonLabels: { + 'app.kubernetes.io/managed-by': 'commodore', + 'app.kubernetes.io/name': 'rollout-operator', + }, + }, + image: { + registry: params.images.rolloutOperator.registry, + repository: params.images.rolloutOperator.repository, + [if std.objectHas(params.images.rolloutOperator, 'tag') then 'tag']: params.images.rolloutOperator.tag, + }, + resources: params.resources, + webhooks: { + [key]: params.webhooks[key] + for key in std.objectFields(params.webhooks) + if key != 'namespaceSelector' + }, + namespaceSelector: params.webhooks.namespaceSelector, + [if !isOpenshift then 'podSecurityContext']: { + fsGroup: 10001, + runAsGroup: 10001, + runAsNonRoot: true, + runAsUser: 10001, + seccompProfile: { + type: 'RuntimeDefault', + }, + }, + securityContext: { + readOnlyRootFilesystem: true, + capabilities: { + drop: [ 'ALL' ], + }, + allowPrivilegeEscalation: false, + }, + serviceMonitor: { + enabled: params.monitoring, + }, +}; + +{ + 'values-component': values, + 'values-overrides': params.helmValues, +} diff --git a/component/main.jsonnet b/component/main.jsonnet index 104d373..59cfc99 100644 --- a/component/main.jsonnet +++ b/component/main.jsonnet @@ -1,10 +1,38 @@ // main template for rollout-operator local kap = import 'lib/kapitan.libjsonnet'; local kube = import 'lib/kube.libjsonnet'; +local prom = import 'lib/prom.libsonnet'; local inv = kap.inventory(); + // The hiera parameters for the component local params = inv.parameters.rollout_operator; +local isOpenshift = std.member([ 'openshift4', 'oke' ], inv.parameters.facts.distribution); + +local namespace = { + apiVersion: 'v1', + kind: 'Namespace', + metadata: { + labels: { + 'app.kubernetes.io/managed-by': 'commodore', + 'app.kubernetes.io/name': params.namespace, + [if isOpenshift then 'openshift.io/cluster-monitoring']: 'true', + }, + name: params.namespace, + }, +}; + +local prometheusRules = prom.generateRules('rollout-operator', { 'rollout-operator.rules': params.alerts.rules }) { + metadata+: { + labels+: { + 'app.kubernetes.io/managed-by': 'commodore', + 'app.kubernetes.io/name': 'rollout-operator', + }, + namespace: params.namespace, + }, +}; // Define outputs below { + '00_namespace': namespace, + [if params.monitoring then '20_prometheus_rule']: prometheusRules, } diff --git a/docs/modules/ROOT/pages/references/parameters.adoc b/docs/modules/ROOT/pages/references/parameters.adoc index 3c78902..164358a 100644 --- a/docs/modules/ROOT/pages/references/parameters.adoc +++ b/docs/modules/ROOT/pages/references/parameters.adoc @@ -11,6 +11,206 @@ default:: `syn-rollout-operator` The namespace in which to deploy this component. +== `charts` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +rollout-operator: + source: https://grafana.github.io/helm-charts + version: 'v0.47.0' +---- + +Holds the reference to the used version of the charts. +See https://github.com/projectsyn/component-rollout-operator/blob/master/class/defaults.yml[class/defaults.yml] for the current version. + + +== `images` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +images: + rolloutOperator: + registry: docker.io + repository: grafana/rollout-operator +---- +example:: ++ +[source,yaml] +---- +images: + rolloutOperator: + registry: my-docker-cache.example.org + tag: latest +---- + +Configures the image registry, repository and tag. + +[TIP] +==== +If the `tag` parameter is not set, the one from the Helm chart will be used. +==== + + +== `resources` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +resources: + requests: + cpu: 100m + memory: 100Mi + limits: + memory: 200Mi +---- + +Configure resource requests and limits of the rollout-operator. + + +== `webhooks` + +Configure rollout-operator webhooks. + +=== `webhooks.enabled` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + enabled: true +---- + +Enable deployment of webhooks. + +=== `webhooks.failurePolicy` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + failurePolicy: 'Fail' +---- + +Validating and mutating webhook failure policy. `Ignore` or `Fail`. + +=== `webhooks.timeoutSeconds` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + timeoutSeconds: 10 +---- + +Timeout in seconds for the prepare-downscale mutating webhook. Must be between 1 and 30. + +=== `webhooks.selfSignedCertSecretName` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + selfSignedCertSecretName: 'certificate' +---- + +Secret resource name for the TLS certificate to be used with the webhooks. + +=== `webhooks.objectSelector` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + objectSelector: {} +---- +example:: ++ +[source,yaml] +---- +webhooks: + objectSelector: + matchExpressions: + - key: app + operator: In + values: + - loki + - mimir +---- + +Selector to filter which objects the webhooks apply to. + +=== `webhooks.namespaceSelector` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +webhooks: + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' +---- + +Namespace selector applied to all webhooks. Defaults to restricting to the release namespace. + + +== `monitoring` + +[horizontal] +type:: boolean +default:: ++ +[source,yaml] +---- +monitoring: true +---- + +Configures deployments of ServiceMonitor and PrometheusRule resources. + + +== `alerts` + +[horizontal] +type:: dict +default:: ++ +[source,yaml] +---- +alerts: + rules: ... +---- + +See https://github.com/projectsyn/component-rollout-operator/blob/master/class/defaults.yml[class/defaults.yml] for default rules. + + == Example [source,yaml] diff --git a/jsonnetfile.jsonnet b/jsonnetfile.jsonnet new file mode 100644 index 0000000..a4d3c60 --- /dev/null +++ b/jsonnetfile.jsonnet @@ -0,0 +1,16 @@ +{ + version: 1, + dependencies: std.prune([ + { + source: { + git: { + remote: 'https://github.com/projectsyn/jsonnet-libs', + subdir: '', + }, + }, + version: 'main', + name: 'syn', + }, + ]), + legacyImports: true, +} diff --git a/renovate.json b/renovate.json index f2e1d67..2c2abe1 100644 --- a/renovate.json +++ b/renovate.json @@ -29,7 +29,6 @@ "patch", "digest" ], - "matchCurrentVersion": "!/^v?0\\./", "automerge": true, "platformAutomerge": false, "labels": [ diff --git a/tests/defaults.yml b/tests/defaults.yml index a4da5b7..109db87 100644 --- a/tests/defaults.yml +++ b/tests/defaults.yml @@ -1,3 +1,9 @@ -# Overwrite parameters here - -# parameters: {...} +parameters: + kapitan: + dependencies: + - type: https + source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/master/lib/openshift4-monitoring-alert-patching.libsonnet + output_path: vendor/lib/alert-patching.libsonnet + - type: https + source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/master/lib/openshift4-monitoring-prom.libsonnet + output_path: vendor/lib/prom.libsonnet diff --git a/tests/golden/defaults/rollout-operator/apps/rollout-operator.yaml b/tests/golden/defaults/rollout-operator/apps/rollout-operator.yaml index e69de29..6825b97 100644 --- a/tests/golden/defaults/rollout-operator/apps/rollout-operator.yaml +++ b/tests/golden/defaults/rollout-operator/apps/rollout-operator.yaml @@ -0,0 +1,4 @@ +spec: + syncPolicy: + syncOptions: + - ServerSideApply=true diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/00_namespace.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/00_namespace.yaml new file mode 100644 index 0000000..14e2739 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/00_namespace.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: syn-rollout-operator + name: syn-rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml new file mode 100644 index 0000000..5463dc1 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml @@ -0,0 +1,50 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: replicatemplates.rollout-operator.grafana.com +spec: + group: rollout-operator.grafana.com + names: + categories: + - all + kind: ReplicaTemplate + plural: replicatemplates + singular: replicatemplate + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Status replicas + jsonPath: .status.replicas + name: StatusReplicas + type: string + - description: Spec replicas + jsonPath: .spec.replicas + name: SpecReplicas + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + labelSelector: + type: string + replicas: + default: 1 + minimum: 0 + type: integer + type: object + status: + properties: + replicas: + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .spec.labelSelector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml new file mode 100644 index 0000000..b5fab2d --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml @@ -0,0 +1,68 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: zoneawarepoddisruptionbudgets.rollout-operator.grafana.com +spec: + group: rollout-operator.grafana.com + names: + kind: ZoneAwarePodDisruptionBudget + plural: zoneawarepoddisruptionbudgets + shortNames: + - zdpb + singular: zoneawarepoddisruptionbudget + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + maxUnavailable: + description: The number of pods that can be unavailable within a + zone or partition. + minimum: 0 + type: integer + maxUnavailablePercentage: + description: Calculate the maxUnavailable value as a percentage + of the StatefulSet's spec.Replica count. This option is not supported + when using podNamePartitionRegex. + maximum: 100 + minimum: 0 + type: integer + podNamePartitionRegex: + 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. + type: string + podNameRegexGroup: + 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. + minimum: 1 + type: integer + selector: + description: A selector for finding pods and statefulsets that this + ZoneAwarePodDisruptionBudget applies to. + properties: + matchLabels: + additionalProperties: + type: string + type: object + required: + - matchLabels + type: object + required: + - selector + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml new file mode 100644 index 0000000..56c8854 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml @@ -0,0 +1,72 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator + namespace: syn-rollout-operator + spec: + containers: + - args: + - -kubernetes.namespace=syn-rollout-operator + - -server-tls.enabled=true + - -server-tls.self-signed-cert.secret-name=certificate + - -server-tls.self-signed-cert.dns-name=rollout-operator.syn-rollout-operator.svc + image: docker.io/grafana/rollout-operator:v0.36.1 + imagePullPolicy: IfNotPresent + name: rollout-operator + ports: + - containerPort: 8001 + name: http-metrics + protocol: TCP + - containerPort: 8443 + name: https + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + securityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + serviceAccountName: rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/no-downscale-webhook.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/no-downscale-webhook.yaml new file mode 100644 index 0000000..9919901 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/no-downscale-webhook.yaml @@ -0,0 +1,38 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + grafana.com/inject-rollout-operator-ca: 'true' + grafana.com/namespace: syn-rollout-operator + helm.sh/chart: rollout-operator-0.47.0 + name: no-downscale-syn-rollout-operator +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: rollout-operator + namespace: syn-rollout-operator + path: /admission/no-downscale + port: 443 + failurePolicy: Fail + name: no-downscale-syn-rollout-operator.grafana.com + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - UPDATE + resources: + - statefulsets + - statefulsets/scale + scope: Namespaced + sideEffects: None diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/pod-eviction-webhook.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/pod-eviction-webhook.yaml new file mode 100644 index 0000000..d38e392 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/pod-eviction-webhook.yaml @@ -0,0 +1,38 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + grafana.com/inject-rollout-operator-ca: 'true' + grafana.com/namespace: syn-rollout-operator + helm.sh/chart: rollout-operator-0.47.0 + name: pod-eviction-syn-rollout-operator +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: rollout-operator + namespace: syn-rollout-operator + path: /admission/pod-eviction + port: 443 + failurePolicy: Fail + name: pod-eviction-syn-rollout-operator.grafana.com + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' + rules: + - apiGroups: + - '' + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods/eviction + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/prepare-downscale-webhook.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/prepare-downscale-webhook.yaml new file mode 100644 index 0000000..df65be9 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/prepare-downscale-webhook.yaml @@ -0,0 +1,40 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + grafana.com/inject-rollout-operator-ca: 'true' + grafana.com/namespace: syn-rollout-operator + helm.sh/chart: rollout-operator-0.47.0 + name: prepare-downscale-syn-rollout-operator +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: rollout-operator + namespace: syn-rollout-operator + path: /admission/prepare-downscale + port: 443 + failurePolicy: Fail + matchPolicy: Equivalent + name: prepare-downscale-syn-rollout-operator.grafana.com + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - UPDATE + resources: + - statefulsets + - statefulsets/scale + scope: Namespaced + sideEffects: NoneOnDryRun + timeoutSeconds: 10 diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml new file mode 100644 index 0000000..d1751be --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml @@ -0,0 +1,52 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +rules: + - apiGroups: + - '' + resources: + - pods + verbs: + - list + - get + - watch + - delete + - apiGroups: + - apps + resources: + - statefulsets + verbs: + - list + - get + - watch + - patch + - apiGroups: + - apps + resources: + - statefulsets/status + verbs: + - update + - apiGroups: + - rollout-operator.grafana.com + resources: + - zoneawarepoddisruptionbudgets + verbs: + - get + - list + - watch + - apiGroups: + - rollout-operator.grafana.com + resources: + - replicatemplates/scale + - replicatemplates/status + verbs: + - get + - patch diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml new file mode 100644 index 0000000..3df4033 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: rollout-operator +subjects: + - kind: ServiceAccount + name: rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/service.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/service.yaml new file mode 100644 index 0000000..f1f0cef --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/service.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +spec: + ports: + - name: http-metrics + port: 8001 + protocol: TCP + targetPort: http-metrics + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator + type: ClusterIP diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..ed2ad3a --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/servicemonitor.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/servicemonitor.yaml new file mode 100644 index 0000000..2a4ffcc --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/servicemonitor.yaml @@ -0,0 +1,18 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator +spec: + endpoints: + - port: http-metrics + scheme: http + selector: + matchLabels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole-binding.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole-binding.yaml new file mode 100644 index 0000000..bd16200 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole-binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: rollout-operator-webhook-clusterrolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rollout-operator-webhook-clusterrole +subjects: + - kind: ServiceAccount + name: rollout-operator + namespace: syn-rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole.yaml new file mode 100644 index 0000000..3e43a66 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-clusterrole.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: rollout-operator-webhook-clusterrole +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - list + - patch + - watch diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role-binding.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role-binding.yaml new file mode 100644 index 0000000..2dc085b --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role-binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: rollout-operator-webhook-rolebinding + namespace: syn-rollout-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: rollout-operator-webhook-role +subjects: + - kind: ServiceAccount + name: rollout-operator + namespace: syn-rollout-operator diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role.yaml new file mode 100644 index 0000000..f032ed3 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/webhook-role.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: rollout-operator-webhook-role + namespace: syn-rollout-operator +rules: + - apiGroups: + - '' + resourceNames: + - certificate + resources: + - secrets + verbs: + - update + - get + - apiGroups: + - '' + resources: + - secrets + verbs: + - create diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/zone-aware-pod-disruption-budget-validating-webhook.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/zone-aware-pod-disruption-budget-validating-webhook.yaml new file mode 100644 index 0000000..ed5ea7e --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/zone-aware-pod-disruption-budget-validating-webhook.yaml @@ -0,0 +1,39 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + grafana.com/inject-rollout-operator-ca: 'true' + grafana.com/namespace: syn-rollout-operator + helm.sh/chart: rollout-operator-0.47.0 + name: zpdb-validation-syn-rollout-operator +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: rollout-operator + namespace: syn-rollout-operator + path: /admission/zpdb-validation + port: 443 + failurePolicy: Fail + name: zpdb-validation-syn-rollout-operator.grafana.com + namespaceSelector: + matchLabels: + rollout-operator.syn.tools/allow: '' + rules: + - apiGroups: + - rollout-operator.grafana.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - zoneawarepoddisruptionbudgets + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 diff --git a/tests/golden/defaults/rollout-operator/rollout-operator/20_prometheus_rule.yaml b/tests/golden/defaults/rollout-operator/rollout-operator/20_prometheus_rule.yaml new file mode 100644 index 0000000..71b8a49 --- /dev/null +++ b/tests/golden/defaults/rollout-operator/rollout-operator/20_prometheus_rule.yaml @@ -0,0 +1,46 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + name: rollout-operator + name: rollout-operator + namespace: syn-rollout-operator +spec: + groups: + - name: rollout-operator.rules + rules: + - alert: SYN_BadZoneAwarePodDisruptionBudgetConfiguration + annotations: + summary: An invalid zone aware pod disruption budget configuration has + been observed. + expr: sum by (job, namespace)(rate(rollout_operator_zpdb_configurations_observed_total{result="invalid"}[5m])) + > 0 + for: 5m + labels: + severity: warning + syn: 'true' + syn_component: rollout-operator + - alert: SYN_HighNumberInflightZpdbRequests + annotations: + summary: A sustained number of inflight ZPDB eviction requests has been + observed. + expr: avg_over_time(rollout_operator_zpdb_inflight_eviction_requests[5m]) + > 10 + for: 5m + labels: + severity: warning + syn: 'true' + syn_component: rollout-operator + - alert: SYN_IncorrectWebhookConfigurationFailurePolicy + annotations: + summary: A validating or mutating rollout-operator webhook has an Ignore + policy set. This should be set to Fail. + expr: count by(type, webhook, namespace) (kube_validating_webhook_failure_policy{policy="Ignore", + webhook=~"^(pod-eviction|zpdb-validation).+"} > 0) + for: 5m + labels: + severity: warning + syn: 'true' + syn_component: rollout-operator diff --git a/tests/golden/openshift/rollout-operator/apps/rollout-operator.yaml b/tests/golden/openshift/rollout-operator/apps/rollout-operator.yaml index e69de29..6825b97 100644 --- a/tests/golden/openshift/rollout-operator/apps/rollout-operator.yaml +++ b/tests/golden/openshift/rollout-operator/apps/rollout-operator.yaml @@ -0,0 +1,4 @@ +spec: + syncPolicy: + syncOptions: + - ServerSideApply=true diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/00_namespace.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/00_namespace.yaml new file mode 100644 index 0000000..04cac73 --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/00_namespace.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: syn-rollout-operator + openshift.io/cluster-monitoring: 'true' + name: syn-rollout-operator diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml new file mode 100644 index 0000000..5463dc1 --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/replica-templates-custom-resource-definition.yaml @@ -0,0 +1,50 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: replicatemplates.rollout-operator.grafana.com +spec: + group: rollout-operator.grafana.com + names: + categories: + - all + kind: ReplicaTemplate + plural: replicatemplates + singular: replicatemplate + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Status replicas + jsonPath: .status.replicas + name: StatusReplicas + type: string + - description: Spec replicas + jsonPath: .spec.replicas + name: SpecReplicas + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + labelSelector: + type: string + replicas: + default: 1 + minimum: 0 + type: integer + type: object + status: + properties: + replicas: + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .spec.labelSelector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml new file mode 100644 index 0000000..b5fab2d --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/crds/zone-aware-pod-disruption-budget-custom-resource-definition.yaml @@ -0,0 +1,68 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: zoneawarepoddisruptionbudgets.rollout-operator.grafana.com +spec: + group: rollout-operator.grafana.com + names: + kind: ZoneAwarePodDisruptionBudget + plural: zoneawarepoddisruptionbudgets + shortNames: + - zdpb + singular: zoneawarepoddisruptionbudget + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + maxUnavailable: + description: The number of pods that can be unavailable within a + zone or partition. + minimum: 0 + type: integer + maxUnavailablePercentage: + description: Calculate the maxUnavailable value as a percentage + of the StatefulSet's spec.Replica count. This option is not supported + when using podNamePartitionRegex. + maximum: 100 + minimum: 0 + type: integer + podNamePartitionRegex: + 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. + type: string + podNameRegexGroup: + 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. + minimum: 1 + type: integer + selector: + description: A selector for finding pods and statefulsets that this + ZoneAwarePodDisruptionBudget applies to. + properties: + matchLabels: + additionalProperties: + type: string + type: object + required: + - matchLabels + type: object + required: + - selector + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml new file mode 100644 index 0000000..d4ad0e4 --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/deployment.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + template: + metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/name: rollout-operator + namespace: syn-rollout-operator + spec: + containers: + - args: + - -kubernetes.namespace=syn-rollout-operator + image: docker.io/grafana/rollout-operator:v0.36.1 + imagePullPolicy: IfNotPresent + name: rollout-operator + ports: + - containerPort: 8001 + name: http-metrics + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + securityContext: {} + serviceAccountName: rollout-operator diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml new file mode 100644 index 0000000..6e7cf26 --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/role.yaml @@ -0,0 +1,44 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +rules: + - apiGroups: + - '' + resources: + - pods + verbs: + - list + - get + - watch + - delete + - apiGroups: + - apps + resources: + - statefulsets + verbs: + - list + - get + - watch + - patch + - apiGroups: + - apps + resources: + - statefulsets/status + verbs: + - update + - apiGroups: + - rollout-operator.grafana.com + resources: + - zoneawarepoddisruptionbudgets + verbs: + - get + - list + - watch diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml new file mode 100644 index 0000000..3df4033 --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/rolebinding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: rollout-operator +subjects: + - kind: ServiceAccount + name: rollout-operator diff --git a/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..ed2ad3a --- /dev/null +++ b/tests/golden/openshift/rollout-operator/rollout-operator/10_rollout_operator/rollout-operator/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/instance: rollout-operator + app.kubernetes.io/managed-by: commodore + app.kubernetes.io/name: rollout-operator + app.kubernetes.io/version: v0.36.1 + helm.sh/chart: rollout-operator-0.47.0 + name: rollout-operator + namespace: syn-rollout-operator diff --git a/tests/openshift.yml b/tests/openshift.yml index a4da5b7..f80f3d0 100644 --- a/tests/openshift.yml +++ b/tests/openshift.yml @@ -1,3 +1,17 @@ -# Overwrite parameters here +parameters: + kapitan: + dependencies: + - type: https + source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/master/lib/openshift4-monitoring-alert-patching.libsonnet + output_path: vendor/lib/alert-patching.libsonnet + - type: https + source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/master/lib/openshift4-monitoring-prom.libsonnet + output_path: vendor/lib/prom.libsonnet -# parameters: {...} + facts: + distribution: openshift4 + + rollout_operator: + webhooks: + enabled: false + monitoring: false