CloudMigrations: Improvements to backend (#91012)

* E2C: Add stat rollup to MigrationSummary

* fix report event url

* open form in new page

* sort folders by heirarchy

* undo accidental commit

* remove another commit

* make folder sorting dynamic

---------

Co-authored-by: joshhunt <josh@trtr.co>
pull/91153/head
Michael Mandrus 11 months ago committed by GitHub
parent 9d639278f4
commit a6088e4ee4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 23
      pkg/services/cloudmigration/cloudmigrationimpl/cloudmigration_test.go
  2. 43
      pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt.go
  3. 2
      pkg/services/cloudmigration/gmsclient/gms_client.go

@ -384,6 +384,29 @@ func Test_DeletedDashboardsNotMigrated(t *testing.T) {
assert.Equal(t, 1, dashCount)
}
// Implementation inspired by ChatGPT, OpenAI's language model.
func Test_SortFolders(t *testing.T) {
folders := []folder.CreateFolderCommand{
{UID: "a", ParentUID: "", Title: "Root"},
{UID: "b", ParentUID: "a", Title: "Child of Root"},
{UID: "c", ParentUID: "b", Title: "Child of b"},
{UID: "d", ParentUID: "a", Title: "Another Child of Root"},
{UID: "e", ParentUID: "", Title: "Another Root"},
}
expected := []folder.CreateFolderCommand{
{UID: "a", ParentUID: "", Title: "Root"},
{UID: "e", ParentUID: "", Title: "Another Root"},
{UID: "b", ParentUID: "a", Title: "Child of Root"},
{UID: "d", ParentUID: "a", Title: "Another Child of Root"},
{UID: "c", ParentUID: "b", Title: "Child of b"},
}
sortedFolders := sortFolders(folders)
require.Equal(t, expected, sortedFolders)
}
func ctxWithSignedInUser() context.Context {
c := &contextmodel.ReqContext{
SignedInUser: &user.SignedInUser{OrgID: 1},

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"sort"
"time"
snapshot "github.com/grafana/grafana-cloud-migration-snapshot/src"
@ -61,6 +62,7 @@ func (s *Service) getMigrationDataJSON(ctx context.Context, signedInUser *user.S
})
}
folders = sortFolders(folders)
for _, f := range folders {
migrationDataSlice = append(migrationDataSlice, cloudmigration.MigrateDataRequestItem{
Type: cloudmigration.FolderDataType,
@ -114,6 +116,7 @@ func (s *Service) getDataSourceCommands(ctx context.Context) ([]datasources.AddD
return result, err
}
// getDashboardAndFolderCommands returns the json payloads required by the dashboard and folder creation APIs
func (s *Service) getDashboardAndFolderCommands(ctx context.Context, signedInUser *user.SignedInUser) ([]dashboards.Dashboard, []folder.CreateFolderCommand, error) {
dashs, err := s.dashboardService.GetAllDashboards(ctx)
if err != nil {
@ -369,3 +372,43 @@ func (s *Service) updateSnapshotWithRetries(ctx context.Context, cmd cloudmigrat
}
return nil
}
// sortFolders implements a sort such that parent folders always come before their children
// Implementation inspired by ChatGPT, OpenAI's language model.
func sortFolders(input []folder.CreateFolderCommand) []folder.CreateFolderCommand {
// Map from UID to the corresponding folder for quick lookup
folderMap := make(map[string]folder.CreateFolderCommand)
for _, folder := range input {
folderMap[folder.UID] = folder
}
// Dynamic map of folderUID to depth
depthMap := make(map[string]int)
// Function to get the depth of a folder based on its parent hierarchy
var getDepth func(uid string) int
getDepth = func(uid string) int {
if uid == "" {
return 0
}
if d, ok := depthMap[uid]; ok {
return d
}
folder, exists := folderMap[uid]
if !exists || folder.ParentUID == "" {
return 1
}
return 1 + getDepth(folder.ParentUID)
}
// Calculate the depth of each folder
for _, folder := range input {
depthMap[folder.UID] = getDepth(folder.UID)
}
// Sort folders by their depth, ensuring a stable sort
sort.SliceStable(input, func(i, j int) bool {
return depthMap[input[i].UID] < depthMap[input[j].UID]
})
return input
}

@ -254,7 +254,7 @@ func (c *gmsClientImpl) ReportEvent(ctx context.Context, session cloudmigration.
return
}
path := fmt.Sprintf("%s/api/v1/snapshots/events", c.buildBasePath(session.ClusterSlug))
path := fmt.Sprintf("%s/api/v1/events", c.buildBasePath(session.ClusterSlug))
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(event); err != nil {

Loading…
Cancel
Save