Dashboards: Fix dashboard UID inconsistency between creation and retrieval in legacy storage (#103568)

This commit is contained in:
Marco de Abreu 2025-04-08 12:25:32 +02:00 committed by GitHub
parent 11bed7b25d
commit c8c55621fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 6 deletions

View File

@ -15,6 +15,7 @@ import (
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" "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/services/dashboards"
"github.com/grafana/grafana/pkg/storage/unified/apistore" "github.com/grafana/grafana/pkg/storage/unified/apistore"
"github.com/grafana/grafana/pkg/storage/unified/resource" "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 { if err != nil {
return obj, err return obj, err
} }
if metaErr != nil {
return obj, metaErr
}
unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) unstructuredMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
if err != nil { if err != nil {
return obj, err return obj, err

View File

@ -810,16 +810,21 @@ func createDashboard(t *testing.T, client *apis.K8sResourceClient, title string,
return nil, err return nil, err
} }
// TODO: Remove once the underlying issue is fixed: // Fetch the generated object to ensure we're not running into any caching or UID mismatch issues
// https://raintank-corp.slack.com/archives/C05FYAPEPKP/p1743111830777889
// This only happens in mode 0.
databaseDash, err := client.Resource.Get(context.Background(), createdDash.GetName(), v1.GetOptions{}) databaseDash, err := client.Resource.Get(context.Background(), createdDash.GetName(), v1.GetOptions{})
if err != nil { 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 // Update a dashboard