This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/superset-kubernetes-operator.git
The following commit(s) were added to refs/heads/main by this push:
new ec2a091 feat(helm): add dnsPolicy and dnsConfig values (#394)
ec2a091 is described below
commit ec2a0916c041751a12fecd120e94ed09bfc9d003
Author: Younsung Lee <[email protected]>
AuthorDate: Thu Oct 1 03:36:42 2026 +0900
feat(helm): add dnsPolicy and dnsConfig values (#394)
* feat(helm): add dnsPolicy and dnsConfig values for manager pod
Expose dnsPolicy and dnsConfig on the operator Deployment so installs can
tune the manager pod resolver, for example lowering ndots to 2 to avoid
unnecessary cluster search-domain queries for external names. Both are
unset by default, preserving the Kubernetes ClusterFirst behavior.
Rendering fails when dnsPolicy is None without dnsConfig.nameservers,
since the API server rejects that pod spec. The schema restricts
dnsPolicy to the Kubernetes enum and dnsConfig to PodDNSConfig fields.
Signed-off-by: younsl <[email protected]>
* docs: link dnsPolicy and dnsConfig changelog entry to #394
Signed-off-by: younsl <[email protected]>
* fix(helm): drop dnsPolicy None nameserver guard test
The API server already rejects a pod spec with dnsPolicy None and no
nameservers, so the chart does not need to cover that case.
Signed-off-by: younsl <[email protected]>
* fix(helm): drop dnsPolicy None nameserver guard
Deployment admission already validates the pod template, so helm install
fails with the API server error directly. Avoid echoing API server
policy in chart templates.
Signed-off-by: younsl <[email protected]>
* fix(helm): drop default value from dnsPolicy schema description
Naming the Kubernetes default in the schema risks drifting from upstream.
Signed-off-by: younsl <[email protected]>
* fix(helm): link corev1.PodDNSConfig from dnsConfig value docs
Signed-off-by: younsl <[email protected]>
* fix(helm): default unset string values to null
Standardize optional string values on ~ instead of "", matching the
chart's existing null defaults (revisionHistoryLimit, PDB bounds). The
schema now accepts null for each of these values and still accepts an
explicit empty string, so existing overrides keep validating. Default
rendered manifests are unchanged.
Signed-off-by: younsl <[email protected]>
---------
Signed-off-by: younsl <[email protected]>
---
charts/superset-operator/README.md | 14 ++++----
charts/superset-operator/templates/deployment.yaml | 7 ++++
.../tests/__snapshot__/full_options_test.yaml.snap | 5 +++
.../tests/optout_and_helpers_test.yaml | 37 +++++++++++++++++--
.../tests/values/full-options.yaml | 7 ++++
charts/superset-operator/values.schema.json | 41 ++++++++++++++++++----
charts/superset-operator/values.yaml | 28 +++++++++------
docs/reference/releases.md | 2 ++
8 files changed, 115 insertions(+), 26 deletions(-)
diff --git a/charts/superset-operator/README.md
b/charts/superset-operator/README.md
index 5028ae9..d57493e 100644
--- a/charts/superset-operator/README.md
+++ b/charts/superset-operator/README.md
@@ -53,30 +53,32 @@ The chart values schema intentionally allows undeclared
top-level keys so shared
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | Affinity rules for the manager pod. See
[corev1.Affinity](https://pkg.go.dev/k8s.io/api/core/v1#Affinity). |
+| dnsConfig | object | `{}` | DNS config for the manager pod. See
[corev1.PodDNSConfig](https://pkg.go.dev/k8s.io/api/core/v1#PodDNSConfig). |
+| dnsPolicy | string | `nil` | DNS policy for the manager pod. |
| extraManifests | list | `[]` | Additional Kubernetes manifests rendered
alongside the chart's own resources. Each entry is a YAML object or a string;
both are passed through Helm's `tpl` function so template expressions such as
`{{ .Release.Namespace }}` are resolved. Use for release-scoped companion
resources (e.g. a cert-manager Certificate, NetworkPolicy, or ExternalSecret).
Do not use for shared cluster infrastructure such as Gateway controllers, CRDs,
or shared Gateways — those ha [...]
| healthProbes.livenessProbe | object |
`{"httpGet":{"path":"/healthz","port":8081},"initialDelaySeconds":15,"periodSeconds":20}`
| Liveness probe for the manager container. See
[corev1.Probe](https://pkg.go.dev/k8s.io/api/core/v1#Probe). |
| healthProbes.readinessProbe | object |
`{"httpGet":{"path":"/readyz","port":8081},"initialDelaySeconds":5,"periodSeconds":10}`
| Readiness probe for the manager container. See
[corev1.Probe](https://pkg.go.dev/k8s.io/api/core/v1#Probe). |
| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. |
| image.repository | string | `"ghcr.io/apache/superset-kubernetes-operator"`
| Docker image repository for the operator manager. |
-| image.tag | string | `""` | Image tag. Defaults to the chart's appVersion
when empty. |
+| image.tag | string | `nil` | Image tag. Defaults to the chart's appVersion
when unset. |
| imagePullSecrets | list | `[]` | Existing Secrets used to pull the operator
image from a private registry. |
| leaderElection.enabled | bool | `true` | Enable leader election so only one
replica is active at a time. Required when `replicas > 1`. |
-| logLevel | string | `""` | Operator log verbosity (`--zap-log-level`). Leave
empty for the default (`info`). Set to `debug` (alias `1`) for per-reconcile
progress logs, or `2` for trace-level internals. |
-| metrics.certSecretName | string | `""` | Name of a Secret containing
`tls.crt`, `tls.key`, and `ca.crt` to use for the metrics server instead of the
built-in self-signed certificate. Typically written by cert-manager. |
+| logLevel | string | `nil` | Operator log verbosity (`--zap-log-level`).
Leave unset for the default (`info`). Set to `debug` (alias `1`) for
per-reconcile progress logs, or `2` for trace-level internals. |
+| metrics.certSecretName | string | `nil` | Name of a Secret containing
`tls.crt`, `tls.key`, and `ca.crt` to use for the metrics server instead of the
built-in self-signed certificate. Typically written by cert-manager. |
| metrics.enabled | bool | `true` | Enable the metrics endpoint. |
| metrics.service.port | int | `8443` | Port the metrics Service listens on. |
| metrics.serviceMonitor.bearerTokenFile | string |
`"/var/run/secrets/kubernetes.io/serviceaccount/token"` | Path to the bearer
token Prometheus uses to authenticate to the metrics endpoint. |
| metrics.serviceMonitor.enabled | bool | `false` | Create a Prometheus
Operator ServiceMonitor for the operator metrics endpoint. Requires the
prometheus-operator CRDs to be installed. |
| metrics.serviceMonitor.interval | string | `"30s"` | How often Prometheus
scrapes the metrics endpoint. |
| metrics.serviceMonitor.labels | object | `{}` | Extra labels on the
ServiceMonitor so Prometheus Operator selects it (e.g. `{release: prometheus}`
for kube-prometheus-stack). |
-| metrics.serviceMonitor.scrapeTimeout | string | `""` | Scrape timeout. Empty
inherits Prometheus' default. |
+| metrics.serviceMonitor.scrapeTimeout | string | `nil` | Scrape timeout.
Unset inherits Prometheus' default. |
| metrics.serviceMonitor.tlsConfig | object | `{"insecureSkipVerify":true}` |
TLS configuration for the ServiceMonitor scrape. The default trusts any
certificate, matching the operator's built-in self-signed flow. Override to
scrape over verified TLS. |
| nodeSelector | object | `{}` | Node selector for the manager pod. |
| podAnnotations | object | `{}` | Extra annotations to add to the manager
pod. |
| podDisruptionBudget.enabled | bool | `false` | Create a PodDisruptionBudget
for the manager pod. Only useful with `replicas >= 2`. |
| podDisruptionBudget.maxUnavailable | intOrString | `nil` | Maximum
unavailable pods (integer or percentage). Defaults to `1` when neither is set. |
| podDisruptionBudget.minAvailable | intOrString | `nil` | Minimum available
pods (integer or percentage). Mutually exclusive with `maxUnavailable`. |
-| podDisruptionBudget.unhealthyPodEvictionPolicy | string | `""` | Unhealthy
pod eviction policy (`IfHealthyBudget` or `AlwaysAllow`). Empty uses the
Kubernetes default. |
+| podDisruptionBudget.unhealthyPodEvictionPolicy | string | `nil` | Unhealthy
pod eviction policy (`IfHealthyBudget` or `AlwaysAllow`). Unset uses the
Kubernetes default. |
| podLabels | object | `{}` | Extra labels to add to the manager pod. |
| podSecurityContext | object |
`{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Pod-level
security context for the manager pod. See
[corev1.PodSecurityContext](https://pkg.go.dev/k8s.io/api/core/v1#PodSecurityContext).
|
| replicas | int | `1` | Number of operator manager replicas. |
@@ -86,7 +88,7 @@ The chart values schema intentionally allows undeclared
top-level keys so shared
| securityContext | object |
`{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}`
| Container-level security context for the manager container. See
[corev1.SecurityContext](https://pkg.go.dev/k8s.io/api/core/v1#SecurityContext).
|
| serviceAccount.annotations | object | `{}` | Annotations to add to the
ServiceAccount. |
| serviceAccount.create | bool | `true` | Whether to create a ServiceAccount
for the operator. |
-| serviceAccount.name | string | `""` | Name of the ServiceAccount to use.
Auto-generated from the release name when empty. |
+| serviceAccount.name | string | `nil` | Name of the ServiceAccount to use.
Auto-generated from the release name when unset. |
| tolerations | list | `[]` | Tolerations for the manager pod. See
[corev1.Toleration](https://pkg.go.dev/k8s.io/api/core/v1#Toleration). |
| topologySpreadConstraints | list | `[]` | Topology spread constraints for
the manager pod. See
[corev1.TopologySpreadConstraint](https://pkg.go.dev/k8s.io/api/core/v1#TopologySpreadConstraint).
|
| watch | object | `{"namespaces":[],"scope":"cluster"}` | Namespace watch
configuration. `scope: cluster` (default) watches all namespaces; manager RBAC
is rendered as ClusterRole + ClusterRoleBinding and requires cluster-scoped
RBAC on install. `scope: namespaces` watches only the namespaces listed in
`watch.namespaces` (falls back to the release namespace when empty); manager
RBAC is rendered as Role + RoleBinding per watched namespace with no manager
ClusterRole. Use on restricted [...]
diff --git a/charts/superset-operator/templates/deployment.yaml
b/charts/superset-operator/templates/deployment.yaml
index 016d558..88dc99d 100644
--- a/charts/superset-operator/templates/deployment.yaml
+++ b/charts/superset-operator/templates/deployment.yaml
@@ -59,6 +59,13 @@ spec:
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
+ {{- with .Values.dnsPolicy }}
+ dnsPolicy: {{ . }}
+ {{- end }}
+ {{- with .Values.dnsConfig }}
+ dnsConfig:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
containers:
- name: manager
image: {{ include "superset-operator.image" . }}
diff --git
a/charts/superset-operator/tests/__snapshot__/full_options_test.yaml.snap
b/charts/superset-operator/tests/__snapshot__/full_options_test.yaml.snap
index d81735c..5e43052 100644
--- a/charts/superset-operator/tests/__snapshot__/full_options_test.yaml.snap
+++ b/charts/superset-operator/tests/__snapshot__/full_options_test.yaml.snap
@@ -91,6 +91,11 @@ renders the full install manifests:
- mountPath: /tmp/k8s-metrics-server/metrics-certs
name: metrics-certs
readOnly: true
+ dnsConfig:
+ options:
+ - name: ndots
+ value: "2"
+ dnsPolicy: ClusterFirst
imagePullSecrets:
- name: superset-operator-registry
nodeSelector:
diff --git a/charts/superset-operator/tests/optout_and_helpers_test.yaml
b/charts/superset-operator/tests/optout_and_helpers_test.yaml
index eac37fd..35ccfed 100644
--- a/charts/superset-operator/tests/optout_and_helpers_test.yaml
+++ b/charts/superset-operator/tests/optout_and_helpers_test.yaml
@@ -55,7 +55,7 @@ tests:
set:
serviceAccount:
create: true
- name: ""
+ name: ~
template: templates/deployment.yaml
asserts:
- equal:
@@ -84,7 +84,7 @@ tests:
set:
serviceAccount:
create: false
- name: ""
+ name: ~
asserts:
- template: templates/deployment.yaml
equal:
@@ -161,6 +161,39 @@ tests:
path: spec.replicas
value: 0
+ # --- dnsPolicy / dnsConfig ---
+ - it: omits dnsPolicy and dnsConfig by default
+ template: templates/deployment.yaml
+ asserts:
+ - notExists:
+ path: spec.template.spec.dnsPolicy
+ - notExists:
+ path: spec.template.spec.dnsConfig
+
+ - it: renders dnsPolicy None with nameservers
+ set:
+ dnsPolicy: None
+ dnsConfig:
+ nameservers:
+ - 169.254.20.10
+ template: templates/deployment.yaml
+ asserts:
+ - equal:
+ path: spec.template.spec.dnsPolicy
+ value: None
+ - equal:
+ path: spec.template.spec.dnsConfig.nameservers
+ value:
+ - 169.254.20.10
+
+ - it: rejects an unknown dnsPolicy
+ set:
+ dnsPolicy: ClusterLast
+ template: templates/deployment.yaml
+ asserts:
+ - failedTemplate:
+ errorPattern: "dnsPolicy"
+
# --- podDisruptionBudget ---
- it: renders no PDB by default
template: templates/poddisruptionbudget.yaml
diff --git a/charts/superset-operator/tests/values/full-options.yaml
b/charts/superset-operator/tests/values/full-options.yaml
index 0fc5e29..afc272b 100644
--- a/charts/superset-operator/tests/values/full-options.yaml
+++ b/charts/superset-operator/tests/values/full-options.yaml
@@ -124,6 +124,13 @@ topologySpreadConstraints:
matchLabels:
control-plane: controller-manager
+dnsPolicy: ClusterFirst
+
+dnsConfig:
+ options:
+ - name: ndots
+ value: "2"
+
podDisruptionBudget:
enabled: true
minAvailable: 1
diff --git a/charts/superset-operator/values.schema.json
b/charts/superset-operator/values.schema.json
index a4c4256..3479e58 100644
--- a/charts/superset-operator/values.schema.json
+++ b/charts/superset-operator/values.schema.json
@@ -14,7 +14,7 @@
"additionalProperties": false,
"properties": {
"repository": { "type": "string" },
- "tag": { "type": "string" },
+ "tag": { "type": ["string", "null"] },
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"]
@@ -57,7 +57,7 @@
"additionalProperties": false,
"properties": {
"create": { "type": "boolean" },
- "name": { "type": "string" },
+ "name": { "type": ["string", "null"] },
"annotations": { "type": "object" }
}
},
@@ -69,8 +69,9 @@
}
},
"logLevel": {
- "description": "Operator log verbosity (--zap-log-level): empty =
default (info). One of \"info\", \"debug\", \"error\", \"panic\", or an integer
level (1 = debug/V1, 2 = V2 trace).",
+ "description": "Operator log verbosity (--zap-log-level): unset =
default (info). One of \"info\", \"debug\", \"error\", \"panic\", or an integer
level (1 = debug/V1, 2 = V2 trace).",
"oneOf": [
+ { "type": "null" },
{ "type": "string", "enum": ["", "info", "debug", "error", "panic",
"1", "2"] },
{ "type": "integer", "enum": [1, 2] }
]
@@ -87,14 +88,14 @@
"port": { "type": "integer" }
}
},
- "certSecretName": { "type": "string" },
+ "certSecretName": { "type": ["string", "null"] },
"serviceMonitor": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"interval": { "type": "string" },
- "scrapeTimeout": { "type": "string" },
+ "scrapeTimeout": { "type": ["string", "null"] },
"labels": { "type": "object" },
"tlsConfig": { "type": "object" },
"bearerTokenFile": { "type": "string" }
@@ -140,6 +141,32 @@
"description": "Topology spread constraints for the manager pod. See
https://pkg.go.dev/k8s.io/api/core/v1#TopologySpreadConstraint",
"type": "array"
},
+ "dnsPolicy": {
+ "description": "DNS policy for the manager pod. Unset uses the
Kubernetes default.",
+ "type": ["string", "null"],
+ "enum": [null, "", "ClusterFirst", "ClusterFirstWithHostNet", "Default",
"None"]
+ },
+ "dnsConfig": {
+ "description": "DNS resolver settings for the manager pod. See
https://pkg.go.dev/k8s.io/api/core/v1#PodDNSConfig",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "nameservers": { "type": "array", "items": { "type": "string" } },
+ "searches": { "type": "array", "items": { "type": "string" } },
+ "options": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "value": { "type": "string" }
+ }
+ }
+ }
+ }
+ },
"podDisruptionBudget": {
"description": "PodDisruptionBudget for the manager pod. See
https://pkg.go.dev/k8s.io/api/policy/v1#PodDisruptionBudgetSpec",
"type": "object",
@@ -161,8 +188,8 @@
]
},
"unhealthyPodEvictionPolicy": {
- "type": "string",
- "enum": ["", "IfHealthyBudget", "AlwaysAllow"]
+ "type": ["string", "null"],
+ "enum": [null, "", "IfHealthyBudget", "AlwaysAllow"]
}
}
},
diff --git a/charts/superset-operator/values.yaml
b/charts/superset-operator/values.yaml
index fddef08..d4d43c5 100644
--- a/charts/superset-operator/values.yaml
+++ b/charts/superset-operator/values.yaml
@@ -1,8 +1,8 @@
image:
# -- Docker image repository for the operator manager.
repository: ghcr.io/apache/superset-kubernetes-operator
- # -- Image tag. Defaults to the chart's appVersion when empty.
- tag: "" # defaults to .Chart.AppVersion
+ # -- Image tag. Defaults to the chart's appVersion when unset.
+ tag: ~
# -- Image pull policy.
pullPolicy: IfNotPresent
@@ -33,8 +33,8 @@ resizePolicy: []
serviceAccount:
# -- Whether to create a ServiceAccount for the operator.
create: true
- # -- Name of the ServiceAccount to use. Auto-generated from the release name
when empty.
- name: ""
+ # -- Name of the ServiceAccount to use. Auto-generated from the release name
when unset.
+ name: ~
# -- Annotations to add to the ServiceAccount.
annotations: {}
@@ -42,9 +42,9 @@ leaderElection:
# -- Enable leader election so only one replica is active at a time.
Required when `replicas > 1`.
enabled: true
-# -- Operator log verbosity (`--zap-log-level`). Leave empty for the default
(`info`).
+# -- Operator log verbosity (`--zap-log-level`). Leave unset for the default
(`info`).
# Set to `debug` (alias `1`) for per-reconcile progress logs, or `2` for
trace-level internals.
-logLevel: ""
+logLevel: ~
metrics:
# -- Enable the metrics endpoint.
@@ -54,15 +54,15 @@ metrics:
port: 8443
# -- Name of a Secret containing `tls.crt`, `tls.key`, and `ca.crt` to use
for the metrics
# server instead of the built-in self-signed certificate. Typically written
by cert-manager.
- certSecretName: ""
+ certSecretName: ~
serviceMonitor:
# -- Create a Prometheus Operator ServiceMonitor for the operator metrics
endpoint.
# Requires the prometheus-operator CRDs to be installed.
enabled: false
# -- How often Prometheus scrapes the metrics endpoint.
interval: 30s
- # -- Scrape timeout. Empty inherits Prometheus' default.
- scrapeTimeout: ""
+ # -- Scrape timeout. Unset inherits Prometheus' default.
+ scrapeTimeout: ~
# -- Extra labels on the ServiceMonitor so Prometheus Operator selects it
# (e.g. `{release: prometheus}` for kube-prometheus-stack).
labels: {}
@@ -119,6 +119,12 @@ affinity: {}
# See
[corev1.TopologySpreadConstraint](https://pkg.go.dev/k8s.io/api/core/v1#TopologySpreadConstraint).
topologySpreadConstraints: []
+# -- DNS policy for the manager pod.
+dnsPolicy: ~
+# -- DNS config for the manager pod.
+# See
[corev1.PodDNSConfig](https://pkg.go.dev/k8s.io/api/core/v1#PodDNSConfig).
+dnsConfig: {}
+
podDisruptionBudget:
# -- Create a PodDisruptionBudget for the manager pod. Only useful with
`replicas >= 2`.
enabled: false
@@ -126,8 +132,8 @@ podDisruptionBudget:
minAvailable: ~
# -- (intOrString) Maximum unavailable pods (integer or percentage).
Defaults to `1` when neither is set.
maxUnavailable: ~
- # -- Unhealthy pod eviction policy (`IfHealthyBudget` or `AlwaysAllow`).
Empty uses the Kubernetes default.
- unhealthyPodEvictionPolicy: ""
+ # -- Unhealthy pod eviction policy (`IfHealthyBudget` or `AlwaysAllow`).
Unset uses the Kubernetes default.
+ unhealthyPodEvictionPolicy: ~
# -- Extra annotations to add to the manager pod.
podAnnotations: {}
diff --git a/docs/reference/releases.md b/docs/reference/releases.md
index 7fa53ff..0d6db87 100644
--- a/docs/reference/releases.md
+++ b/docs/reference/releases.md
@@ -27,12 +27,14 @@ This page tracks notable changes in Apache Superset
Kubernetes Operator releases
- Structured metastore, Valkey, and lifecycle seed-source connection fields
can now be sourced individually from Kubernetes Secret keys, allowing
`Superset` resources to consume provisioner-owned endpoints and credentials
without copying discovered values or assembling a separate connection URI
([#369](https://github.com/apache/superset-kubernetes-operator/pull/369)).
- **Helm `podDisruptionBudget`.** The Helm chart now exposes a
`podDisruptionBudget` value that renders a
[PodDisruptionBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets)
for the operator manager pods. It is disabled by default and falls back to
`maxUnavailable: 1` when no bound is set. Rendering fails for integer or
percentage bounds that would leave zero allowed disruptions at the configured
`replicas` (for example `minAvailable: 1` with one [...]
+- **Helm `dnsPolicy` and `dnsConfig`.** The Helm chart now exposes `dnsPolicy`
and `dnsConfig` values for the operator manager pod
([#394](https://github.com/apache/superset-kubernetes-operator/pull/394),
[@younsl](https://github.com/younsl)).
### Changed
- **Helm chart requires leader election for multiple replicas.** Rendering now
fails when `replicas` is greater than 1 and `leaderElection.enabled` is
`false`. Replicas are active/standby behind the [leader election
Lease](https://kubernetes.io/docs/concepts/architecture/leases/#leader-election);
without it every replica reconciles the same `Superset` resources and races on
Jobs, drains, and status. Existing releases with that combination fail `helm
upgrade` until leader election is enab [...]
- Valkey's default port is now applied at runtime, aligning it with the
existing structured-metastore behavior, instead of being stored by CRD
defaulting. Resources that omit both `valkey.port` and `valkey.portFrom`
therefore no longer materialize `port: 6379`, while generated configuration
continues to use port 6379. This permits `portFrom` without a defaulted literal
conflicting at admission
([#369](https://github.com/apache/superset-kubernetes-operator/pull/369)).
- Kubernetes support now covers the three newest `kind`-published minor
versions instead of two. CI tests Kubernetes 1.37, 1.36, and 1.35 natively,
with the experimental `next` lane disabled again
([#317](https://github.com/apache/superset-kubernetes-operator/pull/317)).
+- Optional string values in the Helm chart (`image.tag`,
`serviceAccount.name`, `logLevel`, `metrics.certSecretName`,
`metrics.serviceMonitor.scrapeTimeout`, `dnsPolicy`,
`podDisruptionBudget.unhealthyPodEvictionPolicy`) now default to `~` (null)
instead of `""`, matching the chart's other unset values. Rendered output is
unchanged, and explicit empty strings are still accepted
([#394](https://github.com/apache/superset-kubernetes-operator/pull/394),
[@younsl](https://github.com/younsl)).
### Fixed