[v3.2] Add grafana dashboard importing API (#11)

* Add API to import grafana templates to kubesphere dashboard
* Merge and fix the latest codes from kubesphere #2501

Signed-off-by: zhu733756 <talonzhu@yunify.com>
This commit is contained in:
zhu733756
2021-08-16 11:41:29 +08:00
committed by zhu733756
parent 9df6df5544
commit 242ceb54f6
217 changed files with 119028 additions and 96 deletions

View File

@@ -0,0 +1,19 @@
// +kubebuilder:object:generate=true
package panels
type BarGaugeOptions struct {
Orientation string `json:"orientation,omitempty"`
TextMode string `json:"textMode,omitempty"`
ColorMode string `json:"colorMode,omitempty"`
GraphMode string `json:"graphMode,omitempty"`
JustifyMode string `json:"justifyMode,omitempty"`
DisplayMode string `json:"displayMode,omitempty"`
Content string `json:"content,omitempty"`
Mode string `json:"mode,omitempty"`
}
// refers to https://pkg.go.dev/github.com/grafana-tools/sdk#BarGaugePanel
type BarGaugePanel struct {
Options *BarGaugeOptions `json:"options,omitempty"`
// FieldConfig FieldConfig `json:"fieldConfig,omitempty"`
}

View File

@@ -0,0 +1,44 @@
// +kubebuilder:object:generate=true
package panels
// Query editor options
type CommonPanel struct {
// Name of the panel
Title string `json:"title,omitempty"`
// Type of the panel
Type string `json:"type,omitempty"`
// Panel ID
Id int64 `json:"id,omitempty"`
// Description
Description *string `json:"description,omitempty"`
// Datasource
Datasource *string `json:"datasource,omitempty"`
// Height
Height *string `json:"height,omitempty"`
Decimals *int64 `json:"decimals,omitempty"`
// A collection of queries
Targets []Target `json:"targets,omitempty"`
// Set series color
Colors []string `json:"colors,omitempty"`
// legend
Legend []string `json:"legend,omitempty"`
// Display unit
Format string `json:"format,omitempty"`
}
// +kubebuilder:object:generate=true
// Query editor options
// Referers to https://pkg.go.dev/github.com/grafana-tools/sdk#Target
type Target struct {
// Reference ID
RefID int64 `json:"refId,omitempty"`
// only support prometheus,and the corresponding fields are as follows:
// Input for fetching metrics.
Expression string `json:"expr,omitempty"`
// Legend format for outputs. You can make a dynamic legend with templating variables.
LegendFormat string `json:"legendFormat,omitempty"`
// Set series time interval
Step string `json:"step,omitempty"`
}

View File

@@ -0,0 +1,229 @@
// +kubebuilder:object:generate=true
package panels
import (
"encoding/json"
"errors"
"reflect"
)
// Supported panel type
// type Panel struct {
// // private property of the bargauge panel
// Options *BarGaugeOptions `json:"options,omitempty"`
// // ****common properties start
// // Name pf the panel
// Title string `json:"title,omitempty"`
// // The type of the panel
// Type string `json:"type,omitempty"`
// // Panel ID
// Id int64 `json:"id,omitempty"`
// // Panel description
// Description string `json:"description,omitempty"`
// // datasource
// Datasource string `json:"datasource,omitempty"`
// // A collection of queries
// Targets []Target `json:"targets,omitempty"`
// // Display as a bar chart
// Bars bool `json:"bars,omitempty"`
// // Set series color
// Colors []string `json:"colors,omitempty"`
// // color settings
// // todo graph
// Color []string `json:"color,omitempty"`
// // Display as a line chart
// Lines bool `json:"lines,omitempty"`
// // Display as a stacked chart
// Stack bool `json:"stack,omitempty"`
// // legend
// Legend []string `json:"legend,omitempty,flow"`
// // height
// Height string `json:"height,omitempty"`
// // transparent
// Transparent bool `json:"transparent,omitempty"`
// HiddenColumns []string `json:"hidden_columns,omitempty,flow"`
// TimeSeriesAggregations []string `json:"time_series_aggregations,omitempty"`
// // value name
// ValueName string `json:"valueName,omitempty"`
// // *****common properties end
// // private property of graph panel
// // Y-axis options
// Yaxes []Yaxis `json:"yaxes,omitempty"`
// // private properties of singlestat panel
// // spark line: full or bottom
// SparkLine string `json:"sparkline,omitempty"`
// // Limit the decimal numbers
// Decimals int64 `json:"decimals,omitempty"`
// // Display unit
// Format string `json:"format,omitempty"`
// // gauge
// Gauge *Gauge `json:"gauge,omitempty"`
// // table panel has no private property
// // private properties of text panel
// HTML string `json:"html,omitempty"`
// Markdown string `json:"markdown,omitempty"`
// }
type (
Panel struct {
CommonPanel `json:",inline"`
*GraphPanel `json:",inline"`
// RowPanel *RowPanel `json:",inline"`
*SinglestatPanel `json:",inline"`
*TablePanel `json:",inline"`
*TextPanel `json:",inline"`
*BarGaugePanel `json:",inline"`
// *CustomPanel `json:",inline"`
}
probePanel struct {
CommonPanel
}
// CustomPanel map[string]runtime.RawExtension
)
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
if err = json.Unmarshal(b, &graph); err == nil {
if !isZero(reflect.ValueOf(graph)) {
p.GraphPanel = &graph
}
}
case "table":
var table TablePanel
if err = json.Unmarshal(b, &table); err == nil {
if !isZero(reflect.ValueOf(table)) {
p.TablePanel = &table
}
}
case "text":
var text TextPanel
if err = json.Unmarshal(b, &text); err == nil {
if !isZero(reflect.ValueOf(text)) {
p.TextPanel = &text
}
}
case "singlestat":
var singlestat SinglestatPanel
if err = json.Unmarshal(b, &singlestat); err == nil {
if !isZero(reflect.ValueOf(singlestat)) {
p.SinglestatPanel = &singlestat
}
}
case "bargauge":
var bargauge BarGaugePanel
if err = json.Unmarshal(b, &bargauge); err == nil {
if !isZero(reflect.ValueOf(bargauge)) {
p.BarGaugePanel = &bargauge
}
}
case "row":
// var row RowPanel
// if err = json.Unmarshal(b, &row); err == nil {
// p.RowPanel = &row
// }
// default:
// var custom = make(CustomPanel)
// if err = json.Unmarshal(b, &custom); err == nil {
// p.CustomPanel = &custom
// }
}
}
return
}
func (p *Panel) MarshalJSON() ([]byte, error) {
var outCommon = struct {
CommonPanel
}{p.CommonPanel}
switch p.Type {
case "graph":
if p.GraphPanel == nil {
return json.Marshal(outCommon)
}
var outGraph = struct {
CommonPanel
GraphPanel
}{p.CommonPanel, *p.GraphPanel}
return json.Marshal(outGraph)
case "table":
if p.TablePanel == nil {
return json.Marshal(outCommon)
}
var outTable = struct {
CommonPanel
TablePanel
}{p.CommonPanel, *p.TablePanel}
return json.Marshal(outTable)
case "text":
if p.TextPanel == nil {
return json.Marshal(outCommon)
}
var outText = struct {
CommonPanel
TextPanel
}{p.CommonPanel, *p.TextPanel}
return json.Marshal(outText)
case "singlestat":
if p.SinglestatPanel == nil {
return json.Marshal(outCommon)
}
var outSinglestat = struct {
CommonPanel
SinglestatPanel
}{p.CommonPanel, *p.SinglestatPanel}
return json.Marshal(outSinglestat)
case "bargauge":
if p.BarGaugePanel == nil {
return json.Marshal(outCommon)
}
var outBarGauge = struct {
CommonPanel
BarGaugePanel
}{p.CommonPanel, *p.BarGaugePanel}
return json.Marshal(outBarGauge)
case "row":
var outRow = struct {
CommonPanel
}{p.CommonPanel}
return json.Marshal(outRow)
// default:
// var outCustom = struct {
// CommonPanel
// CustomPanel
// }{p.CommonPanel, *p.CustomPanel}
// return json.Marshal(outCustom)
}
return nil, errors.New("can't marshal unknown panel type")
}
func isZero(value reflect.Value) bool {
switch value.Kind() {
case reflect.String:
return value.Len() == 0
case reflect.Bool:
return !value.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return value.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return value.Uint() == 0
case reflect.Float32, reflect.Float64:
return value.Float() == 0
case reflect.Interface, reflect.Ptr:
return value.IsNil()
}
return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
}

