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
pull/89140/head
Michael Mandrus 1 year ago committed by GitHub
parent 06c0ce4325
commit 9d3a4e236d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 218
      pkg/services/cloudmigration/api/api.go
  2. 4
      pkg/services/cloudmigration/api/api_test.go
  3. 209
      pkg/services/cloudmigration/api/dtos.go
  4. 19
      pkg/services/cloudmigration/cloudmigration.go
  5. 87
      pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration.go
  6. 22
      pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_noop.go
  7. 22
      pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go
  8. 64
      pkg/services/cloudmigration/cloudmigrationimpl/fake/cloudmigration_fake.go
  9. 14
      pkg/services/cloudmigration/cloudmigrationimpl/store.go
  10. 34
      pkg/services/cloudmigration/cloudmigrationimpl/xorm_store.go
  11. 46
      pkg/services/cloudmigration/cloudmigrationimpl/xorm_store_test.go
  12. 17
      pkg/services/cloudmigration/cmsclient/client.go
  13. 14
      pkg/services/cloudmigration/gmsclient/client.go
  14. 47
      pkg/services/cloudmigration/gmsclient/dtos.go
  15. 62
      pkg/services/cloudmigration/gmsclient/gms_client.go
  16. 19
      pkg/services/cloudmigration/gmsclient/inmemory_client.go
  17. 123
      pkg/services/cloudmigration/model.go
  18. 58
      pkg/services/sqlstore/migrations/cloud_migrations.go
  19. 50
      public/api-enterprise-spec.json
  20. 79
      public/api-merged.json
  21. 58
      public/app/features/migrate-to-cloud/api/endpoints.gen.ts
  22. 8
      public/app/features/migrate-to-cloud/api/index.ts
  23. 4
      public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/CallToAction.tsx
  24. 6
      public/app/features/migrate-to-cloud/onprem/EmptyState/CallToAction/ConnectModal.tsx
  25. 14
      public/app/features/migrate-to-cloud/onprem/Page.tsx
  26. 79
      public/openapi3.json
  27. 8
      scripts/generate-rtk-apis.ts

@ -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
//
// Get a cloud migration.
// swagger:route GET /cloudmigration/migration/{uid} migrations getSession
//
// 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)
}
// swagger:parameters getCloudMigration
type GetCloudMigrationRequest struct {
// UID of a migration
//
// in: path
UID string `json:"uid"`
return response.JSON(http.StatusOK, CloudMigrationSessionResponseDTO{
UID: s.UID,
Slug: s.Slug,
Created: s.Created,
Updated: s.Updated,
})
}
// 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)
}
// swagger:parameters getCloudMigrationRunList
type GetCloudMigrationRunList struct {
// UID of a migration
//
// in: path
UID string `json:"uid"`
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: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 {
}

@ -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",

@ -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,
}
}

@ -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)
}

@ -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)
}

@ -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
}

@ -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)
}

@ -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"},
},

@ -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)
}

@ -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")

@ -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'),

@ -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"))

@ -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"

@ -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"`
}

@ -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,
}
}

@ -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,

@ -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"`
}
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"`
}
func (r CloudMigrationRun) ToResponse() (*MigrateDataResponseDTO, error) {
var result MigrateDataResponseDTO
// 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 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 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
}

@ -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",
})
}

