mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 14:12:24 +08:00
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>
This commit is contained in:
@ -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 {
|
||||
|
Reference in New Issue
Block a user