CloudMigration: Show warning message for successfully migrated non-core data sources (#91545)

* minor performance improvement

* apply a warning to any non-core plugins that successfully migrate

* commit frontend wip while I refactor some stuff

* update api

* repurpose error dialog to be a generic details dialog

* whitespace

* add unit test

* fixes from testing

* fix migration summary

* add comment

* fix localization stuff

* fix backend test

* reduce number of queries to the db

* some PR feedback

* whitespace
This commit is contained in:
Michael Mandrus
2024-08-06 12:35:10 -04:00
committed by GitHub
parent ee78bb653f
commit 6cd0971dc6
20 changed files with 316 additions and 67 deletions

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/cloudmigration"
"github.com/grafana/grafana/pkg/services/cloudmigration/gmsclient"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
@ -23,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/folder/foldertest"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
secretsfakes "github.com/grafana/grafana/pkg/services/secrets/fakes"
secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore"
"github.com/grafana/grafana/pkg/services/user"
@ -399,6 +401,122 @@ func Test_SortFolders(t *testing.T) {
require.Equal(t, expected, sortedFolders)
}
func Test_NonCoreDataSourcesHaveWarning(t *testing.T) {
s := setUpServiceTest(t, false).(*Service)
// Insert a processing snapshot into the database before we start so we query GMS
sess, err := s.store.CreateMigrationSession(context.Background(), cloudmigration.CloudMigrationSession{})
require.NoError(t, err)
snapshotUid, err := s.store.CreateSnapshot(context.Background(), cloudmigration.CloudMigrationSnapshot{
UID: uuid.NewString(),
SessionUID: sess.UID,
Status: cloudmigration.SnapshotStatusProcessing,
GMSSnapshotUID: "gms uid",
})
require.NoError(t, err)
// GMS should return: a core ds, a non-core ds, a non-core ds with an error, and a ds that has been uninstalled
gmsClientMock := &gmsClientMock{
getSnapshotResponse: &cloudmigration.GetSnapshotStatusResponse{
State: cloudmigration.SnapshotStateFinished,
Results: []cloudmigration.CloudMigrationResource{
{
Type: cloudmigration.DatasourceDataType,
RefID: "1", // this will be core
Status: cloudmigration.ItemStatusOK,
SnapshotUID: snapshotUid,
},
{
Type: cloudmigration.DatasourceDataType,
RefID: "2", // this will be non-core
Status: cloudmigration.ItemStatusOK,
SnapshotUID: snapshotUid,
},
{
Type: cloudmigration.DatasourceDataType,
RefID: "3", // this will be non-core with an error
Status: cloudmigration.ItemStatusError,
Error: "please don't overwrite me",
SnapshotUID: snapshotUid,
},
{
Type: cloudmigration.DatasourceDataType,
RefID: "4", // this will be deleted
Status: cloudmigration.ItemStatusOK,
SnapshotUID: snapshotUid,
},
},
},
}
s.gmsClient = gmsClientMock
// Update the internal plugin store and ds store with seed data matching the descriptions above
s.pluginStore = pluginstore.NewFakePluginStore([]pluginstore.Plugin{
{
JSONData: plugins.JSONData{
ID: "1",
},
Class: plugins.ClassCore,
},
{
JSONData: plugins.JSONData{
ID: "2",
},
Class: plugins.ClassExternal,
},
{
JSONData: plugins.JSONData{
ID: "3",
},
Class: plugins.ClassExternal,
},
}...)
s.dsService = &datafakes.FakeDataSourceService{
DataSources: []*datasources.DataSource{
{UID: "1", Type: "1"},
{UID: "2", Type: "2"},
{UID: "3", Type: "3"},
{UID: "4", Type: "4"},
},
}
// Retrieve the snapshot with results
snapshot, err := s.GetSnapshot(ctxWithSignedInUser(), cloudmigration.GetSnapshotsQuery{
SnapshotUID: snapshotUid,
SessionUID: sess.UID,
ResultPage: 1,
ResultLimit: 10,
})
assert.NoError(t, err)
assert.Len(t, snapshot.Resources, 4)
findRef := func(id string) *cloudmigration.CloudMigrationResource {
for _, r := range snapshot.Resources {
if r.RefID == id {
return &r
}
}
return nil
}
shouldBeUnaltered := findRef("1")
assert.Equal(t, cloudmigration.ItemStatusOK, shouldBeUnaltered.Status)
assert.Empty(t, shouldBeUnaltered.Error)
shouldBeAltered := findRef("2")
assert.Equal(t, cloudmigration.ItemStatusWarning, shouldBeAltered.Status)
assert.Equal(t, shouldBeAltered.Error, "Only core data sources are supported. Please ensure the plugin is installed on the cloud stack.")
shouldHaveOriginalError := findRef("3")
assert.Equal(t, cloudmigration.ItemStatusError, shouldHaveOriginalError.Status)
assert.Equal(t, shouldHaveOriginalError.Error, "please don't overwrite me")
uninstalledAltered := findRef("4")
assert.Equal(t, cloudmigration.ItemStatusWarning, uninstalledAltered.Status)
assert.Equal(t, uninstalledAltered.Error, "Only core data sources are supported. Please ensure the plugin is installed on the cloud stack.")
}
func ctxWithSignedInUser() context.Context {
c := &contextmodel.ReqContext{
SignedInUser: &user.SignedInUser{OrgID: 1},
@ -461,6 +579,7 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
tracer,
dashboardService,
mockFolder,
&pluginstore.FakePluginStore{},
kvstore.ProvideService(sqlStore),
)
require.NoError(t, err)