mirror of
https://github.com/grafana/grafana.git
synced 2024-11-23 09:26:43 -06:00
2e16d5499e
* add api route for validating a dashboard json * add feature flag for showDashboardValidationWarnings * tidy up * comments and messages * swagger specs * fix typo * more swagger * tests! * tidy test a little bit * no more ioutil * api will return different status code depending on validation error * clean up * handle 4xx errors * remove console.log * fix backend tests * tidy up * Swagger: Exclude alpha endpoints Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
312 lines
6.9 KiB
Go
312 lines
6.9 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gosimple/slug"
|
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
const RootFolderName = "General"
|
|
|
|
const (
|
|
DashTypeDB = "db"
|
|
DashTypeSnapshot = "snapshot"
|
|
)
|
|
|
|
// Dashboard model
|
|
type Dashboard struct {
|
|
Id int64
|
|
Uid string
|
|
Slug string
|
|
OrgId int64
|
|
GnetId int64
|
|
Version int
|
|
PluginId string
|
|
|
|
Created time.Time
|
|
Updated time.Time
|
|
|
|
UpdatedBy int64
|
|
CreatedBy int64
|
|
FolderId int64
|
|
IsFolder bool
|
|
HasACL bool `xorm:"has_acl"`
|
|
|
|
Title string
|
|
Data *simplejson.Json
|
|
}
|
|
|
|
func (d *Dashboard) SetId(id int64) {
|
|
d.Id = id
|
|
d.Data.Set("id", id)
|
|
}
|
|
|
|
func (d *Dashboard) SetUid(uid string) {
|
|
d.Uid = uid
|
|
d.Data.Set("uid", uid)
|
|
}
|
|
|
|
func (d *Dashboard) SetVersion(version int) {
|
|
d.Version = version
|
|
d.Data.Set("version", version)
|
|
}
|
|
|
|
// GetDashboardIdForSavePermissionCheck return the dashboard id to be used for checking permission of dashboard
|
|
func (d *Dashboard) GetDashboardIdForSavePermissionCheck() int64 {
|
|
if d.Id == 0 {
|
|
return d.FolderId
|
|
}
|
|
|
|
return d.Id
|
|
}
|
|
|
|
// NewDashboard creates a new dashboard
|
|
func NewDashboard(title string) *Dashboard {
|
|
dash := &Dashboard{}
|
|
dash.Data = simplejson.New()
|
|
dash.Data.Set("title", title)
|
|
dash.Title = title
|
|
dash.Created = time.Now()
|
|
dash.Updated = time.Now()
|
|
dash.UpdateSlug()
|
|
return dash
|
|
}
|
|
|
|
// NewDashboardFolder creates a new dashboard folder
|
|
func NewDashboardFolder(title string) *Dashboard {
|
|
folder := NewDashboard(title)
|
|
folder.IsFolder = true
|
|
folder.Data.Set("schemaVersion", 17)
|
|
folder.Data.Set("version", 0)
|
|
folder.IsFolder = true
|
|
return folder
|
|
}
|
|
|
|
// GetTags turns the tags in data json into go string array
|
|
func (d *Dashboard) GetTags() []string {
|
|
return d.Data.Get("tags").MustStringArray()
|
|
}
|
|
|
|
func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
|
|
dash := &Dashboard{}
|
|
dash.Data = data
|
|
dash.Title = dash.Data.Get("title").MustString()
|
|
dash.UpdateSlug()
|
|
update := false
|
|
|
|
if id, err := dash.Data.Get("id").Float64(); err == nil {
|
|
dash.Id = int64(id)
|
|
update = true
|
|
}
|
|
|
|
if uid, err := dash.Data.Get("uid").String(); err == nil {
|
|
dash.Uid = uid
|
|
update = true
|
|
}
|
|
|
|
if version, err := dash.Data.Get("version").Float64(); err == nil && update {
|
|
dash.Version = int(version)
|
|
dash.Updated = time.Now()
|
|
} else {
|
|
dash.Data.Set("version", 0)
|
|
dash.Created = time.Now()
|
|
dash.Updated = time.Now()
|
|
}
|
|
|
|
if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
|
|
dash.GnetId = int64(gnetId)
|
|
}
|
|
|
|
return dash
|
|
}
|
|
|
|
// GetDashboardModel turns the command into the saveable model
|
|
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
|
|
dash := NewDashboardFromJson(cmd.Dashboard)
|
|
userId := cmd.UserId
|
|
|
|
if userId == 0 {
|
|
userId = -1
|
|
}
|
|
|
|
dash.UpdatedBy = userId
|
|
dash.OrgId = cmd.OrgId
|
|
dash.PluginId = cmd.PluginId
|
|
dash.IsFolder = cmd.IsFolder
|
|
dash.FolderId = cmd.FolderId
|
|
dash.UpdateSlug()
|
|
return dash
|
|
}
|
|
|
|
// UpdateSlug updates the slug
|
|
func (d *Dashboard) UpdateSlug() {
|
|
title := d.Data.Get("title").MustString()
|
|
d.Slug = SlugifyTitle(title)
|
|
}
|
|
|
|
func SlugifyTitle(title string) string {
|
|
s := slug.Make(strings.ToLower(title))
|
|
if s == "" {
|
|
// If the dashboard name is only characters outside of the
|
|
// sluggable characters, the slug creation will return an
|
|
// empty string which will mess up URLs. This failsafe picks
|
|
// that up and creates the slug as a base64 identifier instead.
|
|
s = base64.RawURLEncoding.EncodeToString([]byte(title))
|
|
if slug.MaxLength != 0 && len(s) > slug.MaxLength {
|
|
s = s[:slug.MaxLength]
|
|
}
|
|
}
|
|
return s
|
|
}
|
|
|
|
// GetUrl return the html url for a folder if it's folder, otherwise for a dashboard
|
|
func (d *Dashboard) GetUrl() string {
|
|
return GetDashboardFolderUrl(d.IsFolder, d.Uid, d.Slug)
|
|
}
|
|
|
|
// GetDashboardFolderUrl return the html url for a folder if it's folder, otherwise for a dashboard
|
|
func GetDashboardFolderUrl(isFolder bool, uid string, slug string) string {
|
|
if isFolder {
|
|
return GetFolderUrl(uid, slug)
|
|
}
|
|
|
|
return GetDashboardUrl(uid, slug)
|
|
}
|
|
|
|
// GetDashboardUrl returns the HTML url for a dashboard.
|
|
func GetDashboardUrl(uid string, slug string) string {
|
|
return fmt.Sprintf("%s/d/%s/%s", setting.AppSubUrl, uid, slug)
|
|
}
|
|
|
|
// GetKioskModeDashboardUrl returns the HTML url for a dashboard in kiosk mode.
|
|
func GetKioskModeDashboardUrl(uid string, slug string, theme Theme) string {
|
|
return fmt.Sprintf("%s?kiosk&theme=%s", GetDashboardUrl(uid, slug), string(theme))
|
|
}
|
|
|
|
// GetFullDashboardUrl returns the full URL for a dashboard.
|
|
func GetFullDashboardUrl(uid string, slug string) string {
|
|
return fmt.Sprintf("%sd/%s/%s", setting.AppUrl, uid, slug)
|
|
}
|
|
|
|
// GetFolderUrl returns the HTML url for a folder.
|
|
func GetFolderUrl(folderUid string, slug string) string {
|
|
return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug)
|
|
}
|
|
|
|
type ValidateDashboardBeforeSaveResult struct {
|
|
IsParentFolderChanged bool
|
|
}
|
|
|
|
//
|
|
// COMMANDS
|
|
//
|
|
|
|
type SaveDashboardCommand struct {
|
|
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
|
|
UserId int64 `json:"userId"`
|
|
Overwrite bool `json:"overwrite"`
|
|
Message string `json:"message"`
|
|
OrgId int64 `json:"-"`
|
|
RestoredFrom int `json:"-"`
|
|
PluginId string `json:"-"`
|
|
FolderId int64 `json:"folderId"`
|
|
FolderUid string `json:"folderUid"`
|
|
IsFolder bool `json:"isFolder"`
|
|
|
|
UpdatedAt time.Time
|
|
|
|
Result *Dashboard `json:"-"`
|
|
}
|
|
|
|
type ValidateDashboardCommand struct {
|
|
Dashboard string `json:"dashboard" binding:"Required"`
|
|
}
|
|
|
|
type TrimDashboardCommand struct {
|
|
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
|
|
Meta *simplejson.Json `json:"meta"`
|
|
Result *Dashboard `json:"-"`
|
|
}
|
|
|
|
type DashboardProvisioning struct {
|
|
Id int64
|
|
DashboardId int64
|
|
Name string
|
|
ExternalId string
|
|
CheckSum string
|
|
Updated int64
|
|
}
|
|
|
|
type DeleteDashboardCommand struct {
|
|
Id int64
|
|
OrgId int64
|
|
ForceDeleteFolderRules bool
|
|
}
|
|
|
|
type DeleteOrphanedProvisionedDashboardsCommand struct {
|
|
ReaderNames []string
|
|
}
|
|
|
|
//
|
|
// QUERIES
|
|
//
|
|
|
|
type GetDashboardQuery struct {
|
|
Slug string // required if no Id or Uid is specified
|
|
Id int64 // optional if slug is set
|
|
Uid string // optional if slug is set
|
|
OrgId int64
|
|
|
|
Result *Dashboard
|
|
}
|
|
|
|
type DashboardTagCloudItem struct {
|
|
Term string `json:"term"`
|
|
Count int `json:"count"`
|
|
}
|
|
|
|
type GetDashboardTagsQuery struct {
|
|
OrgId int64
|
|
Result []*DashboardTagCloudItem
|
|
}
|
|
|
|
type GetDashboardsQuery struct {
|
|
DashboardIds []int64
|
|
DashboardUIds []string
|
|
Result []*Dashboard
|
|
}
|
|
|
|
type GetDashboardsByPluginIdQuery struct {
|
|
OrgId int64
|
|
PluginId string
|
|
Result []*Dashboard
|
|
}
|
|
|
|
type GetDashboardSlugByIdQuery struct {
|
|
Id int64
|
|
Result string
|
|
}
|
|
|
|
type GetDashboardsBySlugQuery struct {
|
|
OrgId int64
|
|
Slug string
|
|
|
|
Result []*Dashboard
|
|
}
|
|
|
|
type DashboardRef struct {
|
|
Uid string
|
|
Slug string
|
|
}
|
|
|
|
type GetDashboardRefByIdQuery struct {
|
|
Id int64
|
|
Result *DashboardRef
|
|
}
|