View File

@@ -0,0 +1,39 @@
// +kubebuilder:object:generate=true
package panels
// Graph visualizes range query results into a linear graph
type GraphPanel struct {
// Display as a bar chart
Bars bool `json:"bars,omitempty"`
// Display as a line chart
Lines bool `json:"lines,omitempty"`
// Display as a stacked chart
Stack bool `json:"stack,omitempty"`
Xaxis Axis `json:"xaxis,omitempty"`
// Y-axis options
Yaxes []Axis `json:"yaxes,omitempty"`
}
type Axis struct {
// Limit the decimal numbers
Decimals int64 `json:"decimals,omitempty"`
// Display unit
Format string `json:"format,omitempty"`
}
// type Legend struct {
// AlignAsTable bool `json:"alignAsTable,omitempty"`
// Avg bool `json:"avg,omitempty"`
// Current bool `json:"current,omitempty" `
// HideEmpty bool `json:"hideEmpty,omitempty"`
// HideZero bool `json:"hideZero,omitempty"`
// Max bool `json:"max,omitempty"`
// Min bool `json:"min,omitempty"`
// RightSide bool `json:"rightSide,omitempty"`
// Show bool `json:"show,omitempty"`
// SideWidth *uint `json:"sideWidth,omitempty"`
// Total bool `json:"total,omitempty"`
// Values bool `json:"values,omitempty"`
// }

