From 2bc424fbeb8de90ba8fee97044005fe48f898345 Mon Sep 17 00:00:00 2001 From: Roberto Jimenez Sanchez Date: Wed, 3 Dec 2025 12:31:23 +0100 Subject: [PATCH] fix: clarify that folder UIDs are stored as metadata.name, not metadata.uid - Update tree.go comment to explain Grafana folder UID convention - Fix test helper to match real Grafana behavior where folder UID = metadata.name - Update tests to use proper folder naming (UID as name, separate K8s UID) --- .../jobs/export/resources_specific_test.go | 25 +++++++++++++------ .../apis/provisioning/resources/tree.go | 7 +++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/pkg/registry/apis/provisioning/jobs/export/resources_specific_test.go b/pkg/registry/apis/provisioning/jobs/export/resources_specific_test.go index f088154873f..4a5afc4b4c0 100644 --- a/pkg/registry/apis/provisioning/jobs/export/resources_specific_test.go +++ b/pkg/registry/apis/provisioning/jobs/export/resources_specific_test.go @@ -18,6 +18,9 @@ import ( ) // Helper function to create folder objects +// name should be the Grafana folder UID (which becomes metadata.name) +// uid is the Kubernetes UID (metadata.uid) +// title defaults to name but can be overridden via spec.title func createFolderObject(name, uid, parentFolderUID string) unstructured.Unstructured { folder := unstructured.Unstructured{ Object: map[string]interface{}{ @@ -28,7 +31,7 @@ func createFolderObject(name, uid, parentFolderUID string) unstructured.Unstruct "uid": uid, }, "spec": map[string]interface{}{ - "title": name, + "title": name, // title defaults to name, tests can override if needed }, }, } @@ -88,9 +91,11 @@ func TestExportSpecificResources_Success(t *testing.T) { }, } - folderItems := []unstructured.Unstructured{ - createFolderObject("team-a", "team-a-uid", ""), - } + // Create folder with UID as name (matching real Grafana behavior) + teamAFolder := createFolderObject("team-a-uid", "k8s-uid-1", "") + _ = unstructured.SetNestedField(teamAFolder.Object, "team-a", "spec", "title") + + folderItems := []unstructured.Unstructured{teamAFolder} dashboard1 := createDashboardObjectWithFolder("dashboard-1", "team-a-uid") dashboard2 := createDashboardObject("dashboard-2") @@ -312,10 +317,14 @@ func TestExportSpecificResources_FolderPathResolution(t *testing.T) { } // Create folder hierarchy: team-a -> subteam - folderItems := []unstructured.Unstructured{ - createFolderObject("team-a", "team-a-uid", ""), - createFolderObject("subteam", "subteam-uid", "team-a-uid"), - } + // In Grafana, folder UIDs are stored as metadata.name (matching real behavior) + parentFolder := createFolderObject("team-a-uid", "k8s-uid-1", "") + _ = unstructured.SetNestedField(parentFolder.Object, "team-a", "spec", "title") + + childFolder := createFolderObject("subteam-uid", "k8s-uid-2", "team-a-uid") + _ = unstructured.SetNestedField(childFolder.Object, "subteam", "spec", "title") + + folderItems := []unstructured.Unstructured{parentFolder, childFolder} dashboard := createDashboardObjectWithFolder("dashboard-in-nested-folder", "subteam-uid") diff --git a/pkg/registry/apis/provisioning/resources/tree.go b/pkg/registry/apis/provisioning/resources/tree.go index 5f59d3b821d..bcaa63457d9 100644 --- a/pkg/registry/apis/provisioning/resources/tree.go +++ b/pkg/registry/apis/provisioning/resources/tree.go @@ -145,12 +145,11 @@ func (t *folderTree) AddUnstructured(item *unstructured.Unstructured) error { return fmt.Errorf("extract meta accessor: %w", err) } - // Use UID as the identifier since GetFolder() returns UID - // In Grafana's folder API, folders are identified by UID - folderUID := string(item.GetUID()) + // In Grafana, folder UIDs are stored as metadata.name + // The grafana.app/folder annotation contains the folder's metadata.name (which is its Grafana UID) folder := Folder{ Title: meta.FindTitle(item.GetName()), - ID: folderUID, + ID: item.GetName(), } t.mu.Lock() defer t.mu.Unlock()