From 9d3a4e236d2cdb863034dfbd180108d17efbcb2d Mon Sep 17 00:00:00 2001 From: Michael Mandrus <41969079+mmandrus@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:58:59 -0400 Subject: [PATCH] CloudMigrations: Refactor API for async work (#89084) * rename some stuff * more renaming * clean up api * rename more functions * rename cms -> gms * update comment * update swagger gen * update endpoints * overzealous * final touches * dont modify existing migrations * break structs into domain and dtos * add some conversion funcs * fix build * update frontend * try to make swagger happy --- pkg/services/cloudmigration/api/api.go | 220 +++++------------- pkg/services/cloudmigration/api/api_test.go | 4 +- pkg/services/cloudmigration/api/dtos.go | 209 +++++++++++++++++ pkg/services/cloudmigration/cloudmigration.go | 19 +- .../cloudmigrationimpl/cloudmigration.go | 87 ++++--- .../cloudmigrationimpl/cloudmigration_noop.go | 22 +- .../cloudmigrationimpl/cloudmigration_test.go | 22 +- .../fake/cloudmigration_fake.go | 64 +++-- .../cloudmigrationimpl/store.go | 14 +- .../cloudmigrationimpl/xorm_store.go | 34 +-- .../cloudmigrationimpl/xorm_store_test.go | 46 ++-- .../cloudmigration/cmsclient/client.go | 17 -- .../cloudmigration/gmsclient/client.go | 14 ++ pkg/services/cloudmigration/gmsclient/dtos.go | 47 ++++ .../cms_client.go => gmsclient/gms_client.go} | 62 ++++- .../inmemory_client.go | 19 +- pkg/services/cloudmigration/model.go | 115 +++++---- .../sqlstore/migrations/cloud_migrations.go | 58 +++++ public/api-enterprise-spec.json | 60 ++--- public/api-merged.json | 89 ++++--- .../migrate-to-cloud/api/endpoints.gen.ts | 58 ++--- .../features/migrate-to-cloud/api/index.ts | 8 +- .../EmptyState/CallToAction/CallToAction.tsx | 4 +- .../EmptyState/CallToAction/ConnectModal.tsx | 6 +- .../features/migrate-to-cloud/onprem/Page.tsx | 14 +- public/openapi3.json | 105 +++++---- scripts/generate-rtk-apis.ts | 8 +- 27 files changed, 831 insertions(+), 594 deletions(-) create mode 100644 pkg/services/cloudmigration/api/dtos.go delete mode 100644 pkg/services/cloudmigration/cmsclient/client.go create mode 100644 pkg/services/cloudmigration/gmsclient/client.go create mode 100644 pkg/services/cloudmigration/gmsclient/dtos.go rename pkg/services/cloudmigration/{cmsclient/cms_client.go => gmsclient/gms_client.go} (58%) rename pkg/services/cloudmigration/{cmsclient => gmsclient}/inmemory_client.go (63%) diff --git a/pkg/services/cloudmigration/api/api.go b/pkg/services/cloudmigration/api/api.go index b31885a3fe1..66a2107f813 100644 --- a/pkg/services/cloudmigration/api/api.go +++ b/pkg/services/cloudmigration/api/api.go @@ -40,14 +40,16 @@ func RegisterApi( // registerEndpoints Registers Endpoints on Grafana Router func (cma *CloudMigrationAPI) registerEndpoints() { cma.routeRegister.Group("/api/cloudmigration", func(cloudMigrationRoute routing.RouteRegister) { - // migration - cloudMigrationRoute.Get("/migration", routing.Wrap(cma.GetMigrationList)) - cloudMigrationRoute.Post("/migration", routing.Wrap(cma.CreateMigration)) - cloudMigrationRoute.Get("/migration/:uid", routing.Wrap(cma.GetMigration)) - cloudMigrationRoute.Delete("/migration/:uid", routing.Wrap(cma.DeleteMigration)) + cloudMigrationRoute.Get("/migration", routing.Wrap(cma.GetSessionList)) + cloudMigrationRoute.Post("/migration", routing.Wrap(cma.CreateSession)) + cloudMigrationRoute.Get("/migration/:uid", routing.Wrap(cma.GetSession)) + cloudMigrationRoute.Delete("/migration/:uid", routing.Wrap(cma.DeleteSession)) + + // TODO new APIs for snapshot management to replace these cloudMigrationRoute.Post("/migration/:uid/run", routing.Wrap(cma.RunMigration)) cloudMigrationRoute.Get("/migration/:uid/run", routing.Wrap(cma.GetMigrationRunList)) cloudMigrationRoute.Get("/migration/run/:runUID", routing.Wrap(cma.GetMigrationRun)) + cloudMigrationRoute.Get("/token", routing.Wrap(cma.GetToken)) cloudMigrationRoute.Post("/token", routing.Wrap(cma.CreateToken)) cloudMigrationRoute.Delete("/token/:uid", routing.Wrap(cma.DeleteToken)) @@ -141,84 +143,88 @@ func (cma *CloudMigrationAPI) DeleteToken(c *contextmodel.ReqContext) response.R return response.Empty(http.StatusNoContent) } -// swagger:route GET /cloudmigration/migration migrations getMigrationList +// swagger:route GET /cloudmigration/migration migrations getSessionList // -// Get a list of all cloud migrations. +// Get a list of all cloud migration sessions that have been created. // // Responses: -// 200: cloudMigrationListResponse +// 200: cloudMigrationSessionListResponse // 401: unauthorisedError // 403: forbiddenError // 500: internalServerError -func (cma *CloudMigrationAPI) GetMigrationList(c *contextmodel.ReqContext) response.Response { - ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetMigrationList") +func (cma *CloudMigrationAPI) GetSessionList(c *contextmodel.ReqContext) response.Response { + ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetSessionList") defer span.End() - cloudMigrations, err := cma.cloudMigrationService.GetMigrationList(ctx) + sl, err := cma.cloudMigrationService.GetSessionList(ctx) if err != nil { - return response.ErrOrFallback(http.StatusInternalServerError, "migration list error", err) + return response.ErrOrFallback(http.StatusInternalServerError, "session list error", err) } - return response.JSON(http.StatusOK, cloudMigrations) + return response.JSON(http.StatusOK, convertSessionListToDTO(*sl)) } -// swagger:route GET /cloudmigration/migration/{uid} migrations getCloudMigration +// swagger:route GET /cloudmigration/migration/{uid} migrations getSession // -// Get a cloud migration. -// -// It returns migrations that has been created. +// Get a cloud migration session by its uid. // // Responses: -// 200: cloudMigrationResponse +// 200: cloudMigrationSessionResponse // 401: unauthorisedError // 403: forbiddenError // 500: internalServerError -func (cma *CloudMigrationAPI) GetMigration(c *contextmodel.ReqContext) response.Response { - ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetMigration") +func (cma *CloudMigrationAPI) GetSession(c *contextmodel.ReqContext) response.Response { + ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.GetSession") defer span.End() uid := web.Params(c.Req)[":uid"] if err := util.ValidateUID(uid); err != nil { - return response.Error(http.StatusBadRequest, "invalid migration uid", err) + return response.Error(http.StatusBadRequest, "invalid session uid", err) } - cloudMigration, err := cma.cloudMigrationService.GetMigration(ctx, uid) + s, err := cma.cloudMigrationService.GetSession(ctx, uid) if err != nil { - return response.ErrOrFallback(http.StatusNotFound, "migration not found", err) + return response.ErrOrFallback(http.StatusNotFound, "session not found", err) } - return response.JSON(http.StatusOK, cloudMigration) + + return response.JSON(http.StatusOK, CloudMigrationSessionResponseDTO{ + UID: s.UID, + Slug: s.Slug, + Created: s.Created, + Updated: s.Updated, + }) } -// swagger:parameters getCloudMigration -type GetCloudMigrationRequest struct { - // UID of a migration - // - // in: path - UID string `json:"uid"` -} - -// swagger:route POST /cloudmigration/migration migrations createMigration +// swagger:route POST /cloudmigration/migration migrations createSession // -// Create a migration. +// Create a migration session. // // Responses: -// 200: cloudMigrationResponse +// 200: cloudMigrationSessionResponse // 401: unauthorisedError // 403: forbiddenError // 500: internalServerError -func (cma *CloudMigrationAPI) CreateMigration(c *contextmodel.ReqContext) response.Response { - ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.CreateMigration") +func (cma *CloudMigrationAPI) CreateSession(c *contextmodel.ReqContext) response.Response { + ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.CreateSession") defer span.End() - cmd := cloudmigration.CloudMigrationRequest{} + cmd := CloudMigrationSessionRequestDTO{} if err := web.Bind(c.Req, &cmd); err != nil { return response.ErrOrFallback(http.StatusBadRequest, "bad request data", err) } - cloudMigration, err := cma.cloudMigrationService.CreateMigration(ctx, cmd) + s, err := cma.cloudMigrationService.CreateSession(ctx, cloudmigration.CloudMigrationSessionRequest{ + AuthToken: cmd.AuthToken, + }) if err != nil { - return response.ErrOrFallback(http.StatusInternalServerError, "migration creation error", err) + return response.ErrOrFallback(http.StatusInternalServerError, "session creation error", err) } - return response.JSON(http.StatusOK, cloudMigration) + + return response.JSON(http.StatusOK, CloudMigrationSessionResponseDTO{ + UID: s.UID, + Slug: s.Slug, + Created: s.Created, + Updated: s.Updated, + }) } // swagger:route POST /cloudmigration/migration/{uid}/run migrations runCloudMigration @@ -246,15 +252,7 @@ func (cma *CloudMigrationAPI) RunMigration(c *contextmodel.ReqContext) response. return response.ErrOrFallback(http.StatusInternalServerError, "migration run error", err) } - return response.JSON(http.StatusOK, result) -} - -// swagger:parameters runCloudMigration -type RunCloudMigrationRequest struct { - // UID of a migration - // - // in: path - UID string `json:"uid"` + return response.JSON(http.StatusOK, convertMigrateDataResponseToDTO(*result)) } // swagger:route GET /cloudmigration/migration/run/{runUID} migrations getCloudMigrationRun @@ -280,21 +278,13 @@ func (cma *CloudMigrationAPI) GetMigrationRun(c *contextmodel.ReqContext) respon return response.ErrOrFallback(http.StatusInternalServerError, "migration status error", err) } - runResponse, err := migrationStatus.ToResponse() + result, err := migrationStatus.GetResult() if err != nil { cma.log.Error("could not return migration run", "err", err) return response.Error(http.StatusInternalServerError, "migration run get error", err) } - return response.JSON(http.StatusOK, runResponse) -} - -// swagger:parameters getCloudMigrationRun -type GetMigrationRunParams struct { - // RunUID of a migration run - // - // in: path - RunUID string `json:"runUID"` + return response.JSON(http.StatusOK, convertMigrateDataResponseToDTO(*result)) } // swagger:route GET /cloudmigration/migration/{uid}/run migrations getCloudMigrationRunList @@ -320,118 +310,36 @@ func (cma *CloudMigrationAPI) GetMigrationRunList(c *contextmodel.ReqContext) re return response.ErrOrFallback(http.StatusInternalServerError, "list migration status error", err) } - return response.JSON(http.StatusOK, runList) + runs := make([]MigrateDataResponseListDTO, len(runList.Runs)) + for i := 0; i < len(runList.Runs); i++ { + runs[i] = MigrateDataResponseListDTO{runList.Runs[i].RunUID} + } + return response.JSON(http.StatusOK, SnapshotListDTO{ + Runs: runs, + }) } -// swagger:parameters getCloudMigrationRunList -type GetCloudMigrationRunList struct { - // UID of a migration - // - // in: path - UID string `json:"uid"` -} - -// swagger:route DELETE /cloudmigration/migration/{uid} migrations deleteCloudMigration +// swagger:route DELETE /cloudmigration/migration/{uid} migrations deleteSession // -// Delete a migration. +// Delete a migration session by its uid. // // Responses: // 200 // 401: unauthorisedError // 403: forbiddenError // 500: internalServerError -func (cma *CloudMigrationAPI) DeleteMigration(c *contextmodel.ReqContext) response.Response { - ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.DeleteMigration") +func (cma *CloudMigrationAPI) DeleteSession(c *contextmodel.ReqContext) response.Response { + ctx, span := cma.tracer.Start(c.Req.Context(), "MigrationAPI.DeleteSession") defer span.End() uid := web.Params(c.Req)[":uid"] if err := util.ValidateUID(uid); err != nil { - return response.ErrOrFallback(http.StatusBadRequest, "invalid migration uid", err) + return response.ErrOrFallback(http.StatusBadRequest, "invalid session uid", err) } - _, err := cma.cloudMigrationService.DeleteMigration(ctx, uid) + _, err := cma.cloudMigrationService.DeleteSession(ctx, uid) if err != nil { - return response.ErrOrFallback(http.StatusInternalServerError, "migration delete error", err) + return response.ErrOrFallback(http.StatusInternalServerError, "session delete error", err) } return response.Empty(http.StatusOK) } - -// swagger:parameters deleteCloudMigration -type DeleteMigrationRequest struct { - // UID of a migration - // - // in: path - UID string `json:"uid"` -} - -// swagger:response cloudMigrationRunResponse -type CloudMigrationRunResponse struct { - // in: body - Body cloudmigration.MigrateDataResponseDTO -} - -// swagger:response cloudMigrationListResponse -type CloudMigrationListResponse struct { - // in: body - Body cloudmigration.CloudMigrationListResponse -} - -// swagger:parameters createMigration -type CreateMigration struct { - // in:body - // required:true - Body cloudmigration.CloudMigrationRequest -} - -// swagger:response cloudMigrationResponse -type CloudMigrationResponse struct { - // in: body - Body cloudmigration.CloudMigrationResponse -} - -// swagger:response cloudMigrationRunListResponse -type CloudMigrationRunListResponse struct { - // in: body - Body cloudmigration.CloudMigrationRunList -} - -// swagger:parameters getCloudMigrationToken -type GetCloudMigrationToken struct { -} - -// swagger:response cloudMigrationGetTokenResponse -type CloudMigrationGetTokenResponse struct { - // in: body - Body GetAccessTokenResponseDTO -} - -type GetAccessTokenResponseDTO struct { - ID string `json:"id"` - DisplayName string `json:"displayName"` - ExpiresAt string `json:"expiresAt"` - FirstUsedAt string `json:"firstUsedAt"` - LastUsedAt string `json:"lastUsedAt"` - CreatedAt string `json:"createdAt"` -} - -// swagger:response cloudMigrationCreateTokenResponse -type CloudMigrationCreateTokenResponse struct { - // in: body - Body CreateAccessTokenResponseDTO -} - -type CreateAccessTokenResponseDTO struct { - Token string `json:"token"` -} - -// swagger:parameters deleteCloudMigrationToken -type DeleteCloudMigrationToken struct { - // UID of a cloud migration token - // - // in: path - UID string `json:"uid"` -} - -// swagger:response cloudMigrationDeleteTokenResponse -type CloudMigrationDeleteTokenResponse struct { -} diff --git a/pkg/services/cloudmigration/api/api_test.go b/pkg/services/cloudmigration/api/api_test.go index 8126d71de0b..6fc50df2e78 100644 --- a/pkg/services/cloudmigration/api/api_test.go +++ b/pkg/services/cloudmigration/api/api_test.go @@ -181,7 +181,7 @@ func TestCloudMigrationAPI_GetMigrationList(t *testing.T) { requestUrl: "/api/cloudmigration/migration", basicRole: org.RoleAdmin, expectedHttpResult: http.StatusOK, - expectedBody: `{"migrations":[{"uid":"mock_uid_1","stack":"mock_stack_1","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"},{"uid":"mock_uid_2","stack":"mock_stack_2","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"}]}`, + expectedBody: `{"sessions":[{"uid":"mock_uid_1","slug":"mock_stack_1","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"},{"uid":"mock_uid_2","slug":"mock_stack_2","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"}]}`, }, { desc: "should return 403 if no used is not admin", @@ -216,7 +216,7 @@ func TestCloudMigrationAPI_CreateMigration(t *testing.T) { requestBody: `{"auth_token":"asdf"}`, basicRole: org.RoleAdmin, expectedHttpResult: http.StatusOK, - expectedBody: `{"uid":"fake_uid","stack":"fake_stack","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"}`, + expectedBody: `{"uid":"fake_uid","slug":"fake_stack","created":"2024-06-05T17:30:40Z","updated":"2024-06-05T17:30:40Z"}`, }, { desc: "should return 403 if no used is not admin", diff --git a/pkg/services/cloudmigration/api/dtos.go b/pkg/services/cloudmigration/api/dtos.go new file mode 100644 index 00000000000..37cd12eef2e --- /dev/null +++ b/pkg/services/cloudmigration/api/dtos.go @@ -0,0 +1,209 @@ +package api + +import ( + "time" + + "github.com/grafana/grafana/pkg/services/cloudmigration" +) + +// swagger:parameters getCloudMigrationToken +type GetCloudMigrationToken struct { +} + +// swagger:response cloudMigrationGetTokenResponse +type CloudMigrationGetTokenResponse struct { + // in: body + Body GetAccessTokenResponseDTO +} + +type GetAccessTokenResponseDTO struct { + ID string `json:"id"` + DisplayName string `json:"displayName"` + ExpiresAt string `json:"expiresAt"` + FirstUsedAt string `json:"firstUsedAt"` + LastUsedAt string `json:"lastUsedAt"` + CreatedAt string `json:"createdAt"` +} + +// swagger:response cloudMigrationCreateTokenResponse +type CloudMigrationCreateTokenResponse struct { + // in: body + Body CreateAccessTokenResponseDTO +} + +type CreateAccessTokenResponseDTO struct { + Token string `json:"token"` +} + +// swagger:parameters deleteCloudMigrationToken +type DeleteCloudMigrationToken struct { + // UID of a cloud migration token + // + // in: path + UID string `json:"uid"` +} + +// swagger:response cloudMigrationDeleteTokenResponse +type CloudMigrationDeleteTokenResponse struct { +} + +// swagger:response cloudMigrationSessionListResponse +type CloudMigrationSessionListResponse struct { + // in: body + Body CloudMigrationSessionListResponseDTO +} + +type CloudMigrationSessionResponseDTO struct { + UID string `json:"uid"` + Slug string `json:"slug"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` +} + +type CloudMigrationSessionListResponseDTO struct { + Sessions []CloudMigrationSessionResponseDTO `json:"sessions"` +} + +// swagger:parameters getSession +type GetCloudMigrationSessionRequest struct { + // UID of a migration session + // + // in: path + UID string `json:"uid"` +} + +// swagger:response cloudMigrationSessionResponse +type CloudMigrationSessionResponse struct { + // in: body + Body CloudMigrationSessionResponseDTO +} + +// swagger:parameters createSession +type CreateSession struct { + // in:body + // required:true + Body CloudMigrationSessionRequestDTO +} + +type CloudMigrationSessionRequestDTO struct { + AuthToken string `json:"authToken"` +} + +// swagger:parameters runCloudMigration +type RunCloudMigrationRequest struct { + // UID of a migration + // + // in: path + UID string `json:"uid"` +} + +// swagger:response cloudMigrationRunResponse +type CloudMigrationRunResponse struct { + // in: body + Body MigrateDataResponseDTO +} + +type MigrateDataResponseDTO struct { + RunUID string `json:"uid"` + Items []MigrateDataResponseItemDTO `json:"items"` +} + +type MigrateDataResponseItemDTO struct { + // required:true + Type MigrateDataType `json:"type"` + // required:true + RefID string `json:"refId"` + // required:true + Status ItemStatus `json:"status"` + Error string `json:"error,omitempty"` +} + +// swagger:enum MigrateDataType +type MigrateDataType string + +const ( + DashboardDataType MigrateDataType = "DASHBOARD" + DatasourceDataType MigrateDataType = "DATASOURCE" + FolderDataType MigrateDataType = "FOLDER" +) + +// swagger:enum ItemStatus +type ItemStatus string + +const ( + ItemStatusOK ItemStatus = "OK" + ItemStatusError ItemStatus = "ERROR" +) + +// swagger:parameters getCloudMigrationRun +type GetMigrationRunParams struct { + // RunUID of a migration run + // + // in: path + RunUID string `json:"runUID"` +} + +// swagger:parameters getCloudMigrationRunList +type GetCloudMigrationRunList struct { + // UID of a migration + // + // in: path + UID string `json:"uid"` +} + +// swagger:response cloudMigrationRunListResponse +type CloudMigrationRunListResponse struct { + // in: body + Body SnapshotListDTO +} + +type SnapshotListDTO struct { + Runs []MigrateDataResponseListDTO `json:"runs"` +} + +type MigrateDataResponseListDTO struct { + RunUID string `json:"uid"` +} + +// swagger:parameters deleteSession +type DeleteMigrationSessionRequest struct { + // UID of a migration session + // + // in: path + UID string `json:"uid"` +} + +// utility funcs for converting to/from DTO + +func convertSessionListToDTO(sl cloudmigration.CloudMigrationSessionListResponse) CloudMigrationSessionListResponseDTO { + slDTOs := make([]CloudMigrationSessionResponseDTO, len(sl.Sessions)) + for i := 0; i < len(slDTOs); i++ { + s := sl.Sessions[i] + slDTOs[i] = CloudMigrationSessionResponseDTO{ + UID: s.UID, + Slug: s.Slug, + Created: s.Created, + Updated: s.Updated, + } + } + return CloudMigrationSessionListResponseDTO{ + Sessions: slDTOs, + } +} + +func convertMigrateDataResponseToDTO(r cloudmigration.MigrateDataResponse) MigrateDataResponseDTO { + items := make([]MigrateDataResponseItemDTO, len(r.Items)) + for i := 0; i < len(r.Items); i++ { + item := r.Items[i] + items[i] = MigrateDataResponseItemDTO{ + Type: MigrateDataType(item.Type), + RefID: item.RefID, + Status: ItemStatus(item.Status), + Error: item.Error, + } + } + return MigrateDataResponseDTO{ + RunUID: r.RunUID, + Items: items, + } +} diff --git a/pkg/services/cloudmigration/cloudmigration.go b/pkg/services/cloudmigration/cloudmigration.go index bb3d82af074..26b67ce1a09 100644 --- a/pkg/services/cloudmigration/cloudmigration.go +++ b/pkg/services/cloudmigration/cloudmigration.go @@ -11,17 +11,16 @@ type Service interface { GetToken(ctx context.Context) (gcom.TokenView, error) // CreateToken Creates a cloud migration token. CreateToken(ctx context.Context) (CreateAccessTokenResponse, error) - // ValidateToken Sends a request to CMS to test the token. - ValidateToken(ctx context.Context, mig CloudMigration) error + // ValidateToken Sends a request to GMS to test the token. + ValidateToken(ctx context.Context, mig CloudMigrationSession) error DeleteToken(ctx context.Context, uid string) error - CreateMigration(ctx context.Context, req CloudMigrationRequest) (*CloudMigrationResponse, error) - GetMigration(ctx context.Context, migUID string) (*CloudMigration, error) - DeleteMigration(ctx context.Context, migUID string) (*CloudMigration, error) - UpdateMigration(ctx context.Context, migUID string, request CloudMigrationRequest) (*CloudMigrationResponse, error) - GetMigrationList(context.Context) (*CloudMigrationListResponse, error) + CreateSession(ctx context.Context, req CloudMigrationSessionRequest) (*CloudMigrationSessionResponse, error) + GetSession(ctx context.Context, migUID string) (*CloudMigrationSession, error) + DeleteSession(ctx context.Context, migUID string) (*CloudMigrationSession, error) + GetSessionList(context.Context) (*CloudMigrationSessionListResponse, error) - RunMigration(ctx context.Context, migUID string) (*MigrateDataResponseDTO, error) - GetMigrationStatus(ctx context.Context, runUID string) (*CloudMigrationRun, error) - GetMigrationRunList(ctx context.Context, migUID string) (*CloudMigrationRunList, error) + RunMigration(ctx context.Context, migUID string) (*MigrateDataResponse, error) + GetMigrationStatus(ctx context.Context, runUID string) (*CloudMigrationSnapshot, error) + GetMigrationRunList(ctx context.Context, migUID string) (*SnapshotList, error) } diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration.go b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration.go index ec658947b6c..de5982af442 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration.go @@ -16,7 +16,7 @@ import ( "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/cloudmigration" "github.com/grafana/grafana/pkg/services/cloudmigration/api" - "github.com/grafana/grafana/pkg/services/cloudmigration/cmsclient" + "github.com/grafana/grafana/pkg/services/cloudmigration/gmsclient" "github.com/grafana/grafana/pkg/services/contexthandler" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" @@ -38,7 +38,7 @@ type Service struct { cfg *setting.Cfg features featuremgmt.FeatureToggles - cmsClient cmsclient.Client + gmsClient gmsclient.Client dsService datasources.DataSourceService gcomService gcom.Service @@ -95,16 +95,16 @@ func ProvideService( s.api = api.RegisterApi(routeRegister, s, tracer) if !cfg.CloudMigration.IsDeveloperMode { - // get CMS path from the config + // get GMS path from the config domain, err := s.parseCloudMigrationConfig() if err != nil { return nil, fmt.Errorf("config parse error: %w", err) } - s.cmsClient = cmsclient.NewCMSClient(domain) + s.gmsClient = gmsclient.NewGMSClient(domain) s.gcomService = gcom.New(gcom.Config{ApiURL: cfg.GrafanaComAPIURL, Token: cfg.CloudMigration.GcomAPIToken}) } else { - s.cmsClient = cmsclient.NewInMemoryClient() + s.gmsClient = gmsclient.NewInMemoryClient() s.gcomService = &gcomStub{policies: map[string]gcom.AccessPolicy{}, token: nil} s.cfg.StackID = "12345" } @@ -242,7 +242,7 @@ func (s *Service) CreateToken(ctx context.Context) (cloudmigration.CreateAccessT Instance: cloudmigration.Base64HGInstance{ StackID: instance.ID, RegionSlug: instance.RegionSlug, - ClusterSlug: instance.ClusterSlug, // This should be used for routing to CMS + ClusterSlug: instance.ClusterSlug, // This should be used for routing to GMS Slug: instance.Slug, }, }) @@ -275,11 +275,11 @@ func (s *Service) findAccessPolicyByName(ctx context.Context, regionSlug, access return nil, nil } -func (s *Service) ValidateToken(ctx context.Context, cm cloudmigration.CloudMigration) error { +func (s *Service) ValidateToken(ctx context.Context, cm cloudmigration.CloudMigrationSession) error { ctx, span := s.tracer.Start(ctx, "CloudMigrationService.ValidateToken") defer span.End() - if err := s.cmsClient.ValidateKey(ctx, cm); err != nil { + if err := s.gmsClient.ValidateKey(ctx, cm); err != nil { return fmt.Errorf("validating key: %w", err) } @@ -315,10 +315,10 @@ func (s *Service) DeleteToken(ctx context.Context, tokenID string) error { return nil } -func (s *Service) GetMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { +func (s *Service) GetSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { ctx, span := s.tracer.Start(ctx, "CloudMigrationService.GetMigration") defer span.End() - migration, err := s.store.GetMigrationByUID(ctx, uid) + migration, err := s.store.GetMigrationSessionByUID(ctx, uid) if err != nil { return nil, err } @@ -326,25 +326,25 @@ func (s *Service) GetMigration(ctx context.Context, uid string) (*cloudmigration return migration, nil } -func (s *Service) GetMigrationList(ctx context.Context) (*cloudmigration.CloudMigrationListResponse, error) { - values, err := s.store.GetAllCloudMigrations(ctx) +func (s *Service) GetSessionList(ctx context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) { + values, err := s.store.GetAllCloudMigrationSessions(ctx) if err != nil { return nil, err } - migrations := make([]cloudmigration.CloudMigrationResponse, 0) + migrations := make([]cloudmigration.CloudMigrationSessionResponse, 0) for _, v := range values { - migrations = append(migrations, cloudmigration.CloudMigrationResponse{ + migrations = append(migrations, cloudmigration.CloudMigrationSessionResponse{ UID: v.UID, - Stack: v.Stack, + Slug: v.Slug, Created: v.Created, Updated: v.Updated, }) } - return &cloudmigration.CloudMigrationListResponse{Migrations: migrations}, nil + return &cloudmigration.CloudMigrationSessionListResponse{Sessions: migrations}, nil } -func (s *Service) CreateMigration(ctx context.Context, cmd cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { +func (s *Service) CreateSession(ctx context.Context, cmd cloudmigration.CloudMigrationSessionRequest) (*cloudmigration.CloudMigrationSessionResponse, error) { ctx, span := s.tracer.Start(ctx, "CloudMigrationService.createMigration") defer span.End() @@ -359,32 +359,27 @@ func (s *Service) CreateMigration(ctx context.Context, cmd cloudmigration.CloudM } migration := token.ToMigration() - // validate token against cms before saving + // validate token against GMS before saving if err := s.ValidateToken(ctx, migration); err != nil { return nil, fmt.Errorf("token validation: %w", err) } - cm, err := s.store.CreateMigration(ctx, migration) + cm, err := s.store.CreateMigrationSession(ctx, migration) if err != nil { return nil, fmt.Errorf("error creating migration: %w", err) } - return &cloudmigration.CloudMigrationResponse{ + return &cloudmigration.CloudMigrationSessionResponse{ UID: cm.UID, - Stack: token.Instance.Slug, + Slug: token.Instance.Slug, Created: cm.Created, Updated: cm.Updated, }, nil } -func (s *Service) UpdateMigration(ctx context.Context, uid string, request cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { - // TODO: Implement method - return nil, nil -} - -func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration.MigrateDataResponseDTO, error) { +func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration.MigrateDataResponse, error) { // Get migration to read the auth token - migration, err := s.GetMigration(ctx, uid) + migration, err := s.GetSession(ctx, uid) if err != nil { return nil, fmt.Errorf("migration get error: %w", err) } @@ -396,8 +391,8 @@ func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration return nil, fmt.Errorf("migration data get error: %w", err) } - // Call the cms service - resp, err := s.cmsClient.MigrateData(ctx, *migration, *request) + // Call the gms service + resp, err := s.gmsClient.MigrateData(ctx, *migration, *request) if err != nil { s.log.Error("error migrating data: %w", err) return nil, fmt.Errorf("migrate data error: %w", err) @@ -411,9 +406,9 @@ func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration } // save the result of the migration - runUID, err := s.createMigrationRun(ctx, cloudmigration.CloudMigrationRun{ - CloudMigrationUID: migration.UID, - Result: respData, + runUID, err := s.createMigrationRun(ctx, cloudmigration.CloudMigrationSnapshot{ + SessionUID: migration.UID, + Result: respData, }) if err != nil { response.Error(http.StatusInternalServerError, "migration run save error", err) @@ -424,8 +419,8 @@ func (s *Service) RunMigration(ctx context.Context, uid string) (*cloudmigration return resp, nil } -func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.MigrateDataRequestDTO, error) { - var migrationDataSlice []cloudmigration.MigrateDataRequestItemDTO +func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.MigrateDataRequest, error) { + var migrationDataSlice []cloudmigration.MigrateDataRequestItem // Data sources dataSources, err := s.getDataSources(ctx) if err != nil { @@ -433,7 +428,7 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig return nil, err } for _, ds := range dataSources { - migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItemDTO{ + migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{ Type: cloudmigration.DatasourceDataType, RefID: ds.UID, Name: ds.Name, @@ -450,7 +445,7 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig for _, dashboard := range dashboards { dashboard.Data.Del("id") - migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItemDTO{ + migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{ Type: cloudmigration.DashboardDataType, RefID: dashboard.UID, Name: dashboard.Title, @@ -466,14 +461,14 @@ func (s *Service) getMigrationDataJSON(ctx context.Context) (*cloudmigration.Mig } for _, f := range folders { - migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItemDTO{ + migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{ Type: cloudmigration.FolderDataType, RefID: f.UID, Name: f.Title, Data: f, }) } - migrationData := &cloudmigration.MigrateDataRequestDTO{ + migrationData := &cloudmigration.MigrateDataRequest{ Items: migrationDataSlice, } @@ -547,7 +542,7 @@ func (s *Service) getDashboards(ctx context.Context) ([]dashboards.Dashboard, er return result, nil } -func (s *Service) createMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationRun) (string, error) { +func (s *Service) createMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationSnapshot) (string, error) { uid, err := s.store.CreateMigrationRun(ctx, cmr) if err != nil { s.log.Error("Failed to save migration run", "err", err) @@ -556,7 +551,7 @@ func (s *Service) createMigrationRun(ctx context.Context, cmr cloudmigration.Clo return uid, nil } -func (s *Service) GetMigrationStatus(ctx context.Context, runUID string) (*cloudmigration.CloudMigrationRun, error) { +func (s *Service) GetMigrationStatus(ctx context.Context, runUID string) (*cloudmigration.CloudMigrationSnapshot, error) { cmr, err := s.store.GetMigrationStatus(ctx, runUID) if err != nil { return nil, fmt.Errorf("retrieving migration status from db: %w", err) @@ -564,15 +559,15 @@ func (s *Service) GetMigrationStatus(ctx context.Context, runUID string) (*cloud return cmr, nil } -func (s *Service) GetMigrationRunList(ctx context.Context, migUID string) (*cloudmigration.CloudMigrationRunList, error) { +func (s *Service) GetMigrationRunList(ctx context.Context, migUID string) (*cloudmigration.SnapshotList, error) { runs, err := s.store.GetMigrationStatusList(ctx, migUID) if err != nil { return nil, fmt.Errorf("retrieving migration statuses from db: %w", err) } - runList := &cloudmigration.CloudMigrationRunList{Runs: []cloudmigration.MigrateDataResponseListDTO{}} + runList := &cloudmigration.SnapshotList{Runs: []cloudmigration.MigrateDataResponseList{}} for _, s := range runs { - runList.Runs = append(runList.Runs, cloudmigration.MigrateDataResponseListDTO{ + runList.Runs = append(runList.Runs, cloudmigration.MigrateDataResponseList{ RunUID: s.UID, }) } @@ -580,8 +575,8 @@ func (s *Service) GetMigrationRunList(ctx context.Context, migUID string) (*clou return runList, nil } -func (s *Service) DeleteMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { - c, err := s.store.DeleteMigration(ctx, uid) +func (s *Service) DeleteSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { + c, err := s.store.DeleteMigrationSessionByUID(ctx, uid) if err != nil { return c, fmt.Errorf("deleting migration from db: %w", err) } diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_noop.go b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_noop.go index 5049470a537..2f7a808f118 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_noop.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_noop.go @@ -24,42 +24,38 @@ func (s *NoopServiceImpl) DeleteToken(ctx context.Context, uid string) error { return cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) ValidateToken(ctx context.Context, cm cloudmigration.CloudMigration) error { +func (s *NoopServiceImpl) ValidateToken(ctx context.Context, cm cloudmigration.CloudMigrationSession) error { return cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) GetMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { +func (s *NoopServiceImpl) GetSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) GetMigrationList(ctx context.Context) (*cloudmigration.CloudMigrationListResponse, error) { +func (s *NoopServiceImpl) GetSessionList(ctx context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) CreateMigration(ctx context.Context, cm cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { +func (s *NoopServiceImpl) CreateSession(ctx context.Context, cm cloudmigration.CloudMigrationSessionRequest) (*cloudmigration.CloudMigrationSessionResponse, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) UpdateMigration(ctx context.Context, uid string, cm cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { +func (s *NoopServiceImpl) GetMigrationStatus(ctx context.Context, runUID string) (*cloudmigration.CloudMigrationSnapshot, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) GetMigrationStatus(ctx context.Context, runUID string) (*cloudmigration.CloudMigrationRun, error) { +func (s *NoopServiceImpl) GetMigrationRunList(ctx context.Context, uid string) (*cloudmigration.SnapshotList, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) GetMigrationRunList(ctx context.Context, uid string) (*cloudmigration.CloudMigrationRunList, error) { +func (s *NoopServiceImpl) DeleteSession(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { return nil, cloudmigration.ErrFeatureDisabledError } -func (s *NoopServiceImpl) DeleteMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { - return nil, cloudmigration.ErrFeatureDisabledError -} - -func (s *NoopServiceImpl) CreateMigrationRun(context.Context, cloudmigration.CloudMigrationRun) (string, error) { +func (s *NoopServiceImpl) CreateMigrationRun(context.Context, cloudmigration.CloudMigrationSnapshot) (string, error) { return "", cloudmigration.ErrInternalNotImplementedError } -func (s *NoopServiceImpl) RunMigration(context.Context, string) (*cloudmigration.MigrateDataResponseDTO, error) { +func (s *NoopServiceImpl) RunMigration(context.Context, string) (*cloudmigration.MigrateDataResponse, error) { return nil, cloudmigration.ErrFeatureDisabledError } diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go index 05ba69be725..9f4b1d1e4ec 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go @@ -50,7 +50,7 @@ func Test_CreateGetAndDeleteToken(t *testing.T) { _, err = s.GetToken(context.Background()) assert.ErrorIs(t, cloudmigration.ErrTokenNotFound, err) - cm := cloudmigration.CloudMigration{} + cm := cloudmigration.CloudMigrationSession{} err = s.ValidateToken(context.Background(), cm) assert.NoError(t, err) } @@ -62,27 +62,27 @@ func Test_CreateGetRunMigrationsAndRuns(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, createTokenResp.Token) - cmd := cloudmigration.CloudMigrationRequest{ + cmd := cloudmigration.CloudMigrationSessionRequest{ AuthToken: createTokenResp.Token, } - createResp, err := s.CreateMigration(context.Background(), cmd) + createResp, err := s.CreateSession(context.Background(), cmd) require.NoError(t, err) require.NotEmpty(t, createResp.UID) - require.NotEmpty(t, createResp.Stack) + require.NotEmpty(t, createResp.Slug) - getMigResp, err := s.GetMigration(context.Background(), createResp.UID) + getMigResp, err := s.GetSession(context.Background(), createResp.UID) require.NoError(t, err) require.NotNil(t, getMigResp) require.Equal(t, createResp.UID, getMigResp.UID) - require.Equal(t, createResp.Stack, getMigResp.Stack) + require.Equal(t, createResp.Slug, getMigResp.Slug) - listResp, err := s.GetMigrationList(context.Background()) + listResp, err := s.GetSessionList(context.Background()) require.NoError(t, err) require.NotNil(t, listResp) - require.Equal(t, 1, len(listResp.Migrations)) - require.Equal(t, createResp.UID, listResp.Migrations[0].UID) - require.Equal(t, createResp.Stack, listResp.Migrations[0].Stack) + require.Equal(t, 1, len(listResp.Sessions)) + require.Equal(t, createResp.UID, listResp.Sessions[0].UID) + require.Equal(t, createResp.Slug, listResp.Sessions[0].Slug) runResp, err := s.RunMigration(ctxWithSignedInUser(), createResp.UID) require.NoError(t, err) @@ -104,7 +104,7 @@ func Test_CreateGetRunMigrationsAndRuns(t *testing.T) { require.Equal(t, 1, len(listRunResp.Runs)) require.Equal(t, runResp.RunUID, listRunResp.Runs[0].RunUID) - delMigResp, err := s.DeleteMigration(context.Background(), createResp.UID) + delMigResp, err := s.DeleteSession(context.Background(), createResp.UID) require.NoError(t, err) require.NotNil(t, createResp.UID, delMigResp.UID) } diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/fake/cloudmigration_fake.go b/pkg/services/cloudmigration/cloudmigrationimpl/fake/cloudmigration_fake.go index 8448a6e7074..1c568fce0f7 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/fake/cloudmigration_fake.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/fake/cloudmigration_fake.go @@ -33,7 +33,7 @@ func (m FakeServiceImpl) CreateToken(_ context.Context) (cloudmigration.CreateAc return cloudmigration.CreateAccessTokenResponse{Token: "mock_token"}, nil } -func (m FakeServiceImpl) ValidateToken(ctx context.Context, migration cloudmigration.CloudMigration) error { +func (m FakeServiceImpl) ValidateToken(ctx context.Context, migration cloudmigration.CloudMigrationSession) error { panic("implement me") } @@ -44,49 +44,45 @@ func (m FakeServiceImpl) DeleteToken(_ context.Context, _ string) error { return nil } -func (m FakeServiceImpl) CreateMigration(_ context.Context, _ cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { +func (m FakeServiceImpl) CreateSession(_ context.Context, _ cloudmigration.CloudMigrationSessionRequest) (*cloudmigration.CloudMigrationSessionResponse, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } - return &cloudmigration.CloudMigrationResponse{ + return &cloudmigration.CloudMigrationSessionResponse{ UID: "fake_uid", - Stack: "fake_stack", + Slug: "fake_stack", Created: fixedDate, Updated: fixedDate, }, nil } -func (m FakeServiceImpl) GetMigration(_ context.Context, _ string) (*cloudmigration.CloudMigration, error) { +func (m FakeServiceImpl) GetSession(_ context.Context, _ string) (*cloudmigration.CloudMigrationSession, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } - return &cloudmigration.CloudMigration{UID: "fake"}, nil + return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil } -func (m FakeServiceImpl) DeleteMigration(_ context.Context, _ string) (*cloudmigration.CloudMigration, error) { +func (m FakeServiceImpl) DeleteSession(_ context.Context, _ string) (*cloudmigration.CloudMigrationSession, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } - return &cloudmigration.CloudMigration{UID: "fake"}, nil + return &cloudmigration.CloudMigrationSession{UID: "fake"}, nil } -func (m FakeServiceImpl) UpdateMigration(ctx context.Context, uid string, request cloudmigration.CloudMigrationRequest) (*cloudmigration.CloudMigrationResponse, error) { - panic("implement me") -} - -func (m FakeServiceImpl) GetMigrationList(_ context.Context) (*cloudmigration.CloudMigrationListResponse, error) { +func (m FakeServiceImpl) GetSessionList(_ context.Context) (*cloudmigration.CloudMigrationSessionListResponse, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } - return &cloudmigration.CloudMigrationListResponse{ - Migrations: []cloudmigration.CloudMigrationResponse{ - {UID: "mock_uid_1", Stack: "mock_stack_1", Created: fixedDate, Updated: fixedDate}, - {UID: "mock_uid_2", Stack: "mock_stack_2", Created: fixedDate, Updated: fixedDate}, + return &cloudmigration.CloudMigrationSessionListResponse{ + Sessions: []cloudmigration.CloudMigrationSessionResponse{ + {UID: "mock_uid_1", Slug: "mock_stack_1", Created: fixedDate, Updated: fixedDate}, + {UID: "mock_uid_2", Slug: "mock_stack_2", Created: fixedDate, Updated: fixedDate}, }, }, nil } -func (m FakeServiceImpl) RunMigration(_ context.Context, _ string) (*cloudmigration.MigrateDataResponseDTO, error) { +func (m FakeServiceImpl) RunMigration(_ context.Context, _ string) (*cloudmigration.MigrateDataResponse, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } @@ -94,20 +90,20 @@ func (m FakeServiceImpl) RunMigration(_ context.Context, _ string) (*cloudmigrat return &r, nil } -func fakeMigrateDataResponseDTO() cloudmigration.MigrateDataResponseDTO { - return cloudmigration.MigrateDataResponseDTO{ +func fakeMigrateDataResponseDTO() cloudmigration.MigrateDataResponse { + return cloudmigration.MigrateDataResponse{ RunUID: "fake_uid", - Items: []cloudmigration.MigrateDataResponseItemDTO{ + Items: []cloudmigration.MigrateDataResponseItem{ {Type: "type", RefID: "make_refid", Status: "ok", Error: "none"}, }, } } -func (m FakeServiceImpl) CreateMigrationRun(ctx context.Context, run cloudmigration.CloudMigrationRun) (string, error) { +func (m FakeServiceImpl) CreateMigrationRun(ctx context.Context, run cloudmigration.CloudMigrationSnapshot) (string, error) { panic("implement me") } -func (m FakeServiceImpl) GetMigrationStatus(_ context.Context, _ string) (*cloudmigration.CloudMigrationRun, error) { +func (m FakeServiceImpl) GetMigrationStatus(_ context.Context, _ string) (*cloudmigration.CloudMigrationSnapshot, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } @@ -115,23 +111,23 @@ func (m FakeServiceImpl) GetMigrationStatus(_ context.Context, _ string) (*cloud if err != nil { return nil, err } - return &cloudmigration.CloudMigrationRun{ - ID: 0, - UID: "fake_uid", - CloudMigrationUID: "fake_mig_uid", - Result: result, - Created: fixedDate, - Updated: fixedDate, - Finished: fixedDate, + return &cloudmigration.CloudMigrationSnapshot{ + ID: 0, + UID: "fake_uid", + SessionUID: "fake_mig_uid", + Result: result, + Created: fixedDate, + Updated: fixedDate, + Finished: fixedDate, }, nil } -func (m FakeServiceImpl) GetMigrationRunList(_ context.Context, _ string) (*cloudmigration.CloudMigrationRunList, error) { +func (m FakeServiceImpl) GetMigrationRunList(_ context.Context, _ string) (*cloudmigration.SnapshotList, error) { if m.ReturnError { return nil, fmt.Errorf("mock error") } - return &cloudmigration.CloudMigrationRunList{ - Runs: []cloudmigration.MigrateDataResponseListDTO{ + return &cloudmigration.SnapshotList{ + Runs: []cloudmigration.MigrateDataResponseList{ {RunUID: "fake_run_uid_1"}, {RunUID: "fake_run_uid_2"}, }, diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/store.go b/pkg/services/cloudmigration/cloudmigrationimpl/store.go index 45f66bb85f2..58f97f79fce 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/store.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/store.go @@ -7,12 +7,12 @@ import ( ) type store interface { - CreateMigration(ctx context.Context, token cloudmigration.CloudMigration) (*cloudmigration.CloudMigration, error) - GetMigrationByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) - GetAllCloudMigrations(ctx context.Context) ([]*cloudmigration.CloudMigration, error) - DeleteMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) + CreateMigrationSession(ctx context.Context, session cloudmigration.CloudMigrationSession) (*cloudmigration.CloudMigrationSession, error) + GetMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) + GetAllCloudMigrationSessions(ctx context.Context) ([]*cloudmigration.CloudMigrationSession, error) + DeleteMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) - CreateMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationRun) (string, error) - GetMigrationStatus(ctx context.Context, cmrUID string) (*cloudmigration.CloudMigrationRun, error) - GetMigrationStatusList(ctx context.Context, migrationUID string) ([]*cloudmigration.CloudMigrationRun, error) + CreateMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationSnapshot) (string, error) + GetMigrationStatus(ctx context.Context, cmrUID string) (*cloudmigration.CloudMigrationSnapshot, error) + GetMigrationStatusList(ctx context.Context, migrationUID string) ([]*cloudmigration.CloudMigrationSnapshot, error) } diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go index b6686c42dc9..3103aebf685 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go @@ -20,8 +20,8 @@ type sqlStore struct { secretsService secrets.Service } -func (ss *sqlStore) GetMigrationByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { - var cm cloudmigration.CloudMigration +func (ss *sqlStore) GetMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { + var cm cloudmigration.CloudMigrationSession err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { exist, err := sess.Where("uid=?", uid).Get(&cm) if err != nil { @@ -40,7 +40,7 @@ func (ss *sqlStore) GetMigrationByUID(ctx context.Context, uid string) (*cloudmi return &cm, err } -func (ss *sqlStore) CreateMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationRun) (string, error) { +func (ss *sqlStore) CreateMigrationRun(ctx context.Context, cmr cloudmigration.CloudMigrationSnapshot) (string, error) { err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { cmr.Created = time.Now() cmr.Updated = time.Now() @@ -56,7 +56,7 @@ func (ss *sqlStore) CreateMigrationRun(ctx context.Context, cmr cloudmigration.C return cmr.UID, nil } -func (ss *sqlStore) CreateMigration(ctx context.Context, migration cloudmigration.CloudMigration) (*cloudmigration.CloudMigration, error) { +func (ss *sqlStore) CreateMigrationSession(ctx context.Context, migration cloudmigration.CloudMigrationSession) (*cloudmigration.CloudMigrationSession, error) { if err := ss.encryptToken(ctx, &migration); err != nil { return nil, err } @@ -78,8 +78,8 @@ func (ss *sqlStore) CreateMigration(ctx context.Context, migration cloudmigratio return &migration, nil } -func (ss *sqlStore) GetAllCloudMigrations(ctx context.Context) ([]*cloudmigration.CloudMigration, error) { - var migrations = make([]*cloudmigration.CloudMigration, 0) +func (ss *sqlStore) GetAllCloudMigrationSessions(ctx context.Context) ([]*cloudmigration.CloudMigrationSession, error) { + var migrations = make([]*cloudmigration.CloudMigrationSession, 0) err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { return sess.Find(&migrations) }) if err != nil { return nil, err @@ -95,8 +95,8 @@ func (ss *sqlStore) GetAllCloudMigrations(ctx context.Context) ([]*cloudmigratio return migrations, nil } -func (ss *sqlStore) DeleteMigration(ctx context.Context, uid string) (*cloudmigration.CloudMigration, error) { - var c cloudmigration.CloudMigration +func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) { + var c cloudmigration.CloudMigrationSession err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { exist, err := sess.Where("uid=?", uid).Get(&c) if err != nil { @@ -106,7 +106,7 @@ func (ss *sqlStore) DeleteMigration(ctx context.Context, uid string) (*cloudmigr return cloudmigration.ErrMigrationNotFound } id := c.ID - affected, err := sess.Delete(&cloudmigration.CloudMigration{ + affected, err := sess.Delete(&cloudmigration.CloudMigrationSession{ ID: id, }) if affected == 0 { @@ -118,8 +118,8 @@ func (ss *sqlStore) DeleteMigration(ctx context.Context, uid string) (*cloudmigr return &c, err } -func (ss *sqlStore) GetMigrationStatus(ctx context.Context, cmrUID string) (*cloudmigration.CloudMigrationRun, error) { - var c cloudmigration.CloudMigrationRun +func (ss *sqlStore) GetMigrationStatus(ctx context.Context, cmrUID string) (*cloudmigration.CloudMigrationSnapshot, error) { + var c cloudmigration.CloudMigrationSnapshot err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { exist, err := sess.Where("uid=?", cmrUID).Get(&c) if err != nil { @@ -133,11 +133,11 @@ func (ss *sqlStore) GetMigrationStatus(ctx context.Context, cmrUID string) (*clo return &c, err } -func (ss *sqlStore) GetMigrationStatusList(ctx context.Context, migrationUID string) ([]*cloudmigration.CloudMigrationRun, error) { - var runs = make([]*cloudmigration.CloudMigrationRun, 0) +func (ss *sqlStore) GetMigrationStatusList(ctx context.Context, migrationUID string) ([]*cloudmigration.CloudMigrationSnapshot, error) { + var runs = make([]*cloudmigration.CloudMigrationSnapshot, 0) err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { - return sess.Find(&runs, &cloudmigration.CloudMigrationRun{ - CloudMigrationUID: migrationUID, + return sess.Find(&runs, &cloudmigration.CloudMigrationSnapshot{ + SessionUID: migrationUID, }) }) if err != nil { @@ -146,7 +146,7 @@ func (ss *sqlStore) GetMigrationStatusList(ctx context.Context, migrationUID str return runs, nil } -func (ss *sqlStore) encryptToken(ctx context.Context, cm *cloudmigration.CloudMigration) error { +func (ss *sqlStore) encryptToken(ctx context.Context, cm *cloudmigration.CloudMigrationSession) error { s, err := ss.secretsService.Encrypt(ctx, []byte(cm.AuthToken), secrets.WithoutScope()) if err != nil { return fmt.Errorf("encrypting auth token: %w", err) @@ -157,7 +157,7 @@ func (ss *sqlStore) encryptToken(ctx context.Context, cm *cloudmigration.CloudMi return nil } -func (ss *sqlStore) decryptToken(ctx context.Context, cm *cloudmigration.CloudMigration) error { +func (ss *sqlStore) decryptToken(ctx context.Context, cm *cloudmigration.CloudMigrationSession) error { decoded, err := base64.StdEncoding.DecodeString(cm.AuthToken) if err != nil { return fmt.Errorf("token could not be decoded") diff --git a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go index f7fb0234eb8..158efdf624b 100644 --- a/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go +++ b/pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go @@ -22,20 +22,20 @@ func Test_GetAllCloudMigrations(t *testing.T) { _, s := setUpTest(t) ctx := context.Background() - t.Run("get all cloud_migrations", func(t *testing.T) { - value, err := s.GetAllCloudMigrations(ctx) + t.Run("get all cloud_migration_session entries", func(t *testing.T) { + value, err := s.GetAllCloudMigrationSessions(ctx) require.NoError(t, err) require.Equal(t, 3, len(value)) for _, m := range value { switch m.ID { case 1: - require.Equal(t, "11111", m.Stack) + require.Equal(t, "11111", m.Slug) require.Equal(t, "12345", m.AuthToken) case 2: - require.Equal(t, "22222", m.Stack) + require.Equal(t, "22222", m.Slug) require.Equal(t, "6789", m.AuthToken) case 3: - require.Equal(t, "33333", m.Stack) + require.Equal(t, "33333", m.Slug) require.Equal(t, "777", m.AuthToken) default: require.Fail(t, "ID value not expected: "+strconv.FormatInt(m.ID, 10)) @@ -49,24 +49,24 @@ func Test_CreateMigration(t *testing.T) { ctx := context.Background() t.Run("creates migrations and reads it from the db", func(t *testing.T) { - cm := cloudmigration.CloudMigration{ + cm := cloudmigration.CloudMigrationSession{ AuthToken: encodeToken("token"), - Stack: "fake_stack", + Slug: "fake_stack", StackID: 1234, RegionSlug: "fake_slug", ClusterSlug: "fake_cluster_slug", } - mig, err := s.CreateMigration(ctx, cm) + mig, err := s.CreateMigrationSession(ctx, cm) require.NoError(t, err) require.NotEmpty(t, mig.ID) require.NotEmpty(t, mig.UID) - getRes, err := s.GetMigrationByUID(ctx, mig.UID) + getRes, err := s.GetMigrationSessionByUID(ctx, mig.UID) require.NoError(t, err) require.Equal(t, mig.ID, getRes.ID) require.Equal(t, mig.UID, getRes.UID) require.Equal(t, cm.AuthToken, getRes.AuthToken) - require.Equal(t, cm.Stack, getRes.Stack) + require.Equal(t, cm.Slug, getRes.Slug) require.Equal(t, cm.StackID, getRes.StackID) require.Equal(t, cm.RegionSlug, getRes.RegionSlug) require.Equal(t, cm.ClusterSlug, getRes.ClusterSlug) @@ -76,15 +76,15 @@ func Test_CreateMigration(t *testing.T) { func Test_GetMigrationByUID(t *testing.T) { _, s := setUpTest(t) ctx := context.Background() - t.Run("find migration by uid", func(t *testing.T) { + t.Run("find session by uid", func(t *testing.T) { uid := "qwerty" - mig, err := s.GetMigrationByUID(ctx, uid) + mig, err := s.GetMigrationSessionByUID(ctx, uid) require.NoError(t, err) require.Equal(t, uid, mig.UID) }) - t.Run("returns error if migration is not found by uid", func(t *testing.T) { - _, err := s.GetMigrationByUID(ctx, "fake_uid_1234") + t.Run("returns error if session is not found by uid", func(t *testing.T) { + _, err := s.GetMigrationSessionByUID(ctx, "fake_uid_1234") require.ErrorIs(t, cloudmigration.ErrMigrationNotFound, err) }) } @@ -93,14 +93,14 @@ func Test_DeleteMigration(t *testing.T) { _, s := setUpTest(t) ctx := context.Background() - t.Run("deletes a migration from the db", func(t *testing.T) { + t.Run("deletes a session from the db", func(t *testing.T) { uid := "qwerty" - delResp, err := s.DeleteMigration(ctx, uid) + delResp, err := s.DeleteMigrationSessionByUID(ctx, uid) require.NoError(t, err) require.Equal(t, uid, delResp.UID) // now we try to find it, should return an error - _, err = s.GetMigrationByUID(ctx, uid) + _, err = s.GetMigrationSessionByUID(ctx, uid) require.ErrorIs(t, cloudmigration.ErrMigrationNotFound, err) }) } @@ -109,11 +109,11 @@ func Test_CreateMigrationRun(t *testing.T) { _, s := setUpTest(t) ctx := context.Background() - t.Run("creates a migration run and retrieves it from db", func(t *testing.T) { + t.Run("creates a session run and retrieves it from db", func(t *testing.T) { result := []byte("OK") - cmr := cloudmigration.CloudMigrationRun{ - CloudMigrationUID: "asdfg", - Result: result, + cmr := cloudmigration.CloudMigrationSnapshot{ + SessionUID: "asdfg", + Result: result, } createResp, err := s.CreateMigrationRun(ctx, cmr) @@ -173,7 +173,7 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) { // insert cloud migration test data _, err := testDB.GetSqlxSession().Exec(ctx, ` INSERT INTO - cloud_migration (id, uid, auth_token, stack, stack_id, region_slug, cluster_slug, created, updated) + cloud_migration_session (id, uid, auth_token, slug, stack_id, region_slug, cluster_slug, created, updated) VALUES (1,'qwerty', ?, '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'), @@ -188,7 +188,7 @@ func setUpTest(t *testing.T) (*sqlstore.SQLStore, *sqlStore) { // insert cloud migration run test data _, err = testDB.GetSqlxSession().Exec(ctx, ` INSERT INTO - cloud_migration_run (cloud_migration_uid, uid, result, created, updated, finished) + cloud_migration_snapshot (session_uid, uid, result, created, updated, finished) VALUES ('qwerty', 'poiuy', ?, '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000'), ('qwerty', 'lkjhg', ?, '2024-03-25 15:30:36.000', '2024-03-27 15:30:43.000', '2024-03-27 15:30:43.000'), diff --git a/pkg/services/cloudmigration/cmsclient/client.go b/pkg/services/cloudmigration/cmsclient/client.go deleted file mode 100644 index 8b6bd7a0599..00000000000 --- a/pkg/services/cloudmigration/cmsclient/client.go +++ /dev/null @@ -1,17 +0,0 @@ -package cmsclient - -import ( - "context" - - "github.com/grafana/grafana/pkg/apimachinery/errutil" - "github.com/grafana/grafana/pkg/services/cloudmigration" -) - -type Client interface { - ValidateKey(context.Context, cloudmigration.CloudMigration) error - MigrateData(context.Context, cloudmigration.CloudMigration, cloudmigration.MigrateDataRequestDTO) (*cloudmigration.MigrateDataResponseDTO, error) -} - -const logPrefix = "cloudmigration.cmsclient" - -var ErrMigrationNotDeleted = errutil.Internal("cloudmigrations.developerModeEnabled", errutil.WithPublicMessage("Developer mode enabled")) diff --git a/pkg/services/cloudmigration/gmsclient/client.go b/pkg/services/cloudmigration/gmsclient/client.go new file mode 100644 index 00000000000..cafe4d742fa --- /dev/null +++ b/pkg/services/cloudmigration/gmsclient/client.go @@ -0,0 +1,14 @@ +package gmsclient + +import ( + "context" + + "github.com/grafana/grafana/pkg/services/cloudmigration" +) + +type Client interface { + ValidateKey(context.Context, cloudmigration.CloudMigrationSession) error + MigrateData(context.Context, cloudmigration.CloudMigrationSession, cloudmigration.MigrateDataRequest) (*cloudmigration.MigrateDataResponse, error) +} + +const logPrefix = "cloudmigration.gmsclient" diff --git a/pkg/services/cloudmigration/gmsclient/dtos.go b/pkg/services/cloudmigration/gmsclient/dtos.go new file mode 100644 index 00000000000..46f346f283d --- /dev/null +++ b/pkg/services/cloudmigration/gmsclient/dtos.go @@ -0,0 +1,47 @@ +// TODO: Move these to a shared library in common with GMS +package gmsclient + +type MigrateDataType string + +const ( + DashboardDataType MigrateDataType = "DASHBOARD" + DatasourceDataType MigrateDataType = "DATASOURCE" + FolderDataType MigrateDataType = "FOLDER" +) + +type MigrateDataRequestDTO struct { + Items []MigrateDataRequestItemDTO `json:"items"` +} + +type MigrateDataRequestItemDTO struct { + Type MigrateDataType `json:"type"` + RefID string `json:"refId"` + Name string `json:"name"` + Data interface{} `json:"data"` +} + +type ItemStatus string + +const ( + ItemStatusOK ItemStatus = "OK" + ItemStatusError ItemStatus = "ERROR" +) + +type MigrateDataResponseDTO struct { + RunUID string `json:"uid"` + Items []MigrateDataResponseItemDTO `json:"items"` +} + +type MigrateDataResponseListDTO struct { + RunUID string `json:"uid"` +} + +type MigrateDataResponseItemDTO struct { + // required:true + Type MigrateDataType `json:"type"` + // required:true + RefID string `json:"refId"` + // required:true + Status ItemStatus `json:"status"` + Error string `json:"error,omitempty"` +} diff --git a/pkg/services/cloudmigration/cmsclient/cms_client.go b/pkg/services/cloudmigration/gmsclient/gms_client.go similarity index 58% rename from pkg/services/cloudmigration/cmsclient/cms_client.go rename to pkg/services/cloudmigration/gmsclient/gms_client.go index 576e1385d71..eb37cc9d49d 100644 --- a/pkg/services/cloudmigration/cmsclient/cms_client.go +++ b/pkg/services/cloudmigration/gmsclient/gms_client.go @@ -1,4 +1,4 @@ -package cmsclient +package gmsclient import ( "bytes" @@ -11,25 +11,26 @@ import ( "github.com/grafana/grafana/pkg/services/cloudmigration" ) -// NewCMSClient returns an implementation of Client that queries CloudMigrationService -func NewCMSClient(domain string) Client { - return &cmsClientImpl{ +// NewGMSClient returns an implementation of Client that queries GrafanaMigrationService +func NewGMSClient(domain string) Client { + return &gmsClientImpl{ domain: domain, log: log.New(logPrefix), } } -type cmsClientImpl struct { +type gmsClientImpl struct { domain string log *log.ConcreteLogger } -func (c *cmsClientImpl) ValidateKey(ctx context.Context, cm cloudmigration.CloudMigration) error { +func (c *gmsClientImpl) ValidateKey(ctx context.Context, cm cloudmigration.CloudMigrationSession) error { logger := c.log.FromContext(ctx) + // TODO update service url to gms path := fmt.Sprintf("https://cms-%s.%s/cloud-migrations/api/v1/validate-key", cm.ClusterSlug, c.domain) - // validation is an empty POST to CMS with the authorization header included + // validation is an empty POST to GMS with the authorization header included req, err := http.NewRequest("POST", path, bytes.NewReader(nil)) if err != nil { logger.Error("error creating http request for token validation", "err", err.Error()) @@ -63,17 +64,19 @@ func (c *cmsClientImpl) ValidateKey(ctx context.Context, cm cloudmigration.Cloud return nil } -func (c *cmsClientImpl) MigrateData(ctx context.Context, cm cloudmigration.CloudMigration, request cloudmigration.MigrateDataRequestDTO) (*cloudmigration.MigrateDataResponseDTO, error) { +func (c *gmsClientImpl) MigrateData(ctx context.Context, cm cloudmigration.CloudMigrationSession, request cloudmigration.MigrateDataRequest) (*cloudmigration.MigrateDataResponse, error) { logger := c.log.FromContext(ctx) + // TODO update service url to gms path := fmt.Sprintf("https://cms-%s.%s/cloud-migrations/api/v1/migrate-data", cm.ClusterSlug, c.domain) - body, err := json.Marshal(request) + reqDTO := convertRequestToDTO(request) + body, err := json.Marshal(reqDTO) if err != nil { return nil, fmt.Errorf("error marshaling request: %w", err) } - // Send the request to cms with the associated auth token + // Send the request to GMS with the associated auth token req, err := http.NewRequest(http.MethodPost, path, bytes.NewReader(body)) if err != nil { c.log.Error("error creating http request for cloud migration run", "err", err.Error()) @@ -98,11 +101,46 @@ func (c *cmsClientImpl) MigrateData(ctx context.Context, cm cloudmigration.Cloud } }() - var result cloudmigration.MigrateDataResponseDTO - if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { + var respDTO MigrateDataResponseDTO + if err := json.NewDecoder(resp.Body).Decode(&respDTO); err != nil { logger.Error("unmarshalling response body: %w", err) return nil, fmt.Errorf("unmarshalling migration run response: %w", err) } + result := convertResponseFromDTO(respDTO) return &result, nil } + +func convertRequestToDTO(request cloudmigration.MigrateDataRequest) MigrateDataRequestDTO { + items := make([]MigrateDataRequestItemDTO, len(request.Items)) + for i := 0; i < len(request.Items); i++ { + item := request.Items[i] + items[i] = MigrateDataRequestItemDTO{ + Type: MigrateDataType(item.Type), + RefID: item.RefID, + Name: item.Name, + Data: item.Data, + } + } + r := MigrateDataRequestDTO{ + Items: items, + } + return r +} + +func convertResponseFromDTO(result MigrateDataResponseDTO) cloudmigration.MigrateDataResponse { + items := make([]cloudmigration.MigrateDataResponseItem, len(result.Items)) + for i := 0; i < len(result.Items); i++ { + item := result.Items[i] + items[i] = cloudmigration.MigrateDataResponseItem{ + Type: cloudmigration.MigrateDataType(item.Type), + RefID: item.RefID, + Status: cloudmigration.ItemStatus(item.Status), + Error: item.Error, + } + } + return cloudmigration.MigrateDataResponse{ + RunUID: result.RunUID, + Items: items, + } +} diff --git a/pkg/services/cloudmigration/cmsclient/inmemory_client.go b/pkg/services/cloudmigration/gmsclient/inmemory_client.go similarity index 63% rename from pkg/services/cloudmigration/cmsclient/inmemory_client.go rename to pkg/services/cloudmigration/gmsclient/inmemory_client.go index 3c44abe67ae..5e9b74f0db0 100644 --- a/pkg/services/cloudmigration/cmsclient/inmemory_client.go +++ b/pkg/services/cloudmigration/gmsclient/inmemory_client.go @@ -1,4 +1,4 @@ -package cmsclient +package gmsclient import ( "context" @@ -14,24 +14,21 @@ func NewInMemoryClient() Client { type memoryClientImpl struct{} -func (c *memoryClientImpl) ValidateKey(ctx context.Context, cm cloudmigration.CloudMigration) error { - // return ErrMigrationNotDeleted +func (c *memoryClientImpl) ValidateKey(ctx context.Context, cm cloudmigration.CloudMigrationSession) error { return nil } func (c *memoryClientImpl) MigrateData( ctx context.Context, - cm cloudmigration.CloudMigration, - request cloudmigration.MigrateDataRequestDTO, -) (*cloudmigration.MigrateDataResponseDTO, error) { - //return nil, ErrMigrationNotDeleted - - result := cloudmigration.MigrateDataResponseDTO{ - Items: make([]cloudmigration.MigrateDataResponseItemDTO, len(request.Items)), + cm cloudmigration.CloudMigrationSession, + request cloudmigration.MigrateDataRequest, +) (*cloudmigration.MigrateDataResponse, error) { + result := cloudmigration.MigrateDataResponse{ + Items: make([]cloudmigration.MigrateDataResponseItem, len(request.Items)), } for i, v := range request.Items { - result.Items[i] = cloudmigration.MigrateDataResponseItemDTO{ + result.Items[i] = cloudmigration.MigrateDataResponseItem{ Type: v.Type, RefID: v.RefID, Status: cloudmigration.ItemStatusOK, diff --git a/pkg/services/cloudmigration/model.go b/pkg/services/cloudmigration/model.go index bbeb59bc133..d80ed85184f 100644 --- a/pkg/services/cloudmigration/model.go +++ b/pkg/services/cloudmigration/model.go @@ -11,37 +11,37 @@ import ( var ( ErrInternalNotImplementedError = errutil.Internal("cloudmigrations.notImplemented").Errorf("Internal server error") ErrFeatureDisabledError = errutil.Internal("cloudmigrations.disabled").Errorf("Cloud migrations are disabled on this instance") - ErrMigrationNotFound = errutil.NotFound("cloudmigrations.migrationNotFound").Errorf("Migration not found") + ErrMigrationNotFound = errutil.NotFound("cloudmigrations.sessionNotFound").Errorf("Session not found") ErrMigrationRunNotFound = errutil.NotFound("cloudmigrations.migrationRunNotFound").Errorf("Migration run not found") - ErrMigrationNotDeleted = errutil.Internal("cloudmigrations.migrationNotDeleted").Errorf("Migration not deleted") + ErrMigrationNotDeleted = errutil.Internal("cloudmigrations.sessionNotDeleted").Errorf("Session not deleted") ErrTokenNotFound = errutil.NotFound("cloudmigrations.tokenNotFound").Errorf("Token not found") ) -// CloudMigration api dtos -type CloudMigration struct { - ID int64 `json:"id" xorm:"pk autoincr 'id'"` - UID string `json:"uid" xorm:"uid"` - AuthToken string `json:"-"` - Stack string `json:"stack"` - StackID int `json:"stackID" xorm:"stack_id"` - RegionSlug string `json:"regionSlug"` - ClusterSlug string `json:"clusterSlug"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` +// CloudMigration domain structs +type CloudMigrationSession struct { + ID int64 `xorm:"pk autoincr 'id'"` + UID string `xorm:"uid"` + AuthToken string + Slug string + StackID int `xorm:"stack_id"` + RegionSlug string + ClusterSlug string + Created time.Time + Updated time.Time } -type CloudMigrationRun struct { - ID int64 `json:"id" xorm:"pk autoincr 'id'"` - UID string `json:"uid" xorm:"uid"` - CloudMigrationUID string `json:"migrationUid" xorm:"cloud_migration_uid"` - Result []byte `json:"result"` //store raw cms response body - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` - Finished time.Time `json:"finished"` +type CloudMigrationSnapshot struct { + ID int64 `xorm:"pk autoincr 'id'"` + UID string `xorm:"uid"` + SessionUID string `xorm:"session_uid"` + Result []byte //store raw gms response body + Created time.Time + Updated time.Time + Finished time.Time } -func (r CloudMigrationRun) ToResponse() (*MigrateDataResponseDTO, error) { - var result MigrateDataResponseDTO +func (r CloudMigrationSnapshot) GetResult() (*MigrateDataResponse, error) { + var result MigrateDataResponse err := json.Unmarshal(r.Result, &result) if err != nil { return nil, errors.New("could not parse result of run") @@ -50,23 +50,23 @@ func (r CloudMigrationRun) ToResponse() (*MigrateDataResponseDTO, error) { return &result, nil } -type CloudMigrationRunList struct { - Runs []MigrateDataResponseListDTO `json:"runs"` +type SnapshotList struct { + Runs []MigrateDataResponseList } -type CloudMigrationRequest struct { - AuthToken string `json:"authToken"` +type CloudMigrationSessionRequest struct { + AuthToken string } -type CloudMigrationResponse struct { - UID string `json:"uid"` - Stack string `json:"stack"` - Created time.Time `json:"created"` - Updated time.Time `json:"updated"` +type CloudMigrationSessionResponse struct { + UID string + Slug string + Created time.Time + Updated time.Time } -type CloudMigrationListResponse struct { - Migrations []CloudMigrationResponse `json:"migrations"` +type CloudMigrationSessionListResponse struct { + Sessions []CloudMigrationSessionResponse } // access token @@ -80,10 +80,10 @@ type Base64EncodedTokenPayload struct { Instance Base64HGInstance } -func (p Base64EncodedTokenPayload) ToMigration() CloudMigration { - return CloudMigration{ +func (p Base64EncodedTokenPayload) ToMigration() CloudMigrationSession { + return CloudMigrationSession{ AuthToken: p.Token, - Stack: p.Instance.Slug, + Slug: p.Instance.Slug, StackID: p.Instance.StackID, RegionSlug: p.Instance.RegionSlug, ClusterSlug: p.Instance.ClusterSlug, @@ -97,9 +97,8 @@ type Base64HGInstance struct { ClusterSlug string } -// dtos for cms api +// GMS domain structs -// swagger:enum MigrateDataType type MigrateDataType string const ( @@ -108,18 +107,17 @@ const ( FolderDataType MigrateDataType = "FOLDER" ) -type MigrateDataRequestDTO struct { - Items []MigrateDataRequestItemDTO `json:"items"` +type MigrateDataRequest struct { + Items []MigrateDataRequestItem } -type MigrateDataRequestItemDTO struct { - Type MigrateDataType `json:"type"` - RefID string `json:"refId"` - Name string `json:"name"` - Data interface{} `json:"data"` +type MigrateDataRequestItem struct { + Type MigrateDataType + RefID string + Name string + Data interface{} } -// swagger:enum ItemStatus type ItemStatus string const ( @@ -127,21 +125,18 @@ const ( ItemStatusError ItemStatus = "ERROR" ) -type MigrateDataResponseDTO struct { - RunUID string `json:"uid"` - Items []MigrateDataResponseItemDTO `json:"items"` +type MigrateDataResponse struct { + RunUID string + Items []MigrateDataResponseItem } -type MigrateDataResponseListDTO struct { - RunUID string `json:"uid"` +type MigrateDataResponseList struct { + RunUID string } -type MigrateDataResponseItemDTO struct { - // required:true - Type MigrateDataType `json:"type"` - // required:true - RefID string `json:"refId"` - // required:true - Status ItemStatus `json:"status"` - Error string `json:"error,omitempty"` +type MigrateDataResponseItem struct { + Type MigrateDataType + RefID string + Status ItemStatus + Error string } diff --git a/pkg/services/sqlstore/migrations/cloud_migrations.go b/pkg/services/sqlstore/migrations/cloud_migrations.go index 1f3cffd6ed6..596208d66ae 100644 --- a/pkg/services/sqlstore/migrations/cloud_migrations.go +++ b/pkg/services/sqlstore/migrations/cloud_migrations.go @@ -5,6 +5,7 @@ import ( ) func addCloudMigrationsMigrations(mg *Migrator) { + // v1 - synchronous workflow migrationTable := Table{ Name: "cloud_migration", Columns: []*Column{ @@ -63,4 +64,61 @@ func addCloudMigrationsMigrations(mg *Migrator) { mg.AddMigration("Add unique index migration_run_uid", NewAddIndexMigration(migrationRunTable, &Index{ Cols: []string{"uid"}, Type: UniqueIndex, })) + + // v2 - asynchronous workflow refactor + sessionTable := Table{ + Name: "cloud_migration_session", + Columns: []*Column{ + {Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, + {Name: "uid", Type: DB_NVarchar, Length: 40, Nullable: true}, + {Name: "auth_token", Type: DB_Text, Nullable: true}, // encrypted + {Name: "slug", Type: DB_Text}, + {Name: "stack_id", Type: DB_BigInt, Nullable: false}, + {Name: "region_slug", Type: DB_Text, Nullable: false}, + {Name: "cluster_slug", Type: DB_Text, Nullable: false}, + {Name: "created", Type: DB_DateTime, Nullable: false}, + {Name: "updated", Type: DB_DateTime, Nullable: false}, + }, + Indices: []*Index{ + {Cols: []string{"uid"}, Type: UniqueIndex}, + }, + } + migrationSnapshotTable := Table{ + Name: "cloud_migration_snapshot", + Columns: []*Column{ + {Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true}, + {Name: "uid", Type: DB_NVarchar, Length: 40, Nullable: true}, + {Name: "session_uid", Type: DB_NVarchar, Length: 40, Nullable: true}, // get from the cloud service + {Name: "result", Type: DB_Text, Nullable: false}, + {Name: "created", Type: DB_DateTime, Nullable: false}, + {Name: "updated", Type: DB_DateTime, Nullable: false}, + {Name: "finished", Type: DB_DateTime, Nullable: true}, + }, + Indices: []*Index{ + {Cols: []string{"uid"}, Type: UniqueIndex}, + }, + } + + addTableReplaceMigrations(mg, migrationTable, sessionTable, 2, map[string]string{ + "id": "id", + "uid": "uid", + "auth_token": "auth_token", + "slug": "stack", + "stack_id": "stack_id", + "region_slug": "region_slug", + "cluster_slug": "cluster_slug", + "created": "created", + "updated": "updated", + }) + + addTableReplaceMigrations(mg, migrationRunTable, migrationSnapshotTable, 2, map[string]string{ + "id": "id", + "uid": "uid", + "session_uid": "cloud_migration_uid", + "result": "result", + "created": "created", + "updated": "updated", + "finished": "finished", + }) + } diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index 0ff6fb2de46..4dea1f5f8ba 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -3116,18 +3116,18 @@ } } }, - "CloudMigrationListResponse": { + "CloudMigrationSessionListResponseDTO": { "type": "object", "properties": { - "migrations": { + "sessions": { "type": "array", "items": { - "$ref": "#/definitions/CloudMigrationResponse" + "$ref": "#/definitions/CloudMigrationSessionResponseDTO" } } } }, - "CloudMigrationRequest": { + "CloudMigrationSessionRequestDTO": { "type": "object", "properties": { "authToken": { @@ -3135,14 +3135,14 @@ } } }, - "CloudMigrationResponse": { + "CloudMigrationSessionResponseDTO": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" }, - "stack": { + "slug": { "type": "string" }, "uid": { @@ -3154,17 +3154,6 @@ } } }, - "CloudMigrationRunList": { - "type": "object", - "properties": { - "runs": { - "type": "array", - "items": { - "$ref": "#/definitions/MigrateDataResponseListDTO" - } - } - } - }, "ConfFloat64": { "description": "ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf\nto null.", "type": "number", @@ -7048,6 +7037,17 @@ "type": "integer", "format": "int64" }, + "SnapshotListDTO": { + "type": "object", + "properties": { + "runs": { + "type": "array", + "items": { + "$ref": "#/definitions/MigrateDataResponseListDTO" + } + } + } + }, "State": { "type": "string" }, @@ -8342,22 +8342,10 @@ "$ref": "#/definitions/GetAccessTokenResponseDTO" } }, - "cloudMigrationListResponse": { - "description": "", - "schema": { - "$ref": "#/definitions/CloudMigrationListResponse" - } - }, - "cloudMigrationResponse": { - "description": "", - "schema": { - "$ref": "#/definitions/CloudMigrationResponse" - } - }, "cloudMigrationRunListResponse": { "description": "", "schema": { - "$ref": "#/definitions/CloudMigrationRunList" + "$ref": "#/definitions/SnapshotListDTO" } }, "cloudMigrationRunResponse": { @@ -8366,6 +8354,18 @@ "$ref": "#/definitions/MigrateDataResponseDTO" } }, + "cloudMigrationSessionListResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/CloudMigrationSessionListResponseDTO" + } + }, + "cloudMigrationSessionResponse": { + "description": "", + "schema": { + "$ref": "#/definitions/CloudMigrationSessionResponseDTO" + } + }, "conflictError": { "description": "ConflictError", "schema": { diff --git a/public/api-merged.json b/public/api-merged.json index 91eac6c8397..a7ee17cff5a 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -2299,11 +2299,11 @@ "tags": [ "migrations" ], - "summary": "Get a list of all cloud migrations.", - "operationId": "getMigrationList", + "summary": "Get a list of all cloud migration sessions that have been created.", + "operationId": "getSessionList", "responses": { "200": { - "$ref": "#/responses/cloudMigrationListResponse" + "$ref": "#/responses/cloudMigrationSessionListResponse" }, "401": { "$ref": "#/responses/unauthorisedError" @@ -2320,21 +2320,21 @@ "tags": [ "migrations" ], - "summary": "Create a migration.", - "operationId": "createMigration", + "summary": "Create a migration session.", + "operationId": "createSession", "parameters": [ { "name": "Body", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CloudMigrationRequest" + "$ref": "#/definitions/CloudMigrationSessionRequestDTO" } } ], "responses": { "200": { - "$ref": "#/responses/cloudMigrationResponse" + "$ref": "#/responses/cloudMigrationSessionResponse" }, "401": { "$ref": "#/responses/unauthorisedError" @@ -2382,16 +2382,15 @@ }, "/cloudmigration/migration/{uid}": { "get": { - "description": "It returns migrations that has been created.", "tags": [ "migrations" ], - "summary": "Get a cloud migration.", - "operationId": "getCloudMigration", + "summary": "Get a cloud migration session by its uid.", + "operationId": "getSession", "parameters": [ { "type": "string", - "description": "UID of a migration", + "description": "UID of a migration session", "name": "uid", "in": "path", "required": true @@ -2399,7 +2398,7 @@ ], "responses": { "200": { - "$ref": "#/responses/cloudMigrationResponse" + "$ref": "#/responses/cloudMigrationSessionResponse" }, "401": { "$ref": "#/responses/unauthorisedError" @@ -2416,12 +2415,12 @@ "tags": [ "migrations" ], - "summary": "Delete a migration.", - "operationId": "deleteCloudMigration", + "summary": "Delete a migration session by its uid.", + "operationId": "deleteSession", "parameters": [ { "type": "string", - "description": "UID of a migration", + "description": "UID of a migration session", "name": "uid", "in": "path", "required": true @@ -13294,18 +13293,18 @@ } } }, - "CloudMigrationListResponse": { + "CloudMigrationSessionListResponseDTO": { "type": "object", "properties": { - "migrations": { + "sessions": { "type": "array", "items": { - "$ref": "#/definitions/CloudMigrationResponse" + "$ref": "#/definitions/CloudMigrationSessionResponseDTO" } } } }, - "CloudMigrationRequest": { + "CloudMigrationSessionRequestDTO": { "type": "object", "properties": { "authToken": { @@ -13313,14 +13312,14 @@ } } }, - "CloudMigrationResponse": { + "CloudMigrationSessionResponseDTO": { "type": "object", "properties": { "created": { "type": "string", "format": "date-time" }, - "stack": { + "slug": { "type": "string" }, "uid": { @@ -13332,17 +13331,6 @@ } } }, - "CloudMigrationRunList": { - "type": "object", - "properties": { - "runs": { - "type": "array", - "items": { - "$ref": "#/definitions/MigrateDataResponseListDTO" - } - } - } - }, "ConfFloat64": { "description": "ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf\nto null.", "type": "number", @@ -19950,6 +19938,17 @@ "SmtpNotEnabled": { "$ref": "#/definitions/ResponseDetails" }, + "SnapshotListDTO": { + "type": "object", + "properties": { + "runs": { + "type": "array", + "items": { + "$ref": "#/definitions/MigrateDataResponseListDTO" + } + } + } + }, "Span": { "type": "object", "title": "A Span defines a continuous sequence of buckets.", @@ -22383,22 +22382,10 @@ "$ref": "#/definitions/GetAccessTokenResponseDTO" } }, - "cloudMigrationListResponse": { - "description": "(empty)", - "schema": { - "$ref": "#/definitions/CloudMigrationListResponse" - } - }, - "cloudMigrationResponse": { - "description": "(empty)", - "schema": { - "$ref": "#/definitions/CloudMigrationResponse" - } - }, "cloudMigrationRunListResponse": { "description": "(empty)", "schema": { - "$ref": "#/definitions/CloudMigrationRunList" + "$ref": "#/definitions/SnapshotListDTO" } }, "cloudMigrationRunResponse": { @@ -22407,6 +22394,18 @@ "$ref": "#/definitions/MigrateDataResponseDTO" } }, + "cloudMigrationSessionListResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/CloudMigrationSessionListResponseDTO" + } + }, + "cloudMigrationSessionResponse": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/CloudMigrationSessionResponseDTO" + } + }, "conflictError": { "description": "ConflictError", "schema": { diff --git a/public/app/features/migrate-to-cloud/api/endpoints.gen.ts b/public/app/features/migrate-to-cloud/api/endpoints.gen.ts index a2c48cbb401..54beb3847ef 100644 --- a/public/app/features/migrate-to-cloud/api/endpoints.gen.ts +++ b/public/app/features/migrate-to-cloud/api/endpoints.gen.ts @@ -1,19 +1,23 @@ import { baseAPI as api } from './baseAPI'; const injectedRtkApi = api.injectEndpoints({ endpoints: (build) => ({ - getMigrationList: build.query({ + getSessionList: build.query({ query: () => ({ url: `/cloudmigration/migration` }), }), - createMigration: build.mutation({ - query: (queryArg) => ({ url: `/cloudmigration/migration`, method: 'POST', body: queryArg.cloudMigrationRequest }), + createSession: build.mutation({ + query: (queryArg) => ({ + url: `/cloudmigration/migration`, + method: 'POST', + body: queryArg.cloudMigrationSessionRequestDto, + }), }), getCloudMigrationRun: build.query({ query: (queryArg) => ({ url: `/cloudmigration/migration/run/${queryArg.runUid}` }), }), - deleteCloudMigration: build.mutation({ + deleteSession: build.mutation({ query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.uid}`, method: 'DELETE' }), }), - getCloudMigration: build.query({ + getSession: build.query({ query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.uid}` }), }), getCloudMigrationRunList: build.query({ @@ -32,28 +36,28 @@ const injectedRtkApi = api.injectEndpoints({ overrideExisting: false, }); export { injectedRtkApi as generatedAPI }; -export type GetMigrationListApiResponse = /** status 200 (empty) */ CloudMigrationListResponse; -export type GetMigrationListApiArg = void; -export type CreateMigrationApiResponse = /** status 200 (empty) */ CloudMigrationResponse; -export type CreateMigrationApiArg = { - cloudMigrationRequest: CloudMigrationRequest; +export type GetSessionListApiResponse = /** status 200 (empty) */ CloudMigrationSessionListResponseDto; +export type GetSessionListApiArg = void; +export type CreateSessionApiResponse = /** status 200 (empty) */ CloudMigrationSessionResponseDto; +export type CreateSessionApiArg = { + cloudMigrationSessionRequestDto: CloudMigrationSessionRequestDto; }; export type GetCloudMigrationRunApiResponse = /** status 200 (empty) */ MigrateDataResponseDto; export type GetCloudMigrationRunApiArg = { /** RunUID of a migration run */ runUid: string; }; -export type DeleteCloudMigrationApiResponse = unknown; -export type DeleteCloudMigrationApiArg = { - /** UID of a migration */ +export type DeleteSessionApiResponse = unknown; +export type DeleteSessionApiArg = { + /** UID of a migration session */ uid: string; }; -export type GetCloudMigrationApiResponse = /** status 200 (empty) */ CloudMigrationResponse; -export type GetCloudMigrationApiArg = { - /** UID of a migration */ +export type GetSessionApiResponse = /** status 200 (empty) */ CloudMigrationSessionResponseDto; +export type GetSessionApiArg = { + /** UID of a migration session */ uid: string; }; -export type GetCloudMigrationRunListApiResponse = /** status 200 (empty) */ CloudMigrationRunList; +export type GetCloudMigrationRunListApiResponse = /** status 200 (empty) */ SnapshotListDto; export type GetCloudMigrationRunListApiArg = { /** UID of a migration */ uid: string; @@ -69,14 +73,14 @@ export type GetDashboardByUidApiResponse = /** status 200 (empty) */ DashboardFu export type GetDashboardByUidApiArg = { uid: string; }; -export type CloudMigrationResponse = { +export type CloudMigrationSessionResponseDto = { created?: string; - stack?: string; + slug?: string; uid?: string; updated?: string; }; -export type CloudMigrationListResponse = { - migrations?: CloudMigrationResponse[]; +export type CloudMigrationSessionListResponseDto = { + sessions?: CloudMigrationSessionResponseDto[]; }; export type ErrorResponseBody = { /** Error An optional detailed description of the actual error. Only included if running in developer mode. */ @@ -88,7 +92,7 @@ export type ErrorResponseBody = { For example, a 412 Precondition Failed error may include additional information of why that error happened. */ status?: string; }; -export type CloudMigrationRequest = { +export type CloudMigrationSessionRequestDto = { authToken?: string; }; export type MigrateDataResponseItemDto = { @@ -104,7 +108,7 @@ export type MigrateDataResponseDto = { export type MigrateDataResponseListDto = { uid?: string; }; -export type CloudMigrationRunList = { +export type SnapshotListDto = { runs?: MigrateDataResponseListDto[]; }; export type CreateAccessTokenResponseDto = { @@ -154,11 +158,11 @@ export type DashboardFullWithMeta = { meta?: DashboardMeta; }; export const { - useGetMigrationListQuery, - useCreateMigrationMutation, + useGetSessionListQuery, + useCreateSessionMutation, useGetCloudMigrationRunQuery, - useDeleteCloudMigrationMutation, - useGetCloudMigrationQuery, + useDeleteSessionMutation, + useGetSessionQuery, useGetCloudMigrationRunListQuery, useRunCloudMigrationMutation, useCreateCloudMigrationTokenMutation, diff --git a/public/app/features/migrate-to-cloud/api/index.ts b/public/app/features/migrate-to-cloud/api/index.ts index 6ec39eaae3b..696a5a8505b 100644 --- a/public/app/features/migrate-to-cloud/api/index.ts +++ b/public/app/features/migrate-to-cloud/api/index.ts @@ -10,23 +10,23 @@ export const cloudMigrationAPI = generatedAPI.enhanceEndpoints({ createCloudMigrationToken: suppressErrorsOnQuery, // List Cloud Configs - getMigrationList: { + getSessionList: { providesTags: ['cloud-migration-config'] /* should this be a -list? */, }, // Create Cloud Config - createMigration(endpoint) { + createSession(endpoint) { suppressErrorsOnQuery(endpoint); endpoint.invalidatesTags = ['cloud-migration-config']; }, // Get one Cloud Config - getCloudMigration: { + getSession: { providesTags: ['cloud-migration-config'], }, // Delete one Cloud Config - deleteCloudMigration: { + deleteSession: { invalidatesTags: ['cloud-migration-config'], }, diff --git a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx index 9bc1bec1429..9ab5ee9f23e 100644 --- a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx +++ b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx @@ -3,13 +3,13 @@ import React, { useState } from 'react'; import { Box, Button, Text } from '@grafana/ui'; import { Trans } from 'app/core/internationalization'; -import { useCreateMigrationMutation } from '../../../api'; +import { useCreateSessionMutation } from '../../../api'; import { ConnectModal } from './ConnectModal'; export const CallToAction = () => { const [modalOpen, setModalOpen] = useState(false); - const [createMigration, createMigrationResponse] = useCreateMigrationMutation(); + const [createMigration, createMigrationResponse] = useCreateSessionMutation(); return ( <> diff --git a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx index 2236e8bb9f0..42ed70dace8 100644 --- a/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx +++ b/public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx @@ -6,14 +6,14 @@ import { GrafanaTheme2 } from '@grafana/data'; import { Modal, Button, Stack, TextLink, Field, Input, Text, useStyles2, Alert } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; -import { CreateMigrationApiArg } from '../../../api'; +import { CreateSessionApiArg } from '../../../api'; interface Props { isOpen: boolean; isLoading: boolean; isError: boolean; hideModal: () => void; - onConfirm: (connectStackData: CreateMigrationApiArg) => Promise; + onConfirm: (connectStackData: CreateSessionApiArg) => Promise; } interface FormData { @@ -39,7 +39,7 @@ export const ConnectModal = ({ isOpen, isLoading, isError, hideModal, onConfirm const onConfirmConnect: SubmitHandler = (formData) => { onConfirm({ - cloudMigrationRequest: { + cloudMigrationSessionRequestDto: { authToken: formData.token, }, }).then((resp) => { diff --git a/public/app/features/migrate-to-cloud/onprem/Page.tsx b/public/app/features/migrate-to-cloud/onprem/Page.tsx index 27921c54524..3f3799c3722 100644 --- a/public/app/features/migrate-to-cloud/onprem/Page.tsx +++ b/public/app/features/migrate-to-cloud/onprem/Page.tsx @@ -5,10 +5,10 @@ import { Alert, Box, Button, Stack } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; import { - useDeleteCloudMigrationMutation, + useDeleteSessionMutation, useGetCloudMigrationRunListQuery, useGetCloudMigrationRunQuery, - useGetMigrationListQuery, + useGetSessionListQuery, useRunCloudMigrationMutation, } from '../api'; @@ -33,8 +33,8 @@ import { ResourcesTable } from './ResourcesTable'; */ function useGetLatestMigrationDestination() { - const result = useGetMigrationListQuery(); - const latestMigration = result.data?.migrations?.at(-1); + const result = useGetSessionListQuery(); + const latestMigration = result.data?.sessions?.at(-1); return { ...result, @@ -68,7 +68,7 @@ export const Page = () => { const migrationDestination = useGetLatestMigrationDestination(); const lastMigrationRun = useGetLatestMigrationRun(migrationDestination.data?.uid); const [performRunMigration, runMigrationResult] = useRunCloudMigrationMutation(); - const [performDisconnect, disconnectResult] = useDeleteCloudMigrationMutation(); + const [performDisconnect, disconnectResult] = useDeleteSessionMutation(); // isBusy is not a loading state, but indicates that the system is doing *something* // and all buttons should be disabled @@ -136,7 +136,7 @@ export const Page = () => { )} - {migrationMeta.stack && ( + {migrationMeta.slug && ( { title={t('migrate-to-cloud.summary.target-stack-title', 'Uploading to')} value={ <> - {migrationMeta.stack}{' '} + {migrationMeta.slug}{' '}