From c8c55621fb6fee325adb703177311650d4a8ae56 Mon Sep 17 00:00:00 2001 From: Marco de Abreu Date: Tue, 8 Apr 2025 12:25:32 +0200 Subject: [PATCH] Dashboards: Fix dashboard UID inconsistency between creation and retrieval in legacy storage (#103568) --- pkg/registry/apis/dashboard/legacy_storage.go | 14 ++++++++++++++ .../integration/api_validation_test.go | 17 +++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pkg/registry/apis/dashboard/legacy_storage.go b/pkg/registry/apis/dashboard/legacy_storage.go index ceb035e4425..ce269a55c7f 100644 --- a/pkg/registry/apis/dashboard/legacy_storage.go +++ b/pkg/registry/apis/dashboard/legacy_storage.go @@ -15,6 +15,7 @@ import ( grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" + gapiutil "github.com/grafana/grafana/pkg/services/apiserver/utils" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/storage/unified/apistore" "github.com/grafana/grafana/pkg/storage/unified/resource" @@ -82,10 +83,23 @@ func (s *storeWrapper) Create(ctx context.Context, obj runtime.Object, createVal } } + meta, metaErr := utils.MetaAccessor(obj) + if metaErr == nil { + // Reconstruc the same UID as done at the storage level + // https://github.com/grafana/grafana/blob/a84e96fba29c3a1bb384fdbad1c9c658cc79ec8f/pkg/registry/apis/dashboard/legacy/sql_dashboards.go#L287 + // This is necessary because the UID generated during the creation via legacy storage is actually never stored in the database + // and the one returned here is wrong. + meta.SetUID(gapiutil.CalculateClusterWideUID(obj)) + } + if err != nil { return obj, err } + if metaErr != nil { + return obj, metaErr + } + unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) if err != nil { return obj, err diff --git a/pkg/tests/apis/dashboard/integration/api_validation_test.go b/pkg/tests/apis/dashboard/integration/api_validation_test.go index 0a7016e9c2a..4f37a30f0e1 100644 --- a/pkg/tests/apis/dashboard/integration/api_validation_test.go +++ b/pkg/tests/apis/dashboard/integration/api_validation_test.go @@ -810,16 +810,21 @@ func createDashboard(t *testing.T, client *apis.K8sResourceClient, title string, return nil, err } - // TODO: Remove once the underlying issue is fixed: - // https://raintank-corp.slack.com/archives/C05FYAPEPKP/p1743111830777889 - // This only happens in mode 0. + // Fetch the generated object to ensure we're not running into any caching or UID mismatch issues databaseDash, err := client.Resource.Get(context.Background(), createdDash.GetName(), v1.GetOptions{}) if err != nil { - return nil, err + t.Errorf("Potential caching issue: Unable to retrieve newly created dashboard: %v", err) } - require.NotEqual(t, createdDash.GetUID(), databaseDash.GetUID(), "The underlying UID mismatch bug has been fixed, please remove the redundant read!") - return databaseDash, nil + createdMeta, _ := utils.MetaAccessor(createdDash) + databaseMeta, _ := utils.MetaAccessor(databaseDash) + + require.Equal(t, createdDash.GetUID(), databaseDash.GetUID(), "Created and retrieved UID mismatch") + require.Equal(t, createdDash.GetName(), databaseDash.GetName(), "Created and retrieved name mismatch") + require.Equal(t, createdDash.GetResourceVersion(), databaseDash.GetResourceVersion(), "Created and retrieved resource version mismatch") + require.Equal(t, createdMeta.FindTitle("A"), databaseMeta.FindTitle("B"), "Created and retrieved title mismatch") + + return createdDash, nil } // Update a dashboard