View File

@@ -0,0 +1,7 @@
// +kubebuilder:object:generate=true
package panels
// Row groups relevant charts
type RowPanel struct {
}

View File

@@ -0,0 +1,31 @@
// +kubebuilder:object:generate=true
package panels
// SingleStat shows instant query result
type SinglestatPanel struct {
// spark line: full or bottom
SparkLine string `json:"sparkline,omitempty"`
// gauge
Gauge Gauge `json:"gauge,omitempty"`
// value name
ValueName string `json:"valueName,omitempty"`
}
// Gauge for a stat
type Gauge struct {
MaxValue int64 `json:"maxValue,omitempty"`
MinValue int64 `json:"minValue,omitempty"`
Show bool `json:"show,omitempty"`
ThresholdLabels bool `json:"thresholdLabels,omitempty"`
ThresholdMarkers bool `json:"thresholdMarkers,omitempty"`
}
// type SparkLine struct {
// FillColor *string `json:"fillColor,omitempty"`
// Full bool `json:"full,omitempty"`
// LineColor *string `json:"lineColor,omitempty"`
// Show bool `json:"show,omitempty"`
// YMin *float64 `json:"ymin,omitempty"`
// YMax *float64 `json:"ymax,omitempty"`
// }

View File

@@ -0,0 +1,14 @@
// +kubebuilder:object:generate=true
package panels
// a table panel
type TablePanel struct {
Sort *Sort `json:"sort,omitempty"`
Scroll bool `json:"scroll,omitempty"`
}
type Sort struct {
Col int `json:"col,omitempty"`
Desc bool `json:"desc,omitempty"`
}

View File

@@ -0,0 +1,10 @@
// +kubebuilder:object:generate=true
package panels
// dashboard text type
// referers to https://pkg.go.dev/github.com/K-Phoen/grabana/decoder#DashboardText
type TextPanel struct {
Mode string `json:"mode,omitempty"`
Content string `json:"content,omitempty"`
}

View File

