From 83b309c724aef6332d162864dd1ca80b30478390 Mon Sep 17 00:00:00 2001 From: Michael Mandrus <41969079+mmandrus@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:33:11 -0400 Subject: [PATCH] CloudMigrations: Don't migrate dashboards that are soft-deleted (#90454) * skip dashboards that are soft-deleted while building snapshots * add unit test --- .../cloudmigrationimpl/cloudmigration_test.go | 35 ++++++++++++++++++- .../cloudmigrationimpl/snapshot_mgmt.go | 7 ++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go index de629e013cd..9176c1b8a17 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/google/uuid" "github.com/grafana/grafana/pkg/api/routing" @@ -350,6 +351,36 @@ func Test_OnlyQueriesStatusFromGMSWhenRequired(t *testing.T) { } } +func Test_DeletedDashboardsNotMigrated(t *testing.T) { + s := setUpServiceTest(t, false).(*Service) + // modify what the mock returns for just this test case + dashMock := s.dashboardService.(*dashboards.FakeDashboardService) + dashMock.On("GetAllDashboards", mock.Anything).Return( + []*dashboards.Dashboard{ + { + UID: "1", + Data: simplejson.New(), + }, + { + UID: "2", + Data: simplejson.New(), + Deleted: time.Now(), + }, + }, + nil, + ) + + data, err := s.getMigrationDataJSON(context.TODO(), &user.SignedInUser{OrgID: 1}) + assert.NoError(t, err) + dashCount := 0 + for _, it := range data.Items { + if it.Type == cloudmigration.DashboardDataType { + dashCount++ + } + } + assert.Equal(t, 1, dashCount) +} + func ctxWithSignedInUser() context.Context { c := &contextmodel.ReqContext{ SignedInUser: &user.SignedInUser{OrgID: 1}, @@ -400,7 +431,9 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi s, err := ProvideService( cfg, - featuremgmt.WithFeatures(featuremgmt.FlagOnPremToCloudMigrations), + featuremgmt.WithFeatures( + featuremgmt.FlagOnPremToCloudMigrations, + featuremgmt.FlagDashboardRestore), sqlStore, dsService, secretsService, diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go b/pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go index 12884731b32..389e99a9183 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/cloudmigration/slicesext" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/util/retryer" @@ -57,7 +58,13 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S }) } + softDeleteEnabled := s.features.IsEnabledGlobally(featuremgmt.FlagDashboardRestore) + for _, dashboard := range dashboards { + if softDeleteEnabled && !dashboard.Deleted.IsZero() { + continue + } + dashboard.Data.Del("id") migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{ Type: cloudmigration.DashboardDataType,