@ -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,28 +8342,28 @@
"$ref": "#/definitions/GetAccessTokenResponseDTO"
}
},
"cloudMigrationListResponse": {
"cloudMigrationRunListResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/CloudMigrationListResponse"
"$ref": "#/definitions/SnapshotListDTO"
}
},
"cloudMigrationResponse": {
"cloudMigrationRunResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/CloudMigrationResponse"
"$ref": "#/definitions/MigrateDataResponseDTO"
}
},
"cloudMigrationRunListResponse": {
"cloudMigrationSessionListResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/CloudMigrationRunList"
"$ref": "#/definitions/CloudMigrationSessionListResponseDTO"
}
},
"cloudMigrationRunResponse": {
"cloudMigrationSessionResponse": {
"description": "",
"schema": {
"$ref": "#/definitions/MigrateDataResponseDTO"
"$ref": "#/definitions/CloudMigrationSessionResponseDTO"
}
},
"conflictError": {

@ -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,28 +22382,28 @@
"$ref": "#/definitions/GetAccessTokenResponseDTO"
}
},
"cloudMigrationListResponse": {
"cloudMigrationRunListResponse": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/CloudMigrationListResponse"
"$ref": "#/definitions/SnapshotListDTO"
}
},
"cloudMigrationResponse": {
"cloudMigrationRunResponse": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/CloudMigrationResponse"
"$ref": "#/definitions/MigrateDataResponseDTO"
}
},
"cloudMigrationRunListResponse": {
"cloudMigrationSessionListResponse": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/CloudMigrationRunList"
"$ref": "#/definitions/CloudMigrationSessionListResponseDTO"
}
},
"cloudMigrationRunResponse": {
"cloudMigrationSessionResponse": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/MigrateDataResponseDTO"
"$ref": "#/definitions/CloudMigrationSessionResponseDTO"
}
},
"conflictError": {

@ -1,19 +1,23 @@
import { baseAPI as api } from './baseAPI';
const injectedRtkApi = api.injectEndpoints({
endpoints: (build) => ({
getMigrationList: build.query<GetMigrationListApiResponse, GetMigrationListApiArg>({
getSessionList: build.query<GetSessionListApiResponse, GetSessionListApiArg>({
query: () => ({ url: `/cloudmigration/migration` }),
}),
createMigration: build.mutation<CreateMigrationApiResponse, CreateMigrationApiArg>({
query: (queryArg) => ({ url: `/cloudmigration/migration`, method: 'POST', body: queryArg.cloudMigrationRequest }),
createSession: build.mutation<CreateSessionApiResponse, CreateSessionApiArg>({
query: (queryArg) => ({
url: `/cloudmigration/migration`,
method: 'POST',
body: queryArg.cloudMigrationSessionRequestDto,
}),
}),
getCloudMigrationRun: build.query<GetCloudMigrationRunApiResponse, GetCloudMigrationRunApiArg>({
query: (queryArg) => ({ url: `/cloudmigration/migration/run/${queryArg.runUid}` }),
}),
deleteCloudMigration: build.mutation<DeleteCloudMigrationApiResponse, DeleteCloudMigrationApiArg>({
deleteSession: build.mutation<DeleteSessionApiResponse, DeleteSessionApiArg>({
query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.uid}`, method: 'DELETE' }),
}),
getCloudMigration: build.query<GetCloudMigrationApiResponse, GetCloudMigrationApiArg>({
getSession: build.query<GetSessionApiResponse, GetSessionApiArg>({
query: (queryArg) => ({ url: `/cloudmigration/migration/${queryArg.uid}` }),
}),
getCloudMigrationRunList: build.query<GetCloudMigrationRunListApiResponse, GetCloudMigrationRunListApiArg>({
@ -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,

@ -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'],
},

@ -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 (
<>

@ -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<unknown>;
onConfirm: (connectStackData: CreateSessionApiArg) => Promise<unknown>;
}
interface FormData {
@ -39,7 +39,7 @@ export const ConnectModal = ({ isOpen, isLoading, isError, hideModal, onConfirm
const onConfirmConnect: SubmitHandler<FormData> = (formData) => {
onConfirm({
cloudMigrationRequest: {
cloudMigrationSessionRequestDto: {
authToken: formData.token,
},
}).then((resp) => {

@ -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 = () => {
</Alert>
)}
{migrationMeta.stack && (
{migrationMeta.slug && (
<Box
borderColor="weak"
borderStyle="solid"
@ -150,7 +150,7 @@ export const Page = () => {
title={t('migrate-to-cloud.summary.target-stack-title', 'Uploading to')}
value={
<>
{migrationMeta.stack}{' '}
{migrationMeta.slug}{' '}
<Button
disabled={isBusy}
onClick={() => setDisconnectModalOpen(true)}

@ -196,41 +196,41 @@
},
"description": "(empty)"
},
"cloudMigrationListResponse": {
"cloudMigrationRunListResponse": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CloudMigrationListResponse"
"$ref": "#/components/schemas/SnapshotListDTO"
}
}
},
"description": "(empty)"
},
"cloudMigrationResponse": {
"cloudMigrationRunResponse": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CloudMigrationResponse"
"$ref": "#/components/schemas/MigrateDataResponseDTO"
}
}
},
"description": "(empty)"
},
"cloudMigrationRunListResponse": {
"cloudMigrationSessionListResponse": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CloudMigrationRunList"
"$ref": "#/components/schemas/CloudMigrationSessionListResponseDTO"
}
}
},
"description": "(empty)"
},
"cloudMigrationRunResponse": {
"cloudMigrationSessionResponse": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MigrateDataResponseDTO"
"$ref": "#/components/schemas/CloudMigrationSessionResponseDTO"
}
}
},
@ -3673,18 +3673,18 @@
},
"type": "object"
},
"CloudMigrationListResponse": {
"CloudMigrationSessionListResponseDTO": {
"properties": {
"migrations": {
"sessions": {
"items": {
"$ref": "#/components/schemas/CloudMigrationResponse"
"$ref": "#/components/schemas/CloudMigrationSessionResponseDTO"
},
"type": "array"
}
},
"type": "object"
},
"CloudMigrationRequest": {
"CloudMigrationSessionRequestDTO": {
"properties": {
"authToken": {
"type": "string"
@ -3692,13 +3692,13 @@
},
"type": "object"
},
"CloudMigrationResponse": {
"CloudMigrationSessionResponseDTO": {
"properties": {
"created": {
"format": "date-time",
"type": "string"
},
"stack": {
"slug": {
"type": "string"
},
"uid": {
@ -3711,17 +3711,6 @@
},
"type": "object"
},
"CloudMigrationRunList": {
"properties": {
"runs": {
"items": {
"$ref": "#/components/schemas/MigrateDataResponseListDTO"
},
"type": "array"
}
},
"type": "object"
},
"ConfFloat64": {
"description": "ConfFloat64 is a float64. It Marshals float64 values of NaN of Inf\nto null.",
"format": "double",
@ -10328,6 +10317,17 @@
"SmtpNotEnabled": {
"$ref": "#/components/schemas/ResponseDetails"
},
"SnapshotListDTO": {
"properties": {
"runs": {
"items": {
"$ref": "#/components/schemas/MigrateDataResponseListDTO"
},
"type": "array"
}
},
"type": "object"
},
"Span": {
"properties": {
"Length": {
@ -15112,10 +15112,10 @@
},
"/cloudmigration/migration": {
"get": {
"operationId": "getMigrationList",
"operationId": "getSessionList",
"responses": {
"200": {
"$ref": "#/components/responses/cloudMigrationListResponse"
"$ref": "#/components/responses/cloudMigrationSessionListResponse"
},
"401": {
"$ref": "#/components/responses/unauthorisedError"
@ -15127,18 +15127,18 @@
"$ref": "#/components/responses/internalServerError"
}
},
"summary": "Get a list of all cloud migrations.",
"summary": "Get a list of all cloud migration sessions that have been created.",
"tags": [
"migrations"
]
},
"post": {
"operationId": "createMigration",
"operationId": "createSession",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CloudMigrationRequest"
"$ref": "#/components/schemas/CloudMigrationSessionRequestDTO"
}
}
},
@ -15147,7 +15147,7 @@
},
"responses": {
"200": {
"$ref": "#/components/responses/cloudMigrationResponse"
"$ref": "#/components/responses/cloudMigrationSessionResponse"
},
"401": {
"$ref": "#/components/responses/unauthorisedError"
@ -15159,7 +15159,7 @@
"$ref": "#/components/responses/internalServerError"
}
},
"summary": "Create a migration.",
"summary": "Create a migration session.",
"tags": [
"migrations"
]
@ -15201,10 +15201,10 @@
},
"/cloudmigration/migration/{uid}": {
"delete": {
"operationId": "deleteCloudMigration",
"operationId": "deleteSession",
"parameters": [
{
"description": "UID of a migration",
"description": "UID of a migration session",
"in": "path",
"name": "uid",
"required": true,
@ -15224,17 +15224,16 @@
"$ref": "#/components/responses/internalServerError"
}
},
"summary": "Delete a migration.",
"summary": "Delete a migration session by its uid.",
"tags": [
"migrations"
]
},
"get": {
"description": "It returns migrations that has been created.",
"operationId": "getCloudMigration",
"operationId": "getSession",
"parameters": [
{
"description": "UID of a migration",
"description": "UID of a migration session",
"in": "path",
"name": "uid",
"required": true,
@ -15245,7 +15244,7 @@
],
"responses": {
"200": {
"$ref": "#/components/responses/cloudMigrationResponse"
"$ref": "#/components/responses/cloudMigrationSessionResponse"
},
"401": {
"$ref": "#/components/responses/unauthorisedError"
@ -15257,7 +15256,7 @@
"$ref": "#/components/responses/internalServerError"
}
},
"summary": "Get a cloud migration.",
"summary": "Get a cloud migration session by its uid.",
"tags": [
"migrations"
]

@ -13,13 +13,13 @@ const config: ConfigFile = {
apiImport: 'baseAPI',
filterEndpoints: [
'createCloudMigrationToken',
'getMigrationList',
'getCloudMigration',
'createMigration',
'getSessionList',
'getSession',
'createSession',
'deleteSession',
'runCloudMigration',
'getCloudMigrationRun',
'getCloudMigrationRunList',
'deleteCloudMigration',
'getDashboardByUid',
],
},

Loading…
Cancel
Save