@@ -0,0 +1,296 @@
// +build !ignore_autogenerated
/*
Copyright 2020 The KubeSphere authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by controller-gen. DO NOT EDIT.
package panels
import ()
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Axis) DeepCopyInto(out *Axis) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Axis.
func (in *Axis) DeepCopy() *Axis {
if in == nil {
return nil
}
out := new(Axis)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BarGaugeOptions) DeepCopyInto(out *BarGaugeOptions) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarGaugeOptions.
func (in *BarGaugeOptions) DeepCopy() *BarGaugeOptions {
if in == nil {
return nil
}
out := new(BarGaugeOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BarGaugePanel) DeepCopyInto(out *BarGaugePanel) {
*out = *in
if in.Options != nil {
in, out := &in.Options, &out.Options
*out = new(BarGaugeOptions)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarGaugePanel.
func (in *BarGaugePanel) DeepCopy() *BarGaugePanel {
if in == nil {
return nil
}
out := new(BarGaugePanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CommonPanel) DeepCopyInto(out *CommonPanel) {
*out = *in
if in.Description != nil {
in, out := &in.Description, &out.Description
*out = new(string)
**out = **in
}
if in.Datasource != nil {
in, out := &in.Datasource, &out.Datasource
*out = new(string)
**out = **in
}
if in.Height != nil {
in, out := &in.Height, &out.Height
*out = new(string)
**out = **in
}
if in.Decimals != nil {
in, out := &in.Decimals, &out.Decimals
*out = new(int64)
**out = **in
}
if in.Targets != nil {
in, out := &in.Targets, &out.Targets
*out = make([]Target, len(*in))
copy(*out, *in)
}
if in.Colors != nil {
in, out := &in.Colors, &out.Colors
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Legend != nil {
in, out := &in.Legend, &out.Legend
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonPanel.
func (in *CommonPanel) DeepCopy() *CommonPanel {
if in == nil {
return nil
}
out := new(CommonPanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Gauge) DeepCopyInto(out *Gauge) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Gauge.
func (in *Gauge) DeepCopy() *Gauge {
if in == nil {
return nil
}
out := new(Gauge)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GraphPanel) DeepCopyInto(out *GraphPanel) {
*out = *in
out.Xaxis = in.Xaxis
if in.Yaxes != nil {
in, out := &in.Yaxes, &out.Yaxes
*out = make([]Axis, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GraphPanel.
func (in *GraphPanel) DeepCopy() *GraphPanel {
if in == nil {
return nil
}
out := new(GraphPanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Panel) DeepCopyInto(out *Panel) {
*out = *in
in.CommonPanel.DeepCopyInto(&out.CommonPanel)
if in.GraphPanel != nil {
in, out := &in.GraphPanel, &out.GraphPanel
*out = new(GraphPanel)
(*in).DeepCopyInto(*out)
}
if in.SinglestatPanel != nil {
in, out := &in.SinglestatPanel, &out.SinglestatPanel
*out = new(SinglestatPanel)
**out = **in
}
if in.TablePanel != nil {
in, out := &in.TablePanel, &out.TablePanel
*out = new(TablePanel)
(*in).DeepCopyInto(*out)
}
if in.TextPanel != nil {
in, out := &in.TextPanel, &out.TextPanel
*out = new(TextPanel)
**out = **in
}
if in.BarGaugePanel != nil {
in, out := &in.BarGaugePanel, &out.BarGaugePanel
*out = new(BarGaugePanel)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Panel.
func (in *Panel) DeepCopy() *Panel {
if in == nil {
return nil
}
out := new(Panel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RowPanel) DeepCopyInto(out *RowPanel) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RowPanel.
func (in *RowPanel) DeepCopy() *RowPanel {
if in == nil {
return nil
}
out := new(RowPanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SinglestatPanel) DeepCopyInto(out *SinglestatPanel) {
*out = *in
out.Gauge = in.Gauge
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SinglestatPanel.
func (in *SinglestatPanel) DeepCopy() *SinglestatPanel {
if in == nil {
return nil
}
out := new(SinglestatPanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Sort) DeepCopyInto(out *Sort) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sort.
func (in *Sort) DeepCopy() *Sort {
if in == nil {
return nil
}
out := new(Sort)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TablePanel) DeepCopyInto(out *TablePanel) {
*out = *in
if in.Sort != nil {
in, out := &in.Sort, &out.Sort
*out = new(Sort)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TablePanel.
func (in *TablePanel) DeepCopy() *TablePanel {
if in == nil {
return nil
}
out := new(TablePanel)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Target) DeepCopyInto(out *Target) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target.
func (in *Target) DeepCopy() *Target {
if in == nil {
return nil
}
out := new(Target)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TextPanel) DeepCopyInto(out *TextPanel) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TextPanel.
func (in *TextPanel) DeepCopy() *TextPanel {
if in == nil {
return nil
}
out := new(TextPanel)
in.DeepCopyInto(out)
return out
}