diff --git a/pkg/registry/apis/provisioning/jobs/export/resources.go b/pkg/registry/apis/provisioning/jobs/export/resources.go index e46c3b7e4f4..467bafb0290 100644 --- a/pkg/registry/apis/provisioning/jobs/export/resources.go +++ b/pkg/registry/apis/provisioning/jobs/export/resources.go @@ -225,7 +225,9 @@ func exportSingleResource( } // Convert dashboard if needed - if err := convertDashboardIfNeeded(ctx, gvr, item, meta, clients, dashboardShim, versionClients, resourceRef, &result, progress); err != nil { + var err error + item, meta, err = convertDashboardIfNeeded(ctx, gvr, item, meta, clients, dashboardShim, versionClients, resourceRef, &result, progress) + if err != nil { return err } if result.Error != nil { @@ -305,6 +307,7 @@ func fetchAndValidateResource( } // convertDashboardIfNeeded converts a dashboard to its original API version if needed. +// Returns the potentially updated item and meta accessor. func convertDashboardIfNeeded( ctx context.Context, gvr schema.GroupVersionResource, @@ -316,9 +319,9 @@ func convertDashboardIfNeeded( resourceRef provisioning.ResourceRef, result *jobs.JobResourceResult, progress jobs.JobProgressRecorder, -) error { +) (*unstructured.Unstructured, utils.GrafanaMetaAccessor, error) { if gvr.GroupResource() != resources.DashboardResource.GroupResource() { - return nil + return item, meta, nil } // Create or reuse the dashboard shim (shared across all dashboard resources) @@ -332,7 +335,7 @@ func convertDashboardIfNeeded( if err != nil { result.Error = fmt.Errorf("converting dashboard %s/%s/%s: %w", resourceRef.Group, resourceRef.Kind, resourceRef.Name, err) progress.Record(ctx, *result) - return progress.TooManyErrors() + return nil, nil, progress.TooManyErrors() } // Re-extract meta after shim conversion in case the item changed @@ -341,10 +344,10 @@ func convertDashboardIfNeeded( result.Action = repository.FileActionIgnored result.Error = fmt.Errorf("extracting meta accessor after conversion for resource %s: %w", result.Name, err) progress.Record(ctx, *result) - return progress.TooManyErrors() + return nil, nil, progress.TooManyErrors() } - return nil + return item, meta, nil } // computeExportPath computes the export path by combining the base path with the folder path from the tree. diff --git a/pkg/tests/apis/provisioning/export_resources_test.go b/pkg/tests/apis/provisioning/export_resources_test.go index 0bc0baeb82c..6c8f44c8e1a 100644 --- a/pkg/tests/apis/provisioning/export_resources_test.go +++ b/pkg/tests/apis/provisioning/export_resources_test.go @@ -80,7 +80,7 @@ func TestIntegrationProvisioning_ExportSpecificResources(t *testing.T) { dashboard2File := filepath.Join(helper.ProvisioningPath, "test-dashboard-created-at-v2beta1.json") // Check dashboard1 - body1, err := os.ReadFile(dashboard1File) + body1, err := os.ReadFile(dashboard1File) //nolint:gosec require.NoError(t, err, "exported file should exist for dashboard1") obj1 := map[string]any{} err = json.Unmarshal(body1, &obj1) @@ -90,7 +90,7 @@ func TestIntegrationProvisioning_ExportSpecificResources(t *testing.T) { require.Equal(t, "test-v1", val) // Check dashboard2 - body2, err := os.ReadFile(dashboard2File) + body2, err := os.ReadFile(dashboard2File) //nolint:gosec require.NoError(t, err, "exported file should exist for dashboard2") obj2 := map[string]any{} err = json.Unmarshal(body2, &obj2) @@ -140,7 +140,7 @@ func TestIntegrationProvisioning_ExportSpecificResourcesWithPath(t *testing.T) { // Verify dashboard was exported to custom path expectedFile := filepath.Join(helper.ProvisioningPath, "custom", "path", "test-dashboard-created-at-v1.json") - body, err := os.ReadFile(expectedFile) + body, err := os.ReadFile(expectedFile) //nolint:gosec require.NoError(t, err, "exported file should exist at custom path") obj := map[string]any{} err = json.Unmarshal(body, &obj) @@ -323,7 +323,8 @@ func TestIntegrationProvisioning_ExportSpecificResourcesWithFolderStructure(t *t // Create unmanaged dashboard in the folder dashboard := helper.LoadYAMLOrJSONFile("exportunifiedtorepository/dashboard-test-v1.yaml") // Set folder UID in dashboard spec - unstructured.SetNestedField(dashboard.Object, string(folderUID), "spec", "folder") + err = unstructured.SetNestedField(dashboard.Object, string(folderUID), "spec", "folder") + require.NoError(t, err, "should be able to set folder UID") dashboardObj, err := helper.DashboardsV1.Resource.Create(ctx, dashboard, metav1.CreateOptions{}) require.NoError(t, err, "should be able to create dashboard in folder") @@ -359,7 +360,7 @@ func TestIntegrationProvisioning_ExportSpecificResourcesWithFolderStructure(t *t // The folder path should be included in the file path based on the folder title // Folder title is "Test Export Folder", which gets slugified to "test-export-folder" expectedFile := filepath.Join(helper.ProvisioningPath, "test-export-folder", "test-dashboard-created-at-v1.json") - body, err := os.ReadFile(expectedFile) + body, err := os.ReadFile(expectedFile) //nolint:gosec require.NoError(t, err, "exported file should exist with folder structure") obj := map[string]any{} err = json.Unmarshal(body, &obj)