Repository: NetApp/harvest
Pull request #1554 (2022-11-28 14:48:46)

feat: ensure dashboards have only one expanded section


Patch:
diff --git a/grafana/dashboards/cmode/aggregate.json b/grafana/dashboards/cmode/aggregate.json
index 0e38927b..69eedf59 100644
--- a/grafana/dashboards/cmode/aggregate.json
+++ b/grafana/dashboards/cmode/aggregate.json
@@ -2297,7 +2297,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": null,
       "gridPos": {
         "h": 1,
@@ -2971,7 +2971,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": null,
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/cdot.json b/grafana/dashboards/cmode/cdot.json
index 402a1140..bb83f9e4 100644
--- a/grafana/dashboards/cmode/cdot.json
+++ b/grafana/dashboards/cmode/cdot.json
@@ -619,7 +619,7 @@
       "type": "table"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "gridPos": {
         "h": 1,
         "w": 24,
diff --git a/grafana/dashboards/cmode/cluster.json b/grafana/dashboards/cmode/cluster.json
index cd460719..0ac7362f 100644
--- a/grafana/dashboards/cmode/cluster.json
+++ b/grafana/dashboards/cmode/cluster.json
@@ -976,7 +976,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/compliance.json b/grafana/dashboards/cmode/compliance.json
index c414be4e..2fdf0513 100644
--- a/grafana/dashboards/cmode/compliance.json
+++ b/grafana/dashboards/cmode/compliance.json
@@ -1629,7 +1629,7 @@
       "type": "table"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/data_protection_snapshot.json b/grafana/dashboards/cmode/data_protection_snapshot.json
index 2d22c7b3..3e82b5a9 100644
--- a/grafana/dashboards/cmode/data_protection_snapshot.json
+++ b/grafana/dashboards/cmode/data_protection_snapshot.json
@@ -989,7 +989,7 @@
       "type": "table"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/lun.json b/grafana/dashboards/cmode/lun.json
index 24e45e3b..19fecf0d 100644
--- a/grafana/dashboards/cmode/lun.json
+++ b/grafana/dashboards/cmode/lun.json
@@ -456,7 +456,7 @@
       "type": "stat"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/metadata.json b/grafana/dashboards/cmode/metadata.json
index a5df9064..bb9dc85a 100644
--- a/grafana/dashboards/cmode/metadata.json
+++ b/grafana/dashboards/cmode/metadata.json
@@ -2027,7 +2027,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "fieldConfig": {
         "defaults": {},
@@ -3342,7 +3342,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "fieldConfig": {
         "defaults": {},
@@ -3815,7 +3815,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "fieldConfig": {
         "defaults": {},
diff --git a/grafana/dashboards/cmode/power.json b/grafana/dashboards/cmode/power.json
index 2c810109..00f58710 100644
--- a/grafana/dashboards/cmode/power.json
+++ b/grafana/dashboards/cmode/power.json
@@ -968,7 +968,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": null,
       "gridPos": {
         "h": 1,
@@ -1600,7 +1600,7 @@
       "type": "table"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": null,
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/shelf.json b/grafana/dashboards/cmode/shelf.json
index 54bd4618..a604e0a9 100644
--- a/grafana/dashboards/cmode/shelf.json
+++ b/grafana/dashboards/cmode/shelf.json
@@ -1558,7 +1558,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
@@ -1709,7 +1709,7 @@
       "type": "bargauge"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
@@ -1922,7 +1922,7 @@
       "type": "bargauge"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
diff --git a/grafana/dashboards/cmode/snapmirror.json b/grafana/dashboards/cmode/snapmirror.json
index c444e358..0571b4db 100644
--- a/grafana/dashboards/cmode/snapmirror.json
+++ b/grafana/dashboards/cmode/snapmirror.json
@@ -1011,7 +1011,7 @@
       "type": "table"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "fieldConfig": {
         "defaults": {},
@@ -1856,7 +1856,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "fieldConfig": {
         "defaults": {},
@@ -2065,7 +2065,7 @@
       "type": "timeseries"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,
@@ -3340,7 +3340,7 @@
       "datasource": "${DS_PROMETHEUS}"
     },
     {
-      "collapsed": false,
+      "collapsed": true,
       "datasource": "${DS_PROMETHEUS}",
       "gridPos": {
         "h": 1,


Test patch:
diff --git a/cmd/tools/grafana/dashboard_test.go b/cmd/tools/grafana/dashboard_test.go
index 2bb51c5e..8226a6b9 100644
--- a/cmd/tools/grafana/dashboard_test.go
+++ b/cmd/tools/grafana/dashboard_test.go
@@ -586,3 +586,59 @@ func allVariables(data []byte) []variable {
 	})
 	return variables
 }
+
+func TestOnlyHighlightsExpanded(t *testing.T) {
+	dir := "../../../grafana/dashboards/cmode"
+
+	exceptions := map[string]int{
+		"cmode/shelf.json":    2,
+		"cmode/security.json": 3,
+	}
+	// count number of expanded sections in dashboard and ensure num expanded = 1
+	visitDashboards(dir, func(path string, data []byte) {
+		checkExpansion(t, exceptions, path, data)
+	})
+}
+
+func checkExpansion(t *testing.T, exceptions map[string]int, path string, data []byte) {
+	pathCollapsed := make(map[string]bool)
+	titles := make([]string, 0)
+	// visit all panel
+	visitAllPanels(data, func(path string, key, value gjson.Result) {
+		collapsed := value.Get("collapsed")
+		if !collapsed.Exists() {
+			return
+		}
+		title := value.Get("title")
+		pathCollapsed[path] = collapsed.Bool()
+		if !collapsed.Bool() {
+			titles = append(titles, title.String())
+		}
+	})
+	if len(titles) == 0 {
+		return
+	}
+	dashPath := shortPath(path)
+	// By default, a single expanded row is allowed.
+	allowed := 1
+	v, ok := exceptions[dashPath]
+	if ok {
+		allowed = v
+	}
+	if len(titles) != allowed {
+		t.Errorf("%s expanded section(s) want=%d got=%d", dashPath, allowed, len(titles))
+	}
+}
+
+func visitAllPanels(data []byte, handle func(path string, key gjson.Result, value gjson.Result)) {
+	gjson.GetBytes(data, "panels").ForEach(func(key, value gjson.Result) bool {
+		path := fmt.Sprintf("panels[%d]", key.Int())
+		handle(path, key, value)
+		value.Get("panels").ForEach(func(key2, value2 gjson.Result) bool {
+			path2 := fmt.Sprintf("%spanels[%d]", path, key2.Int())
+			handle(path2, key2, value2)
+			return true
+		})
+		return true
+	})
+}