Dashboard V0->V1 Migration: Schema migration v36 (#100757)
--------- Co-authored-by: Todd Treece <360020+toddtreece@users.noreply.github.com> Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com> Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com>
This commit is contained in:
co-authored by
Todd Treece
Haris Rozajac
Stephanie Hingtgen
parent
6767adb4a6
commit
59c2f15433
@@ -12,11 +12,16 @@ import (
|
||||
dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
||||
dashv2 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
func TestConversionMatrixExist(t *testing.T) {
|
||||
// Initialize the migrator with a test data source provider
|
||||
migration.Initialize(testutil.GetTestProvider())
|
||||
|
||||
versions := []v1.Object{
|
||||
&dashv0.Dashboard{Spec: common.Unstructured{Object: map[string]any{"title": "dashboardV0"}}},
|
||||
&dashv1.Dashboard{Spec: common.Unstructured{Object: map[string]any{"title": "dashboardV1"}}},
|
||||
|
||||
@@ -1,11 +1,50 @@
|
||||
package migration
|
||||
|
||||
import "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
import (
|
||||
"sync"
|
||||
|
||||
func Migrate(dash map[string]any, targetVersion int) error {
|
||||
if dash == nil {
|
||||
dash = map[string]any{}
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
)
|
||||
|
||||
// Initialize provides the migrator singleton with required dependencies and builds the map of migrations.
|
||||
func Initialize(dsInfoProvider schemaversion.DataSourceInfoProvider) {
|
||||
migratorInstance.init(dsInfoProvider)
|
||||
}
|
||||
|
||||
// Migrate migrates the given dashboard to the target version.
|
||||
// This will block until the migrator is initialized.
|
||||
func Migrate(dash map[string]interface{}, targetVersion int) error {
|
||||
return migratorInstance.migrate(dash, targetVersion)
|
||||
}
|
||||
|
||||
var (
|
||||
migratorInstance = &migrator{
|
||||
migrations: map[int]schemaversion.SchemaVersionMigrationFunc{},
|
||||
ready: make(chan struct{}),
|
||||
}
|
||||
initOnce sync.Once
|
||||
)
|
||||
|
||||
type migrator struct {
|
||||
ready chan struct{}
|
||||
migrations map[int]schemaversion.SchemaVersionMigrationFunc
|
||||
}
|
||||
|
||||
func (m *migrator) init(dsInfoProvider schemaversion.DataSourceInfoProvider) {
|
||||
initOnce.Do(func() {
|
||||
m.migrations = schemaversion.GetMigrations(dsInfoProvider)
|
||||
close(m.ready)
|
||||
})
|
||||
}
|
||||
|
||||
func (m *migrator) migrate(dash map[string]interface{}, targetVersion int) error {
|
||||
if dash == nil {
|
||||
return schemaversion.NewMigrationError("dashboard is nil", 0, targetVersion)
|
||||
}
|
||||
|
||||
// wait for the migrator to be initialized
|
||||
<-m.ready
|
||||
|
||||
inputVersion := schemaversion.GetSchemaVersion(dash)
|
||||
dash["schemaVersion"] = inputVersion
|
||||
|
||||
@@ -16,7 +55,7 @@ func Migrate(dash map[string]any, targetVersion int) error {
|
||||
}
|
||||
|
||||
for nextVersion := inputVersion + 1; nextVersion <= targetVersion; nextVersion++ {
|
||||
if migration, ok := schemaversion.Migrations[nextVersion]; ok {
|
||||
if migration, ok := m.migrations[nextVersion]; ok {
|
||||
if err := migration(dash); err != nil {
|
||||
return schemaversion.NewMigrationError("migration failed", inputVersion, nextVersion)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,25 @@ func TestMigrate(t *testing.T) {
|
||||
files, err := os.ReadDir(INPUT_DIR)
|
||||
require.NoError(t, err)
|
||||
|
||||
migration.Initialize(&mockDataSourceInfoProvider{
|
||||
dataSourceInfo: []schemaversion.DataSourceInfo{
|
||||
{
|
||||
Default: true,
|
||||
UID: "default-ds-uid",
|
||||
ID: 1,
|
||||
Type: "prometheus",
|
||||
Name: "Default Test Datasource",
|
||||
},
|
||||
{
|
||||
UID: "non-default-test-ds-uid",
|
||||
ID: 2,
|
||||
Type: "loki",
|
||||
Name: "Non Default Test Datasource",
|
||||
APIVersion: "1",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
t.Run("minimum version check", func(t *testing.T) {
|
||||
err := migration.Migrate(map[string]interface{}{
|
||||
"schemaVersion": schemaversion.MIN_VERSION - 1,
|
||||
@@ -100,3 +119,13 @@ func load(t *testing.T, path string) (dash map[string]interface{}, inputVersion
|
||||
inputVersion, name = parseInputName(t, path)
|
||||
return dash, inputVersion, name
|
||||
}
|
||||
|
||||
var _ schemaversion.DataSourceInfoProvider = &mockDataSourceInfoProvider{}
|
||||
|
||||
type mockDataSourceInfoProvider struct {
|
||||
dataSourceInfo []schemaversion.DataSourceInfo
|
||||
}
|
||||
|
||||
func (m *mockDataSourceInfoProvider) GetDataSourceInfo() []schemaversion.DataSourceInfo {
|
||||
return m.dataSourceInfo
|
||||
}
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
package schemaversion
|
||||
|
||||
import "strconv"
|
||||
|
||||
type SchemaVersionMigrationFunc func(map[string]interface{}) error
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
MIN_VERSION = 36
|
||||
MIN_VERSION = 35
|
||||
LATEST_VERSION = 41
|
||||
)
|
||||
|
||||
var Migrations = map[int]SchemaVersionMigrationFunc{
|
||||
37: V37,
|
||||
38: V38,
|
||||
39: V39,
|
||||
40: V40,
|
||||
41: V41,
|
||||
type SchemaVersionMigrationFunc func(map[string]interface{}) error
|
||||
|
||||
type DataSourceInfo struct {
|
||||
Default bool
|
||||
UID string
|
||||
Name string
|
||||
Type string
|
||||
ID int64
|
||||
APIVersion string
|
||||
}
|
||||
|
||||
type DataSourceInfoProvider interface {
|
||||
GetDataSourceInfo() []DataSourceInfo
|
||||
}
|
||||
|
||||
func GetMigrations(dsInfoProvider DataSourceInfoProvider) map[int]SchemaVersionMigrationFunc {
|
||||
return map[int]SchemaVersionMigrationFunc{
|
||||
36: V36(dsInfoProvider),
|
||||
37: V37,
|
||||
38: V38,
|
||||
39: V39,
|
||||
40: V40,
|
||||
41: V41,
|
||||
}
|
||||
}
|
||||
|
||||
func GetSchemaVersion(dash map[string]interface{}) int {
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
package schemaversion
|
||||
|
||||
// V36 migrates dashboard datasource references from string names to UIDs.
|
||||
// This migration converts datasource references in annotations, template variables, and panels
|
||||
// from the old format (string name or UID) to the new format (object with uid, type, apiVersion).
|
||||
// This matches the frontend migration in DashboardMigrator.ts.
|
||||
func V36(dsInfo DataSourceInfoProvider) SchemaVersionMigrationFunc {
|
||||
datasources := dsInfo.GetDataSourceInfo()
|
||||
return func(dashboard map[string]interface{}) error {
|
||||
dashboard["schemaVersion"] = int(36)
|
||||
|
||||
migrateAnnotations(dashboard, datasources)
|
||||
migrateTemplateVariables(dashboard, datasources)
|
||||
migratePanels(dashboard, datasources)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// getDataSourceRef creates a datasource reference object with uid, type and optional apiVersion
|
||||
func getDataSourceRef(ds *DataSourceInfo) map[string]interface{} {
|
||||
if ds == nil {
|
||||
return nil
|
||||
}
|
||||
ref := map[string]interface{}{
|
||||
"uid": ds.UID,
|
||||
"type": ds.Type,
|
||||
}
|
||||
if ds.APIVersion != "" {
|
||||
ref["apiVersion"] = ds.APIVersion
|
||||
}
|
||||
return ref
|
||||
}
|
||||
|
||||
// getDefaultDSInstanceSettings returns the default datasource if one exists
|
||||
func getDefaultDSInstanceSettings(datasources []DataSourceInfo) *DataSourceInfo {
|
||||
for _, ds := range datasources {
|
||||
if ds.Default {
|
||||
return &DataSourceInfo{
|
||||
UID: ds.UID,
|
||||
Type: ds.Type,
|
||||
Name: ds.Name,
|
||||
APIVersion: ds.APIVersion,
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getInstanceSettings looks up a datasource by name or uid reference
|
||||
func getInstanceSettings(nameOrRef interface{}, datasources []DataSourceInfo) *DataSourceInfo {
|
||||
if nameOrRef == nil || nameOrRef == "default" {
|
||||
return getDefaultDSInstanceSettings(datasources)
|
||||
}
|
||||
|
||||
for _, ds := range datasources {
|
||||
if str, ok := nameOrRef.(string); ok {
|
||||
if str == ds.Name || str == ds.UID {
|
||||
return &DataSourceInfo{
|
||||
UID: ds.UID,
|
||||
Type: ds.Type,
|
||||
Name: ds.Name,
|
||||
APIVersion: ds.APIVersion,
|
||||
}
|
||||
}
|
||||
}
|
||||
if ref, ok := nameOrRef.(map[string]interface{}); ok {
|
||||
if uid, hasUID := ref["uid"]; hasUID {
|
||||
if uid == ds.UID {
|
||||
return &DataSourceInfo{
|
||||
UID: ds.UID,
|
||||
Type: ds.Type,
|
||||
Name: ds.Name,
|
||||
APIVersion: ds.APIVersion,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateDatasourceNameToRef converts a datasource name/uid string to a reference object
|
||||
// Matches the frontend migrateDatasourceNameToRef function in DashboardMigrator.ts
|
||||
func migrateDatasourceNameToRef(nameOrRef interface{}, options map[string]bool, datasources []DataSourceInfo) map[string]interface{} {
|
||||
if options["returnDefaultAsNull"] && (nameOrRef == nil || nameOrRef == "default") {
|
||||
return nil
|
||||
}
|
||||
|
||||
if dsRef, ok := nameOrRef.(map[string]interface{}); ok {
|
||||
if _, hasUID := dsRef["uid"]; hasUID {
|
||||
return dsRef
|
||||
}
|
||||
}
|
||||
|
||||
ds := getInstanceSettings(nameOrRef, datasources)
|
||||
if ds != nil {
|
||||
return getDataSourceRef(ds)
|
||||
}
|
||||
|
||||
if dsName, ok := nameOrRef.(string); ok && dsName != "" {
|
||||
return map[string]interface{}{
|
||||
"uid": dsName,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// migrateAnnotations updates datasource references in dashboard annotations
|
||||
func migrateAnnotations(dashboard map[string]interface{}, datasources []DataSourceInfo) {
|
||||
annotations, ok := dashboard["annotations"].(map[string]interface{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
list, ok := annotations["list"].([]interface{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, query := range list {
|
||||
queryMap, ok := query.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if ds, exists := queryMap["datasource"]; exists {
|
||||
queryMap["datasource"] = migrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// migrateTemplateVariables updates datasource references in dashboard variables
|
||||
func migrateTemplateVariables(dashboard map[string]interface{}, datasources []DataSourceInfo) {
|
||||
templating, ok := dashboard["templating"].(map[string]interface{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
list, ok := templating["list"].([]interface{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, variable := range list {
|
||||
varMap, ok := variable.(map[string]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if varType, ok := varMap["type"].(string); ok && varType == "query" {
|
||||
if ds, exists := varMap["datasource"]; exists {
|
||||
varMap["datasource"] = migrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// migratePanels updates datasource references in dashboard panels
|
||||
func migratePanels(dashboard map[string]interface{}, datasources []DataSourceInfo) {
|
||||
if panels, ok := dashboard["panels"].([]interface{}); ok {
|
||||
for _, panel := range panels {
|
||||
if panelMap, ok := panel.(map[string]interface{}); ok {
|
||||
migratePanelDatasources(panelMap, datasources)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// migratePanelDatasources updates datasource references in a single panel and its targets
|
||||
func migratePanelDatasources(panelMap map[string]interface{}, datasources []DataSourceInfo) {
|
||||
if targets, hasTargets := panelMap["targets"].([]interface{}); hasTargets && len(targets) > 0 {
|
||||
panelDataSourceWasDefault := false
|
||||
|
||||
// Handle panel datasource
|
||||
if ds, exists := panelMap["datasource"]; exists {
|
||||
if ds == nil {
|
||||
defaultDS := getDefaultDSInstanceSettings(datasources)
|
||||
panelMap["datasource"] = getDataSourceRef(defaultDS)
|
||||
panelDataSourceWasDefault = true
|
||||
} else {
|
||||
panelMap["datasource"] = migrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": true}, datasources)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle target datasources
|
||||
for _, target := range targets {
|
||||
if targetMap, ok := target.(map[string]interface{}); ok {
|
||||
ds, exists := targetMap["datasource"]
|
||||
|
||||
// Check if target datasource is null or has no uid
|
||||
isNullOrNoUID := !exists || ds == nil
|
||||
if !isNullOrNoUID {
|
||||
if dsMap, ok := ds.(map[string]interface{}); ok {
|
||||
if uid, hasUID := dsMap["uid"]; !hasUID || uid == nil {
|
||||
isNullOrNoUID = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isNullOrNoUID {
|
||||
// If panel doesn't have mixed datasource, use panel's datasource
|
||||
if panelDS, ok := panelMap["datasource"].(map[string]interface{}); ok {
|
||||
if uid, hasUID := panelDS["uid"].(string); hasUID && uid != "-- Mixed --" {
|
||||
targetMap["datasource"] = panelDS
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Migrate existing target datasource
|
||||
targetDS := migrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
|
||||
targetMap["datasource"] = targetDS
|
||||
}
|
||||
|
||||
// Update panel datasource if it was default and target is not an expression
|
||||
if panelDataSourceWasDefault {
|
||||
if targetDS, ok := targetMap["datasource"].(map[string]interface{}); ok {
|
||||
if uid, ok := targetDS["uid"].(string); ok && uid != "__expr__" {
|
||||
panelMap["datasource"] = targetDS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,571 @@
|
||||
package schemaversion_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
|
||||
)
|
||||
|
||||
func TestV36(t *testing.T) {
|
||||
// Pass the mock provider to V36
|
||||
migration := schemaversion.V36(testutil.GetTestProvider())
|
||||
|
||||
tests := []migrationTestCase{
|
||||
{
|
||||
name: "dashboard with no datasources",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with null datasource should get default datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": nil,
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with mixed datasources should preserve target datasources",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"uid": "-- Mixed --",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": "other-ds",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"uid": "-- Mixed --",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with specific datasource should apply to targets without datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Default",
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": nil,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"uid": nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with annotations using default datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Default",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with annotations using non-default datasource by UID",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "other-ds",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with annotations using non-default datasource by name",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"annotations": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with template variables using default datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with template variables using non-default datasource by UID",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": "other-ds",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with template variables using non-default datasource by name",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"templating": map[string]interface{}{
|
||||
"list": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "query",
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panels using default datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Default",
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Default",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panels using non-default datasource by UID",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "other-ds",
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "other-ds",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with panels using non-default datasource by name",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dashboard with mixed panel and target datasources",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Default",
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": "other-ds",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with null datasource and expression queries should get default datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": nil,
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"refId": "A",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"refId": "B",
|
||||
"datasource": map[string]interface{}{
|
||||
"uid": "__expr__",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"refId": "A",
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds",
|
||||
"apiVersion": "v1",
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"refId": "B",
|
||||
"datasource": map[string]interface{}{
|
||||
"uid": "__expr__",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "panel with null datasource should inherit from query datasource",
|
||||
input: map[string]interface{}{
|
||||
"schemaVersion": 35,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": nil,
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": "Elasticsearch",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"schemaVersion": 36,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
"targets": []interface{}{
|
||||
map[string]interface{}{
|
||||
"datasource": map[string]interface{}{
|
||||
"type": "elasticsearch",
|
||||
"uid": "other-ds",
|
||||
"apiVersion": "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
runMigrationTests(t, tests, migration)
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": "Non Default Test Datasource",
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": "non-default-test-ds-uid",
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": "default",
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": "non-existing-ds",
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"type": "graph",
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"id": 1,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"legend": true
|
||||
},
|
||||
"title": "Boolean Legend True",
|
||||
"id": 2,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"legend": false
|
||||
},
|
||||
"title": "Boolean Legend False",
|
||||
"id": 3,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode",
|
||||
"id": 4,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"legend": {
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False",
|
||||
"id": 5,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table"
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend",
|
||||
"id": 6,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": "default",
|
||||
"title": "Mixed Datasources Panel",
|
||||
"id": 7,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": "non-default-test-ds-uid"
|
||||
},
|
||||
{
|
||||
"datasource": "Non Default Test Datasource"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"title": "Mixed Panel with Mixed Targets",
|
||||
"id": 8,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": "non-default-test-ds-uid"
|
||||
},
|
||||
{
|
||||
"datasource": "Non Default Test Datasource"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": "non-existing-ds",
|
||||
"title": "Non-existing Datasource Panel",
|
||||
"id": 9,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": "non-existing-ds"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": true,
|
||||
"schemaVersion": 35,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"type": "query",
|
||||
"datasource": "default",
|
||||
"name": "default_var"
|
||||
},
|
||||
{
|
||||
"type": "query",
|
||||
"datasource": "Non Default Test Datasource",
|
||||
"name": "es_var_by_name"
|
||||
},
|
||||
{
|
||||
"type": "query",
|
||||
"datasource": "non-default-test-ds-uid",
|
||||
"name": "es_var_by_uid"
|
||||
},
|
||||
{
|
||||
"type": "query",
|
||||
"datasource": null,
|
||||
"name": "null_var"
|
||||
},
|
||||
{
|
||||
"type": "query",
|
||||
"datasource": "non-existing-ds",
|
||||
"name": "non_existing_var"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": true
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": false
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "hidden"
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table"
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": true,
|
||||
"schemaVersion": 36,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": true,
|
||||
"schemaVersion": 37,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": true,
|
||||
"schemaVersion": 38,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": true,
|
||||
"schemaVersion": 39,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": "",
|
||||
"schemaVersion": 40,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations \u0026 Alerts",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by Name",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Annotation by UID",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Default Annotation",
|
||||
"type": "dashboard"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"enable": true,
|
||||
"name": "Test Non-existing Annotation",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {},
|
||||
"title": "No Legend Config",
|
||||
"type": "graph"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend True"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Boolean Legend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "Hidden DisplayMode"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"showLegend": false
|
||||
}
|
||||
},
|
||||
"title": "ShowLegend False"
|
||||
},
|
||||
{
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"showLegend": true
|
||||
}
|
||||
},
|
||||
"title": "Visible Legend"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
},
|
||||
"id": 7,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Datasources Panel"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "-- Mixed --"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Mixed Panel with Mixed Targets"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
},
|
||||
"id": 9,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Non-existing Datasource Panel"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": "",
|
||||
"schemaVersion": 41,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "default_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_name",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "1",
|
||||
"type": "loki",
|
||||
"uid": "non-default-test-ds-uid"
|
||||
},
|
||||
"name": "es_var_by_uid",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"name": "null_var",
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "non-existing-ds"
|
||||
},
|
||||
"name": "non_existing_var",
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "utc",
|
||||
"title": "New dashboard",
|
||||
"version": 0,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package testutil
|
||||
|
||||
import "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
|
||||
type TestDataSourceProvider struct{}
|
||||
|
||||
func (m *TestDataSourceProvider) GetDataSourceInfo() []schemaversion.DataSourceInfo {
|
||||
return []schemaversion.DataSourceInfo{
|
||||
{
|
||||
Default: true,
|
||||
UID: "default-ds",
|
||||
Type: "prometheus",
|
||||
APIVersion: "v1",
|
||||
Name: "Default",
|
||||
ID: 1,
|
||||
},
|
||||
{
|
||||
Default: false,
|
||||
UID: "other-ds",
|
||||
Type: "elasticsearch",
|
||||
APIVersion: "v2",
|
||||
Name: "Elasticsearch",
|
||||
ID: 2,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetTestProvider returns a singleton instance of the test provider
|
||||
func GetTestProvider() *TestDataSourceProvider {
|
||||
return &TestDataSourceProvider{}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
)
|
||||
|
||||
type datasourceInfoProvider struct {
|
||||
datasourceService datasources.DataSourceService
|
||||
}
|
||||
|
||||
func (d *datasourceInfoProvider) GetDataSourceInfo() []schemaversion.DataSourceInfo {
|
||||
query := datasources.GetAllDataSourcesQuery{}
|
||||
dataSources, err := d.datasourceService.GetAllDataSources(context.Background(), &query)
|
||||
|
||||
if err != nil {
|
||||
return []schemaversion.DataSourceInfo{}
|
||||
}
|
||||
|
||||
out := make([]schemaversion.DataSourceInfo, 0, len(dataSources))
|
||||
|
||||
for _, ds := range dataSources {
|
||||
out = append(out, schemaversion.DataSourceInfo{
|
||||
Name: ds.Name,
|
||||
UID: ds.UID,
|
||||
ID: ds.ID,
|
||||
Type: ds.Type,
|
||||
Default: ds.IsDefault,
|
||||
APIVersion: ds.APIVersion,
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
@@ -13,13 +13,16 @@ import (
|
||||
dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
)
|
||||
|
||||
func TestDashboardAPIBuilder_Mutate(t *testing.T) {
|
||||
migration.Initialize(testutil.GetTestProvider())
|
||||
tests := []struct {
|
||||
name string
|
||||
inputObj runtime.Object
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
||||
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
||||
dashv2 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration"
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/conversion"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/librarypanels"
|
||||
@@ -98,6 +100,7 @@ func RegisterAPIService(
|
||||
apiregistration builder.APIRegistrar,
|
||||
dashboardService dashboards.DashboardService,
|
||||
provisioningDashboardService dashboards.DashboardProvisioningService,
|
||||
datasourceService datasources.DataSourceService,
|
||||
dashboardPermissions dashboards.PermissionsRegistrationService,
|
||||
accessControl accesscontrol.AccessControl,
|
||||
accessClient claims.AccessClient,
|
||||
@@ -144,6 +147,9 @@ func RegisterAPIService(
|
||||
},
|
||||
reg: reg,
|
||||
}
|
||||
migration.Initialize(&datasourceInfoProvider{
|
||||
datasourceService: datasourceService,
|
||||
})
|
||||
apiregistration.RegisterAPI(builder)
|
||||
return builder
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user