From e5cee8723ad1ba93c6a163fa37ed83e95b509d12 Mon Sep 17 00:00:00 2001 From: Armando Ruocco Date: Wed, 12 Aug 2026 12:13:22 +0200 Subject: [PATCH] fix(operator): drop stale klio-wal from container allowlist The plugin injects a single klio-plugin sidecar covering both base backups and WAL streaming, and Spec.Containers is only ever read for klio-plugin and klio-restore (operator/internal/cnpgi/lifecycle.go). A user-defined klio-wal override therefore passed validation and was then silently ignored. Remove klio-wal from the CEL allowlist and from the merge-behavior comment, lower MaxItems to 2, and regenerate the CRD, the Helm chart CRD and the API docs. The CSV spec descriptor is hand-maintained and updated in place. This narrows validation: a PluginConfiguration that still carries a klio-wal entry is rejected on any update that touches spec.containers. On clusters without CRD validation ratcheting (Kubernetes before 1.30, or the gate explicitly disabled) any update to the object is rejected. Removing the entry is always safe, since the sidecar it named no longer exists. Closes #68 Signed-off-by: Armando Ruocco --- documentation/web/docs/user/api/_klio_api.md | 2 +- operator/api/v1alpha1/plugin_configuration_types.go | 6 +++--- .../crd/bases/klio.cnpg.io_pluginconfigurations.yaml | 9 ++++----- .../bases/klio-operator.clusterserviceversion.yaml | 2 +- operator/dist/chart/crds/pluginconfiguration-crd.yaml | 9 ++++----- operator/internal/cnpgi/lifecycle_test.go | 2 +- 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/documentation/web/docs/user/api/_klio_api.md b/documentation/web/docs/user/api/_klio_api.md index b1b3c162..d666a314 100644 --- a/documentation/web/docs/user/api/_klio_api.md +++ b/documentation/web/docs/user/api/_klio_api.md @@ -158,7 +158,7 @@ _Appears in:_ | `clusterName` _string_ | ClusterName is the name of the PostgreSQL cluster we are connecting to | True | | MinLength: 1
Required: \{\}
| | `pprof` _boolean_ | Pprof enables the pprof endpoint for performance profiling | | | Optional: \{\}
| | `mode` _[ServerMode](#servermode)_ | Mode selects the operation mode of the plugin. | True | standard | Enum: [standard read-only]
| -| `containers` _[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.36/#container-v1-core) array_ | Containers allows defining a list of containers that will be merged with the Klio sidecar containers.
This enables users to customize the sidecars with additional environment variables, volume mounts,
resource limits, and other container settings without polluting the PostgreSQL container environment.
Merge behavior:
- Containers are matched by name (klio-plugin, klio-wal, klio-restore)
- User customizations serve as the base
- Klio required values (name, args, CONTAINER_NAME env var) always override user values
- User-defined environment variables and volume mounts are preserved
- Template defaults are applied only for fields not set by the user or Klio | | | MaxItems: 3
Optional: \{\}
| +| `containers` _[Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.36/#container-v1-core) array_ | Containers allows defining a list of containers that will be merged with the Klio sidecar containers.
This enables users to customize the sidecars with additional environment variables, volume mounts,
resource limits, and other container settings without polluting the PostgreSQL container environment.
Merge behavior:
- Containers are matched by name (klio-plugin, klio-restore)
- User customizations serve as the base
- Klio required values (name, args, CONTAINER_NAME env var) always override user values
- User-defined environment variables and volume mounts are preserved
- Template defaults are applied only for fields not set by the user or Klio | | | MaxItems: 2
Optional: \{\}
| #### PluginConfigurationStatus diff --git a/operator/api/v1alpha1/plugin_configuration_types.go b/operator/api/v1alpha1/plugin_configuration_types.go index 3e1d9fec..83d07b7d 100644 --- a/operator/api/v1alpha1/plugin_configuration_types.go +++ b/operator/api/v1alpha1/plugin_configuration_types.go @@ -87,17 +87,17 @@ type PluginConfigurationSpec struct { // resource limits, and other container settings without polluting the PostgreSQL container environment. // // Merge behavior: - // - Containers are matched by name (klio-plugin, klio-wal, klio-restore) + // - Containers are matched by name (klio-plugin, klio-restore) // - User customizations serve as the base // - Klio required values (name, args, CONTAINER_NAME env var) always override user values // - User-defined environment variables and volume mounts are preserved // - Template defaults are applied only for fields not set by the user or Klio // // +optional - // +kubebuilder:validation:MaxItems=3 + // +kubebuilder:validation:MaxItems=2 // +listType=map // +listMapKey=name - // +kubebuilder:validation:XValidation:rule="self.all(c, c.name in ['klio-plugin', 'klio-wal', 'klio-restore'])",message="container name must be one of: klio-plugin, klio-wal, klio-restore" + // +kubebuilder:validation:XValidation:rule="self.all(c, c.name in ['klio-plugin', 'klio-restore'])",message="container name must be one of: klio-plugin, klio-restore" Containers []corev1.Container `json:"containers,omitempty"` } diff --git a/operator/config/crd/bases/klio.cnpg.io_pluginconfigurations.yaml b/operator/config/crd/bases/klio.cnpg.io_pluginconfigurations.yaml index e51b6805..830fbbc1 100644 --- a/operator/config/crd/bases/klio.cnpg.io_pluginconfigurations.yaml +++ b/operator/config/crd/bases/klio.cnpg.io_pluginconfigurations.yaml @@ -58,7 +58,7 @@ spec: resource limits, and other container settings without polluting the PostgreSQL container environment. Merge behavior: - - Containers are matched by name (klio-plugin, klio-wal, klio-restore) + - Containers are matched by name (klio-plugin, klio-restore) - User customizations serve as the base - Klio required values (name, args, CONTAINER_NAME env var) always override user values - User-defined environment variables and volume mounts are preserved @@ -1582,15 +1582,14 @@ spec: required: - name type: object - maxItems: 3 + maxItems: 2 type: array x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: 'container name must be one of: klio-plugin, klio-wal, - klio-restore' - rule: self.all(c, c.name in ['klio-plugin', 'klio-wal', 'klio-restore']) + - message: 'container name must be one of: klio-plugin, klio-restore' + rule: self.all(c, c.name in ['klio-plugin', 'klio-restore']) mode: default: standard description: Mode selects the operation mode of the plugin. diff --git a/operator/config/manifests/bases/klio-operator.clusterserviceversion.yaml b/operator/config/manifests/bases/klio-operator.clusterserviceversion.yaml index 895f2db1..6d925218 100644 --- a/operator/config/manifests/bases/klio-operator.clusterserviceversion.yaml +++ b/operator/config/manifests/bases/klio-operator.clusterserviceversion.yaml @@ -344,7 +344,7 @@ spec: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - urn:alm:descriptor:com.tectonic.ui:advanced - description: Advanced overrides for the Klio sidecar containers (klio-plugin, - klio-wal, klio-restore). Use at your own risk. + klio-restore). Use at your own risk. displayName: Sidecar Container Overrides path: containers x-descriptors: diff --git a/operator/dist/chart/crds/pluginconfiguration-crd.yaml b/operator/dist/chart/crds/pluginconfiguration-crd.yaml index 03e94c7f..3b2e1408 100644 --- a/operator/dist/chart/crds/pluginconfiguration-crd.yaml +++ b/operator/dist/chart/crds/pluginconfiguration-crd.yaml @@ -57,7 +57,7 @@ spec: resource limits, and other container settings without polluting the PostgreSQL container environment. Merge behavior: - - Containers are matched by name (klio-plugin, klio-wal, klio-restore) + - Containers are matched by name (klio-plugin, klio-restore) - User customizations serve as the base - Klio required values (name, args, CONTAINER_NAME env var) always override user values - User-defined environment variables and volume mounts are preserved @@ -1581,15 +1581,14 @@ spec: required: - name type: object - maxItems: 3 + maxItems: 2 type: array x-kubernetes-list-map-keys: - name x-kubernetes-list-type: map x-kubernetes-validations: - - message: 'container name must be one of: klio-plugin, klio-wal, - klio-restore' - rule: self.all(c, c.name in ['klio-plugin', 'klio-wal', 'klio-restore']) + - message: 'container name must be one of: klio-plugin, klio-restore' + rule: self.all(c, c.name in ['klio-plugin', 'klio-restore']) mode: default: standard description: Mode selects the operation mode of the plugin. diff --git a/operator/internal/cnpgi/lifecycle_test.go b/operator/internal/cnpgi/lifecycle_test.go index 09f4a415..9b5edceb 100644 --- a/operator/internal/cnpgi/lifecycle_test.go +++ b/operator/internal/cnpgi/lifecycle_test.go @@ -162,7 +162,7 @@ func TestFindUserContainer(t *testing.T) { containerName: KlioPluginContainerName, customContainers: []corev1.Container{ { - Name: "klio-wal", + Name: "klio-restore", Image: "other-image:latest", }, },