CloudMigrations: Create resource dependency map to validate snapshot request (#102594)
* CloudMigrations: Create resource dependency map to validate snapshot request * CloudMigrations: Validate resource types dependencies in create snapshot request * CloudMigrations: Update service interface to pass parsed resource types for creation * CloudMigrations: Conditionally append resource to snapshot if enabled * CloudMigrations: Add /cloudmigration/resources/dependencies endpoint * CloudMigrations: Properly filter dashboards and folders from snapshot
This commit is contained in:
@@ -13,6 +13,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
@@ -40,10 +45,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// Service Define the cloudmigration.Service Implementation.
|
||||
@@ -142,7 +143,7 @@ func ProvideService(
|
||||
libraryElementsService: libraryElementsService,
|
||||
ngAlert: ngAlert,
|
||||
}
|
||||
s.api = api.RegisterApi(routeRegister, s, tracer, accessControl)
|
||||
s.api = api.RegisterApi(routeRegister, s, tracer, accessControl, cloudmigration.ResourceDependency)
|
||||
|
||||
httpClientS3, err := httpClientProvider.New()
|
||||
if err != nil {
|
||||
@@ -471,31 +472,32 @@ func (s *Service) DeleteSession(ctx context.Context, orgID int64, signedInUser *
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedInUser, sessionUid string) (*cloudmigration.CloudMigrationSnapshot, error) {
|
||||
func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedInUser, cmd cloudmigration.CreateSnapshotCommand) (*cloudmigration.CloudMigrationSnapshot, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "CloudMigrationService.CreateSnapshot", trace.WithAttributes(
|
||||
attribute.String("sessionUid", sessionUid),
|
||||
attribute.String("sessionUid", cmd.SessionUID),
|
||||
))
|
||||
defer span.End()
|
||||
|
||||
if s.cfg.CloudMigration.SnapshotFolder == "" {
|
||||
return nil, fmt.Errorf("snapshot folder is not set")
|
||||
}
|
||||
|
||||
// fetch session for the gms auth token
|
||||
session, err := s.store.GetMigrationSessionByUID(ctx, signedInUser.GetOrgID(), sessionUid)
|
||||
session, err := s.store.GetMigrationSessionByUID(ctx, signedInUser.GetOrgID(), cmd.SessionUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching migration session for uid %s: %w", sessionUid, err)
|
||||
return nil, fmt.Errorf("fetching migration session for uid %s: %w", cmd.SessionUID, err)
|
||||
}
|
||||
|
||||
// query gms to establish new snapshot s.cfg.CloudMigration.StartSnapshotTimeout
|
||||
initResp, err := s.gmsClient.StartSnapshot(ctx, *session)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing snapshot with GMS for session %s: %w", sessionUid, err)
|
||||
return nil, fmt.Errorf("initializing snapshot with GMS for session %s: %w", cmd.SessionUID, err)
|
||||
}
|
||||
|
||||
if s.cfg.CloudMigration.SnapshotFolder == "" {
|
||||
return nil, fmt.Errorf("snapshot folder is not set")
|
||||
}
|
||||
// save snapshot to the db
|
||||
snapshot := cloudmigration.CloudMigrationSnapshot{
|
||||
UID: util.GenerateShortUID(),
|
||||
SessionUID: sessionUid,
|
||||
SessionUID: cmd.SessionUID,
|
||||
Status: cloudmigration.SnapshotStatusCreating,
|
||||
EncryptionKey: initResp.EncryptionKey,
|
||||
GMSSnapshotUID: initResp.SnapshotID,
|
||||
@@ -511,7 +513,7 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
|
||||
// Update status to "creating" to ensure the frontend polls from now on
|
||||
if err := s.updateSnapshotWithRetries(ctx, cloudmigration.UpdateSnapshotCmd{
|
||||
UID: uid,
|
||||
SessionID: sessionUid,
|
||||
SessionID: cmd.SessionUID,
|
||||
Status: cloudmigration.SnapshotStatusCreating,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
@@ -536,7 +538,7 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
|
||||
s.report(asyncCtx, session, gmsclient.EventStartBuildingSnapshot, 0, nil, signedInUser.UserUID)
|
||||
|
||||
start := time.Now()
|
||||
err := s.buildSnapshot(asyncCtx, signedInUser, initResp.MaxItemsPerPartition, initResp.Metadata, snapshot)
|
||||
err := s.buildSnapshot(asyncCtx, signedInUser, initResp.MaxItemsPerPartition, initResp.Metadata, snapshot, cmd.ResourceTypes)
|
||||
if err != nil {
|
||||
asyncSpan.SetStatus(codes.Error, "error building snapshot")
|
||||
asyncSpan.RecordError(err)
|
||||
@@ -545,7 +547,7 @@ func (s *Service) CreateSnapshot(ctx context.Context, signedInUser *user.SignedI
|
||||
// Update status to error with retries
|
||||
if err := s.updateSnapshotWithRetries(asyncCtx, cloudmigration.UpdateSnapshotCmd{
|
||||
UID: snapshot.UID,
|
||||
SessionID: sessionUid,
|
||||
SessionID: cmd.SessionUID,
|
||||
Status: cloudmigration.SnapshotStatusError,
|
||||
}); err != nil {
|
||||
s.log.Error("critical failure during snapshot creation - please report any error logs")
|
||||
|
||||
Reference in New Issue
Block a user