grafana/pkg/plugins/dashboards.go
Marcus Efraimsson 0e8377a9f4 Update logic for create/update dashboard, validation and plugin dashboard links (#10809)
* enables overwrite if dashboard allready exist in folder

* dashboard: Don't allow creating a folder named General

* dashboards: update logic for save/update dashboard

No id and uid creates a new dashboard/folder.
No id and uid, with an existing title in folder allows overwrite
  of dashboard.
Id without uid, allows update of existing dashboard/folder without
  overwrite.
Uid without id allows update of existing dashboard/folder without
  overwrite.
Id without uid, with an existing title in folder allows overwrite
  of dashboard/folder and updated will have the uid of overwritten.
Uid without id, with an existing title in folder allows overwrite
  of dashboard/folder and new will have the same uid as provided.
Trying to change an existing folder to a dashboard yields error.
Trying to change an existing dashboard to a folder yields error.

* dashboards: include folder id when confirmed to save with overwrite

* dashboards: fixes due to new url structure

Return importedUrl property in response to importing dashboards and
getting plugin dashboards and use this for redirects/links in the
frontend.
2018-02-08 12:48:38 +01:00

113 lines
2.8 KiB
Go

package plugins
import (
"os"
"path/filepath"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
m "github.com/grafana/grafana/pkg/models"
)
type PluginDashboardInfoDTO struct {
PluginId string `json:"pluginId"`
Title string `json:"title"`
Imported bool `json:"imported"`
ImportedUri string `json:"importedUri"`
ImportedUrl string `json:"importedUrl"`
Slug string `json:"slug"`
DashboardId int64 `json:"dashboardId"`
ImportedRevision int64 `json:"importedRevision"`
Revision int64 `json:"revision"`
Description string `json:"description"`
Path string `json:"path"`
Removed bool `json:"removed"`
}
func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) {
plugin, exists := Plugins[pluginId]
if !exists {
return nil, PluginNotFoundError{pluginId}
}
result := make([]*PluginDashboardInfoDTO, 0)
// load current dashboards
query := m.GetDashboardsByPluginIdQuery{OrgId: orgId, PluginId: pluginId}
if err := bus.Dispatch(&query); err != nil {
return nil, err
}
existingMatches := make(map[int64]bool)
for _, include := range plugin.Includes {
if include.Type != PluginTypeDashboard {
continue
}
res := &PluginDashboardInfoDTO{}
var dashboard *m.Dashboard
var err error
if dashboard, err = loadPluginDashboard(plugin.Id, include.Path); err != nil {
return nil, err
}
res.Path = include.Path
res.PluginId = plugin.Id
res.Title = dashboard.Title
res.Revision = dashboard.Data.Get("revision").MustInt64(1)
// find existing dashboard
for _, existingDash := range query.Result {
if existingDash.Slug == dashboard.Slug {
res.DashboardId = existingDash.Id
res.Imported = true
res.ImportedUri = "db/" + existingDash.Slug
res.ImportedUrl = existingDash.GetUrl()
res.ImportedRevision = existingDash.Data.Get("revision").MustInt64(1)
existingMatches[existingDash.Id] = true
}
}
result = append(result, res)
}
// find deleted dashboards
for _, dash := range query.Result {
if _, exists := existingMatches[dash.Id]; !exists {
result = append(result, &PluginDashboardInfoDTO{
Slug: dash.Slug,
DashboardId: dash.Id,
Removed: true,
})
}
}
return result, nil
}
func loadPluginDashboard(pluginId, path string) (*m.Dashboard, error) {
plugin, exists := Plugins[pluginId]
if !exists {
return nil, PluginNotFoundError{pluginId}
}
dashboardFilePath := filepath.Join(plugin.PluginDir, path)
reader, err := os.Open(dashboardFilePath)
if err != nil {
return nil, err
}
defer reader.Close()
data, err := simplejson.NewFromReader(reader)
if err != nil {
return nil, err
}
return m.NewDashboardFromJson(data), nil
}