mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
EnityAPI: update summary builder to support library panels (#70280)
This commit is contained in:
parent
ece3629804
commit
da66aefa87
@ -46,6 +46,9 @@ const (
|
|||||||
// in the folder registry service.
|
// in the folder registry service.
|
||||||
StandardKindAlertRule = "alertrule"
|
StandardKindAlertRule = "alertrule"
|
||||||
|
|
||||||
|
// StandardKindLibraryPanel is for library panels
|
||||||
|
StandardKindLibraryPanel = "librarypanel"
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
// References are referenced from objects
|
// References are referenced from objects
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
@ -395,6 +395,11 @@ func readpanelInfo(iter *jsoniter.Iterator, lookup DatasourceLookup) panelInfo {
|
|||||||
case "pluginVersion":
|
case "pluginVersion":
|
||||||
panel.PluginVersion = iter.ReadString() // since 7x (the saved version for the plugin model)
|
panel.PluginVersion = iter.ReadString() // since 7x (the saved version for the plugin model)
|
||||||
|
|
||||||
|
case "libraryPanel":
|
||||||
|
var v map[string]string
|
||||||
|
iter.ReadVal(&v)
|
||||||
|
panel.LibraryPanel = v["uid"]
|
||||||
|
|
||||||
case "datasource":
|
case "datasource":
|
||||||
targets.addDatasource(iter)
|
targets.addDatasource(iter)
|
||||||
|
|
||||||
|
@ -81,6 +81,10 @@ func NewStaticDashboardSummaryBuilder(lookup DatasourceLookup, sanitize bool) en
|
|||||||
panelRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
|
panelRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
|
||||||
dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
|
dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
|
||||||
}
|
}
|
||||||
|
if panel.LibraryPanel != "" {
|
||||||
|
panelRefs.Add(entity.StandardKindLibraryPanel, panel.Type, panel.LibraryPanel)
|
||||||
|
dashboardRefs.Add(entity.StandardKindLibraryPanel, panel.Type, panel.LibraryPanel)
|
||||||
|
}
|
||||||
for _, v := range panel.Datasource {
|
for _, v := range panel.Datasource {
|
||||||
dashboardRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
|
dashboardRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
|
||||||
panelRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
|
panelRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -12,7 +13,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadSummaries(t *testing.T) {
|
func TestGdevReadSummaries(t *testing.T) {
|
||||||
devdash := "../../../../../devenv/dev-dashboards/panel-graph/"
|
devdash := "../../../../../devenv/dev-dashboards/panel-graph/"
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -65,3 +66,50 @@ func TestReadSummaries(t *testing.T) {
|
|||||||
// accumulated in the walk test
|
// accumulated in the walk test
|
||||||
require.Equal(t, []string{}, failed)
|
require.Equal(t, []string{}, failed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadSummaries(t *testing.T) {
|
||||||
|
names := []string{
|
||||||
|
"with-library-panels",
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
reader := GetEntitySummaryBuilder()
|
||||||
|
failed := make([]string, 0, 10)
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
|
fpath := path.Join("testdata", name+".json")
|
||||||
|
// Ignore gosec warning G304 since it's a test
|
||||||
|
// nolint:gosec
|
||||||
|
body, err := os.ReadFile(fpath)
|
||||||
|
if err != nil {
|
||||||
|
require.NoError(t, err, "error reading: "+fpath)
|
||||||
|
}
|
||||||
|
|
||||||
|
summary, _, err := reader(ctx, name, body)
|
||||||
|
if err != nil {
|
||||||
|
require.NoError(t, err, "error parsing: "+fpath)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := json.MarshalIndent(summary, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
require.NoError(t, err, "error formatting: "+fpath)
|
||||||
|
}
|
||||||
|
|
||||||
|
gpath := path.Join("testdata", name+"-info.json")
|
||||||
|
|
||||||
|
// Ignore gosec warning G304 since it's a test
|
||||||
|
// nolint:gosec
|
||||||
|
golden, _ := os.ReadFile(gpath)
|
||||||
|
|
||||||
|
if !bytes.Equal(out, golden) {
|
||||||
|
failed = append(failed, name)
|
||||||
|
err = os.WriteFile(gpath, out, 0600)
|
||||||
|
if err != nil {
|
||||||
|
require.NoError(t, err, "error writing snapshot: "+fpath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// accumulated in the walk test
|
||||||
|
require.Equal(t, []string{}, failed)
|
||||||
|
}
|
||||||
|
67
pkg/services/store/kind/dashboard/testdata/with-library-panels-info.json
vendored
Normal file
67
pkg/services/store/kind/dashboard/testdata/with-library-panels-info.json
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "pppp",
|
||||||
|
"fields": {
|
||||||
|
"schemaVersion": 38
|
||||||
|
},
|
||||||
|
"nested": [
|
||||||
|
{
|
||||||
|
"uid": "with-library-panels#1",
|
||||||
|
"kind": "panel",
|
||||||
|
"name": "green pie",
|
||||||
|
"fields": {
|
||||||
|
"type": ""
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"family": "ds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "librarypanel",
|
||||||
|
"ID": "a7975b7a-fb53-4ab7-951d-15810953b54f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "plugin",
|
||||||
|
"type": "panel"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "with-library-panels#2",
|
||||||
|
"kind": "panel",
|
||||||
|
"name": "green pie",
|
||||||
|
"fields": {
|
||||||
|
"type": ""
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"family": "ds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "librarypanel",
|
||||||
|
"ID": "e1d5f519-dabd-47c6-9ad7-83d181ce1cee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "plugin",
|
||||||
|
"type": "panel"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"family": "ds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "librarypanel",
|
||||||
|
"ID": "a7975b7a-fb53-4ab7-951d-15810953b54f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "librarypanel",
|
||||||
|
"ID": "e1d5f519-dabd-47c6-9ad7-83d181ce1cee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"family": "plugin",
|
||||||
|
"type": "panel"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
72
pkg/services/store/kind/dashboard/testdata/with-library-panels.json
vendored
Normal file
72
pkg/services/store/kind/dashboard/testdata/with-library-panels.json
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"refresh": "",
|
||||||
|
"schemaVersion": 38,
|
||||||
|
"style": "dark",
|
||||||
|
"tags": [],
|
||||||
|
"templating": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"from": "now-6h",
|
||||||
|
"to": "now"
|
||||||
|
},
|
||||||
|
"timepicker": {},
|
||||||
|
"timezone": "",
|
||||||
|
"title": "pppp",
|
||||||
|
"uid": "cabf1b1f-e126-4a44-8b06-83ce5d85b161",
|
||||||
|
"version": 3,
|
||||||
|
"weekStart": ""
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,9 @@ type panelInfo struct {
|
|||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Type string `json:"type,omitempty"` // PluginID
|
Type string `json:"type,omitempty"` // PluginID
|
||||||
PluginVersion string `json:"pluginVersion,omitempty"`
|
PluginVersion string `json:"pluginVersion,omitempty"`
|
||||||
Datasource []DataSourceRef `json:"datasource,omitempty"` // UIDs
|
LibraryPanel string `json:"libraryPanel,omitempty"` // UID of referenced library panel
|
||||||
Transformer []string `json:"transformer,omitempty"` // ids of the transformation steps
|
Datasource []DataSourceRef `json:"datasource,omitempty"` // UIDs
|
||||||
|
Transformer []string `json:"transformer,omitempty"` // ids of the transformation steps
|
||||||
// Rows define panels as sub objects
|
// Rows define panels as sub objects
|
||||||
Collapsed []panelInfo `json:"collapsed,omitempty"`
|
Collapsed []panelInfo `json:"collapsed,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,7 @@ func GetEntityKindInfo() entity.EntityKindInfo {
|
|||||||
func GetEntitySummaryBuilder() entity.EntitySummaryBuilder {
|
func GetEntitySummaryBuilder() entity.EntitySummaryBuilder {
|
||||||
return func(ctx context.Context, uid string, body []byte) (*entity.EntitySummary, []byte, error) {
|
return func(ctx context.Context, uid string, body []byte) (*entity.EntitySummary, []byte, error) {
|
||||||
if uid != "default" {
|
if uid != "default" {
|
||||||
parts := strings.Split(uid, "-")
|
if !(strings.HasPrefix(uid, "user-") || strings.HasPrefix(uid, "team-")) {
|
||||||
if len(parts) != 2 {
|
|
||||||
return nil, nil, fmt.Errorf("expecting UID: default, user-{#}, or team-{#}")
|
|
||||||
}
|
|
||||||
if !(parts[0] == "team" || parts[0] == "user") {
|
|
||||||
return nil, nil, fmt.Errorf("expecting UID: default, user-{#}, or team-{#}")
|
return nil, nil, fmt.Errorf("expecting UID: default, user-{#}, or team-{#}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,10 @@ func (r *registry) GetSummaryBuilder(kind string) entity.EntitySummaryBuilder {
|
|||||||
defer r.mutex.RUnlock()
|
defer r.mutex.RUnlock()
|
||||||
|
|
||||||
v, ok := r.kinds[kind]
|
v, ok := r.kinds[kind]
|
||||||
|
if !ok {
|
||||||
|
// fallback to default
|
||||||
|
v, ok = r.kinds[entity.StandardKindJSONObj]
|
||||||
|
}
|
||||||
if ok {
|
if ok {
|
||||||
return v.builder
|
return v.builder
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user