From 198375599eb9d95a7a7094702ff86c42a8477c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Fri, 21 Nov 2025 14:41:45 +0100 Subject: [PATCH] Fix/ignore some common dashboard problems (#114296) * Fix some common problems found when parsing dashboards for indexing --- .../store/kind/dashboard/dashboard.go | 31 +++- .../store/kind/dashboard/dashboard_test.go | 1 + .../k8s-wrapper-with-parsing-errors-info.json | 74 ++++++++++ .../k8s-wrapper-with-parsing-errors.json | 133 ++++++++++++++++++ 4 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors-info.json create mode 100644 pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors.json diff --git a/pkg/services/store/kind/dashboard/dashboard.go b/pkg/services/store/kind/dashboard/dashboard.go index 656eefc15f3..88cbb4d1f45 100644 --- a/pkg/services/store/kind/dashboard/dashboard.go +++ b/pkg/services/store/kind/dashboard/dashboard.go @@ -276,6 +276,12 @@ func readDashboardIter(jsonPath string, iter *jsoniter.Iterator, lookup Datasour } for sub := iter.ReadObject(); sub != ""; sub = iter.ReadObject() { + // Skip all null values silently. + if iter.WhatIsNext() == jsoniter.NilValue { + iter.Skip() + continue + } + if sub == "list" { templatingListPath := templatingPath + ".list" if !checkAndSkipUnexpectedElement(iter, templatingListPath, lc, jsoniter.ArrayValue) { @@ -283,6 +289,12 @@ func readDashboardIter(jsonPath string, iter *jsoniter.Iterator, lookup Datasour } for ix := 0; iter.ReadArray(); ix++ { + // Skip all null elements silently. + if iter.WhatIsNext() == jsoniter.NilValue { + iter.Skip() + continue + } + tv := templateVariable{} templatingListElementPath := fmt.Sprintf("%s[%d]", templatingListPath, ix) @@ -308,7 +320,12 @@ func readDashboardIter(jsonPath string, iter *jsoniter.Iterator, lookup Datasour case "query": tv.query = iter.Read() case "current": - if !checkAndSkipUnexpectedElement(iter, templatingListElementPath+".current", lc, jsoniter.ObjectValue) { + if !checkAndSkipUnexpectedElement(iter, templatingListElementPath+".current", lc, jsoniter.ObjectValue, jsoniter.ArrayValue) { + continue + } + + if iter.WhatIsNext() == jsoniter.ArrayValue { + iter.Skip() continue } @@ -527,10 +544,18 @@ func readpanelInfo(iter *jsoniter.Iterator, lookup DatasourceLookup, jsonPath st switch field { case "id": - if !checkAndSkipUnexpectedElement(iter, jsonPath+".id", lc, jsoniter.NumberValue) { + if !checkAndSkipUnexpectedElement(iter, jsonPath+".id", lc, jsoniter.NumberValue, jsoniter.StringValue) { continue } - panel.ID = iter.ReadInt64() + + if iter.WhatIsNext() == jsoniter.StringValue { + id, err := strconv.ParseInt(iter.ReadString(), 10, 64) + if err == nil { + panel.ID = id + } + } else { + panel.ID = iter.ReadInt64() + } case "type": if !checkAndSkipUnexpectedElement(iter, jsonPath+".type", lc, jsoniter.StringValue) { diff --git a/pkg/services/store/kind/dashboard/dashboard_test.go b/pkg/services/store/kind/dashboard/dashboard_test.go index 5e31a86f8bd..91e657df1a8 100644 --- a/pkg/services/store/kind/dashboard/dashboard_test.go +++ b/pkg/services/store/kind/dashboard/dashboard_test.go @@ -75,6 +75,7 @@ func TestReadDashboard(t *testing.T) { "k8s-wrapper", "k8s-wrapper-editable-string", "k8s-wrapper-tags-string", + "k8s-wrapper-with-parsing-errors", } devdash := "../../../../../devenv/dev-dashboards/" diff --git a/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors-info.json b/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors-info.json new file mode 100644 index 00000000000..6451c3d805b --- /dev/null +++ b/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors-info.json @@ -0,0 +1,74 @@ +{ + "id": 141, + "title": "pppp", + "tags": null, + "datasource": [ + { + "uid": "default.uid", + "type": "default.type" + } + ], + "panels": [ + { + "id": 1, + "title": "green pie", + "libraryPanel": "a7975b7a-fb53-4ab7-951d-15810953b54f", + "datasource": [ + { + "uid": "default.uid", + "type": "default.type" + } + ] + }, + { + "id": 2, + "title": "green pie", + "libraryPanel": "e1d5f519-dabd-47c6-9ad7-83d181ce1cee", + "datasource": [ + { + "uid": "default.uid", + "type": "default.type" + } + ] + }, + { + "id": 7, + "title": "", + "type": "barchart", + "datasource": [ + { + "uid": "default.uid", + "type": "default.type" + } + ] + }, + { + "id": 8, + "title": "", + "type": "graph", + "datasource": [ + { + "uid": "default.uid", + "type": "default.type" + } + ] + }, + { + "id": 3, + "title": "collapsed row", + "type": "row", + "collapsed": [ + { + "id": 42, + "title": "blue pie", + "libraryPanel": "l3d2s634-fdgf-75u4-3fg3-67j966ii7jur" + } + ] + } + ], + "schemaVersion": 38, + "linkCount": 0, + "timeFrom": "now-6h", + "timeTo": "now", + "timezone": "" +} \ No newline at end of file diff --git a/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors.json b/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors.json new file mode 100644 index 00000000000..73d2ce0ea22 --- /dev/null +++ b/pkg/services/store/kind/dashboard/testdata/k8s-wrapper-with-parsing-errors.json @@ -0,0 +1,133 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "adfbg6f", + "namespace": "default", + "uid": "b396894e-56bf-4a01-837b-64157912ca00", + "creationTimestamp": "2024-10-30T18:30:54Z", + "annotations": { + "grafana.app/createdBy": "user:be2g71ke8yoe8b", + "grafana.app/originHash": "Grafana v9.2.0 (NA)", + "grafana.app/originName": "UI", + "grafana.app/originPath": "/dashboard/new" + } + }, + "spec": { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 141, + "links": [], + "liveNow": false, + "panels": [ + { + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": "1", + "libraryPanel": { + "name": "green pie", + "uid": "a7975b7a-fb53-4ab7-951d-15810953b54f" + }, + "title": "green pie" + }, + { + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "libraryPanel": { + "name": "red pie", + "uid": "e1d5f519-dabd-47c6-9ad7-83d181ce1cee" + }, + "title": "green pie" + }, + { + "id": "7", + "type": "barchart" + }, + { + "id": 8, + "type": "graph" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 3, + "panels": [ + { + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 42, + "libraryPanel": { + "name": "blue pie", + "uid": "l3d2s634-fdgf-75u4-3fg3-67j966ii7jur" + }, + "title": "blue pie" + } + ], + "title": "collapsed row", + "type": "row" + } + ], + "refresh": "", + "schemaVersion": 38, + "tags": [], + "templating": { + "list": null, + "list": [ + null, + { + "current": [] + }, + { + "current": { + "value": "default" + } + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "pppp", + "uid": "adfbg6f", + "version": 3, + "weekStart": "" + } +}