mirror of https://github.com/grafana/grafana.git
v13 should be no-op
This commit is contained in:
parent
5f105e6aea
commit
aec271036b
|
@ -1,822 +1,11 @@
|
||||||
package schemaversion
|
package schemaversion
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
// Default field config structure
|
// V13 is a no-op migration
|
||||||
func getDefaultFieldConfig() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{},
|
|
||||||
"overrides": []interface{}{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default color mode for field config
|
|
||||||
func getDefaultColorMode() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default custom properties for field config
|
|
||||||
func getDefaultCustomProperties() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "linear",
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default mappings and thresholds
|
|
||||||
func getDefaultMappings() []interface{} {
|
|
||||||
return []interface{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDefaultThresholds() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default legend options
|
|
||||||
func getDefaultLegendOptions() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default tooltip options
|
|
||||||
func getDefaultTooltipOptions() map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default threshold steps for timeseries
|
|
||||||
func getDefaultThresholdSteps() []interface{} {
|
|
||||||
return []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": interface{}(nil), // null in JSON, represents -Infinity
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// V13 migrates graph panels to timeseries panels with complete field config and options conversion.
|
|
||||||
// This migration replicates the complete graphPanelChangedHandler logic from the frontend, including:
|
|
||||||
// - Panel type conversion from 'graph' to 'timeseries'
|
|
||||||
// - Complete field config conversion (y-axis, series overrides, thresholds, etc.)
|
|
||||||
// - Options conversion (legend, tooltip, etc.)
|
|
||||||
// - Time regions conversion to annotations
|
|
||||||
func V13(_ context.Context, dashboard map[string]interface{}) error {
|
func V13(_ context.Context, dashboard map[string]interface{}) error {
|
||||||
dashboard["schemaVersion"] = 13
|
dashboard["schemaVersion"] = 13
|
||||||
|
|
||||||
panels, ok := dashboard["panels"].([]interface{})
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range panels {
|
|
||||||
panel, ok := p.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only process graph panels (convert them to timeseries)
|
|
||||||
if panel["type"] != "graph" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert panel type from 'graph' to 'timeseries'
|
|
||||||
panel["type"] = "timeseries"
|
|
||||||
|
|
||||||
// Convert complete field config and options (replicating graphPanelChangedHandler)
|
|
||||||
convertFieldConfig(panel)
|
|
||||||
convertOptions(panel)
|
|
||||||
convertSeriesOverrides(panel)
|
|
||||||
convertThresholds(panel)
|
|
||||||
convertTimeRegions(panel)
|
|
||||||
|
|
||||||
// Clean up old graph-specific properties
|
|
||||||
cleanupGraphProperties(panel)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertFieldConfig converts graph field config to timeseries format
|
|
||||||
func convertFieldConfig(panel map[string]interface{}) {
|
|
||||||
// Initialize fieldConfig if it doesn't exist
|
|
||||||
if panel["fieldConfig"] == nil {
|
|
||||||
panel["fieldConfig"] = getDefaultFieldConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defaults, ok := fieldConfig["defaults"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default color mode
|
|
||||||
defaults["color"] = getDefaultColorMode()
|
|
||||||
|
|
||||||
// Set default custom properties
|
|
||||||
defaults["custom"] = getDefaultCustomProperties()
|
|
||||||
|
|
||||||
// Set default mappings and thresholds
|
|
||||||
defaults["mappings"] = getDefaultMappings()
|
|
||||||
defaults["thresholds"] = getDefaultThresholds()
|
|
||||||
|
|
||||||
// Convert y-axis settings to field config
|
|
||||||
if yaxes, ok := panel["yaxes"].([]interface{}); ok && len(yaxes) > 0 {
|
|
||||||
if y1, ok := yaxes[0].(map[string]interface{}); ok {
|
|
||||||
// Convert y-axis properties to field config defaults
|
|
||||||
if unit, ok := y1["format"].(string); ok {
|
|
||||||
defaults["unit"] = unit
|
|
||||||
}
|
|
||||||
if decimals, ok := y1["decimals"]; ok {
|
|
||||||
defaults["decimals"] = decimals
|
|
||||||
}
|
|
||||||
if min, ok := y1["min"]; ok {
|
|
||||||
defaults["min"] = min
|
|
||||||
}
|
|
||||||
if max, ok := y1["max"]; ok {
|
|
||||||
defaults["max"] = max
|
|
||||||
}
|
|
||||||
if label, ok := y1["label"].(string); ok {
|
|
||||||
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
|
|
||||||
custom["axisLabel"] = label
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if show, ok := y1["show"].(bool); ok {
|
|
||||||
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
|
|
||||||
if show {
|
|
||||||
custom["axisPlacement"] = "auto"
|
|
||||||
} else {
|
|
||||||
custom["axisPlacement"] = "hidden"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if logBase, ok := y1["logBase"].(float64); ok && (logBase == 2 || logBase == 10) {
|
|
||||||
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
|
|
||||||
custom["scaleDistribution"] = map[string]interface{}{
|
|
||||||
"type": "log",
|
|
||||||
"log": logBase,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up old y-axis properties
|
|
||||||
delete(panel, "yaxes")
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertOptions converts graph options to timeseries format
|
|
||||||
func convertOptions(panel map[string]interface{}) {
|
|
||||||
// Initialize options if it doesn't exist
|
|
||||||
if panel["options"] == nil {
|
|
||||||
panel["options"] = map[string]interface{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
options, ok := panel["options"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default legend options
|
|
||||||
options["legend"] = getDefaultLegendOptions()
|
|
||||||
|
|
||||||
// Set default tooltip options
|
|
||||||
options["tooltip"] = getDefaultTooltipOptions()
|
|
||||||
|
|
||||||
// Convert legend settings from old graph format
|
|
||||||
if legend, ok := panel["legend"].(map[string]interface{}); ok {
|
|
||||||
legendOptions, ok := options["legend"].(map[string]interface{})
|
|
||||||
if ok {
|
|
||||||
if show, ok := legend["show"].(bool); ok && !show {
|
|
||||||
legendOptions["showLegend"] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if alignAsTable, ok := legend["alignAsTable"].(bool); ok && alignAsTable {
|
|
||||||
legendOptions["displayMode"] = "table"
|
|
||||||
}
|
|
||||||
|
|
||||||
if rightSide, ok := legend["rightSide"].(bool); ok && rightSide {
|
|
||||||
legendOptions["placement"] = "right"
|
|
||||||
}
|
|
||||||
|
|
||||||
if sideWidth, ok := legend["sideWidth"]; ok {
|
|
||||||
legendOptions["width"] = sideWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(panel, "legend")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert tooltip settings from old graph format
|
|
||||||
if tooltip, ok := panel["tooltip"].(map[string]interface{}); ok {
|
|
||||||
tooltipOptions, ok := options["tooltip"].(map[string]interface{})
|
|
||||||
if ok {
|
|
||||||
if shared, ok := tooltip["shared"].(bool); ok {
|
|
||||||
if shared {
|
|
||||||
tooltipOptions["mode"] = "multi"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sort, ok := tooltip["sort"]; ok && tooltipOptions["mode"] == "multi" {
|
|
||||||
switch sort {
|
|
||||||
case float64(1):
|
|
||||||
tooltipOptions["sort"] = "asc"
|
|
||||||
case float64(2):
|
|
||||||
tooltipOptions["sort"] = "desc"
|
|
||||||
default:
|
|
||||||
tooltipOptions["sort"] = "none"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(panel, "tooltip")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertSeriesOverrides converts graph series overrides to field config overrides
|
|
||||||
func convertSeriesOverrides(panel map[string]interface{}) {
|
|
||||||
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
overrides, ok := fieldConfig["overrides"].([]interface{})
|
|
||||||
if !ok {
|
|
||||||
overrides = []interface{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert aliasColors to overrides
|
|
||||||
overrides = convertAliasColors(panel, overrides)
|
|
||||||
|
|
||||||
// Convert seriesOverrides to field config overrides
|
|
||||||
overrides = convertSeriesOverridesToFieldConfig(panel, overrides)
|
|
||||||
|
|
||||||
fieldConfig["overrides"] = overrides
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertAliasColors(panel map[string]interface{}, overrides []interface{}) []interface{} {
|
|
||||||
if aliasColors, ok := panel["aliasColors"].(map[string]interface{}); ok {
|
|
||||||
for alias, color := range aliasColors {
|
|
||||||
if colorStr, ok := color.(string); ok && colorStr != "" {
|
|
||||||
override := createColorOverride(alias, colorStr)
|
|
||||||
overrides = append(overrides, override)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return overrides
|
|
||||||
}
|
|
||||||
|
|
||||||
func createColorOverride(alias, colorStr string) map[string]interface{} {
|
|
||||||
return map[string]interface{}{
|
|
||||||
"matcher": map[string]interface{}{
|
|
||||||
"id": "byName",
|
|
||||||
"options": alias,
|
|
||||||
},
|
|
||||||
"properties": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"id": "color",
|
|
||||||
"value": map[string]interface{}{
|
|
||||||
"mode": "fixed",
|
|
||||||
"fixedColor": colorStr,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertSeriesOverridesToFieldConfig(panel map[string]interface{}, overrides []interface{}) []interface{} {
|
|
||||||
if seriesOverrides, ok := panel["seriesOverrides"].([]interface{}); ok {
|
|
||||||
for _, seriesOverride := range seriesOverrides {
|
|
||||||
if seriesMap, ok := seriesOverride.(map[string]interface{}); ok {
|
|
||||||
override := createSeriesOverride(seriesMap)
|
|
||||||
if override != nil {
|
|
||||||
overrides = append(overrides, override)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return overrides
|
|
||||||
}
|
|
||||||
|
|
||||||
func createSeriesOverride(seriesMap map[string]interface{}) map[string]interface{} {
|
|
||||||
alias, hasAlias := seriesMap["alias"].(string)
|
|
||||||
if !hasAlias {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
aliasIsRegex := isAliasRegex(alias)
|
|
||||||
properties := extractSeriesProperties(seriesMap)
|
|
||||||
|
|
||||||
if len(properties) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]interface{}{
|
|
||||||
"matcher": map[string]interface{}{
|
|
||||||
"id": getMatcherId(aliasIsRegex),
|
|
||||||
"options": alias,
|
|
||||||
},
|
|
||||||
"properties": properties,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isAliasRegex(alias string) bool {
|
|
||||||
if len(alias) <= 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
firstChar := alias[0]
|
|
||||||
lastChar := alias[len(alias)-1]
|
|
||||||
|
|
||||||
regexChars := []byte{'/', '~', '@', ';', '%', '#', '\''}
|
|
||||||
for _, char := range regexChars {
|
|
||||||
if firstChar == char && firstChar == lastChar {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint:gocyclo
|
|
||||||
func extractSeriesProperties(seriesMap map[string]interface{}) []interface{} {
|
|
||||||
properties := []interface{}{}
|
|
||||||
|
|
||||||
// Fill opacity
|
|
||||||
if fill, ok := seriesMap["fill"]; ok {
|
|
||||||
if fillNum, ok := fill.(float64); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.fillOpacity",
|
|
||||||
"value": fillNum * 10, // was 0-10, new is 0-100
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill below to
|
|
||||||
if fillBelowTo, ok := seriesMap["fillBelowTo"]; ok {
|
|
||||||
if fillBelowToVal, ok := fillBelowTo.(float64); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.fillBelowTo",
|
|
||||||
"value": fillBelowToVal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill gradient
|
|
||||||
if fillGradient, ok := seriesMap["fillGradient"]; ok {
|
|
||||||
if fillGradientVal, ok := fillGradient.(float64); ok && fillGradientVal > 0 {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.fillGradient",
|
|
||||||
"value": "opacity",
|
|
||||||
})
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.fillOpacity",
|
|
||||||
"value": fillGradientVal * 10,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show points
|
|
||||||
if points, ok := seriesMap["points"]; ok {
|
|
||||||
if pointsBool, ok := points.(bool); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.showPoints",
|
|
||||||
"value": pointsBool,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw style (bars)
|
|
||||||
if bars, ok := seriesMap["bars"]; ok {
|
|
||||||
if barsBool, ok := bars.(bool); ok {
|
|
||||||
if barsBool {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.drawStyle",
|
|
||||||
"value": "bars",
|
|
||||||
})
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.fillOpacity",
|
|
||||||
"value": 100,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.drawStyle",
|
|
||||||
"value": "line",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw style (lines)
|
|
||||||
if lines, ok := seriesMap["lines"]; ok {
|
|
||||||
if linesBool, ok := lines.(bool); ok {
|
|
||||||
if linesBool {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.drawStyle",
|
|
||||||
"value": "line",
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.lineWidth",
|
|
||||||
"value": 0,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line width
|
|
||||||
if linewidth, ok := seriesMap["linewidth"]; ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.lineWidth",
|
|
||||||
"value": linewidth,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point radius
|
|
||||||
if pointradius, ok := seriesMap["pointradius"]; ok {
|
|
||||||
if radius, ok := pointradius.(float64); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.pointSize",
|
|
||||||
"value": 2 + radius*2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dash length
|
|
||||||
if dashLength, ok := seriesMap["dashLength"]; ok {
|
|
||||||
if dashLengthVal, ok := dashLength.(float64); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.dashLength",
|
|
||||||
"value": dashLengthVal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Space length
|
|
||||||
if spaceLength, ok := seriesMap["spaceLength"]; ok {
|
|
||||||
if spaceLengthVal, ok := spaceLength.(float64); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.spaceLength",
|
|
||||||
"value": spaceLengthVal,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dashes
|
|
||||||
if dashes, ok := seriesMap["dashes"]; ok {
|
|
||||||
if dashesBool, ok := dashes.(bool); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.lineStyle",
|
|
||||||
"value": map[string]interface{}{
|
|
||||||
"fill": func() string {
|
|
||||||
if dashesBool {
|
|
||||||
return "dash"
|
|
||||||
}
|
|
||||||
return "solid"
|
|
||||||
}(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stack
|
|
||||||
if stack, ok := seriesMap["stack"]; ok {
|
|
||||||
if stackStr, ok := stack.(string); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.stacking",
|
|
||||||
"value": stackStr,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform
|
|
||||||
if transform, ok := seriesMap["transform"]; ok {
|
|
||||||
if transformStr, ok := transform.(string); ok {
|
|
||||||
value := "constant"
|
|
||||||
if transformStr == "negative-Y" {
|
|
||||||
value = "negative-Y"
|
|
||||||
}
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "custom.transform",
|
|
||||||
"value": value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color
|
|
||||||
if color, ok := seriesMap["color"]; ok {
|
|
||||||
if colorStr, ok := color.(string); ok {
|
|
||||||
properties = append(properties, map[string]interface{}{
|
|
||||||
"id": "color",
|
|
||||||
"value": map[string]interface{}{
|
|
||||||
"mode": "fixed",
|
|
||||||
"fixedColor": colorStr,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return properties
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertThresholds converts graph thresholds to the new step-based threshold system
|
|
||||||
func convertThresholds(panel map[string]interface{}) {
|
|
||||||
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
defaults, ok := fieldConfig["defaults"].(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if oldThresholds, ok := panel["thresholds"].([]interface{}); ok && len(oldThresholds) > 0 {
|
|
||||||
convertExistingThresholds(defaults, oldThresholds)
|
|
||||||
} else {
|
|
||||||
setDefaultThresholds(defaults)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up old thresholds
|
|
||||||
delete(panel, "thresholds")
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertExistingThresholds(defaults map[string]interface{}, oldThresholds []interface{}) {
|
|
||||||
area, line := extractThresholdStyles(oldThresholds)
|
|
||||||
|
|
||||||
// Sort thresholds by value
|
|
||||||
sortedThresholds := sortThresholdsByValue(oldThresholds)
|
|
||||||
|
|
||||||
// Convert to step-based thresholds
|
|
||||||
steps := buildThresholdSteps(sortedThresholds)
|
|
||||||
|
|
||||||
// Add base transparent step if needed
|
|
||||||
steps = addBaseTransparentStep(steps)
|
|
||||||
|
|
||||||
// Set threshold style mode
|
|
||||||
setThresholdDisplayMode(defaults, area, line)
|
|
||||||
|
|
||||||
// Set the new thresholds
|
|
||||||
defaults["thresholds"] = map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": steps,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractThresholdStyles(oldThresholds []interface{}) (bool, bool) {
|
|
||||||
area, line := false, false
|
|
||||||
for _, t := range oldThresholds {
|
|
||||||
if threshold, ok := t.(map[string]interface{}); ok {
|
|
||||||
if !area {
|
|
||||||
if fill, ok := threshold["fill"].(bool); ok && fill {
|
|
||||||
area = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !line {
|
|
||||||
if lineStyle, ok := threshold["line"].(bool); ok && lineStyle {
|
|
||||||
line = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if area && line {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return area, line
|
|
||||||
}
|
|
||||||
|
|
||||||
func sortThresholdsByValue(oldThresholds []interface{}) []map[string]interface{} {
|
|
||||||
sortedThresholds := make([]map[string]interface{}, len(oldThresholds))
|
|
||||||
for i, t := range oldThresholds {
|
|
||||||
if threshold, ok := t.(map[string]interface{}); ok {
|
|
||||||
sortedThresholds[i] = threshold
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by value
|
|
||||||
for i := 0; i < len(sortedThresholds)-1; i++ {
|
|
||||||
for j := i + 1; j < len(sortedThresholds); j++ {
|
|
||||||
if val1, ok1 := sortedThresholds[i]["value"].(float64); ok1 {
|
|
||||||
if val2, ok2 := sortedThresholds[j]["value"].(float64); ok2 {
|
|
||||||
if val1 > val2 {
|
|
||||||
sortedThresholds[i], sortedThresholds[j] = sortedThresholds[j], sortedThresholds[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sortedThresholds
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildThresholdSteps(sortedThresholds []map[string]interface{}) []interface{} {
|
|
||||||
steps := []interface{}{}
|
|
||||||
|
|
||||||
for i, threshold := range sortedThresholds {
|
|
||||||
op, _ := threshold["op"].(string)
|
|
||||||
value, _ := threshold["value"].(float64)
|
|
||||||
|
|
||||||
switch op {
|
|
||||||
case "gt":
|
|
||||||
steps = append(steps, map[string]interface{}{
|
|
||||||
"value": value,
|
|
||||||
"color": getThresholdColor(threshold),
|
|
||||||
})
|
|
||||||
case "lt":
|
|
||||||
steps = appendLtThresholdSteps(steps, i, threshold, value, sortedThresholds)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return steps
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendLtThresholdSteps(steps []interface{}, index int, threshold map[string]interface{}, value float64, sortedThresholds []map[string]interface{}) []interface{} {
|
|
||||||
// Add base transparent step for first lt threshold
|
|
||||||
if index == 0 {
|
|
||||||
steps = append(steps, map[string]interface{}{
|
|
||||||
"value": interface{}(nil), // -Infinity equivalent
|
|
||||||
"color": "transparent",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if next threshold is gt and there's a gap
|
|
||||||
if index+1 < len(sortedThresholds) {
|
|
||||||
nextThreshold := sortedThresholds[index+1]
|
|
||||||
if nextOp, ok := nextThreshold["op"].(string); ok && nextOp == "gt" {
|
|
||||||
if nextValue, ok := nextThreshold["value"].(float64); ok && nextValue > value {
|
|
||||||
steps = append(steps, map[string]interface{}{
|
|
||||||
"value": value,
|
|
||||||
"color": "transparent",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return steps
|
|
||||||
}
|
|
||||||
|
|
||||||
func addBaseTransparentStep(steps []interface{}) []interface{} {
|
|
||||||
if len(steps) == 0 {
|
|
||||||
return steps
|
|
||||||
}
|
|
||||||
|
|
||||||
if firstStep, ok := steps[0].(map[string]interface{}); ok {
|
|
||||||
if firstValue, ok := firstStep["value"].(float64); ok && firstValue != -1e308 {
|
|
||||||
steps = append([]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "transparent",
|
|
||||||
"value": interface{}(nil),
|
|
||||||
},
|
|
||||||
}, steps...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return steps
|
|
||||||
}
|
|
||||||
|
|
||||||
func setThresholdDisplayMode(defaults map[string]interface{}, area, line bool) {
|
|
||||||
displayMode := determineDisplayMode(area, line)
|
|
||||||
|
|
||||||
if defaults["custom"] == nil {
|
|
||||||
defaults["custom"] = map[string]interface{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
|
|
||||||
custom["thresholdsStyle"] = map[string]interface{}{
|
|
||||||
"mode": displayMode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func determineDisplayMode(area, line bool) string {
|
|
||||||
if area && line {
|
|
||||||
return "line+area"
|
|
||||||
} else if area {
|
|
||||||
return "area"
|
|
||||||
} else if line {
|
|
||||||
return "line"
|
|
||||||
}
|
|
||||||
return "line"
|
|
||||||
}
|
|
||||||
|
|
||||||
func setDefaultThresholds(defaults map[string]interface{}) {
|
|
||||||
if defaults["custom"] == nil {
|
|
||||||
defaults["custom"] = map[string]interface{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if custom, ok := defaults["custom"].(map[string]interface{}); ok {
|
|
||||||
custom["thresholdsStyle"] = map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add default threshold steps that match the timeseries plugin defaults
|
|
||||||
defaults["thresholds"] = map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": getDefaultThresholdSteps(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertTimeRegions converts graph time regions to annotations
|
|
||||||
func convertTimeRegions(panel map[string]interface{}) {
|
|
||||||
// This is a simplified version - in the real frontend, time regions get converted to
|
|
||||||
// dashboard annotations, but for the backend migration we'll just clean them up
|
|
||||||
delete(panel, "timeRegions")
|
|
||||||
}
|
|
||||||
|
|
||||||
// getThresholdColor extracts the color from a threshold object
|
|
||||||
func getThresholdColor(threshold map[string]interface{}) string {
|
|
||||||
if colorMode, ok := threshold["colorMode"].(string); ok {
|
|
||||||
switch colorMode {
|
|
||||||
case "critical":
|
|
||||||
return "red"
|
|
||||||
case "warning":
|
|
||||||
return "orange"
|
|
||||||
case "custom":
|
|
||||||
if fillColor, ok := threshold["fillColor"].(string); ok && fillColor != "" {
|
|
||||||
return fillColor
|
|
||||||
}
|
|
||||||
if lineColor, ok := threshold["lineColor"].(string); ok && lineColor != "" {
|
|
||||||
return lineColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "red"
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanupGraphProperties removes old graph-specific properties
|
|
||||||
func cleanupGraphProperties(panel map[string]interface{}) {
|
|
||||||
// Remove old graph-specific properties that are no longer needed
|
|
||||||
delete(panel, "aliasColors")
|
|
||||||
delete(panel, "seriesOverrides")
|
|
||||||
delete(panel, "dashes")
|
|
||||||
delete(panel, "dashLength")
|
|
||||||
delete(panel, "spaceLength")
|
|
||||||
delete(panel, "nullPointMode")
|
|
||||||
delete(panel, "steppedLine")
|
|
||||||
delete(panel, "points")
|
|
||||||
delete(panel, "bars")
|
|
||||||
delete(panel, "lines")
|
|
||||||
delete(panel, "stack")
|
|
||||||
delete(panel, "percentage")
|
|
||||||
delete(panel, "legend")
|
|
||||||
delete(panel, "tooltip")
|
|
||||||
delete(panel, "yaxes")
|
|
||||||
delete(panel, "xaxis")
|
|
||||||
delete(panel, "grid")
|
|
||||||
delete(panel, "thresholds")
|
|
||||||
delete(panel, "timeRegions")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMatcherId(aliasIsRegex bool) string {
|
|
||||||
if aliasIsRegex {
|
|
||||||
return "byRegexp"
|
|
||||||
}
|
|
||||||
return "byName"
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,565 +9,30 @@ import (
|
||||||
func TestV13(t *testing.T) {
|
func TestV13(t *testing.T) {
|
||||||
tests := []migrationTestCase{
|
tests := []migrationTestCase{
|
||||||
{
|
{
|
||||||
name: "graph panel with grid thresholds gets converted to timeseries with step-based thresholds",
|
name: "v13 no-op migration, updates schema version only",
|
||||||
input: map[string]interface{}{
|
input: map[string]interface{}{
|
||||||
"title": "V13 Graph Panel Line Thresholds Test",
|
"title": "V13 No-Op Migration Test Dashboard",
|
||||||
"schemaVersion": 12,
|
"schemaVersion": 12,
|
||||||
"panels": []interface{}{
|
"panels": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"type": "graph",
|
"type": "graph",
|
||||||
|
"title": "Panel remains unchanged",
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"grid": map[string]interface{}{
|
|
||||||
"threshold1": 200,
|
|
||||||
"threshold2": 400,
|
|
||||||
"threshold1Color": "yellow",
|
|
||||||
"threshold2Color": "red",
|
|
||||||
"thresholdLine": true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: map[string]interface{}{
|
expected: map[string]interface{}{
|
||||||
"title": "V13 Graph Panel Line Thresholds Test",
|
"title": "V13 No-Op Migration Test Dashboard",
|
||||||
"schemaVersion": 13,
|
"schemaVersion": 13,
|
||||||
"panels": []interface{}{
|
"panels": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"type": "timeseries",
|
"type": "graph",
|
||||||
|
"title": "Panel remains unchanged",
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"fieldConfig": map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{
|
|
||||||
"color": map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
},
|
},
|
||||||
"custom": map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
},
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "linear",
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"mappings": []interface{}{},
|
|
||||||
"thresholds": map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": nil,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": []interface{}{},
|
|
||||||
},
|
|
||||||
"options": map[string]interface{}{
|
|
||||||
"legend": map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
},
|
|
||||||
"tooltip": map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "graph panel with fill thresholds gets converted to timeseries with area thresholds",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Fill Thresholds Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "graph",
|
|
||||||
"id": 2,
|
|
||||||
"grid": map[string]interface{}{
|
|
||||||
"threshold1": 100,
|
|
||||||
"threshold2": 300,
|
|
||||||
"threshold1Color": "green",
|
|
||||||
"threshold2Color": "blue",
|
|
||||||
"thresholdLine": false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Fill Thresholds Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "timeseries",
|
|
||||||
"id": 2,
|
|
||||||
"fieldConfig": map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{
|
|
||||||
"color": map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
},
|
|
||||||
"custom": map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "linear",
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"mappings": []interface{}{},
|
|
||||||
"thresholds": map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": nil,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": []interface{}{},
|
|
||||||
},
|
|
||||||
"options": map[string]interface{}{
|
|
||||||
"legend": map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
},
|
|
||||||
"tooltip": map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "graph panel with aliasColors gets converted to timeseries with field config overrides",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Alias Colors Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "graph",
|
|
||||||
"id": 3,
|
|
||||||
"aliasColors": map[string]interface{}{
|
|
||||||
"series1": "red",
|
|
||||||
"series2": "blue",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Alias Colors Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "timeseries",
|
|
||||||
"id": 3,
|
|
||||||
"fieldConfig": map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{
|
|
||||||
"color": map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
},
|
|
||||||
"custom": map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "linear",
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"mappings": []interface{}{},
|
|
||||||
"thresholds": map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": nil,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"matcher": map[string]interface{}{
|
|
||||||
"id": "byName",
|
|
||||||
"options": "series1",
|
|
||||||
},
|
|
||||||
"properties": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"id": "color",
|
|
||||||
"value": map[string]interface{}{
|
|
||||||
"mode": "fixed",
|
|
||||||
"fixedColor": "red",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"matcher": map[string]interface{}{
|
|
||||||
"id": "byName",
|
|
||||||
"options": "series2",
|
|
||||||
},
|
|
||||||
"properties": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"id": "color",
|
|
||||||
"value": map[string]interface{}{
|
|
||||||
"mode": "fixed",
|
|
||||||
"fixedColor": "blue",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"options": map[string]interface{}{
|
|
||||||
"legend": map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
},
|
|
||||||
"tooltip": map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "graph panel with y-axis configuration gets converted to timeseries with field config",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Y-Axis Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "graph",
|
|
||||||
"id": 4,
|
|
||||||
"yaxes": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"label": "Y-Axis Label",
|
|
||||||
"show": true,
|
|
||||||
"logBase": 10.0,
|
|
||||||
"format": "short",
|
|
||||||
"decimals": 2,
|
|
||||||
"min": 0.0,
|
|
||||||
"max": 100.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel Y-Axis Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "timeseries",
|
|
||||||
"id": 4,
|
|
||||||
"fieldConfig": map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{
|
|
||||||
"color": map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
},
|
|
||||||
"unit": "short",
|
|
||||||
"decimals": 2,
|
|
||||||
"min": 0.0,
|
|
||||||
"max": 100.0,
|
|
||||||
"custom": map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "Y-Axis Label",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "log",
|
|
||||||
"log": 10.0,
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"mappings": []interface{}{},
|
|
||||||
"thresholds": map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": nil,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": []interface{}{},
|
|
||||||
},
|
|
||||||
"options": map[string]interface{}{
|
|
||||||
"legend": map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
},
|
|
||||||
"tooltip": map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "non-graph panel is unchanged",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 Non-Graph Panel Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "singlestat",
|
|
||||||
"id": 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 Non-Graph Panel Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "singlestat",
|
|
||||||
"id": 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "graph panel without grid gets converted to timeseries with basic structure",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel No Grid Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "graph",
|
|
||||||
"id": 6,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 Graph Panel No Grid Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
"panels": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"type": "timeseries",
|
|
||||||
"id": 6,
|
|
||||||
"fieldConfig": map[string]interface{}{
|
|
||||||
"defaults": map[string]interface{}{
|
|
||||||
"color": map[string]interface{}{
|
|
||||||
"mode": "palette-classic",
|
|
||||||
},
|
|
||||||
"custom": map[string]interface{}{
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": map[string]interface{}{
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false,
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": map[string]interface{}{
|
|
||||||
"type": "linear",
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": map[string]interface{}{
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none",
|
|
||||||
},
|
|
||||||
"thresholdsStyle": map[string]interface{}{
|
|
||||||
"mode": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"mappings": []interface{}{},
|
|
||||||
"thresholds": map[string]interface{}{
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "green",
|
|
||||||
"value": nil,
|
|
||||||
},
|
|
||||||
map[string]interface{}{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": []interface{}{},
|
|
||||||
},
|
|
||||||
"options": map[string]interface{}{
|
|
||||||
"legend": map[string]interface{}{
|
|
||||||
"calcs": []interface{}{},
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true,
|
|
||||||
},
|
|
||||||
"tooltip": map[string]interface{}{
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "dashboard without panels is unchanged",
|
|
||||||
input: map[string]interface{}{
|
|
||||||
"title": "V13 No Panels Test",
|
|
||||||
"schemaVersion": 12,
|
|
||||||
},
|
|
||||||
expected: map[string]interface{}{
|
|
||||||
"title": "V13 No Panels Test",
|
|
||||||
"schemaVersion": 13,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
runMigrationTests(t, tests, schemaversion.V13)
|
runMigrationTests(t, tests, schemaversion.V13)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,80 +21,20 @@
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
|
"autoMigrateFrom": "graph",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "default-ds-uid"
|
"uid": "default-ds-uid"
|
||||||
},
|
},
|
||||||
"fieldConfig": {
|
"grid": {
|
||||||
"defaults": {
|
"threshold1": 200,
|
||||||
"color": {
|
"threshold1Color": "yellow",
|
||||||
"mode": "palette-classic"
|
"threshold2": 400,
|
||||||
},
|
"threshold2Color": "red",
|
||||||
"custom": {
|
"thresholdLine": true
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -109,80 +49,20 @@
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"autoMigrateFrom": "graph",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "default-ds-uid"
|
"uid": "default-ds-uid"
|
||||||
},
|
},
|
||||||
"fieldConfig": {
|
"grid": {
|
||||||
"defaults": {
|
"threshold1": 100,
|
||||||
"color": {
|
"threshold1Color": "green",
|
||||||
"mode": "palette-classic"
|
"threshold2": 300,
|
||||||
},
|
"threshold2Color": "blue",
|
||||||
"custom": {
|
"thresholdLine": false
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -197,80 +77,18 @@
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"autoMigrateFrom": "graph",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "default-ds-uid"
|
"uid": "default-ds-uid"
|
||||||
},
|
},
|
||||||
"fieldConfig": {
|
"grid": {
|
||||||
"defaults": {
|
"threshold1": 150,
|
||||||
"color": {
|
"threshold1Color": "orange",
|
||||||
"mode": "palette-classic"
|
"thresholdLine": true
|
||||||
},
|
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -285,72 +103,18 @@
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"autoMigrateFrom": "graph",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "default-ds-uid"
|
"uid": "default-ds-uid"
|
||||||
},
|
},
|
||||||
"fieldConfig": {
|
"grid": {
|
||||||
"defaults": {
|
"threshold1": 200,
|
||||||
"color": {
|
"threshold1Color": "yellow",
|
||||||
"mode": "palette-classic"
|
"thresholdLine": false
|
||||||
},
|
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "line"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
@ -361,6 +125,13 @@
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"thresholds": [
|
||||||
|
{
|
||||||
|
"color": "purple",
|
||||||
|
"colorMode": "custom",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
"title": "Graph with Existing Thresholds",
|
"title": "Graph with Existing Thresholds",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,79 +21,12 @@
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
|
"autoMigrateFrom": "graph",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "gdev-prometheus"
|
"uid": "gdev-prometheus"
|
||||||
},
|
},
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"color": {
|
|
||||||
"mode": "palette-classic"
|
|
||||||
},
|
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
|
|
@ -21,286 +21,57 @@
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
"fieldConfig": {
|
"autoMigrateFrom": "graph",
|
||||||
"defaults": {
|
"grid": {
|
||||||
"color": {
|
"threshold1": 200,
|
||||||
"mode": "palette-classic"
|
"threshold1Color": "yellow",
|
||||||
},
|
"threshold2": 400,
|
||||||
"custom": {
|
"threshold2Color": "red",
|
||||||
"axisBorderShow": false,
|
"thresholdLine": true
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"title": "Graph with Line Thresholds",
|
"title": "Graph with Line Thresholds",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldConfig": {
|
"autoMigrateFrom": "graph",
|
||||||
"defaults": {
|
"grid": {
|
||||||
"color": {
|
"threshold1": 100,
|
||||||
"mode": "palette-classic"
|
"threshold1Color": "green",
|
||||||
},
|
"threshold2": 300,
|
||||||
"custom": {
|
"threshold2Color": "blue",
|
||||||
"axisBorderShow": false,
|
"thresholdLine": false
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"title": "Graph with Fill Thresholds",
|
"title": "Graph with Fill Thresholds",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldConfig": {
|
"autoMigrateFrom": "graph",
|
||||||
"defaults": {
|
"grid": {
|
||||||
"color": {
|
"threshold1": 150,
|
||||||
"mode": "palette-classic"
|
"threshold1Color": "orange",
|
||||||
},
|
"thresholdLine": true
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"title": "Graph with Single Threshold",
|
"title": "Graph with Single Threshold",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldConfig": {
|
"autoMigrateFrom": "graph",
|
||||||
"defaults": {
|
"grid": {
|
||||||
"color": {
|
"threshold1": 200,
|
||||||
"mode": "palette-classic"
|
"threshold1Color": "yellow",
|
||||||
},
|
"thresholdLine": false
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "line"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
},
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"options": {
|
"thresholds": [
|
||||||
"legend": {
|
{
|
||||||
"calcs": [],
|
"color": "purple",
|
||||||
"displayMode": "list",
|
"colorMode": "custom",
|
||||||
"placement": "bottom",
|
"value": 50
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
"title": "Graph with Existing Thresholds",
|
"title": "Graph with Existing Thresholds",
|
||||||
"type": "timeseries"
|
"type": "timeseries"
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,75 +21,8 @@
|
||||||
"links": [],
|
"links": [],
|
||||||
"panels": [
|
"panels": [
|
||||||
{
|
{
|
||||||
"fieldConfig": {
|
"autoMigrateFrom": "graph",
|
||||||
"defaults": {
|
|
||||||
"color": {
|
|
||||||
"mode": "palette-classic"
|
|
||||||
},
|
|
||||||
"custom": {
|
|
||||||
"axisBorderShow": false,
|
|
||||||
"axisCenteredZero": false,
|
|
||||||
"axisColorMode": "text",
|
|
||||||
"axisLabel": "",
|
|
||||||
"axisPlacement": "auto",
|
|
||||||
"barAlignment": 0,
|
|
||||||
"barWidthFactor": 0.6,
|
|
||||||
"drawStyle": "points",
|
|
||||||
"fillOpacity": 0,
|
|
||||||
"gradientMode": "none",
|
|
||||||
"hideFrom": {
|
|
||||||
"legend": false,
|
|
||||||
"tooltip": false,
|
|
||||||
"viz": false
|
|
||||||
},
|
|
||||||
"insertNulls": false,
|
|
||||||
"lineInterpolation": "linear",
|
|
||||||
"lineWidth": 1,
|
|
||||||
"pointSize": 5,
|
|
||||||
"scaleDistribution": {
|
|
||||||
"type": "linear"
|
|
||||||
},
|
|
||||||
"showPoints": "auto",
|
|
||||||
"showValues": false,
|
|
||||||
"spanNulls": false,
|
|
||||||
"stacking": {
|
|
||||||
"group": "A",
|
|
||||||
"mode": "none"
|
|
||||||
},
|
|
||||||
"thresholdsStyle": {
|
|
||||||
"mode": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"options": {
|
|
||||||
"legend": {
|
|
||||||
"calcs": [],
|
|
||||||
"displayMode": "list",
|
|
||||||
"placement": "bottom",
|
|
||||||
"showLegend": true
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"hideZeros": false,
|
|
||||||
"mode": "single",
|
|
||||||
"sort": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"datasource": {
|
"datasource": {
|
||||||
|
|
|
@ -2549,7 +2549,7 @@
|
||||||
"count": 4
|
"count": 4
|
||||||
},
|
},
|
||||||
"@typescript-eslint/no-explicit-any": {
|
"@typescript-eslint/no-explicit-any": {
|
||||||
"count": 24
|
"count": 21
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public/app/features/dashboard/state/DashboardModel.repeat.test.ts": {
|
"public/app/features/dashboard/state/DashboardModel.repeat.test.ts": {
|
||||||
|
|
|
@ -403,72 +403,8 @@ export class DashboardMigrator {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldVersion < 13 && finalTargetVersion >= 13) {
|
if (oldVersion < 13 && finalTargetVersion >= 13) {
|
||||||
// update graph yaxes changes
|
// graph panel auto migrates to either barchart, bargauge, histogram or timeseries (all standard Grafana plugins)
|
||||||
panelUpgrades.push((panel: any) => {
|
// see public/app/features/dashboard/state/getPanelPluginToMigrateTo.ts
|
||||||
if (panel.type !== 'graph') {
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
if (!panel.grid) {
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!panel.thresholds) {
|
|
||||||
panel.thresholds = [];
|
|
||||||
}
|
|
||||||
const t1: any = {},
|
|
||||||
t2: any = {};
|
|
||||||
|
|
||||||
if (panel.grid.threshold1 !== null) {
|
|
||||||
t1.value = panel.grid.threshold1;
|
|
||||||
if (panel.grid.thresholdLine) {
|
|
||||||
t1.line = true;
|
|
||||||
t1.lineColor = panel.grid.threshold1Color;
|
|
||||||
t1.colorMode = 'custom';
|
|
||||||
} else {
|
|
||||||
t1.fill = true;
|
|
||||||
t1.fillColor = panel.grid.threshold1Color;
|
|
||||||
t1.colorMode = 'custom';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (panel.grid.threshold2 !== null) {
|
|
||||||
t2.value = panel.grid.threshold2;
|
|
||||||
if (panel.grid.thresholdLine) {
|
|
||||||
t2.line = true;
|
|
||||||
t2.lineColor = panel.grid.threshold2Color;
|
|
||||||
t2.colorMode = 'custom';
|
|
||||||
} else {
|
|
||||||
t2.fill = true;
|
|
||||||
t2.fillColor = panel.grid.threshold2Color;
|
|
||||||
t2.colorMode = 'custom';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNumber(t1.value)) {
|
|
||||||
if (isNumber(t2.value)) {
|
|
||||||
if (t1.value > t2.value) {
|
|
||||||
t1.op = t2.op = 'lt';
|
|
||||||
panel.thresholds.push(t1);
|
|
||||||
panel.thresholds.push(t2);
|
|
||||||
} else {
|
|
||||||
t1.op = t2.op = 'gt';
|
|
||||||
panel.thresholds.push(t1);
|
|
||||||
panel.thresholds.push(t2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t1.op = 'gt';
|
|
||||||
panel.thresholds.push(t1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete panel.grid.threshold1;
|
|
||||||
delete panel.grid.threshold1Color;
|
|
||||||
delete panel.grid.threshold2;
|
|
||||||
delete panel.grid.threshold2Color;
|
|
||||||
delete panel.grid.thresholdLine;
|
|
||||||
|
|
||||||
return panel;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldVersion < 14 && finalTargetVersion >= 14) {
|
if (oldVersion < 14 && finalTargetVersion >= 14) {
|
||||||
|
|
Loading…
Reference in New Issue