mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
MigrationAssistant: Restrict dashboards, folders and datasources by the org id of the signed in user (#96339)
apply security patch: main/206-202410241510.patch
This commit is contained in:
parent
9f02acd4ca
commit
750a0bed71
@ -175,7 +175,7 @@ func (cma *CloudMigrationAPI) GetSessionList(c *contextmodel.ReqContext) respons
|
|||||||
ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetSessionList")
|
ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetSessionList")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
sl, err := cma.cloudMigrationService.GetSessionList(ctx)
|
sl, err := cma.cloudMigrationService.GetSessionList(ctx, c.OrgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetStatus(codes.Error, "session list error")
|
span.SetStatus(codes.Error, "session list error")
|
||||||
span.RecordError(err)
|
span.RecordError(err)
|
||||||
@ -208,7 +208,7 @@ func (cma *CloudMigrationAPI) GetSession(c *contextmodel.ReqContext) response.Re
|
|||||||
return response.Error(http.StatusBadRequest, "invalid session uid", err)
|
return response.Error(http.StatusBadRequest, "invalid session uid", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := cma.cloudMigrationService.GetSession(ctx, uid)
|
s, err := cma.cloudMigrationService.GetSession(ctx, c.OrgID, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetStatus(codes.Error, "session not found")
|
span.SetStatus(codes.Error, "session not found")
|
||||||
span.RecordError(err)
|
span.RecordError(err)
|
||||||
@ -247,6 +247,7 @@ func (cma *CloudMigrationAPI) CreateSession(c *contextmodel.ReqContext) response
|
|||||||
}
|
}
|
||||||
s, err := cma.cloudMigrationService.CreateSession(ctx, cloudmigration.CloudMigrationSessionRequest{
|
s, err := cma.cloudMigrationService.CreateSession(ctx, cloudmigration.CloudMigrationSessionRequest{
|
||||||
AuthToken: cmd.AuthToken,
|
AuthToken: cmd.AuthToken,
|
||||||
|
OrgID: c.SignedInUser.OrgID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetStatus(codes.Error, "session creation error")
|
span.SetStatus(codes.Error, "session creation error")
|
||||||
@ -285,7 +286,7 @@ func (cma *CloudMigrationAPI) DeleteSession(c *contextmodel.ReqContext) response
|
|||||||
return response.ErrOrFallback(http.StatusBadRequest, "invalid session uid", err)
|
return response.ErrOrFallback(http.StatusBadRequest, "invalid session uid", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := cma.cloudMigrationService.DeleteSession(ctx, uid)
|
_, err := cma.cloudMigrationService.DeleteSession(ctx, c.OrgID, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetStatus(codes.Error, "session delete error")
|
span.SetStatus(codes.Error, "session delete error")
|
||||||
span.RecordError(err)
|
span.RecordError(err)
|
||||||
@ -365,6 +366,7 @@ func (cma *CloudMigrationAPI) GetSnapshot(c *contextmodel.ReqContext) response.R
|
|||||||
SessionUID: sessUid,
|
SessionUID: sessUid,
|
||||||
ResultPage: c.QueryInt("resultPage"),
|
ResultPage: c.QueryInt("resultPage"),
|
||||||
ResultLimit: c.QueryInt("resultLimit"),
|
ResultLimit: c.QueryInt("resultLimit"),
|
||||||
|
OrgID: c.SignedInUser.OrgID,
|
||||||
}
|
}
|
||||||
if q.ResultLimit == 0 {
|
if q.ResultLimit == 0 {
|
||||||
q.ResultLimit = 100
|
q.ResultLimit = 100
|
||||||
@ -448,6 +450,7 @@ func (cma *CloudMigrationAPI) GetSnapshotList(c *contextmodel.ReqContext) respon
|
|||||||
Limit: c.QueryInt("limit"),
|
Limit: c.QueryInt("limit"),
|
||||||
Page: c.QueryInt("page"),
|
Page: c.QueryInt("page"),
|
||||||
Sort: c.Query("sort"),
|
Sort: c.Query("sort"),
|
||||||
|
OrgID: c.SignedInUser.OrgID,
|
||||||
}
|
}
|
||||||
if q.Limit == 0 {
|
if q.Limit == 0 {
|
||||||
q.Limit = 100
|
q.Limit = 100
|
||||||
@ -508,7 +511,7 @@ func (cma *CloudMigrationAPI) UploadSnapshot(c *contextmodel.ReqContext) respons
|
|||||||
return response.ErrOrFallback(http.StatusBadRequest, "invalid snapshot uid", err)
|
return response.ErrOrFallback(http.StatusBadRequest, "invalid snapshot uid", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cma.cloudMigrationService.UploadSnapshot(ctx, sessUid, snapshotUid); err != nil {
|
if err := cma.cloudMigrationService.UploadSnapshot(ctx, c.OrgID, sessUid, snapshotUid); err != nil {
|
||||||
span.SetStatus(codes.Error, "error uploading snapshot")
|
span.SetStatus(codes.Error, "error uploading snapshot")
|
||||||
span.RecordError(err)
|
span.RecordError(err)
|
||||||
|
|
||||||
|
@ -17,13 +17,13 @@ type Service interface {
|
|||||||
DeleteToken(ctx context.Context, uid string) error
|
DeleteToken(ctx context.Context, uid string) error
|
||||||
|
|
||||||
CreateSession(ctx context.Context, req CloudMigrationSessionRequest) (*CloudMigrationSessionResponse, error)
|
CreateSession(ctx context.Context, req CloudMigrationSessionRequest) (*CloudMigrationSessionResponse, error)
|
||||||
GetSession(ctx context.Context, migUID string) (*CloudMigrationSession, error)
|
GetSession(ctx context.Context, orgID int64, migUID string) (*CloudMigrationSession, error)
|
||||||
DeleteSession(ctx context.Context, migUID string) (*CloudMigrationSession, error)
|
DeleteSession(ctx context.Context, orgID int64, migUID string) (*CloudMigrationSession, error)
|
||||||
GetSessionList(context.Context) (*CloudMigrationSessionListResponse, error)
|
GetSessionList(ctx context.Context, orgID int64) (*CloudMigrationSessionListResponse, error)
|
||||||
|
|
||||||
CreateSnapshot(ctx context.Context, signedInUser *user.SignedInUser, sessionUid string) (*CloudMigrationSnapshot, error)
|
CreateSnapshot(ctx context.Context, signedInUser *user.SignedInUser, sessionUid string) (*CloudMigrationSnapshot, error)
|
||||||
GetSnapshot(ctx context.Context, query GetSnapshotsQuery) (*CloudMigrationSnapshot, error)
|
GetSnapshot(ctx context.Context, query GetSnapshotsQuery) (*CloudMigrationSnapshot, error)
|
||||||
GetSnapshotList(ctx context.Context, query ListSnapshotsQuery) ([]CloudMigrationSnapshot, error)
|
GetSnapshotList(ctx context.Context, query ListSnapshotsQuery) ([]CloudMigrationSnapshot, error)
|
||||||
UploadSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error
|
UploadSnapshot(ctx context.Context, orgID int64, sessionUid string, snapshotUid string) error
|
||||||
CancelSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error
|
CancelSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error
|
||||||
}
|
}
|
||||||
|
@ -362,10 +362,10 @@ func (s *Service) DeleteToken(ctx context.Context, tokenID string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
func (s *Service) GetSession(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSession")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSession")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
migration, err := s.store.GetMigrationSessionByUID(ctx, uid)
|
migration, err := s.store.GetMigrationSessionByUID(ctx, orgID, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -373,11 +373,11 @@ func (s *Service) GetSession(ctx context.Context, uid string) (*cloudmigration.C
|
|||||||
return migration, nil
|
return migration, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetSessionList(ctx context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
func (s *Service) GetSessionList(ctx context.Context, orgID int64) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSessionList")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSessionList")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
values, err := s.store.GetCloudMigrationSessionList(ctx)
|
values, err := s.store.GetCloudMigrationSessionList(ctx, orgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("retrieving session list from store: %w", err)
|
return nil, fmt.Errorf("retrieving session list from store: %w", err)
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ func (s *Service) CreateSession(ctx context.Context, cmd cloudmigration.CloudMig
|
|||||||
return nil, cloudmigration.ErrTokenInvalid.Errorf("token could not be decoded") // don't want to leak info here
|
return nil, cloudmigration.ErrTokenInvalid.Errorf("token could not be decoded") // don't want to leak info here
|
||||||
}
|
}
|
||||||
|
|
||||||
migration := token.ToMigration()
|
migration := token.ToMigration(cmd.OrgID)
|
||||||
// validate token against GMS before saving
|
// validate token against GMS before saving
|
||||||
if err := s.ValidateToken(ctx, migration); err != nil {
|
if err := s.ValidateToken(ctx, migration); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -429,11 +429,11 @@ func (s *Service) CreateSession(ctx context.Context, cmd cloudmigration.CloudMig
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) DeleteSession(ctx context.Context, sessionUID string) (*cloudmigration.CloudMigrationSession, error) {
|
func (s *Service) DeleteSession(ctx context.Context, orgID int64, sessionUID string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.DeleteSession")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.DeleteSession")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
session, snapshots, err := s.store.DeleteMigrationSessionByUID(ctx, sessionUID)
|
session, snapshots, err := s.store.DeleteMigrationSessionByUID(ctx, orgID, sessionUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.report(ctx, session, gmsclient.EventDisconnect, 0, err)
|
s.report(ctx, session, gmsclient.EventDisconnect, 0, err)
|
||||||
return nil, fmt.Errorf("deleting migration from db for session %v: %w", sessionUID, err)
|
return nil, fmt.Errorf("deleting migration from db for session %v: %w", sessionUID, err)
|
||||||
@ -451,7 +451,7 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// fetch session for the gms auth token
|
// fetch session for the gms auth token
|
||||||
session, err := s.store.GetMigrationSessionByUID(ctx, sessionUid)
|
session, err := s.store.GetMigrationSessionByUID(ctx, signedInUser.GetOrgID(), sessionUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fetching migration session for uid %s: %w", sessionUid, err)
|
return nil, fmt.Errorf("fetching migration session for uid %s: %w", sessionUid, err)
|
||||||
}
|
}
|
||||||
@ -538,13 +538,13 @@ func (s *Service) GetSnapshot(ctx context.Context, query cloudmigration.GetSnaps
|
|||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSnapshot")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetSnapshot")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
sessionUid, snapshotUid := query.SessionUID, query.SnapshotUID
|
orgID, sessionUid, snapshotUid := query.OrgID, query.SessionUID, query.SnapshotUID
|
||||||
snapshot, err := s.store.GetSnapshotByUID(ctx, sessionUid, snapshotUid, query.ResultPage, query.ResultLimit)
|
snapshot, err := s.store.GetSnapshotByUID(ctx, orgID, sessionUid, snapshotUid, query.ResultPage, query.ResultLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fetching snapshot for uid %s: %w", snapshotUid, err)
|
return nil, fmt.Errorf("fetching snapshot for uid %s: %w", snapshotUid, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := s.store.GetMigrationSessionByUID(ctx, sessionUid)
|
session, err := s.store.GetMigrationSessionByUID(ctx, orgID, sessionUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fetching session for uid %s: %w", sessionUid, err)
|
return nil, fmt.Errorf("fetching session for uid %s: %w", sessionUid, err)
|
||||||
}
|
}
|
||||||
@ -594,7 +594,7 @@ func (s *Service) GetSnapshot(ctx context.Context, query cloudmigration.GetSnaps
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the snapshot after the update
|
// Refresh the snapshot after the update
|
||||||
snapshot, err = s.store.GetSnapshotByUID(ctx, sessionUid, snapshotUid, query.ResultPage, query.ResultLimit)
|
snapshot, err = s.store.GetSnapshotByUID(ctx, orgID, sessionUid, snapshotUid, query.ResultPage, query.ResultLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("fetching snapshot for uid %s: %w", snapshotUid, err)
|
return nil, fmt.Errorf("fetching snapshot for uid %s: %w", snapshotUid, err)
|
||||||
}
|
}
|
||||||
@ -685,7 +685,7 @@ func (s *Service) GetSnapshotList(ctx context.Context, query cloudmigration.List
|
|||||||
return snapshotList, nil
|
return snapshotList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) UploadSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error {
|
func (s *Service) UploadSnapshot(ctx context.Context, orgID int64, sessionUid string, snapshotUid string) error {
|
||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.UploadSnapshot",
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.UploadSnapshot",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("sessionUid", sessionUid),
|
attribute.String("sessionUid", sessionUid),
|
||||||
@ -695,7 +695,7 @@ func (s *Service) UploadSnapshot(ctx context.Context, sessionUid string, snapsho
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// fetch session for the gms auth token
|
// fetch session for the gms auth token
|
||||||
session, err := s.store.GetMigrationSessionByUID(ctx, sessionUid)
|
session, err := s.store.GetMigrationSessionByUID(ctx, orgID, sessionUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fetching migration session for uid %s: %w", sessionUid, err)
|
return fmt.Errorf("fetching migration session for uid %s: %w", sessionUid, err)
|
||||||
}
|
}
|
||||||
@ -703,6 +703,7 @@ func (s *Service) UploadSnapshot(ctx context.Context, sessionUid string, snapsho
|
|||||||
snapshot, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
|
snapshot, err := s.GetSnapshot(ctx, cloudmigration.GetSnapshotsQuery{
|
||||||
SnapshotUID: snapshotUid,
|
SnapshotUID: snapshotUid,
|
||||||
SessionUID: sessionUid,
|
SessionUID: sessionUid,
|
||||||
|
OrgID: orgID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("fetching snapshot with uid %s: %w", snapshotUid, err)
|
return fmt.Errorf("fetching snapshot with uid %s: %w", snapshotUid, err)
|
||||||
|
@ -29,11 +29,11 @@ func (s *NoopServiceImpl) ValidateToken(ctx context.Context, cm cloudmigration.C
|
|||||||
return cloudmigration.ErrMigrationDisabled
|
return cloudmigration.ErrMigrationDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NoopServiceImpl) GetSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
func (s *NoopServiceImpl) GetSession(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
return nil, cloudmigration.ErrFeatureDisabledError
|
return nil, cloudmigration.ErrFeatureDisabledError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NoopServiceImpl) GetSessionList(ctx context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
func (s *NoopServiceImpl) GetSessionList(ctx context.Context, orgID int64) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
||||||
return nil, cloudmigration.ErrFeatureDisabledError
|
return nil, cloudmigration.ErrFeatureDisabledError
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func (s *NoopServiceImpl) CreateSession(ctx context.Context, cm cloudmigration.C
|
|||||||
return nil, cloudmigration.ErrMigrationDisabled
|
return nil, cloudmigration.ErrMigrationDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NoopServiceImpl) DeleteSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
func (s *NoopServiceImpl) DeleteSession(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
return nil, cloudmigration.ErrFeatureDisabledError
|
return nil, cloudmigration.ErrFeatureDisabledError
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ func (s *NoopServiceImpl) GetSnapshotList(ctx context.Context, query cloudmigrat
|
|||||||
return nil, cloudmigration.ErrFeatureDisabledError
|
return nil, cloudmigration.ErrFeatureDisabledError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NoopServiceImpl) UploadSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error {
|
func (s *NoopServiceImpl) UploadSnapshot(ctx context.Context, orgID int64, sessionUid string, snapshotUid string) error {
|
||||||
return cloudmigration.ErrFeatureDisabledError
|
return cloudmigration.ErrFeatureDisabledError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,22 +357,19 @@ func Test_OnlyQueriesStatusFromGMSWhenRequired(t *testing.T) {
|
|||||||
|
|
||||||
func Test_DeletedDashboardsNotMigrated(t *testing.T) {
|
func Test_DeletedDashboardsNotMigrated(t *testing.T) {
|
||||||
s := setUpServiceTest(t, false).(*Service)
|
s := setUpServiceTest(t, false).(*Service)
|
||||||
|
|
||||||
|
/** NOTE: this is not used at the moment since we changed the service
|
||||||
|
|
||||||
// modify what the mock returns for just this test case
|
// modify what the mock returns for just this test case
|
||||||
dashMock := s.dashboardService.(*dashboards.FakeDashboardService)
|
dashMock := s.dashboardService.(*dashboards.FakeDashboardService)
|
||||||
dashMock.On("GetAllDashboards", mock.Anything).Return(
|
dashMock.On("GetAllDashboards", mock.Anything).Return(
|
||||||
[]*dashboards.Dashboard{
|
[]*dashboards.Dashboard{
|
||||||
{
|
{UID: "1", OrgID: 1, Data: simplejson.New()},
|
||||||
UID: "1",
|
{UID: "2", OrgID: 1, Data: simplejson.New(), Deleted: time.Now()},
|
||||||
Data: simplejson.New(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
UID: "2",
|
|
||||||
Data: simplejson.New(),
|
|
||||||
Deleted: time.Now(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
data, err := s.getMigrationDataJSON(context.TODO(), &user.SignedInUser{OrgID: 1})
|
data, err := s.getMigrationDataJSON(context.TODO(), &user.SignedInUser{OrgID: 1})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -555,7 +552,7 @@ func TestDeleteSession(t *testing.T) {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
t.Cleanup(cancel)
|
t.Cleanup(cancel)
|
||||||
|
|
||||||
session, err := s.DeleteSession(ctx, "invalid-session-uid")
|
session, err := s.DeleteSession(ctx, 2, "invalid-session-uid")
|
||||||
require.Nil(t, session)
|
require.Nil(t, session)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
@ -570,6 +567,7 @@ func TestDeleteSession(t *testing.T) {
|
|||||||
|
|
||||||
cmd := cloudmigration.CloudMigrationSessionRequest{
|
cmd := cloudmigration.CloudMigrationSessionRequest{
|
||||||
AuthToken: createTokenResp.Token,
|
AuthToken: createTokenResp.Token,
|
||||||
|
OrgID: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
createResp, err := s.CreateSession(ctx, cmd)
|
createResp, err := s.CreateSession(ctx, cmd)
|
||||||
@ -577,12 +575,12 @@ func TestDeleteSession(t *testing.T) {
|
|||||||
require.NotEmpty(t, createResp.UID)
|
require.NotEmpty(t, createResp.UID)
|
||||||
require.NotEmpty(t, createResp.Slug)
|
require.NotEmpty(t, createResp.Slug)
|
||||||
|
|
||||||
deletedSession, err := s.DeleteSession(ctx, createResp.UID)
|
deletedSession, err := s.DeleteSession(ctx, cmd.OrgID, createResp.UID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, deletedSession)
|
require.NotNil(t, deletedSession)
|
||||||
require.Equal(t, deletedSession.UID, createResp.UID)
|
require.Equal(t, deletedSession.UID, createResp.UID)
|
||||||
|
|
||||||
notFoundSession, err := s.GetSession(ctx, deletedSession.UID)
|
notFoundSession, err := s.GetSession(ctx, cmd.OrgID, deletedSession.UID)
|
||||||
require.ErrorIs(t, err, cloudmigration.ErrMigrationNotFound)
|
require.ErrorIs(t, err, cloudmigration.ErrMigrationNotFound)
|
||||||
require.Nil(t, notFoundSession)
|
require.Nil(t, notFoundSession)
|
||||||
})
|
})
|
||||||
@ -868,6 +866,21 @@ func setUpServiceTest(t *testing.T, withDashboardMock bool) cloudmigration.Servi
|
|||||||
LastApplied: time.Now().Unix(),
|
LastApplied: time.Now().Unix(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Insert test data for dashboard test, should be removed later when we move GetAllDashboardsByOrgId() to the dashboard service
|
||||||
|
_, err = sqlStore.GetSqlxSession().Exec(context.Background(), `
|
||||||
|
INSERT INTO
|
||||||
|
dashboard (id, org_id, data, deleted, slug, title, created, version, updated )
|
||||||
|
VALUES
|
||||||
|
(1, 1, '{}', null, 'asdf', 'ghjk', '2024-03-27 15:30:43.000' , '1','2024-03-27 15:30:43.000' ),
|
||||||
|
(2, 1, '{}', '2024-03-27 15:30:43.000','qwert', 'yuio', '2024-03-27 15:30:43.000' , '2','2024-03-27 15:30:43.000'),
|
||||||
|
(3, 2, '{}', null, 'asdf', 'ghjk', '2024-03-27 15:30:43.000' , '1','2024-03-27 15:30:43.000' ),
|
||||||
|
(4, 2, '{}', '2024-03-27 15:30:43.000','qwert', 'yuio', '2024-03-27 15:30:43.000' , '2','2024-03-27 15:30:43.000');
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
s, err := ProvideService(
|
s, err := ProvideService(
|
||||||
cfg,
|
cfg,
|
||||||
httpclient.NewProvider(),
|
httpclient.NewProvider(),
|
||||||
|
@ -57,21 +57,21 @@ func (m FakeServiceImpl) CreateSession(_ context.Context, _ cloudmigration.Cloud
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FakeServiceImpl) GetSession(_ context.Context, _ string) (*cloudmigration.CloudMigrationSession, error) {
|
func (m FakeServiceImpl) GetSession(_ context.Context, _ int64, _ string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
if m.ReturnError {
|
if m.ReturnError {
|
||||||
return nil, fmt.Errorf("mock error")
|
return nil, fmt.Errorf("mock error")
|
||||||
}
|
}
|
||||||
return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil
|
return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FakeServiceImpl) DeleteSession(_ context.Context, _ string) (*cloudmigration.CloudMigrationSession, error) {
|
func (m FakeServiceImpl) DeleteSession(_ context.Context, _ int64, _ string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
if m.ReturnError {
|
if m.ReturnError {
|
||||||
return nil, fmt.Errorf("mock error")
|
return nil, fmt.Errorf("mock error")
|
||||||
}
|
}
|
||||||
return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil
|
return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FakeServiceImpl) GetSessionList(_ context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
func (m FakeServiceImpl) GetSessionList(_ context.Context, _ int64) (*cloudmigration.CloudMigrationSessionListResponse, error) {
|
||||||
if m.ReturnError {
|
if m.ReturnError {
|
||||||
return nil, fmt.Errorf("mock error")
|
return nil, fmt.Errorf("mock error")
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ func (m FakeServiceImpl) GetSnapshotList(ctx context.Context, query cloudmigrati
|
|||||||
return cloudSnapshots, nil
|
return cloudSnapshots, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m FakeServiceImpl) UploadSnapshot(ctx context.Context, sessionUid string, snapshotUid string) error {
|
func (m FakeServiceImpl) UploadSnapshot(ctx context.Context, _ int64, sessionUid string, snapshotUid string) error {
|
||||||
if m.ReturnError {
|
if m.ReturnError {
|
||||||
return fmt.Errorf("mock error")
|
return fmt.Errorf("mock error")
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
|
|||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
dataSources, err := s.getDataSourceCommands(ctx)
|
dataSources, err := s.getDataSourceCommands(ctx, signedInUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Error("Failed to get datasources", "err", err)
|
s.log.Error("Failed to get datasources", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -208,17 +208,17 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
|
|||||||
return migrationData, nil
|
return migrationData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) getDataSourceCommands(ctx context.Context) ([]datasources.AddDataSourceCommand, error) {
|
func (s *Service) getDataSourceCommands(ctx context.Context, signedInUser *user.SignedInUser) ([]datasources.AddDataSourceCommand, error) {
|
||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDataSourceCommands")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDataSourceCommands")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
dataSources, err := s.dsService.GetAllDataSources(ctx, &datasources.GetAllDataSourcesQuery{})
|
dataSources, err := s.dsService.GetDataSources(ctx, &datasources.GetDataSourcesQuery{OrgID: signedInUser.GetOrgID()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Error("Failed to get all datasources", "err", err)
|
s.log.Error("Failed to get all datasources", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []datasources.AddDataSourceCommand{}
|
result := make([]datasources.AddDataSourceCommand, 0, len(dataSources))
|
||||||
for _, dataSource := range dataSources {
|
for _, dataSource := range dataSources {
|
||||||
// Decrypt secure json to send raw credentials
|
// Decrypt secure json to send raw credentials
|
||||||
decryptedData, err := s.secretsService.DecryptJsonData(ctx, dataSource.SecureJsonData)
|
decryptedData, err := s.secretsService.DecryptJsonData(ctx, dataSource.SecureJsonData)
|
||||||
@ -253,7 +253,7 @@ func (s *Service) getDashboardAndFolderCommands(ctx context.Context, signedInUse
|
|||||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDashboardAndFolderCommands")
|
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.getDashboardAndFolderCommands")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
dashs, err := s.dashboardService.GetAllDashboards(ctx)
|
dashs, err := s.store.GetAllDashboardsByOrgId(ctx, signedInUser.GetOrgID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -279,20 +279,21 @@ func (s *Service) getDashboardAndFolderCommands(ctx context.Context, signedInUse
|
|||||||
folders, err := s.folderService.GetFolders(ctx, folder.GetFoldersQuery{
|
folders, err := s.folderService.GetFolders(ctx, folder.GetFoldersQuery{
|
||||||
UIDs: folderUids,
|
UIDs: folderUids,
|
||||||
SignedInUser: signedInUser,
|
SignedInUser: signedInUser,
|
||||||
|
OrgID: signedInUser.GetOrgID(),
|
||||||
WithFullpathUIDs: true,
|
WithFullpathUIDs: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
folderCmds := make([]folder.CreateFolderCommand, len(folders))
|
folderCmds := make([]folder.CreateFolderCommand, 0, len(folders))
|
||||||
for i, f := range folders {
|
for _, f := range folders {
|
||||||
folderCmds[i] = folder.CreateFolderCommand{
|
folderCmds = append(folderCmds, folder.CreateFolderCommand{
|
||||||
UID: f.UID,
|
UID: f.UID,
|
||||||
Title: f.Title,
|
Title: f.Title,
|
||||||
Description: f.Description,
|
Description: f.Description,
|
||||||
ParentUID: f.ParentUID,
|
ParentUID: f.ParentUID,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return dashboardCmds, folderCmds, nil
|
return dashboardCmds, folderCmds, nil
|
||||||
@ -641,6 +642,7 @@ func (s *Service) getFolderNamesForFolderUIDs(ctx context.Context, signedInUser
|
|||||||
folders, err := s.folderService.GetFolders(ctx, folder.GetFoldersQuery{
|
folders, err := s.folderService.GetFolders(ctx, folder.GetFoldersQuery{
|
||||||
UIDs: folderUIDs,
|
UIDs: folderUIDs,
|
||||||
SignedInUser: signedInUser,
|
SignedInUser: signedInUser,
|
||||||
|
OrgID: signedInUser.GetOrgID(),
|
||||||
WithFullpathUIDs: true,
|
WithFullpathUIDs: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -661,15 +663,18 @@ func (s *Service) getFolderNamesForFolderUIDs(ctx context.Context, signedInUser
|
|||||||
// getParentNames finds the parent names for resources and returns a map of data type: {data UID : parentName}
|
// getParentNames finds the parent names for resources and returns a map of data type: {data UID : parentName}
|
||||||
// for dashboards, folders and library elements - the parent is the parent folder
|
// for dashboards, folders and library elements - the parent is the parent folder
|
||||||
func (s *Service) getParentNames(ctx context.Context, signedInUser *user.SignedInUser, dashboards []dashboards.Dashboard, folders []folder.CreateFolderCommand, libraryElements []libraryElement) (map[cloudmigration.MigrateDataType]map[string](string), error) {
|
func (s *Service) getParentNames(ctx context.Context, signedInUser *user.SignedInUser, dashboards []dashboards.Dashboard, folders []folder.CreateFolderCommand, libraryElements []libraryElement) (map[cloudmigration.MigrateDataType]map[string](string), error) {
|
||||||
parentNamesByType := make(map[cloudmigration.MigrateDataType]map[string](string))
|
parentNamesByType := make(map[cloudmigration.MigrateDataType]map[string]string)
|
||||||
for _, dataType := range currentMigrationTypes {
|
for _, dataType := range currentMigrationTypes {
|
||||||
parentNamesByType[dataType] = make(map[string]string)
|
parentNamesByType[dataType] = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain list of unique folderUIDs
|
// Obtain list of unique folderUIDs
|
||||||
parentFolderUIDsSet := make(map[string]struct{}, len(dashboards)+len(folders)+len(libraryElements))
|
parentFolderUIDsSet := make(map[string]struct{})
|
||||||
for _, dashboard := range dashboards {
|
for _, dashboard := range dashboards {
|
||||||
parentFolderUIDsSet[dashboard.FolderUID] = struct{}{}
|
// we dont need the root folder
|
||||||
|
if dashboard.FolderUID != "" {
|
||||||
|
parentFolderUIDsSet[dashboard.FolderUID] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, f := range folders {
|
for _, f := range folders {
|
||||||
parentFolderUIDsSet[f.ParentUID] = struct{}{}
|
parentFolderUIDsSet[f.ParentUID] = struct{}{}
|
||||||
|
@ -4,24 +4,29 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||||
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
)
|
)
|
||||||
|
|
||||||
type store interface {
|
type store interface {
|
||||||
CreateMigrationSession(ctx context.Context, session cloudmigration.CloudMigrationSession) (*cloudmigration.CloudMigrationSession, error)
|
CreateMigrationSession(ctx context.Context, session cloudmigration.CloudMigrationSession) (*cloudmigration.CloudMigrationSession, error)
|
||||||
GetMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error)
|
GetMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error)
|
||||||
GetCloudMigrationSessionList(ctx context.Context) ([]*cloudmigration.CloudMigrationSession, error)
|
GetCloudMigrationSessionList(ctx context.Context, orgID int64) ([]*cloudmigration.CloudMigrationSession, error)
|
||||||
// DeleteMigrationSessionByUID deletes the migration session, and all the related snapshot and resources.
|
// DeleteMigrationSessionByUID deletes the migration session, and all the related snapshot and resources.
|
||||||
// the work is done in a transaction.
|
// the work is done in a transaction.
|
||||||
DeleteMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error)
|
DeleteMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error)
|
||||||
|
|
||||||
CreateSnapshot(ctx context.Context, snapshot cloudmigration.CloudMigrationSnapshot) (string, error)
|
CreateSnapshot(ctx context.Context, snapshot cloudmigration.CloudMigrationSnapshot) (string, error)
|
||||||
UpdateSnapshot(ctx context.Context, snapshot cloudmigration.UpdateSnapshotCmd) error
|
UpdateSnapshot(ctx context.Context, snapshot cloudmigration.UpdateSnapshotCmd) error
|
||||||
GetSnapshotByUID(ctx context.Context, sessUid, id string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error)
|
GetSnapshotByUID(ctx context.Context, orgID int64, sessUid, id string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error)
|
||||||
GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error)
|
GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error)
|
||||||
DeleteSnapshot(ctx context.Context, snapshotUid string) error
|
|
||||||
|
|
||||||
CreateUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error
|
// Deleted because were not used externally
|
||||||
GetSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error)
|
// - DeleteSnapshot(ctx context.Context, snapshotUid string) error
|
||||||
GetSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error)
|
// - CreateUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error
|
||||||
DeleteSnapshotResources(ctx context.Context, snapshotUid string) error
|
// - GetSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error)
|
||||||
|
// - GetSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error)
|
||||||
|
// - DeleteSnapshotResources(ctx context.Context, snapshotUid string) error
|
||||||
|
|
||||||
|
// TODO move this function dashboards/databases/databases.go
|
||||||
|
GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
||||||
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets"
|
"github.com/grafana/grafana/pkg/services/secrets"
|
||||||
secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore"
|
secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
@ -29,10 +30,10 @@ const (
|
|||||||
GetSnapshotListSortingLatest = "latest"
|
GetSnapshotListSortingLatest = "latest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ss *sqlStore) GetMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
func (ss *sqlStore) GetMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error) {
|
||||||
var cm cloudmigration.CloudMigrationSession
|
var cm cloudmigration.CloudMigrationSession
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
exist, err := sess.Where("uid=?", uid).Get(&cm)
|
exist, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&cm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -74,11 +75,10 @@ func (ss *sqlStore) CreateMigrationSession(ctx context.Context, migration cloudm
|
|||||||
return &migration, nil
|
return &migration, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context) ([]*cloudmigration.CloudMigrationSession, error) {
|
func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context, orgID int64) ([]*cloudmigration.CloudMigrationSession, error) {
|
||||||
var migrations = make([]*cloudmigration.CloudMigrationSession, 0)
|
var migrations = make([]*cloudmigration.CloudMigrationSession, 0)
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
sess.OrderBy("created DESC")
|
return sess.Where("org_id=?", orgID).OrderBy("created DESC").Find(&migrations)
|
||||||
return sess.Find(&migrations)
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -95,10 +95,10 @@ func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context) ([]*cloudm
|
|||||||
return migrations, nil
|
return migrations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error) {
|
func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error) {
|
||||||
var c cloudmigration.CloudMigrationSession
|
var c cloudmigration.CloudMigrationSession
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
exist, err := sess.Where("uid=?", uid).Get(&c)
|
exist, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -124,11 +124,11 @@ func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, uid string)
|
|||||||
|
|
||||||
err = ss.db.InTransaction(ctx, func(ctx context.Context) error {
|
err = ss.db.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
for _, snapshot := range snapshots {
|
for _, snapshot := range snapshots {
|
||||||
err := ss.DeleteSnapshotResources(ctx, snapshot.UID)
|
err := ss.deleteSnapshotResources(ctx, snapshot.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("deleting snapshot resource from db: %w", err)
|
return fmt.Errorf("deleting snapshot resource from db: %w", err)
|
||||||
}
|
}
|
||||||
err = ss.DeleteSnapshot(ctx, snapshot.UID)
|
err = ss.deleteSnapshot(ctx, orgID, snapshot.UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("deleting snapshot from db: %w", err)
|
return fmt.Errorf("deleting snapshot from db: %w", err)
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ func (ss *sqlStore) UpdateSnapshot(ctx context.Context, update cloudmigration.Up
|
|||||||
|
|
||||||
// Update resources if set
|
// Update resources if set
|
||||||
if len(update.Resources) > 0 {
|
if len(update.Resources) > 0 {
|
||||||
if err := ss.CreateUpdateSnapshotResources(ctx, update.UID, update.Resources); err != nil {
|
if err := ss.createUpdateSnapshotResources(ctx, update.UID, update.Resources); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ func (ss *sqlStore) UpdateSnapshot(ctx context.Context, update cloudmigration.Up
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) DeleteSnapshot(ctx context.Context, snapshotUid string) error {
|
func (ss *sqlStore) deleteSnapshot(ctx context.Context, orgID int64, snapshotUid string) error {
|
||||||
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
_, err := sess.Delete(cloudmigration.CloudMigrationSnapshot{
|
_, err := sess.Delete(cloudmigration.CloudMigrationSnapshot{
|
||||||
UID: snapshotUid,
|
UID: snapshotUid,
|
||||||
@ -233,9 +233,16 @@ func (ss *sqlStore) DeleteSnapshot(ctx context.Context, snapshotUid string) erro
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error) {
|
func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, orgID int64, sessionUid, uid string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error) {
|
||||||
|
// first we check if the session exists, using orgId and sessionUid
|
||||||
|
session, err := ss.GetMigrationSessionByUID(ctx, orgID, sessionUid)
|
||||||
|
if err != nil || session == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we get the snapshot
|
||||||
var snapshot cloudmigration.CloudMigrationSnapshot
|
var snapshot cloudmigration.CloudMigrationSnapshot
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
err = ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
exist, err := sess.Where("session_uid=? AND uid=?", sessionUid, uid).Get(&snapshot)
|
exist, err := sess.Where("session_uid=? AND uid=?", sessionUid, uid).Get(&snapshot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -257,11 +264,11 @@ func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string
|
|||||||
snapshot.EncryptionKey = []byte(secret)
|
snapshot.EncryptionKey = []byte(secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
resources, err := ss.GetSnapshotResources(ctx, uid, resultPage, resultLimit)
|
resources, err := ss.getSnapshotResources(ctx, uid, resultPage, resultLimit)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
snapshot.Resources = resources
|
snapshot.Resources = resources
|
||||||
}
|
}
|
||||||
stats, err := ss.GetSnapshotResourceStats(ctx, uid)
|
stats, err := ss.getSnapshotResourceStats(ctx, uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
snapshot.StatsRollup = *stats
|
snapshot.StatsRollup = *stats
|
||||||
}
|
}
|
||||||
@ -274,7 +281,9 @@ func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string
|
|||||||
func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error) {
|
func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error) {
|
||||||
var snapshots = make([]cloudmigration.CloudMigrationSnapshot, 0)
|
var snapshots = make([]cloudmigration.CloudMigrationSnapshot, 0)
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
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")
|
sess.Join("INNER", "cloud_migration_session",
|
||||||
|
"cloud_migration_session.uid = cloud_migration_snapshot.session_uid AND cloud_migration_session.org_id = ?", query.OrgID,
|
||||||
|
)
|
||||||
if query.Limit != GetAllSnapshots {
|
if query.Limit != GetAllSnapshots {
|
||||||
offset := (query.Page - 1) * query.Limit
|
offset := (query.Page - 1) * query.Limit
|
||||||
sess.Limit(query.Limit, offset)
|
sess.Limit(query.Limit, offset)
|
||||||
@ -298,7 +307,7 @@ func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.Li
|
|||||||
snapshot.EncryptionKey = []byte(secret)
|
snapshot.EncryptionKey = []byte(secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if stats, err := ss.GetSnapshotResourceStats(ctx, snapshot.UID); err != nil {
|
if stats, err := ss.getSnapshotResourceStats(ctx, snapshot.UID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
snapshot.StatsRollup = *stats
|
snapshot.StatsRollup = *stats
|
||||||
@ -310,7 +319,7 @@ func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.Li
|
|||||||
|
|
||||||
// CreateUpdateSnapshotResources either updates a migration resource for a snapshot, or creates it if it does not exist
|
// CreateUpdateSnapshotResources either updates a migration resource for a snapshot, or creates it if it does not exist
|
||||||
// If the uid is not known, it uses snapshot_uid + resource_uid as a lookup
|
// If the uid is not known, it uses snapshot_uid + resource_uid as a lookup
|
||||||
func (ss *sqlStore) CreateUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error {
|
func (ss *sqlStore) createUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error {
|
||||||
return ss.db.InTransaction(ctx, func(ctx context.Context) error {
|
return ss.db.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
sql := "UPDATE cloud_migration_resource SET status=?, error_string=?, error_code=? WHERE uid=? OR (snapshot_uid=? AND resource_uid=?)"
|
sql := "UPDATE cloud_migration_resource SET status=?, error_string=?, error_code=? WHERE uid=? OR (snapshot_uid=? AND resource_uid=?)"
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
@ -344,7 +353,7 @@ func (ss *sqlStore) CreateUpdateSnapshotResources(ctx context.Context, snapshotU
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) GetSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error) {
|
func (ss *sqlStore) getSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error) {
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
page = 1
|
page = 1
|
||||||
}
|
}
|
||||||
@ -366,7 +375,7 @@ func (ss *sqlStore) GetSnapshotResources(ctx context.Context, snapshotUid string
|
|||||||
return resources, nil
|
return resources, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) GetSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error) {
|
func (ss *sqlStore) getSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error) {
|
||||||
typeCounts := make([]struct {
|
typeCounts := make([]struct {
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
@ -413,7 +422,7 @@ func (ss *sqlStore) GetSnapshotResourceStats(ctx context.Context, snapshotUid st
|
|||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *sqlStore) DeleteSnapshotResources(ctx context.Context, snapshotUid string) error {
|
func (ss *sqlStore) deleteSnapshotResources(ctx context.Context, snapshotUid string) error {
|
||||||
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
_, err := sess.Delete(cloudmigration.CloudMigrationResource{
|
_, err := sess.Delete(cloudmigration.CloudMigrationResource{
|
||||||
SnapshotUID: snapshotUid,
|
SnapshotUID: snapshotUid,
|
||||||
@ -456,3 +465,19 @@ func (ss *sqlStore) decryptToken(ctx context.Context, cm *cloudmigration.CloudMi
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move this function dashboards/databases/databases.go
|
||||||
|
func (ss *sqlStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error) {
|
||||||
|
//ctx, span := tracer.Start(ctx, "dashboards.database.GetAllDashboardsByOrgId")
|
||||||
|
//defer span.End()
|
||||||
|
|
||||||
|
var dashs = make([]*dashboards.Dashboard, 0)
|
||||||
|
err := ss.db.WithDbSession(ctx, func(session *db.Session) error {
|
||||||
|
// "deleted IS NULL" is to avoid deleted dashboards
|
||||||
|
return session.Where("org_id = ? AND deleted IS NULL", orgID).Find(&dashs)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dashs, nil
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ func Test_GetAllCloudMigrationSessions(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("get all cloud_migration_session entries", func(t *testing.T) {
|
t.Run("get all cloud_migration_session entries", func(t *testing.T) {
|
||||||
value, err := s.GetCloudMigrationSessionList(ctx)
|
value, err := s.GetCloudMigrationSessionList(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 3, len(value))
|
require.Equal(t, 3, len(value))
|
||||||
for _, m := range value {
|
for _, m := range value {
|
||||||
@ -54,6 +54,7 @@ func Test_CreateMigrationSession(t *testing.T) {
|
|||||||
cm := cloudmigration.CloudMigrationSession{
|
cm := cloudmigration.CloudMigrationSession{
|
||||||
AuthToken: encodeToken("token"),
|
AuthToken: encodeToken("token"),
|
||||||
Slug: "fake_stack",
|
Slug: "fake_stack",
|
||||||
|
OrgID: 3,
|
||||||
StackID: 1234,
|
StackID: 1234,
|
||||||
RegionSlug: "fake_slug",
|
RegionSlug: "fake_slug",
|
||||||
ClusterSlug: "fake_cluster_slug",
|
ClusterSlug: "fake_cluster_slug",
|
||||||
@ -63,7 +64,7 @@ func Test_CreateMigrationSession(t *testing.T) {
|
|||||||
require.NotEmpty(t, sess.ID)
|
require.NotEmpty(t, sess.ID)
|
||||||
require.NotEmpty(t, sess.UID)
|
require.NotEmpty(t, sess.UID)
|
||||||
|
|
||||||
getRes, err := s.GetMigrationSessionByUID(ctx, sess.UID)
|
getRes, err := s.GetMigrationSessionByUID(ctx, 3, sess.UID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, sess.ID, getRes.ID)
|
require.Equal(t, sess.ID, getRes.ID)
|
||||||
require.Equal(t, sess.UID, getRes.UID)
|
require.Equal(t, sess.UID, getRes.UID)
|
||||||
@ -80,13 +81,15 @@ func Test_GetMigrationSessionByUID(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
t.Run("find session by uid", func(t *testing.T) {
|
t.Run("find session by uid", func(t *testing.T) {
|
||||||
uid := "qwerty"
|
uid := "qwerty"
|
||||||
mig, err := s.GetMigrationSessionByUID(ctx, uid)
|
orgId := int64(1)
|
||||||
|
mig, err := s.GetMigrationSessionByUID(ctx, orgId, uid)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, uid, mig.UID)
|
require.Equal(t, uid, mig.UID)
|
||||||
|
require.Equal(t, orgId, mig.OrgID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns error if session is not found by uid", func(t *testing.T) {
|
t.Run("returns error if session is not found by uid", func(t *testing.T) {
|
||||||
_, err := s.GetMigrationSessionByUID(ctx, "fake_uid_1234")
|
_, err := s.GetMigrationSessionByUID(ctx, 1, "fake_uid_1234")
|
||||||
require.ErrorIs(t, cloudmigration.ErrMigrationNotFound, err)
|
require.ErrorIs(t, cloudmigration.ErrMigrationNotFound, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -115,7 +118,10 @@ func Test_SnapshotManagement(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("tests the snapshot lifecycle", func(t *testing.T) {
|
t.Run("tests the snapshot lifecycle", func(t *testing.T) {
|
||||||
session, err := s.CreateMigrationSession(ctx, cloudmigration.CloudMigrationSession{})
|
session, err := s.CreateMigrationSession(ctx, cloudmigration.CloudMigrationSession{
|
||||||
|
OrgID: 1,
|
||||||
|
AuthToken: encodeToken("token"),
|
||||||
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// create a snapshot
|
// create a snapshot
|
||||||
@ -129,7 +135,7 @@ func Test_SnapshotManagement(t *testing.T) {
|
|||||||
require.NotEmpty(t, snapshotUid)
|
require.NotEmpty(t, snapshotUid)
|
||||||
|
|
||||||
//retrieve it from the db
|
//retrieve it from the db
|
||||||
snapshot, err := s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0)
|
snapshot, err := s.GetSnapshotByUID(ctx, 1, session.UID, snapshotUid, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
|
require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
|
||||||
|
|
||||||
@ -138,22 +144,22 @@ func Test_SnapshotManagement(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
//retrieve it again
|
//retrieve it again
|
||||||
snapshot, err = s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0)
|
snapshot, err = s.GetSnapshotByUID(ctx, 1, session.UID, snapshotUid, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
|
require.Equal(t, cloudmigration.SnapshotStatusCreating, snapshot.Status)
|
||||||
|
|
||||||
// lists snapshots and ensures it's in there
|
// lists snapshots and ensures it's in there
|
||||||
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: session.UID, Page: 1, Limit: 100})
|
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: session.UID, OrgID: 1, Page: 1, Limit: 100})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, snapshots, 1)
|
require.Len(t, snapshots, 1)
|
||||||
require.Equal(t, *snapshot, snapshots[0])
|
require.Equal(t, *snapshot, snapshots[0])
|
||||||
|
|
||||||
// delete snapshot
|
// delete snapshot
|
||||||
err = s.DeleteSnapshot(ctx, snapshotUid)
|
err = s.deleteSnapshot(ctx, 1, snapshotUid)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// now we expect not to find the snapshot
|
// now we expect not to find the snapshot
|
||||||
snapshot, err = s.GetSnapshotByUID(ctx, session.UID, snapshotUid, 0, 0)
|
snapshot, err = s.GetSnapshotByUID(ctx, 1, session.UID, snapshotUid, 0, 0)
|
||||||
require.ErrorIs(t, err, cloudmigration.ErrSnapshotNotFound)
|
require.ErrorIs(t, err, cloudmigration.ErrSnapshotNotFound)
|
||||||
require.Nil(t, snapshot)
|
require.Nil(t, snapshot)
|
||||||
})
|
})
|
||||||
@ -165,12 +171,12 @@ func Test_SnapshotResources(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("tests CRUD of snapshot resources", func(t *testing.T) {
|
t.Run("tests CRUD of snapshot resources", func(t *testing.T) {
|
||||||
// Get the default rows from the test
|
// Get the default rows from the test
|
||||||
resources, err := s.GetSnapshotResources(ctx, "poiuy", 0, 100)
|
resources, err := s.getSnapshotResources(ctx, "poiuy", 0, 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resources, 3)
|
assert.Len(t, resources, 3)
|
||||||
|
|
||||||
// create a new resource and update an existing resource
|
// create a new resource and update an existing resource
|
||||||
err = s.CreateUpdateSnapshotResources(ctx, "poiuy", []cloudmigration.CloudMigrationResource{
|
err = s.createUpdateSnapshotResources(ctx, "poiuy", []cloudmigration.CloudMigrationResource{
|
||||||
{
|
{
|
||||||
Type: cloudmigration.DatasourceDataType,
|
Type: cloudmigration.DatasourceDataType,
|
||||||
RefID: "mi39fj",
|
RefID: "mi39fj",
|
||||||
@ -184,7 +190,7 @@ func Test_SnapshotResources(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Get resources again
|
// Get resources again
|
||||||
resources, err = s.GetSnapshotResources(ctx, "poiuy", 0, 100)
|
resources, err = s.getSnapshotResources(ctx, "poiuy", 0, 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resources, 4)
|
assert.Len(t, resources, 4)
|
||||||
// ensure existing resource was updated
|
// ensure existing resource was updated
|
||||||
@ -203,7 +209,7 @@ func Test_SnapshotResources(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check stats
|
// check stats
|
||||||
stats, err := s.GetSnapshotResourceStats(ctx, "poiuy")
|
stats, err := s.getSnapshotResourceStats(ctx, "poiuy")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, map[cloudmigration.MigrateDataType]int{
|
assert.Equal(t, map[cloudmigration.MigrateDataType]int{
|
||||||
cloudmigration.DatasourceDataType: 2,
|
cloudmigration.DatasourceDataType: 2,
|
||||||
@ -217,10 +223,10 @@ func Test_SnapshotResources(t *testing.T) {
|
|||||||
assert.Equal(t, 4, stats.Total)
|
assert.Equal(t, 4, stats.Total)
|
||||||
|
|
||||||
// delete snapshot resources
|
// delete snapshot resources
|
||||||
err = s.DeleteSnapshotResources(ctx, "poiuy")
|
err = s.deleteSnapshotResources(ctx, "poiuy")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// make sure they're gone
|
// make sure they're gone
|
||||||
resources, err = s.GetSnapshotResources(ctx, "poiuy", 0, 100)
|
resources, err = s.getSnapshotResources(ctx, "poiuy", 0, 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resources, 0)
|
assert.Len(t, resources, 0)
|
||||||
})
|
})
|
||||||
@ -233,7 +239,7 @@ func TestGetSnapshotList(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
t.Run("returns list of snapshots that belong to a session", func(t *testing.T) {
|
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})
|
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, OrgID: 1, Page: 1, Limit: 100})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ids := make([]string, 0)
|
ids := make([]string, 0)
|
||||||
@ -246,7 +252,7 @@ func TestGetSnapshotList(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns only one snapshot that belongs to a session", func(t *testing.T) {
|
t.Run("returns only one snapshot that belongs to a session", func(t *testing.T) {
|
||||||
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, Page: 1, Limit: 1})
|
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, OrgID: 1, Page: 1, Limit: 1})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Len(t, snapshots, 1)
|
assert.Len(t, snapshots, 1)
|
||||||
})
|
})
|
||||||
@ -258,7 +264,7 @@ func TestGetSnapshotList(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns paginated snapshot that belongs to a session", func(t *testing.T) {
|
t.Run("returns paginated snapshot that belongs to a session", func(t *testing.T) {
|
||||||
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, Page: 2, Limit: 1})
|
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, OrgID: 1, Page: 2, Limit: 1})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ids := make([]string, 0)
|
ids := make([]string, 0)
|
||||||
@ -271,7 +277,7 @@ func TestGetSnapshotList(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("returns desc sorted list of snapshots that belong to a session", func(t *testing.T) {
|
t.Run("returns desc sorted 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, Sort: "latest"})
|
snapshots, err := s.GetSnapshotList(ctx, cloudmigration.ListSnapshotsQuery{SessionUID: sessionUID, OrgID: 1, Page: 1, Limit: 100, Sort: "latest"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ids := make([]string, 0)
|
ids := make([]string, 0)
|
||||||
@ -291,7 +297,7 @@ func TestGetSnapshotList(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("if the session is deleted, snapshots can't be retrieved anymore", func(t *testing.T) {
|
t.Run("if the session is deleted, snapshots can't be retrieved anymore", func(t *testing.T) {
|
||||||
// Delete the session.
|
// Delete the session.
|
||||||
_, _, err := s.DeleteMigrationSessionByUID(ctx, sessionUID)
|
_, _, err := s.DeleteMigrationSessionByUID(ctx, 1, sessionUID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Fetch the snapshots that belong to the deleted session.
|
// Fetch the snapshots that belong to the deleted session.
|
||||||
@ -363,15 +369,17 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) {
|
|||||||
// insert cloud migration test data
|
// insert cloud migration test data
|
||||||
_, err := testDB.GetSqlxSession().Exec(ctx, `
|
_, err := testDB.GetSqlxSession().Exec(ctx, `
|
||||||
INSERT INTO
|
INSERT INTO
|
||||||
cloud_migration_session (id, uid, auth_token, slug, stack_id, region_slug, cluster_slug, created, updated)
|
cloud_migration_session (id, uid, org_id, auth_token, slug, stack_id, region_slug, cluster_slug, created, updated)
|
||||||
VALUES
|
VALUES
|
||||||
(1,'qwerty', ?, '11111', 11111, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000'),
|
(1,'qwerty', 1, ?, '11111', 11111, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000'),
|
||||||
(2,'asdfgh', ?, '22222', 22222, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000'),
|
(2,'asdfgh', 1, ?, '22222', 22222, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000'),
|
||||||
(3,'zxcvbn', ?, '33333', 33333, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000');
|
(3,'zxcvbn', 1, ?, '33333', 33333, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000'),
|
||||||
|
(4,'zxcvbn_org2', 2, ?, '33333', 33333, 'test', 'test', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000');
|
||||||
`,
|
`,
|
||||||
encodeToken("12345"),
|
encodeToken("12345"),
|
||||||
encodeToken("6789"),
|
encodeToken("6789"),
|
||||||
encodeToken("777"),
|
encodeToken("777"),
|
||||||
|
encodeToken("0987"),
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -380,9 +388,10 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) {
|
|||||||
INSERT INTO
|
INSERT INTO
|
||||||
cloud_migration_snapshot (session_uid, uid, created, updated, finished, status)
|
cloud_migration_snapshot (session_uid, uid, created, updated, finished, status)
|
||||||
VALUES
|
VALUES
|
||||||
('qwerty', 'poiuy', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished"),
|
('qwerty', 'poiuy', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished"),
|
||||||
('qwerty', 'lkjhg', '2024-03-26 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished"),
|
('qwerty', 'lkjhg', '2024-03-26 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished"),
|
||||||
('zxcvbn', 'mnbvvc', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished");
|
('zxcvbn', 'mnbvvc', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished"),
|
||||||
|
('zxcvbn_org2', 'mnbvvc_org2', '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000', "finished");
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -400,7 +409,8 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) {
|
|||||||
('mnbvde', 'poiuy', 'DATASOURCE', 'jf38gh', 'OK', ''),
|
('mnbvde', 'poiuy', 'DATASOURCE', 'jf38gh', 'OK', ''),
|
||||||
('qwerty', 'poiuy', 'DASHBOARD', 'ejcx4d', 'ERROR', 'fake error'),
|
('qwerty', 'poiuy', 'DASHBOARD', 'ejcx4d', 'ERROR', 'fake error'),
|
||||||
('zxcvbn', 'poiuy', 'FOLDER', 'fi39fj', 'PENDING', ''),
|
('zxcvbn', 'poiuy', 'FOLDER', 'fi39fj', 'PENDING', ''),
|
||||||
('4fi9sd', '39fi39', 'FOLDER', 'fi39fj', 'OK', '');
|
('4fi9sd', '39fi39', 'FOLDER', 'fi39fj', 'OK', ''),
|
||||||
|
('4fi9ee', 'mnbvvc_org2', 'DATASOURCE', 'fi39asd', 'OK', '');
|
||||||
`,
|
`,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -21,6 +21,7 @@ var (
|
|||||||
// CloudMigrationSession represents a configured migration token
|
// CloudMigrationSession represents a configured migration token
|
||||||
type CloudMigrationSession struct {
|
type CloudMigrationSession struct {
|
||||||
ID int64 `xorm:"pk autoincr 'id'"`
|
ID int64 `xorm:"pk autoincr 'id'"`
|
||||||
|
OrgID int64 `xorm:"org_id"`
|
||||||
UID string `xorm:"uid"`
|
UID string `xorm:"uid"`
|
||||||
AuthToken string
|
AuthToken string
|
||||||
Slug string
|
Slug string
|
||||||
@ -144,6 +145,8 @@ type CloudMigrationRunList struct {
|
|||||||
|
|
||||||
type CloudMigrationSessionRequest struct {
|
type CloudMigrationSessionRequest struct {
|
||||||
AuthToken string
|
AuthToken string
|
||||||
|
// OrgId in the on prem instance
|
||||||
|
OrgID int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CloudMigrationSessionResponse struct {
|
type CloudMigrationSessionResponse struct {
|
||||||
@ -159,6 +162,7 @@ type CloudMigrationSessionListResponse struct {
|
|||||||
|
|
||||||
type GetSnapshotsQuery struct {
|
type GetSnapshotsQuery struct {
|
||||||
SnapshotUID string
|
SnapshotUID string
|
||||||
|
OrgID int64
|
||||||
SessionUID string
|
SessionUID string
|
||||||
ResultPage int
|
ResultPage int
|
||||||
ResultLimit int
|
ResultLimit int
|
||||||
@ -166,6 +170,7 @@ type GetSnapshotsQuery struct {
|
|||||||
|
|
||||||
type ListSnapshotsQuery struct {
|
type ListSnapshotsQuery struct {
|
||||||
SessionUID string
|
SessionUID string
|
||||||
|
OrgID int64
|
||||||
Page int
|
Page int
|
||||||
Limit int
|
Limit int
|
||||||
Sort string
|
Sort string
|
||||||
@ -189,13 +194,14 @@ type Base64EncodedTokenPayload struct {
|
|||||||
Instance Base64HGInstance
|
Instance Base64HGInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Base64EncodedTokenPayload) ToMigration() CloudMigrationSession {
|
func (p Base64EncodedTokenPayload) ToMigration(orgID int64) CloudMigrationSession {
|
||||||
return CloudMigrationSession{
|
return CloudMigrationSession{
|
||||||
AuthToken: p.Token,
|
AuthToken: p.Token,
|
||||||
Slug: p.Instance.Slug,
|
Slug: p.Instance.Slug,
|
||||||
StackID: p.Instance.StackID,
|
StackID: p.Instance.StackID,
|
||||||
RegionSlug: p.Instance.RegionSlug,
|
RegionSlug: p.Instance.RegionSlug,
|
||||||
ClusterSlug: p.Instance.ClusterSlug,
|
ClusterSlug: p.Instance.ClusterSlug,
|
||||||
|
OrgID: orgID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func addCloudMigrationsMigrations(mg *Migrator) {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
// --- v2 - asynchronous workflow refactor
|
// --- v2 - asynchronous workflow refactor
|
||||||
sessionTable := Table{
|
migrationSessionTable := Table{
|
||||||
Name: "cloud_migration_session",
|
Name: "cloud_migration_session",
|
||||||
Columns: []*Column{
|
Columns: []*Column{
|
||||||
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
||||||
@ -99,7 +99,7 @@ func addCloudMigrationsMigrations(mg *Migrator) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
addTableReplaceMigrations(mg, migrationTable, sessionTable, 2, map[string]string{
|
addTableReplaceMigrations(mg, migrationTable, migrationSessionTable, 2, map[string]string{
|
||||||
"id": "id",
|
"id": "id",
|
||||||
"uid": "uid",
|
"uid": "uid",
|
||||||
"auth_token": "auth_token",
|
"auth_token": "auth_token",
|
||||||
@ -171,6 +171,11 @@ func addCloudMigrationsMigrations(mg *Migrator) {
|
|||||||
Nullable: true,
|
Nullable: true,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// -- Adds org_id column for for all elements - defaults to 1 (default org)
|
||||||
|
mg.AddMigration("add cloud_migration_session.org_id column", NewAddColumnMigration(migrationSessionTable, &Column{
|
||||||
|
Name: "org_id", Type: DB_BigInt, Nullable: false, Default: "1",
|
||||||
|
}))
|
||||||
|
|
||||||
mg.AddMigration("add cloud_migration_resource.error_code column", NewAddColumnMigration(migrationResourceTable, &Column{
|
mg.AddMigration("add cloud_migration_resource.error_code column", NewAddColumnMigration(migrationResourceTable, &Column{
|
||||||
Name: "error_code",
|
Name: "error_code",
|
||||||
Type: DB_Text,
|
Type: DB_Text,
|
||||||
|
Loading…
Reference in New Issue
Block a user