Skip to content

Commit

Permalink
Merge pull request #14 from kubermatic/2023-update
Browse files Browse the repository at this point in the history
  • Loading branch information
wurbanski authored Sep 5, 2023
2 parents c2e84f5 + b21de6d commit 0dd5f00
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 113 deletions.
36 changes: 18 additions & 18 deletions board.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type (
Type string `json:"type"`
Auto bool `json:"auto,omitempty"`
AutoCount *int `json:"auto_count,omitempty"`
Datasource *string `json:"datasource"`
Datasource interface{} `json:"datasource"`
Refresh BoolInt `json:"refresh"`
Options []Option `json:"options"`
IncludeAll bool `json:"includeAll"`
Expand Down Expand Up @@ -111,23 +111,23 @@ type (
Value interface{} `json:"value"` // TODO select more precise type
}
Annotation struct {
Name string `json:"name"`
Datasource *string `json:"datasource"`
ShowLine bool `json:"showLine"`
IconColor string `json:"iconColor"`
LineColor string `json:"lineColor"`
IconSize uint `json:"iconSize"`
Enable bool `json:"enable"`
Query string `json:"query"`
Expr string `json:"expr"`
Step string `json:"step"`
TextField string `json:"textField"`
TextFormat string `json:"textFormat"`
TitleFormat string `json:"titleFormat"`
TagsField string `json:"tagsField"`
Tags []string `json:"tags"`
TagKeys string `json:"tagKeys"`
Type string `json:"type"`
Name string `json:"name"`
Datasource interface{} `json:"datasource"`
ShowLine bool `json:"showLine"`
IconColor string `json:"iconColor"`
LineColor string `json:"lineColor"`
IconSize uint `json:"iconSize"`
Enable bool `json:"enable"`
Query string `json:"query"`
Expr string `json:"expr"`
Step string `json:"step"`
TextField string `json:"textField"`
TextFormat string `json:"textFormat"`
TitleFormat string `json:"titleFormat"`
TagsField string `json:"tagsField"`
Tags []string `json:"tags"`
TagKeys string `json:"tagKeys"`
Type string `json:"type"`
}
// Link represents link to another dashboard or external weblink
Link struct {
Expand Down
41 changes: 39 additions & 2 deletions dashboard-unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ func TestUnmarshal_DashboardWithGraphWithTargets26(t *testing.T) {
if panel.OfType != sdk.GraphType {
t.Errorf("panel type should be %d (\"graph\") type but got %d", sdk.GraphType, panel.OfType)
}
if *panel.Datasource != sdk.MixedSource {
t.Errorf("panel Datasource should be \"%s\" but got \"%s\"", sdk.MixedSource, *panel.Datasource)
if panel.Datasource != sdk.MixedSource {
t.Errorf("panel Datasource should be \"%s\" but got \"%s\"", sdk.MixedSource, panel.Datasource)
}
if len(panel.GraphPanel.Targets) != 2 {
t.Errorf("panel has 2 targets but got %d", len(panel.GraphPanel.Targets))
Expand Down Expand Up @@ -188,3 +188,40 @@ func TestUnmarshal_DashboardWithMixedYaxes(t *testing.T) {
t.Errorf("panel #1 has wrong max value: %f, expected: %f", max4.Value, 100.0)
}
}

func TestUnmarshal_DashboardWithGraphWithTargets83(t *testing.T) {
var board sdk.Board
raw, _ := ioutil.ReadFile("testdata/default-panels-graph-with-target-8.3.json")

err := json.Unmarshal(raw, &board)

if err != nil {
t.Fatal(err)
}
if len(board.Panels) != 2 {
t.Fatalf("board should have 2 panels but got %d", len(board.Panels))
}
rowPanel := board.Panels[0]
if rowPanel.OfType != sdk.RowType {
t.Errorf("panel type should be %d (\"row\") type but got %d", sdk.GraphType, rowPanel.OfType)
}

panel := board.Panels[1]
if panel.OfType != sdk.GraphType {
t.Errorf("panel type should be %d (\"graph\") type but got %d", sdk.GraphType, panel.OfType)
}

if len(panel.GraphPanel.Targets) != 1 {
t.Errorf("panel has 1 targets but got %d", len(panel.GraphPanel.Targets))
}

target := panel.GraphPanel.Targets[0]
datasource, ok := target.Datasource.(map[string]interface{})
if !ok {
t.Fatalf("target Datasource should be a map but got %T", panel.Datasource)
}
if datasource["type"] != "prometheus" {
t.Errorf("target datasource should be of type \"prometheus\" but got %s", datasource["type"])
}

}
182 changes: 99 additions & 83 deletions panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"sort"
)

// Each panel may be one of these types.
Expand Down Expand Up @@ -66,9 +68,9 @@ type (
}
panelType int8
CommonPanel struct {
Datasource *string `json:"datasource,omitempty"` // metrics
Editable bool `json:"editable"`
Error bool `json:"error"`
Datasource interface{} `json:"datasource,omitempty"` // metrics
Editable bool `json:"editable"`
Error bool `json:"error"`
GridPos struct {
H *int `json:"h,omitempty"`
W *int `json:"w,omitempty"`
Expand Down Expand Up @@ -374,9 +376,9 @@ type (
FieldConfigDefaults struct {
Unit string `json:"unit"`
Decimals *int `json:"decimals,omitempty"`
Min *int `json:"min,omitempty"`
Max *int `json:"max,omitempty"`
Color FieldConfigColor `json:"color,omitempty"`
Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"`
Color FieldConfigColor `json:"color"`
Thresholds Thresholds `json:"thresholds"`
Custom FieldConfigCustom `json:"custom"`
Links []Link `json:"links,omitempty"`
Expand Down Expand Up @@ -420,8 +422,8 @@ type (
Steps []ThresholdStep `json:"steps"`
}
ThresholdStep struct {
Color string `json:"color"`
Value *int `json:"value"`
Color string `json:"color"`
Value *float64 `json:"value"`
}
FieldConfigColor struct {
Mode string `json:"mode"`
Expand Down Expand Up @@ -550,9 +552,9 @@ type (

// for an any panel
type Target struct {
RefID string `json:"refId"`
Datasource string `json:"datasource,omitempty"`
Hide bool `json:"hide,omitempty"`
RefID string `json:"refId"`
Datasource interface{} `json:"datasource,omitempty"`
Hide bool `json:"hide,omitempty"`

// For PostgreSQL
Table string `json:"table,omitempty"`
Expand Down Expand Up @@ -1040,78 +1042,85 @@ type probePanel struct {

func (p *Panel) UnmarshalJSON(b []byte) (err error) {
var probe probePanel
if err = json.Unmarshal(b, &probe); err == nil {
p.CommonPanel = probe.CommonPanel
switch probe.Type {
case "graph":
var graph GraphPanel
p.OfType = GraphType
if err = json.Unmarshal(b, &graph); err == nil {
p.GraphPanel = &graph
}
case "table":
var table TablePanel
p.OfType = TableType
if err = json.Unmarshal(b, &table); err == nil {
p.TablePanel = &table
}
case "text":
var text TextPanel
p.OfType = TextType
if err = json.Unmarshal(b, &text); err == nil {
p.TextPanel = &text
}
case "singlestat":
var singlestat SinglestatPanel
p.OfType = SinglestatType
if err = json.Unmarshal(b, &singlestat); err == nil {
p.SinglestatPanel = &singlestat
}
case "stat":
var stat StatPanel
p.OfType = StatType
if err = json.Unmarshal(b, &stat); err == nil {
p.StatPanel = &stat
}
case "dashlist":
var dashlist DashlistPanel
p.OfType = DashlistType
if err = json.Unmarshal(b, &dashlist); err == nil {
p.DashlistPanel = &dashlist
}
case "bargauge":
var bargauge BarGaugePanel
p.OfType = BarGaugeType
if err = json.Unmarshal(b, &bargauge); err == nil {
p.BarGaugePanel = &bargauge
}
case "heatmap":
var heatmap HeatmapPanel
p.OfType = HeatmapType
if err = json.Unmarshal(b, &heatmap); err == nil {
p.HeatmapPanel = &heatmap
}
case "timeseries":
var timeseries TimeseriesPanel
p.OfType = TimeseriesType
if err = json.Unmarshal(b, &timeseries); err == nil {
p.TimeseriesPanel = &timeseries
}
case "row":
var rowpanel RowPanel
p.OfType = RowType
if err = json.Unmarshal(b, &rowpanel); err == nil {
p.RowPanel = &rowpanel
}
default:
var custom = make(CustomPanel)
p.OfType = CustomType
if err = json.Unmarshal(b, &custom); err == nil {
p.CustomPanel = &custom
}
if err = json.Unmarshal(b, &probe); err != nil {
return err
}

p.CommonPanel = probe.CommonPanel
switch probe.Type {
case "graph":
var graph GraphPanel
p.OfType = GraphType
if err = json.Unmarshal(b, &graph); err == nil {
p.GraphPanel = &graph
}
case "table":
var table TablePanel
p.OfType = TableType
if err = json.Unmarshal(b, &table); err == nil {
p.TablePanel = &table
}
case "text":
var text TextPanel
p.OfType = TextType
if err = json.Unmarshal(b, &text); err == nil {
p.TextPanel = &text
}
case "singlestat":
var singlestat SinglestatPanel
p.OfType = SinglestatType
if err = json.Unmarshal(b, &singlestat); err == nil {
p.SinglestatPanel = &singlestat
}
case "stat":
var stat StatPanel
p.OfType = StatType
if err = json.Unmarshal(b, &stat); err == nil {
p.StatPanel = &stat
}
case "dashlist":
var dashlist DashlistPanel
p.OfType = DashlistType
if err = json.Unmarshal(b, &dashlist); err == nil {
p.DashlistPanel = &dashlist
}
case "bargauge":
var bargauge BarGaugePanel
p.OfType = BarGaugeType
if err = json.Unmarshal(b, &bargauge); err == nil {
p.BarGaugePanel = &bargauge
}
case "heatmap":
var heatmap HeatmapPanel
p.OfType = HeatmapType
if err = json.Unmarshal(b, &heatmap); err == nil {
p.HeatmapPanel = &heatmap
}
case "timeseries":
var timeseries TimeseriesPanel
p.OfType = TimeseriesType
if err = json.Unmarshal(b, &timeseries); err == nil {
p.TimeseriesPanel = &timeseries
}
case "row":
var rowpanel RowPanel
p.OfType = RowType
if err = json.Unmarshal(b, &rowpanel); err == nil {
p.RowPanel = &rowpanel
}
default:
var custom = make(CustomPanel)
p.OfType = CustomType
if err = json.Unmarshal(b, &custom); err == nil {
p.CustomPanel = &custom
}
}

if err != nil && (probe.Title != "" || probe.Type != "") {
err = fmt.Errorf("%w (panel %q of type %q)", err, probe.Title, probe.Type)
}
return

return err
}

func (p *Panel) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -1211,11 +1220,18 @@ func (c customPanelOutput) MarshalJSON() ([]byte, error) {
// Append custom keys to marshalled CommonPanel.
buf := bytes.NewBuffer(b[:len(b)-1])

for k, v := range c.CustomPanel {
// Sort keys to make output idempotent
keys := make([]string, 0, len(c.CustomPanel))
for k := range c.CustomPanel {
keys = append(keys, k)
}
sort.Strings(keys)

for _, k := range keys {
buf.WriteString(`,"`)
buf.WriteString(k)
buf.WriteString(`":`)
b, err := json.Marshal(v)
b, err := json.Marshal(c.CustomPanel[k])
if err != nil {
return b, err
}
Expand Down
Loading

0 comments on commit 0dd5f00

Please sign in to comment.