diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go index 6929da5b830..d1a07ed5aac 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go @@ -316,6 +316,7 @@ func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error) { var snapshots = make([]cloudmigration.CloudMigrationSnapshot, 0) err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { + sess.Join("INNER", "cloud_migration_session", "cloud_migration_session.uid = cloud_migration_snapshot.session_uid") if query.Limit != GetAllSnapshots { offset := (query.Page - 1) * query.Limit sess.Limit(query.Limit, offset) diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go index 143d9f5e83a..c1a12e2d584 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go @@ -3,6 +3,7 @@ package cloudmigrationimpl import ( "context" "encoding/base64" + "slices" "strconv" "testing" @@ -12,7 +13,6 @@ import ( secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/tests/testsuite" - "github.com/grafana/grafana/pkg/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -171,12 +171,12 @@ func Test_SnapshotManagement(t *testing.T) { ctx := context.Background() t.Run("tests the snapshot lifecycle", func(t *testing.T) { - var snapshotUid string - sessionUid := util.GenerateShortUID() + session, err := s.CreateMigrationSession(ctx, cloudmigration.CloudMigrationSession{}) + require.NoError(t, err) // create a snapshot cmr := cloudmigration.CloudMigrationSnapshot{ - SessionUID: sessionUid, + SessionUID: session.UID, Status: cloudmigration.SnapshotStatusCreating, } @@ -185,21 +185,21 @@ func Test_SnapshotManagement(t *testing.T) { require.NotEmpty(t, snapshotUid) //retrieve it from the db - snapshot, err := s.GetSnapshotByUID(ctx, sessionUid, snapshotUid, 0, 0) + snapshot, err := s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0) require.NoError(t, err) require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status) // update its status - err = s.UpdateSnapshot(ctx, cloudmigration.UpdateSnapshotCmd{UID: snapshotUid, Status: cloudmigration.SnapshotStatusCreating, SessionID: sessionUid}) + err = s.UpdateSnapshot(ctx, cloudmigration.UpdateSnapshotCmd{UID: snapshotUid, Status: cloudmigration.SnapshotStatusCreating, SessionID: session.UID}) require.NoError(t, err) //retrieve it again - snapshot, err = s.GetSnapshotByUID(ctx, sessionUid, snapshotUid, 0, 0) + snapshot, err = s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0) require.NoError(t, err) require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status) // lists snapshots and ensures it's in there - snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUid, Page: 1, Limit: 100}) + snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: session.UID, Page: 1, Limit: 100}) require.NoError(t, err) require.Len(t, snapshots, 1) require.Equal(t, *snapshot, snapshots[0]) @@ -209,7 +209,7 @@ func Test_SnapshotManagement(t *testing.T) { require.NoError(t, err) // now we expect not to find the snapshot - snapshot, err = s.GetSnapshotByUID(ctx, sessionUid, snapshotUid, 0, 0) + snapshot, err = s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0) require.ErrorIs(t, err, cloudmigration.ErrSnapshotNotFound) require.Nil(t, snapshot) }) @@ -282,6 +282,49 @@ func Test_SnapshotResources(t *testing.T) { }) } +func TestGetSnapshotList(t *testing.T) { + t.Parallel() + + _, s := setUpTest(t) + // Taken from setUpTest + sessionUID := "qwerty" + ctx := context.Background() + + t.Run("returns list of snapshots that belong to a session", func(t *testing.T) { + snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, Page: 1, Limit: 100}) + require.NoError(t, err) + + ids := make([]string, 0) + for _, snapshot := range snapshots { + ids = append(ids, snapshot.UID) + } + slices.Sort(ids) + + // There are 3 snapshots in the db but only 2 of them belong to this specific session. + assert.Equal(t, []string{"lkjhg", "poiuy"}, ids) + }) + + t.Run("only the snapshots that belong to a specific session are returned", func(t *testing.T) { + snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: "session-uid-that-doesnt-exist", Page: 1, Limit: 100}) + require.NoError(t, err) + assert.Empty(t, snapshots) + }) + + t.Run("if the session is deleted, snapshots can't be retrieved anymore", func(t *testing.T) { + // Delete the session. + _, _, err := s.DeleteMigrationSessionByUID(ctx, sessionUID) + require.NoError(t, err) + + // Fetch the snapshots that belong to the deleted session. + snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, Page: 1, Limit: 100}) + require.NoError(t, err) + + // No snapshots should be returned because the session that + // they belong to has been deleted. + assert.Empty(t, snapshots) + }) +} + func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) { testDB := db.InitTestDB(t) s := &sqlStore{ @@ -318,6 +361,12 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) { ) require.NoError(t, err) + // Store encryption keys used to encrypt/decrypt snapshots. + for _, snapshotUid := range []string{"poiuy", "lkjhg", "mnbvvc"} { + err = s.secretsStore.Set(ctx, secretskv.AllOrganizations, snapshotUid, secretType, "encryption_key") + require.NoError(t, err) + } + _, err = testDB.GetSqlxSession().Exec(ctx, ` INSERT INTO cloud_migration_resource (uid, snapshot_uid, resource_type, resource_uid, status, error_string)