feat: provides MT Dashboard service (#110447)
This commit is contained in:
@@ -2,6 +2,8 @@ package schemaversion
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -9,7 +11,7 @@ const (
|
||||
LATEST_VERSION = 41
|
||||
)
|
||||
|
||||
type SchemaVersionMigrationFunc func(map[string]interface{}) error
|
||||
type SchemaVersionMigrationFunc func(context.Context, map[string]interface{}) error
|
||||
|
||||
type DataSourceInfo struct {
|
||||
Default bool
|
||||
@@ -21,7 +23,9 @@ type DataSourceInfo struct {
|
||||
}
|
||||
|
||||
type DataSourceInfoProvider interface {
|
||||
GetDataSourceInfo() []DataSourceInfo
|
||||
// GetDataSourceInfo returns a list of all data sources with their info
|
||||
// The context must have the namespace in it
|
||||
GetDataSourceInfo(ctx context.Context) []DataSourceInfo
|
||||
}
|
||||
|
||||
type PanelPluginInfo struct {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
@@ -68,7 +69,7 @@ func runMigrationTests(t *testing.T, testCases []migrationTestCase, migrationFun
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := migrationFunc(tt.input)
|
||||
err := migrationFunc(context.Background(), tt.input)
|
||||
if tt.expectedError != "" {
|
||||
require.Error(t, err)
|
||||
require.Equal(t, tt.expectedError, err.Error())
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V14 migrates the sharedCrosshair boolean property to graphTooltip integer property.
|
||||
// This migration converts the old boolean shared crosshair setting to the new integer-based
|
||||
// graph tooltip setting for consistency with updated dashboard tooltip behavior.
|
||||
@@ -20,7 +22,7 @@ package schemaversion
|
||||
// "panels": [...]
|
||||
// }
|
||||
|
||||
func V14(dashboard map[string]interface{}) error {
|
||||
func V14(_ context.Context, dashboard map[string]interface{}) error {
|
||||
// Convert sharedCrosshair boolean to graphTooltip integer
|
||||
sharedCrosshair := GetBoolValue(dashboard, "sharedCrosshair")
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V15 migration is a no-op migration
|
||||
// It only updates the schema version to 15
|
||||
// It's created to keep the migration history consistent with frontend migrator
|
||||
@@ -19,7 +21,7 @@ package schemaversion
|
||||
// "panels": [...]
|
||||
// }
|
||||
|
||||
func V15(dashboard map[string]interface{}) error {
|
||||
func V15(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 15
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ const (
|
||||
|
||||
// V16 migrates dashboard layout from the old row-based system to the modern grid-based layout.
|
||||
// This migration follows the exact logic from DashboardMigrator.ts to ensure consistency between frontend and backend.
|
||||
func V16(dashboard map[string]interface{}) error {
|
||||
func V16(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 16
|
||||
|
||||
upgradeToGridLayout(dashboard)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"sort"
|
||||
)
|
||||
@@ -36,7 +37,7 @@ import (
|
||||
// ]
|
||||
//
|
||||
// The minSpan property is removed after conversion.
|
||||
func V17(dashboard map[string]interface{}) error {
|
||||
func V17(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 17
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V18 migrates gauge panel options from the legacy `options-gauge` format to the new `options` format.
|
||||
// This migration restructures gauge panel configuration to use the modern options structure with valueOptions.
|
||||
//
|
||||
@@ -42,7 +44,7 @@ package schemaversion
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
func V18(dashboard map[string]interface{}) error {
|
||||
func V18(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 18
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
@@ -36,7 +37,7 @@ import (
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
func V19(dashboard map[string]interface{}) error {
|
||||
func V19(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 19
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
|
||||
@@ -64,7 +65,7 @@ import (
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
func V20(dashboard map[string]interface{}) error {
|
||||
func V20(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 20
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
|
||||
@@ -55,7 +56,7 @@ import (
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
func V21(dashboard map[string]interface{}) error {
|
||||
func V21(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 21
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V22 migrates table panel styles to set align property to 'auto'.
|
||||
// This migration ensures that all table panel styles have their align property
|
||||
// set to 'auto' for consistent alignment behavior.
|
||||
@@ -27,7 +29,7 @@ package schemaversion
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
func V22(dashboard map[string]interface{}) error {
|
||||
func V22(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 22
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package schemaversion
|
||||
|
||||
import "github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
|
||||
)
|
||||
|
||||
// V23 migrates multi variables to ensure their current property is aligned with their multi property.
|
||||
// This migration ensures that variables with multi=true have current.value and current.text as arrays,
|
||||
@@ -23,7 +27,7 @@ import "github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
|
||||
// { "type": "query", "multi": false, "current": { "value": "B", "text": "B" } }
|
||||
// ]
|
||||
// }
|
||||
func V23(dashboard map[string]interface{}) error {
|
||||
func V23(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 23
|
||||
|
||||
templating, ok := dashboard["templating"].(map[string]interface{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -199,7 +200,7 @@ func V24(panelProvider PanelPluginInfoProvider) SchemaVersionMigrationFunc {
|
||||
return migrator.migrate
|
||||
}
|
||||
|
||||
func (m *v24Migrator) migrate(dashboard map[string]interface{}) error {
|
||||
func (m *v24Migrator) migrate(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 24
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V25 migration is a no-op migration
|
||||
// It only updates the schema version to 25
|
||||
// It's created to keep the migration history consistent with frontend migrator
|
||||
@@ -43,7 +45,7 @@ package schemaversion
|
||||
// }
|
||||
// }
|
||||
|
||||
func V25(dashboard map[string]interface{}) error {
|
||||
func V25(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(25)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V26 migration performs two main tasks:
|
||||
// 1. Converts all text2 panels to text panels by changing the type field
|
||||
// 2. Removes the angular field from panel options if it exists
|
||||
@@ -80,7 +82,7 @@ package schemaversion
|
||||
// "title": "Graph Panel"
|
||||
// }
|
||||
// ]
|
||||
func V26(dashboard map[string]interface{}) error {
|
||||
func V26(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 26
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V27 migrates repeated panels and constant variables.
|
||||
//
|
||||
// The migration performs two main tasks:
|
||||
@@ -73,7 +75,7 @@ package schemaversion
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
func V27(dashboard map[string]interface{}) error {
|
||||
func V27(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 27
|
||||
|
||||
// Remove repeated panels
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -66,12 +67,12 @@ func V28(panelProvider PanelPluginInfoProvider) SchemaVersionMigrationFunc {
|
||||
statPanelVersion: statPanelVersion,
|
||||
}
|
||||
|
||||
return func(dashboard map[string]interface{}) error {
|
||||
return migrator.migrate(dashboard)
|
||||
return func(ctx context.Context, dashboard map[string]interface{}) error {
|
||||
return migrator.migrate(context.Background(), dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *v28Migrator) migrate(dashboard map[string]interface{}) error {
|
||||
func (m *v28Migrator) migrate(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 28
|
||||
|
||||
// Migrate singlestat panels
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V29 migrates query variables to ensure their refresh property is set to 1 (on dashboard load)
|
||||
// if it is not 1 or 2, and clears their options array if present.
|
||||
//
|
||||
@@ -22,7 +24,7 @@ package schemaversion
|
||||
// { "type": "query", "refresh": 1, "options": [] }
|
||||
// ]
|
||||
// }
|
||||
func V29(dashboard map[string]interface{}) error {
|
||||
func V29(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 29
|
||||
|
||||
templating, ok := dashboard["templating"].(map[string]interface{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -89,7 +90,7 @@ import (
|
||||
// "tooltip": { "mode": "multi" }
|
||||
// }
|
||||
// }
|
||||
func V30(dashboard map[string]interface{}) error {
|
||||
func V30(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = 30
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V31 adds a merge transformer after any labelsToFields transformer in panel transformations.
|
||||
//
|
||||
// This migration addresses data processing workflow optimization by automatically inserting
|
||||
@@ -48,7 +50,7 @@ package schemaversion
|
||||
// { "id": "merge", "options": {} }
|
||||
// ]
|
||||
// }
|
||||
func V31(dashboard map[string]interface{}) error {
|
||||
func V31(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(31)
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V32 is a no-op migration that serves as a placeholder for consistency.
|
||||
//
|
||||
// The migration performs no modifications to the dashboard structure and simply
|
||||
@@ -21,7 +23,7 @@ package schemaversion
|
||||
// "schemaVersion": 32,
|
||||
// "panels": [...] // unchanged
|
||||
// }
|
||||
func V32(dashboard map[string]interface{}) error {
|
||||
func V32(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(32)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package schemaversion
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// V33 migrates panel datasource references from string names to UIDs.
|
||||
//
|
||||
// This migration addresses datasource references in dashboard panels and their targets
|
||||
@@ -57,8 +61,8 @@ package schemaversion
|
||||
// ]
|
||||
// }
|
||||
func V33(dsInfo DataSourceInfoProvider) SchemaVersionMigrationFunc {
|
||||
datasources := dsInfo.GetDataSourceInfo()
|
||||
return func(dashboard map[string]interface{}) error {
|
||||
return func(ctx context.Context, dashboard map[string]interface{}) error {
|
||||
datasources := dsInfo.GetDataSourceInfo(ctx)
|
||||
if dashboard == nil {
|
||||
dashboard = map[string]interface{}{}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V34 migrates CloudWatch queries that use multiple statistics into separate queries.
|
||||
//
|
||||
// This migration addresses CloudWatch queries where a single query uses multiple statistics
|
||||
@@ -53,7 +55,7 @@ package schemaversion
|
||||
// { name: "CloudWatch Alerts - Maximum", dimensions: {"InstanceId": "i-123"}, namespace: "AWS/EC2", region: "us-east-1", prefixMatching: false, statistic: "Maximum" },
|
||||
// { name: "CloudWatch Alerts - Minimum", dimensions: {"InstanceId": "i-123"}, namespace: "AWS/EC2", region: "us-east-1", prefixMatching: false, statistic: "Minimum" }
|
||||
// ]
|
||||
func V34(dashboard map[string]interface{}) error {
|
||||
func V34(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(34)
|
||||
|
||||
// Migrate panel queries if panels exist
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V35 ensures x-axis visibility in timeseries panels to prevent dashboard breakage.
|
||||
//
|
||||
// This migration addresses a specific issue where timeseries panels with all axes
|
||||
@@ -33,7 +35,7 @@ package schemaversion
|
||||
// properties: [{ id: "custom.axisPlacement", value: "auto" }]
|
||||
// }]
|
||||
// }
|
||||
func V35(dashboard map[string]interface{}) error {
|
||||
func V35(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(35)
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V36 migrates dashboard datasource references from legacy string format to structured UID-based objects.
|
||||
//
|
||||
// This migration addresses a critical evolution in Grafana's datasource architecture where datasource
|
||||
@@ -73,8 +75,8 @@ package schemaversion
|
||||
// }]
|
||||
// }
|
||||
func V36(dsInfo DataSourceInfoProvider) SchemaVersionMigrationFunc {
|
||||
datasources := dsInfo.GetDataSourceInfo()
|
||||
return func(dashboard map[string]interface{}) error {
|
||||
return func(ctx context.Context, dashboard map[string]interface{}) error {
|
||||
datasources := dsInfo.GetDataSourceInfo(ctx)
|
||||
dashboard["schemaVersion"] = int(36)
|
||||
|
||||
migrateAnnotations(dashboard, datasources)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V37 normalizes legend configuration to use `showLegend` property consistently.
|
||||
//
|
||||
// This migration addresses inconsistencies in how legend visibility was handled.
|
||||
@@ -71,7 +73,7 @@ package schemaversion
|
||||
// showLegend: true
|
||||
// }
|
||||
// }
|
||||
func V37(dashboard map[string]interface{}) error {
|
||||
func V37(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(37)
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V38 migrates table panel configuration from displayMode to the structured cellOptions format.
|
||||
//
|
||||
// This migration addresses limitations in the original table panel cell display configuration where
|
||||
@@ -70,7 +72,7 @@ package schemaversion
|
||||
// }
|
||||
// }]
|
||||
// }]
|
||||
func V38(dashboard map[string]interface{}) error {
|
||||
func V38(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(38)
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V39 migrates timeSeriesTable transformation configuration to support extensible per-query options.
|
||||
//
|
||||
// This migration addresses limitations in the original timeSeriesTable transformation design where
|
||||
@@ -45,7 +47,7 @@ package schemaversion
|
||||
// "C": { stat: "last" }
|
||||
// }
|
||||
// }]
|
||||
func V39(dashboard map[string]interface{}) error {
|
||||
func V39(_ context.Context, dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(39)
|
||||
|
||||
panels, ok := dashboard["panels"].([]interface{})
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V40 normalizes the dashboard refresh property to ensure consistent string typing.
|
||||
//
|
||||
// This migration addresses type inconsistencies in dashboard refresh configuration that could
|
||||
@@ -33,7 +35,7 @@ package schemaversion
|
||||
// refresh: "" // normalized to empty string
|
||||
// refresh: "" // normalized to empty string
|
||||
// refresh: "" // property added with empty string
|
||||
func V40(dash map[string]interface{}) error {
|
||||
func V40(_ context.Context, dash map[string]interface{}) error {
|
||||
dash["schemaVersion"] = int(40)
|
||||
if _, ok := dash["refresh"].(string); !ok {
|
||||
dash["refresh"] = ""
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package schemaversion
|
||||
|
||||
import "context"
|
||||
|
||||
// V41 removes the deprecated time_options property from dashboard timepicker configuration.
|
||||
//
|
||||
// This migration addresses technical debt by cleaning up legacy timepicker settings that have
|
||||
@@ -30,7 +32,7 @@ package schemaversion
|
||||
// timepicker: {
|
||||
// refresh_intervals: ["5s", "10s", "30s", "1m"]
|
||||
// }
|
||||
func V41(dash map[string]interface{}) error {
|
||||
func V41(_ context.Context, dash map[string]interface{}) error {
|
||||
dash["schemaVersion"] = int(41)
|
||||
if timepicker, ok := dash["timepicker"].(map[string]interface{}); ok {
|
||||
// time_options is a legacy property that was not used since grafana version 5
|
||||
|
||||
Reference in New Issue
Block a user