grafana/pkg/models/dashboards.go

185 lines
3.8 KiB
Go
Raw Normal View History

2014-08-08 18:35:15 +08:00
package models
import (
2014-11-20 19:11:07 +08:00
"errors"
"strings"
2014-08-22 04:09:48 +08:00
"time"
"github.com/gosimple/slug"
2016-03-12 07:13:06 +08:00
"github.com/grafana/grafana/pkg/components/simplejson"
2014-08-08 18:35:15 +08:00
)
2014-11-20 19:11:07 +08:00
// Typed errors
var (
ErrDashboardNotFound = errors.New("Dashboard not found")
ErrDashboardSnapshotNotFound = errors.New("Dashboard snapshot not found")
ErrDashboardWithSameNameExists = errors.New("A dashboard with the same name already exists")
ErrDashboardVersionMismatch = errors.New("The dashboard has been changed by someone else")
ErrDashboardTitleEmpty = errors.New("Dashboard title cannot be empty")
2014-10-07 03:31:54 +08:00
)
type UpdatePluginDashboardError struct {
PluginId string
}
func (d UpdatePluginDashboardError) Error() string {
return "Dashboard belong to plugin"
}
var (
DashTypeJson = "file"
DashTypeDB = "db"
DashTypeScript = "script"
DashTypeSnapshot = "snapshot"
)
// Dashboard model
2014-08-08 18:35:15 +08:00
type Dashboard struct {
Id int64
Slug string
OrgId int64
GnetId int64
Version int
PluginId string
2014-11-20 19:11:07 +08:00
Created time.Time
Updated time.Time
2014-08-22 04:09:48 +08:00
2015-12-18 17:52:05 +08:00
UpdatedBy int64
2016-01-28 14:00:24 +08:00
CreatedBy int64
2015-12-18 16:20:23 +08:00
2014-08-22 04:09:48 +08:00
Title string
2016-03-12 07:13:06 +08:00
Data *simplejson.Json
2014-08-22 04:09:48 +08:00
}
// NewDashboard creates a new dashboard
2014-08-08 18:35:15 +08:00
func NewDashboard(title string) *Dashboard {
dash := &Dashboard{}
2016-03-12 07:13:06 +08:00
dash.Data = simplejson.New()
dash.Data.Set("title", title)
dash.Title = title
2015-11-20 20:37:24 +08:00
dash.Created = time.Now()
2015-11-20 20:52:50 +08:00
dash.Updated = time.Now()
dash.UpdateSlug()
2014-08-08 18:35:15 +08:00
return dash
}
// GetTags turns the tags in data json into go string array
func (dash *Dashboard) GetTags() []string {
2016-03-12 07:13:06 +08:00
return dash.Data.Get("tags").MustStringArray()
}
2016-03-12 07:13:06 +08:00
func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
2014-12-22 19:25:08 +08:00
dash := &Dashboard{}
dash.Data = data
2016-03-12 07:13:06 +08:00
dash.Title = dash.Data.Get("title").MustString()
2015-11-20 20:52:50 +08:00
dash.UpdateSlug()
2014-08-08 18:35:15 +08:00
2016-03-12 07:13:06 +08:00
if id, err := dash.Data.Get("id").Float64(); err == nil {
dash.Id = int64(id)
2016-03-12 07:13:06 +08:00
if version, err := dash.Data.Get("version").Float64(); err == nil {
dash.Version = int(version)
2015-11-20 20:52:50 +08:00
dash.Updated = time.Now()
}
} else {
2016-03-12 07:13:06 +08:00
dash.Data.Set("version", 0)
2015-11-20 20:52:50 +08:00
dash.Created = time.Now()
dash.Updated = time.Now()
2014-08-08 18:35:15 +08:00
}
if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
dash.GnetId = int64(gnetId)
}
2014-12-22 19:25:08 +08:00
return dash
2014-08-08 18:35:15 +08:00
}
// GetDashboardModel turns the command into the savable model
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
dash := NewDashboardFromJson(cmd.Dashboard)
userId := cmd.UserId
if userId == 0 {
userId = -1
}
2016-03-12 07:13:06 +08:00
if dash.Data.Get("version").MustInt(0) == 0 {
dash.CreatedBy = userId
2016-01-28 14:00:24 +08:00
}
2016-03-12 07:13:06 +08:00
dash.UpdatedBy = userId
2016-01-28 14:00:24 +08:00
dash.OrgId = cmd.OrgId
dash.PluginId = cmd.PluginId
dash.UpdateSlug()
return dash
}
// GetString a
func (dash *Dashboard) GetString(prop string, defaultValue string) string {
2016-03-12 07:13:06 +08:00
return dash.Data.Get(prop).MustString(defaultValue)
2014-08-08 18:35:15 +08:00
}
// UpdateSlug updates the slug
func (dash *Dashboard) UpdateSlug() {
2016-03-12 07:13:06 +08:00
title := strings.ToLower(dash.Data.Get("title").MustString())
dash.Slug = slug.Make(title)
}
//
// COMMANDS
//
type SaveDashboardCommand struct {
2016-03-12 07:13:06 +08:00
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
UserId int64 `json:"userId"`
OrgId int64 `json:"-"`
Overwrite bool `json:"overwrite"`
PluginId string `json:"-"`
History and Version Control for Dashboard Updates A simple version control system for dashboards. Closes #1504. Goals 1. To create a new dashboard version every time a dashboard is saved. 2. To allow users to view all versions of a given dashboard. 3. To allow users to rollback to a previous version of a dashboard. 4. To allow users to compare two versions of a dashboard. Usage Navigate to a dashboard, and click the settings cog. From there, click the "Changelog" button to be brought to the Changelog view. In this view, a table containing each version of a dashboard can be seen. Each entry in the table represents a dashboard version. A selectable checkbox, the version number, date created, name of the user who created that version, and commit message is shown in the table, along with a button that allows a user to restore to a previous version of that dashboard. If a user wants to restore to a previous version of their dashboard, they can do so by clicking the previously mentioned button. If a user wants to compare two different versions of a dashboard, they can do so by clicking the checkbox of two different dashboard versions, then clicking the "Compare versions" button located below the dashboard. From there, the user is brought to a view showing a summary of the dashboard differences. Each summarized change contains a link that can be clicked to take the user a JSON diff highlighting the changes line by line. Overview of Changes Backend Changes - A `dashboard_version` table was created to store each dashboard version, along with a dashboard version model and structs to represent the queries and commands necessary for the dashboard version API methods. - API endpoints were created to support working with dashboard versions. - Methods were added to create, update, read, and destroy dashboard versions in the database. - Logic was added to compute the diff between two versions, and display it to the user. - The dashboard migration logic was updated to save a "Version 1" of each existing dashboard in the database. Frontend Changes - New views - Methods to pull JSON and HTML from endpoints New API Endpoints Each endpoint requires the authorization header to be sent in the format, ``` Authorization: Bearer <jwt> ``` where `<jwt>` is a JSON web token obtained from the Grafana admin panel. `GET "/api/dashboards/db/:dashboardId/versions?orderBy=<string>&limit=<int>&start=<int>"` Get all dashboard versions for the given dashboard ID. Accepts three URL parameters: - `orderBy` String to order the results by. Possible values are `version`, `created`, `created_by`, `message`. Default is `versions`. Ordering is always in descending order. - `limit` Maximum number of results to return - `start` Position in results to start from `GET "/api/dashboards/db/:dashboardId/versions/:id"` Get an individual dashboard version by ID, for the given dashboard ID. `POST "/api/dashboards/db/:dashboardId/restore"` Restore to the given dashboard version. Post body is of content-type `application/json`, and must contain. ```json { "dashboardId": <int>, "version": <int> } ``` `GET "/api/dashboards/db/:dashboardId/compare/:versionA...:versionB"` Compare two dashboard versions by ID for the given dashboard ID, returning a JSON delta formatted representation of the diff. The URL format follows what GitHub does. For example, visiting [/api/dashboards/db/18/compare/22...33](http://ec2-54-80-139-44.compute-1.amazonaws.com:3000/api/dashboards/db/18/compare/22...33) will return the diff between versions 22 and 33 for the dashboard ID 18. Dependencies Added - The Go package [gojsondiff](https://github.com/yudai/gojsondiff) was added and vendored.
2017-05-25 07:14:39 +08:00
Message string `json:"message"`
Result *Dashboard
}
type DeleteDashboardCommand struct {
Slug string
OrgId int64
}
//
// QUERIES
//
type GetDashboardQuery struct {
Slug string
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
Result []*Dashboard
}
type GetDashboardsByPluginIdQuery struct {
OrgId int64
PluginId string
Result []*Dashboard
}
2016-03-17 16:01:58 +08:00
type GetDashboardSlugByIdQuery struct {
Id int64
Result string
}