Schema: convert dashboards from v1beta1 to v2beta1 (#109037)
- Implement full conversion pipeline from v1beta1 → v2beta1 - Ensure frontend–backend parity for all dashboard serialization paths - Add automatic data loss detection for conversions (panels, queries, annotations, links, variables) - Extract atomic conversion functions for v0 → v1beta1 → v2alpha1 → v2beta1 - Introduce conversion metrics and detailed logging for loss tracking - Normalize datasource resolution, defaults, and annotation processing - Improve panel layout serialization and y-coordinate normalization - Fix inconsistencies in nested panels and collapsed row behavior - Refine variable handling: - Filter refId from variable query specs - Default variable refresh to 'never' (matches frontend) - Fix constant and interval variable handling for missing queries - Unify schema defaults (enable, hide, iconColor, editable, liveNow) - Fix pluginId usage (UID vs type) and datasource references - Fix metrics.go bug swallowing errors (return nil → return err) - Add tests for version-specific conversion error handling - Add data loss detection tests using source/target version comparison - Clean up lint issues, legacy code, and redundant files - Update OpenAPI snapshots and migrated dashboards - Improve backend migrator to reuse datasource provider and match frontend logic Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com> Co-authored-by: Oscar Kilhed <oscar.kilhed@grafana.com> Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com>
This commit is contained in:
co-authored by
Haris Rozajac
Oscar Kilhed
Stephanie Hingtgen
parent
09942c08db
commit
e463781077
@@ -40,13 +40,7 @@
|
||||
]
|
||||
},
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"name": "Annotations & Alerts",
|
||||
"datasource": "grafana",
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
|
||||
@@ -43,7 +43,10 @@
|
||||
"list": [
|
||||
{
|
||||
"name": "Annotations & Alerts",
|
||||
"datasource": "grafana",
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "grafana"
|
||||
},
|
||||
"enable": true
|
||||
}
|
||||
]
|
||||
|
||||
+3
-1
@@ -110,7 +110,9 @@
|
||||
"enable": true,
|
||||
"iconColor": "purple",
|
||||
"datasource": {
|
||||
"uid": "prometheus"
|
||||
"uid": "default-ds-uid",
|
||||
"type": "prometheus",
|
||||
"apiVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
{
|
||||
"name": "Unknown Datasource Annotation - Tests unknown datasource preserved as UID",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"apiVersion": "v1",
|
||||
"uid": "unknown-datasource-name"
|
||||
}
|
||||
}
|
||||
@@ -119,7 +121,9 @@
|
||||
{
|
||||
"refId": "B",
|
||||
"datasource": {
|
||||
"uid": "existing-target-uid"
|
||||
"uid": "existing-target-uid",
|
||||
"type": "elasticsearch",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -137,7 +141,8 @@
|
||||
"refId": "A",
|
||||
"datasource": {
|
||||
"uid": "existing-target-uid",
|
||||
"type": "elasticsearch"
|
||||
"type": "elasticsearch",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -167,7 +172,9 @@
|
||||
{
|
||||
"refId": "A",
|
||||
"datasource": {
|
||||
"uid": "existing-target-uid"
|
||||
"uid": "existing-target-uid",
|
||||
"type": "elasticsearch",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -188,7 +195,9 @@
|
||||
{
|
||||
"refId": "A",
|
||||
"datasource": {
|
||||
"uid": "existing-target-uid"
|
||||
"uid": "existing-target-uid",
|
||||
"type": "elasticsearch",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -257,7 +266,9 @@
|
||||
{
|
||||
"refId": "A",
|
||||
"datasource": {
|
||||
"uid": "existing-target-uid"
|
||||
"uid": "existing-target-uid",
|
||||
"type": "elasticsearch",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"title": "v42 Migration Test - Harky Must",
|
||||
"schemaVersion": 41,
|
||||
"panels": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Panel with hideFrom.viz = true",
|
||||
"type": "timeseries",
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Field1"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.hideFrom",
|
||||
"value": {
|
||||
"viz": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -49,14 +49,22 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"__systemRef": "hideSeriesFrom",
|
||||
"matcher": {
|
||||
"id": "__systemRef",
|
||||
"options": "hiddenSeries"
|
||||
"id": "byNames",
|
||||
"options": {
|
||||
"mode": "exclude",
|
||||
"names": ["foo"],
|
||||
"prefix": "All except:",
|
||||
"readOnly": true
|
||||
}
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.hideFrom",
|
||||
"value": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": true
|
||||
}
|
||||
}
|
||||
@@ -103,6 +111,10 @@
|
||||
"defaults": {},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Time"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "unit",
|
||||
@@ -123,13 +135,18 @@
|
||||
"defaults": {},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byValue",
|
||||
"options": {
|
||||
"op": "gte",
|
||||
"reducer": "allIsZero",
|
||||
"value": 0
|
||||
}
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.hideFrom",
|
||||
"value": {
|
||||
"viz": false,
|
||||
"tooltip": false
|
||||
}
|
||||
"id": "unit",
|
||||
"value": "short"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -144,12 +161,17 @@
|
||||
"defaults": {},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "{__name__=\"ALERTS\", alertname=\"k6CloudServiceErrorsLogged\"}"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.hideFrom",
|
||||
"value": {
|
||||
"viz": true,
|
||||
"tooltip": false
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+12
-4
@@ -12,14 +12,20 @@
|
||||
"annotations": [
|
||||
{
|
||||
"name": "deployment",
|
||||
"datasource": "prometheus",
|
||||
"datasource": {
|
||||
"uid": "default-ds-uid",
|
||||
"type": "prometheus"
|
||||
},
|
||||
"enable": true,
|
||||
"iconColor": "red",
|
||||
"query": "ALERTS{alertname=\"DeploymentStarted\"}"
|
||||
},
|
||||
{
|
||||
"name": "alerts",
|
||||
"datasource": "loki",
|
||||
"datasource": {
|
||||
"uid": "loki-uid",
|
||||
"type": "loki"
|
||||
},
|
||||
"enable": false,
|
||||
"iconColor": "yellow",
|
||||
"query": "{job=\"alertmanager\"}"
|
||||
@@ -32,12 +38,14 @@
|
||||
{
|
||||
"name": "environment",
|
||||
"type": "filter",
|
||||
"allFormat": null
|
||||
"allFormat": null,
|
||||
"query": "label_values(up, instance)"
|
||||
},
|
||||
{
|
||||
"name": "service",
|
||||
"datasource": "prometheus",
|
||||
"allFormat": "glob"
|
||||
"allFormat": "glob",
|
||||
"query": "label_values(up, instance)"
|
||||
},
|
||||
{
|
||||
"name": "region",
|
||||
|
||||
Reference in New Issue
Block a user