From 686fa5d510c669477089c821ad77adadbbddc496 Mon Sep 17 00:00:00 2001 From: Nicolas Takashi Date: Thu, 23 Jul 2026 16:00:31 +0100 Subject: [PATCH] [ENHANCEMENT] Preserve unknown fields at panel spec and display level The panel spec (spec.panels[].spec) and its display object are closed schemas: any field not declared upstream is pruned or rejected at Kubernetes admission. This is inconsistent with plugin.spec, queries and variable specs, which already preserve unknown fields, and it prevents plugins and downstream tooling from attaching panel-level metadata when PersesDashboard resources are managed via the operator/GitOps. Add +kubebuilder:pruning:PreserveUnknownFields (without Schemaless, so the declared fields stay validated) on Panel.Spec and PanelSpec.Display, and regenerate the CUE. Refs: https://github.com/perses/perses-operator/issues/435 Signed-off-by: Nicolas Takashi --- cue/dashboard/dashboard_go_gen.cue | 11 ++++++++++- go/dashboard/dashboard.go | 10 +++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/cue/dashboard/dashboard_go_gen.cue b/cue/dashboard/dashboard_go_gen.cue index a082989..7652c8c 100644 --- a/cue/dashboard/dashboard_go_gen.cue +++ b/cue/dashboard/dashboard_go_gen.cue @@ -20,6 +20,10 @@ import plugin_9 "github.com/perses/spec/cue/plugin" } #PanelSpec: { + // Preserve unknown fields so plugins and downstream tooling can attach display-level + // metadata without it being pruned at admission. The declared fields above stay validated; + // Schemaless is intentionally not used, as that would drop their schema entirely. + // +kubebuilder:pruning:PreserveUnknownFields display?: null | #PanelDisplay @go(Display,*PanelDisplay) plugin: plugin_9.#Plugin @go(Plugin) queries?: [...#Query] @go(Queries,[]Query) @@ -27,7 +31,12 @@ import plugin_9 "github.com/perses/spec/cue/plugin" } #Panel: { - kind: string @go(Kind) + kind: string @go(Kind) + + // Preserve unknown fields so plugins and downstream tooling can attach panel-level + // metadata without it being pruned at admission. The declared fields stay validated; + // Schemaless is intentionally not used, as that would drop their schema entirely. + // +kubebuilder:pruning:PreserveUnknownFields spec: #PanelSpec @go(Spec) } diff --git a/go/dashboard/dashboard.go b/go/dashboard/dashboard.go index 5929c93..f9cbab3 100644 --- a/go/dashboard/dashboard.go +++ b/go/dashboard/dashboard.go @@ -37,6 +37,10 @@ type PanelDisplay struct { } type PanelSpec struct { + // Preserve unknown fields so plugins and downstream tooling can attach display-level + // metadata without it being pruned at admission. The declared fields above stay validated; + // Schemaless is intentionally not used, as that would drop their schema entirely. + // +kubebuilder:pruning:PreserveUnknownFields Display *PanelDisplay `json:"display,omitempty" yaml:"display,omitempty"` Plugin plugin.Plugin `json:"plugin" yaml:"plugin"` Queries []Query `json:"queries,omitempty" yaml:"queries,omitempty"` @@ -44,7 +48,11 @@ type PanelSpec struct { } type Panel struct { - Kind string `json:"kind" yaml:"kind"` + Kind string `json:"kind" yaml:"kind"` + // Preserve unknown fields so plugins and downstream tooling can attach panel-level + // metadata without it being pruned at admission. The declared fields stay validated; + // Schemaless is intentionally not used, as that would drop their schema entirely. + // +kubebuilder:pruning:PreserveUnknownFields Spec PanelSpec `json:"spec" yaml:"spec"` }