| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	"encoding/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
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"path" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 20:50:47 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/dashboards" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							| 
									
										
										
										
											2017-06-06 06:14:40 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/components/dashdiffs" | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/components/simplejson" | 
					
						
							| 
									
										
										
										
											2016-05-24 13:39:58 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/log" | 
					
						
							| 
									
										
										
										
											2015-03-23 03:14:00 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/metrics" | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/middleware" | 
					
						
							|  |  |  | 	m "github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins" | 
					
						
							| 
									
										
										
										
											2017-06-12 21:48:55 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/guardian" | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-01 02:52:57 +08:00
										 |  |  | func isDashboardStarredByUser(c *middleware.Context, dashId int64) (bool, error) { | 
					
						
							| 
									
										
										
										
											2015-02-02 18:32:32 +08:00
										 |  |  | 	if !c.IsSignedIn { | 
					
						
							|  |  |  | 		return false, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	query := m.IsStarredByUserQuery{UserId: c.UserId, DashboardId: dashId} | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return query.Result, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | func dashboardGuardianResponse(err error) Response { | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return ApiError(500, "Error while checking dashboard permissions", err) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return ApiError(403, "Access denied to this dashboard", nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 21:48:55 +08:00
										 |  |  | func GetDashboard(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2018-01-30 04:23:07 +08:00
										 |  |  | 	dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0, c.Params(":uid")) | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	if rsp != nil { | 
					
						
							|  |  |  | 		return rsp | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 23:54:37 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	if canView, err := guardian.CanView(); err != nil || !canView { | 
					
						
							| 
									
										
										
										
											2017-06-23 05:43:55 +08:00
										 |  |  | 		fmt.Printf("%v", err) | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							| 
									
										
										
										
											2017-06-12 21:48:55 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	canEdit, _ := guardian.CanEdit() | 
					
						
							|  |  |  | 	canSave, _ := guardian.CanSave() | 
					
						
							| 
									
										
										
										
											2017-06-23 06:34:19 +08:00
										 |  |  | 	canAdmin, _ := guardian.CanAdmin() | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-12 21:48:55 +08:00
										 |  |  | 	isStarred, err := isDashboardStarredByUser(c, dash.Id) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return ApiError(500, "Error while checking if dashboard was starred by user", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-18 19:38:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-29 01:53:19 +08:00
										 |  |  | 	// Finding creator and last updater of the dashboard
 | 
					
						
							| 
									
										
										
										
											2016-01-28 13:55:54 +08:00
										 |  |  | 	updater, creator := "Anonymous", "Anonymous" | 
					
						
							|  |  |  | 	if dash.UpdatedBy > 0 { | 
					
						
							| 
									
										
										
										
											2016-01-28 14:00:24 +08:00
										 |  |  | 		updater = getUserLogin(dash.UpdatedBy) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if dash.CreatedBy > 0 { | 
					
						
							|  |  |  | 		creator = getUserLogin(dash.CreatedBy) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-18 19:38:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 	meta := dtos.DashboardMeta{ | 
					
						
							|  |  |  | 		IsStarred:   isStarred, | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 		Slug:        dash.Slug, | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 		Type:        m.DashTypeDB, | 
					
						
							|  |  |  | 		CanStar:     c.IsSignedIn, | 
					
						
							|  |  |  | 		CanSave:     canSave, | 
					
						
							|  |  |  | 		CanEdit:     canEdit, | 
					
						
							| 
									
										
										
										
											2017-06-23 06:34:19 +08:00
										 |  |  | 		CanAdmin:    canAdmin, | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 		Created:     dash.Created, | 
					
						
							|  |  |  | 		Updated:     dash.Updated, | 
					
						
							|  |  |  | 		UpdatedBy:   updater, | 
					
						
							|  |  |  | 		CreatedBy:   creator, | 
					
						
							|  |  |  | 		Version:     dash.Version, | 
					
						
							|  |  |  | 		HasAcl:      dash.HasAcl, | 
					
						
							|  |  |  | 		IsFolder:    dash.IsFolder, | 
					
						
							| 
									
										
										
										
											2017-06-24 04:00:26 +08:00
										 |  |  | 		FolderId:    dash.FolderId, | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 		FolderTitle: "Root", | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// lookup folder title
 | 
					
						
							| 
									
										
										
										
											2017-06-24 04:00:26 +08:00
										 |  |  | 	if dash.FolderId > 0 { | 
					
						
							|  |  |  | 		query := m.GetDashboardQuery{Id: dash.FolderId, OrgId: c.OrgId} | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 		if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 			return ApiError(500, "Dashboard folder could not be read", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		meta.FolderTitle = query.Result.Title | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-30 22:24:14 +08:00
										 |  |  | 	if dash.IsFolder { | 
					
						
							|  |  |  | 		meta.Url = m.GetFolderUrl(dash.Uid, dash.Slug) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		meta.Url = m.GetDashboardUrl(dash.Uid, dash.Slug) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 21:40:10 +08:00
										 |  |  | 	// make sure db version is in sync with json model version
 | 
					
						
							|  |  |  | 	dash.Data.Set("version", dash.Version) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-04 14:36:44 +08:00
										 |  |  | 	dto := dtos.DashboardFullWithMeta{ | 
					
						
							|  |  |  | 		Dashboard: dash.Data, | 
					
						
							| 
									
										
										
										
											2017-06-17 04:57:37 +08:00
										 |  |  | 		Meta:      meta, | 
					
						
							| 
									
										
										
										
											2015-01-29 19:10:34 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 23:00:39 +08:00
										 |  |  | 	c.TimeRequest(metrics.M_Api_Dashboard_Get) | 
					
						
							| 
									
										
										
										
											2017-06-12 21:48:55 +08:00
										 |  |  | 	return Json(200, dto) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-28 13:55:54 +08:00
										 |  |  | func getUserLogin(userId int64) string { | 
					
						
							| 
									
										
										
										
											2016-01-28 14:00:24 +08:00
										 |  |  | 	query := m.GetUserByIdQuery{Id: userId} | 
					
						
							|  |  |  | 	err := bus.Dispatch(&query) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return "Anonymous" | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		user := query.Result | 
					
						
							|  |  |  | 		return user.Login | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-28 13:55:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-30 04:23:07 +08:00
										 |  |  | func getDashboardHelper(orgId int64, slug string, id int64, uid string) (*m.Dashboard, Response) { | 
					
						
							|  |  |  | 	var query m.GetDashboardQuery | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(uid) > 0 { | 
					
						
							|  |  |  | 		query = m.GetDashboardQuery{Uid: uid, Id: id, OrgId: orgId} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		query = m.GetDashboardQuery{Slug: slug, Id: id, OrgId: orgId} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 		return nil, ApiError(404, "Dashboard not found", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return query.Result, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func DeleteDashboard(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2018-01-31 23:51:06 +08:00
										 |  |  | 	query := m.GetDashboardsBySlugQuery{OrgId: c.OrgId, Slug: c.Params(":slug")} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to retrieve dashboards by slug", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(query.Result) > 1 { | 
					
						
							|  |  |  | 		return Json(412, util.DynMap{"status": "multiple-slugs-exists", "message": m.ErrDashboardsWithSameSlugExists.Error()}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-30 04:23:07 +08:00
										 |  |  | 	dash, rsp := getDashboardHelper(c.OrgId, c.Params(":slug"), 0, "") | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	if rsp != nil { | 
					
						
							|  |  |  | 		return rsp | 
					
						
							| 
									
										
										
										
											2017-06-13 05:05:32 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	cmd := m.DeleteDashboardCommand{OrgId: c.OrgId, Id: dash.Id} | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 	if err := bus.Dispatch(&cmd); err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-13 05:05:32 +08:00
										 |  |  | 		return ApiError(500, "Failed to delete dashboard", err) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	var resp = map[string]interface{}{"title": dash.Title} | 
					
						
							| 
									
										
										
										
											2017-06-13 05:05:32 +08:00
										 |  |  | 	return Json(200, resp) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 23:46:31 +08:00
										 |  |  | func DeleteDashboardByUid(c *middleware.Context) Response { | 
					
						
							|  |  |  | 	dash, rsp := getDashboardHelper(c.OrgId, "", 0, c.Params(":uid")) | 
					
						
							|  |  |  | 	if rsp != nil { | 
					
						
							|  |  |  | 		return rsp | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd := m.DeleteDashboardCommand{OrgId: c.OrgId, Id: dash.Id} | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&cmd); err != nil { | 
					
						
							|  |  |  | 		return ApiError(500, "Failed to delete dashboard", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var resp = map[string]interface{}{"title": dash.Title} | 
					
						
							|  |  |  | 	return Json(200, resp) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) Response { | 
					
						
							| 
									
										
										
										
											2017-06-05 22:34:32 +08:00
										 |  |  | 	cmd.OrgId = c.OrgId | 
					
						
							|  |  |  | 	cmd.UserId = c.UserId | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-20 22:38:25 +08:00
										 |  |  | 	dash := cmd.GetDashboardModel() | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							| 
									
										
										
										
											2017-06-13 05:05:32 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-24 04:00:26 +08:00
										 |  |  | 	if dash.IsFolder && dash.FolderId > 0 { | 
					
						
							| 
									
										
										
										
											2017-06-16 08:45:21 +08:00
										 |  |  | 		return ApiError(400, m.ErrDashboardFolderCannotHaveParent.Error(), nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-29 18:24:34 +08:00
										 |  |  | 	// Check if Title is empty
 | 
					
						
							|  |  |  | 	if dash.Title == "" { | 
					
						
							|  |  |  | 		return ApiError(400, m.ErrDashboardTitleEmpty.Error(), nil) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-20 22:38:25 +08:00
										 |  |  | 	if dash.Id == 0 { | 
					
						
							| 
									
										
										
										
											2015-09-11 23:17:10 +08:00
										 |  |  | 		limitReached, err := middleware.QuotaReached(c, "dashboard") | 
					
						
							| 
									
										
										
										
											2015-07-20 22:38:25 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 			return ApiError(500, "failed to get quota", err) | 
					
						
							| 
									
										
										
										
											2015-07-20 22:38:25 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if limitReached { | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 			return ApiError(403, "Quota reached", nil) | 
					
						
							| 
									
										
										
										
											2015-07-20 22:38:25 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 20:50:47 +08:00
										 |  |  | 	dashItem := &dashboards.SaveDashboardItem{ | 
					
						
							|  |  |  | 		Dashboard: dash, | 
					
						
							|  |  |  | 		Message:   cmd.Message, | 
					
						
							| 
									
										
										
										
											2016-11-24 18:22:13 +08:00
										 |  |  | 		OrgId:     c.OrgId, | 
					
						
							|  |  |  | 		UserId:    c.UserId, | 
					
						
							| 
									
										
										
										
											2017-12-12 20:18:00 +08:00
										 |  |  | 		Overwrite: cmd.Overwrite, | 
					
						
							| 
									
										
										
										
											2016-11-24 18:22:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 21:20:52 +08:00
										 |  |  | 	dashboard, err := dashboards.GetRepository().SaveDashboard(dashItem) | 
					
						
							| 
									
										
										
										
											2017-12-01 20:50:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if err == m.ErrDashboardTitleEmpty { | 
					
						
							|  |  |  | 		return ApiError(400, m.ErrDashboardTitleEmpty.Error(), nil) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err == m.ErrDashboardContainsInvalidAlertData { | 
					
						
							| 
									
										
										
										
											2016-11-24 18:22:13 +08:00
										 |  |  | 		return ApiError(500, "Invalid alert data. Cannot save dashboard", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-01-06 00:04:29 +08:00
										 |  |  | 		if err == m.ErrDashboardWithSameNameExists { | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 			return Json(412, util.DynMap{"status": "name-exists", "message": err.Error()}) | 
					
						
							| 
									
										
										
										
											2015-03-03 05:24:01 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if err == m.ErrDashboardVersionMismatch { | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 			return Json(412, util.DynMap{"status": "version-mismatch", "message": err.Error()}) | 
					
						
							| 
									
										
										
										
											2015-01-06 00:04:29 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-08 19:41:46 +08:00
										 |  |  | 		if pluginErr, ok := err.(m.UpdatePluginDashboardError); ok { | 
					
						
							| 
									
										
										
										
											2016-07-12 14:41:56 +08:00
										 |  |  | 			message := "The dashboard belongs to plugin " + pluginErr.PluginId + "." | 
					
						
							| 
									
										
										
										
											2016-07-08 19:41:46 +08:00
										 |  |  | 			// look up plugin name
 | 
					
						
							|  |  |  | 			if pluginDef, exist := plugins.Plugins[pluginErr.PluginId]; exist { | 
					
						
							| 
									
										
										
										
											2016-07-12 14:41:56 +08:00
										 |  |  | 				message = "The dashboard belongs to plugin " + pluginDef.Name + "." | 
					
						
							| 
									
										
										
										
											2016-07-08 19:41:46 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return Json(412, util.DynMap{"status": "plugin-dashboard", "message": message}) | 
					
						
							| 
									
										
										
										
											2015-01-06 00:04:29 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-04 13:46:46 +08:00
										 |  |  | 		if err == m.ErrDashboardNotFound { | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 			return Json(404, util.DynMap{"status": "not-found", "message": err.Error()}) | 
					
						
							| 
									
										
										
										
											2015-05-04 13:46:46 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-08 15:35:06 +08:00
										 |  |  | 		return ApiError(500, "Failed to save dashboard", err) | 
					
						
							| 
									
										
										
										
											2016-04-13 16:33:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-01 20:50:47 +08:00
										 |  |  | 	if err == m.ErrDashboardFailedToUpdateAlertData { | 
					
						
							|  |  |  | 		return ApiError(500, "Invalid alert data. Cannot save dashboard", err) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 06:37:54 +08:00
										 |  |  | 	var url string | 
					
						
							|  |  |  | 	if dash.IsFolder { | 
					
						
							|  |  |  | 		url = m.GetFolderUrl(dashboard.Uid, dashboard.Slug) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		url = m.GetDashboardUrl(dashboard.Uid, dashboard.Slug) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 23:00:39 +08:00
										 |  |  | 	c.TimeRequest(metrics.M_Api_Dashboard_Save) | 
					
						
							| 
									
										
										
										
											2018-01-31 06:37:54 +08:00
										 |  |  | 	return Json(200, util.DynMap{ | 
					
						
							|  |  |  | 		"status":  "success", | 
					
						
							|  |  |  | 		"slug":    dashboard.Slug, | 
					
						
							|  |  |  | 		"version": dashboard.Version, | 
					
						
							|  |  |  | 		"id":      dashboard.Id, | 
					
						
							|  |  |  | 		"uid":     dashboard.Uid, | 
					
						
							|  |  |  | 		"url":     url, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | func GetHomeDashboard(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2016-04-03 04:54:06 +08:00
										 |  |  | 	prefsQuery := m.GetPreferencesWithDefaultsQuery{OrgId: c.OrgId, UserId: c.UserId} | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&prefsQuery); err != nil { | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | 		return ApiError(500, "Failed to get preferences", err) | 
					
						
							| 
									
										
										
										
											2016-03-17 17:29:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 04:54:06 +08:00
										 |  |  | 	if prefsQuery.Result.HomeDashboardId != 0 { | 
					
						
							|  |  |  | 		slugQuery := m.GetDashboardSlugByIdQuery{Id: prefsQuery.Result.HomeDashboardId} | 
					
						
							|  |  |  | 		err := bus.Dispatch(&slugQuery) | 
					
						
							| 
									
										
										
										
											2016-05-24 13:39:58 +08:00
										 |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			dashRedirect := dtos.DashboardRedirect{RedirectUri: "db/" + slugQuery.Result} | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | 			return Json(200, &dashRedirect) | 
					
						
							| 
									
										
										
										
											2016-05-24 13:39:58 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			log.Warn("Failed to get slug from database, %s", err.Error()) | 
					
						
							| 
									
										
										
										
											2016-03-17 17:29:34 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 05:06:07 +08:00
										 |  |  | 	filePath := path.Join(setting.StaticRootPath, "dashboards/home.json") | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	file, err := os.Open(filePath) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | 		return ApiError(500, "Failed to load home dashboard", err) | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-04 14:36:44 +08:00
										 |  |  | 	dash := dtos.DashboardFullWithMeta{} | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	dash.Meta.IsHome = true | 
					
						
							| 
									
										
										
										
											2017-12-14 02:18:10 +08:00
										 |  |  | 	dash.Meta.CanEdit = c.SignedInUser.HasRole(m.ROLE_EDITOR) | 
					
						
							| 
									
										
										
										
											2017-06-17 09:25:24 +08:00
										 |  |  | 	dash.Meta.FolderTitle = "Root" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	jsonParser := json.NewDecoder(file) | 
					
						
							| 
									
										
										
										
											2015-05-04 14:36:44 +08:00
										 |  |  | 	if err := jsonParser.Decode(&dash.Dashboard); err != nil { | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | 		return ApiError(500, "Failed to load home dashboard", err) | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | 	if c.HasUserRole(m.ROLE_ADMIN) && !c.HasHelpFlag(m.HelpFlagGettingStartedPanelDismissed) { | 
					
						
							|  |  |  | 		addGettingStartedPanelToHomeDashboard(dash.Dashboard) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 15:56:45 +08:00
										 |  |  | 	return Json(200, &dash) | 
					
						
							| 
									
										
										
										
											2015-02-03 22:04:35 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-05-12 20:11:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | func addGettingStartedPanelToHomeDashboard(dash *simplejson.Json) { | 
					
						
							| 
									
										
										
										
											2017-08-25 20:47:57 +08:00
										 |  |  | 	panels := dash.Get("panels").MustArray() | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	newpanel := simplejson.NewFromAny(map[string]interface{}{ | 
					
						
							| 
									
										
										
										
											2017-10-11 01:48:06 +08:00
										 |  |  | 		"type": "gettingstarted", | 
					
						
							|  |  |  | 		"id":   123123, | 
					
						
							|  |  |  | 		"gridPos": map[string]interface{}{ | 
					
						
							|  |  |  | 			"x": 0, | 
					
						
							|  |  |  | 			"y": 3, | 
					
						
							| 
									
										
										
										
											2017-10-25 01:22:56 +08:00
										 |  |  | 			"w": 24, | 
					
						
							| 
									
										
										
										
											2017-10-11 01:48:06 +08:00
										 |  |  | 			"h": 4, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	panels = append(panels, newpanel) | 
					
						
							| 
									
										
										
										
											2017-08-25 20:47:57 +08:00
										 |  |  | 	dash.Set("panels", panels) | 
					
						
							| 
									
										
										
										
											2016-12-08 17:25:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 05:57:09 +08:00
										 |  |  | // GetDashboardVersions returns all dashboard versions as JSON
 | 
					
						
							|  |  |  | func GetDashboardVersions(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	dashId := c.ParamsInt64(":dashboardId") | 
					
						
							| 
									
										
										
										
											2017-06-14 06:28:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 22:34:32 +08:00
										 |  |  | 	query := m.GetDashboardVersionsQuery{ | 
					
						
							|  |  |  | 		OrgId:       c.OrgId, | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 		DashboardId: dashId, | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 		Limit:       c.QueryInt("limit"), | 
					
						
							|  |  |  | 		Start:       c.QueryInt("start"), | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 		return ApiError(404, fmt.Sprintf("No versions found for dashboardId %d", dashId), err) | 
					
						
							| 
									
										
										
										
											2017-06-02 05:57:09 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-06 04:59:04 +08:00
										 |  |  | 	for _, version := range query.Result { | 
					
						
							|  |  |  | 		if version.RestoredFrom == version.Version { | 
					
						
							| 
									
										
										
										
											2017-06-07 05:04:14 +08:00
										 |  |  | 			version.Message = "Initial save (created by migration)" | 
					
						
							| 
									
										
										
										
											2017-06-06 04:59:04 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if version.RestoredFrom > 0 { | 
					
						
							|  |  |  | 			version.Message = fmt.Sprintf("Restored from version %d", version.RestoredFrom) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if version.ParentVersion == 0 { | 
					
						
							|  |  |  | 			version.Message = "Initial save" | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 05:57:09 +08:00
										 |  |  | 	return Json(200, query.Result) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetDashboardVersion returns the dashboard version with the given ID.
 | 
					
						
							| 
									
										
										
										
											2017-06-02 05:57:09 +08:00
										 |  |  | func GetDashboardVersion(c *middleware.Context) Response { | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	dashId := c.ParamsInt64(":dashboardId") | 
					
						
							| 
									
										
										
										
											2017-06-14 06:28:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dashId, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							| 
									
										
										
										
											2017-06-14 06:28:34 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 22:34:32 +08:00
										 |  |  | 	query := m.GetDashboardVersionQuery{ | 
					
						
							|  |  |  | 		OrgId:       c.OrgId, | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 		DashboardId: dashId, | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 		Version:     c.ParamsInt(":id"), | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-05 22:34:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 		return ApiError(500, fmt.Sprintf("Dashboard version %d not found for dashboardId %d", query.Version, dashId), err) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	creator := "Anonymous" | 
					
						
							|  |  |  | 	if query.Result.CreatedBy > 0 { | 
					
						
							|  |  |  | 		creator = getUserLogin(query.Result.CreatedBy) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dashVersionMeta := &m.DashboardVersionMeta{ | 
					
						
							|  |  |  | 		DashboardVersion: *query.Result, | 
					
						
							|  |  |  | 		CreatedBy:        creator, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 05:57:09 +08:00
										 |  |  | 	return Json(200, dashVersionMeta) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 17:50:09 +08:00
										 |  |  | // POST /api/dashboards/calculate-diff performs diffs on two dashboards
 | 
					
						
							|  |  |  | func CalculateDashboardDiff(c *middleware.Context, apiOptions dtos.CalculateDiffOptions) Response { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 17:50:09 +08:00
										 |  |  | 	options := dashdiffs.Options{ | 
					
						
							|  |  |  | 		OrgId:    c.OrgId, | 
					
						
							|  |  |  | 		DiffType: dashdiffs.ParseDiffType(apiOptions.DiffType), | 
					
						
							|  |  |  | 		Base: dashdiffs.DiffTarget{ | 
					
						
							|  |  |  | 			DashboardId:      apiOptions.Base.DashboardId, | 
					
						
							|  |  |  | 			Version:          apiOptions.Base.Version, | 
					
						
							|  |  |  | 			UnsavedDashboard: apiOptions.Base.UnsavedDashboard, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		New: dashdiffs.DiffTarget{ | 
					
						
							|  |  |  | 			DashboardId:      apiOptions.New.DashboardId, | 
					
						
							|  |  |  | 			Version:          apiOptions.New.Version, | 
					
						
							|  |  |  | 			UnsavedDashboard: apiOptions.New.UnsavedDashboard, | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 17:50:09 +08:00
										 |  |  | 	result, err := dashdiffs.CalculateDiff(&options) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-06-07 20:21:40 +08:00
										 |  |  | 		if err == m.ErrDashboardVersionNotFound { | 
					
						
							|  |  |  | 			return ApiError(404, "Dashboard version not found", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 17:50:09 +08:00
										 |  |  | 		return ApiError(500, "Unable to compute diff", err) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-06 05:29:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 17:50:09 +08:00
										 |  |  | 	if options.DiffType == dashdiffs.DiffDelta { | 
					
						
							|  |  |  | 		return Respond(200, result.Delta).Header("Content-Type", "application/json") | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return Respond(200, result.Delta).Header("Content-Type", "text/html") | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // RestoreDashboardVersion restores a dashboard to the given version.
 | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | func RestoreDashboardVersion(c *middleware.Context, apiCmd dtos.RestoreDashboardVersionCommand) Response { | 
					
						
							| 
									
										
										
										
											2018-01-30 04:23:07 +08:00
										 |  |  | 	dash, rsp := getDashboardHelper(c.OrgId, "", c.ParamsInt64(":dashboardId"), "") | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	if rsp != nil { | 
					
						
							|  |  |  | 		return rsp | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 01:47:44 +08:00
										 |  |  | 	guardian := guardian.NewDashboardGuardian(dash.Id, c.OrgId, c.SignedInUser) | 
					
						
							|  |  |  | 	if canSave, err := guardian.CanSave(); err != nil || !canSave { | 
					
						
							|  |  |  | 		return dashboardGuardianResponse(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	versionQuery := m.GetDashboardVersionQuery{DashboardId: dash.Id, Version: apiCmd.Version, OrgId: c.OrgId} | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 	if err := bus.Dispatch(&versionQuery); err != nil { | 
					
						
							|  |  |  | 		return ApiError(404, "Dashboard version not found", nil) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 	version := versionQuery.Result | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 	saveCmd := m.SaveDashboardCommand{} | 
					
						
							| 
									
										
										
										
											2017-06-06 04:59:04 +08:00
										 |  |  | 	saveCmd.RestoredFrom = version.Version | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 	saveCmd.OrgId = c.OrgId | 
					
						
							|  |  |  | 	saveCmd.UserId = c.UserId | 
					
						
							|  |  |  | 	saveCmd.Dashboard = version.Data | 
					
						
							| 
									
										
										
										
											2017-06-18 06:24:38 +08:00
										 |  |  | 	saveCmd.Dashboard.Set("version", dash.Version) | 
					
						
							| 
									
										
										
										
											2018-02-01 01:16:45 +08:00
										 |  |  | 	saveCmd.Dashboard.Set("uid", dash.Uid) | 
					
						
							| 
									
										
										
										
											2017-06-06 04:59:04 +08:00
										 |  |  | 	saveCmd.Message = fmt.Sprintf("Restored from version %d", version.Version) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-05 23:45:27 +08:00
										 |  |  | 	return PostDashboard(c, saveCmd) | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-13 16:45:53 +08:00
										 |  |  | func GetDashboardTags(c *middleware.Context) { | 
					
						
							|  |  |  | 	query := m.GetDashboardTagsQuery{OrgId: c.OrgId} | 
					
						
							|  |  |  | 	err := bus.Dispatch(&query) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		c.JsonApiErr(500, "Failed to get tags from database", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c.JSON(200, query.Result) | 
					
						
							|  |  |  | } |