2014-12-22 05:25:08 -06:00
package sqlstore
import (
2018-01-30 16:31:02 -06:00
"strings"
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-24 18:14:39 -05:00
"time"
2015-02-04 04:35:59 -06:00
2015-02-05 03:37:13 -06:00
"github.com/grafana/grafana/pkg/bus"
2015-03-22 14:14:00 -05:00
"github.com/grafana/grafana/pkg/metrics"
2015-02-05 03:37:13 -06:00
m "github.com/grafana/grafana/pkg/models"
2015-06-05 01:15:38 -05:00
"github.com/grafana/grafana/pkg/services/search"
2018-01-31 10:27:28 -06:00
"github.com/grafana/grafana/pkg/util"
2014-12-22 05:25:08 -06:00
)
func init ( ) {
2014-12-29 06:58:06 -06:00
bus . AddHandler ( "sql" , SaveDashboard )
bus . AddHandler ( "sql" , GetDashboard )
2016-01-28 18:41:23 -06:00
bus . AddHandler ( "sql" , GetDashboards )
2014-12-29 06:58:06 -06:00
bus . AddHandler ( "sql" , DeleteDashboard )
bus . AddHandler ( "sql" , SearchDashboards )
2015-01-06 11:39:26 -06:00
bus . AddHandler ( "sql" , GetDashboardTags )
2016-03-17 03:01:58 -05:00
bus . AddHandler ( "sql" , GetDashboardSlugById )
2018-02-01 06:32:00 -06:00
bus . AddHandler ( "sql" , GetDashboardUIDById )
2016-07-08 02:35:06 -05:00
bus . AddHandler ( "sql" , GetDashboardsByPluginId )
2018-01-30 16:31:02 -06:00
bus . AddHandler ( "sql" , GetDashboardPermissionsForUser )
2018-02-01 07:13:42 -06:00
bus . AddHandler ( "sql" , GetDashboardsBySlug )
2018-02-19 04:12:56 -06:00
bus . AddHandler ( "sql" , ValidateDashboardBeforeSave )
2014-12-22 05:25:08 -06:00
}
2018-01-31 10:27:28 -06:00
var generateNewUid func ( ) string = util . GenerateShortUid
2014-12-29 06:58:06 -06:00
func SaveDashboard ( cmd * m . SaveDashboardCommand ) error {
2017-05-23 03:56:23 -05:00
return inTransaction ( func ( sess * DBSession ) error {
2018-01-23 05:28:56 -06:00
return saveDashboard ( sess , cmd )
} )
}
2017-06-01 16:30:31 -05:00
2018-01-23 05:28:56 -06:00
func saveDashboard ( sess * DBSession , cmd * m . SaveDashboardCommand ) error {
dash := cmd . GetDashboardModel ( )
2015-01-05 10:04:29 -06:00
2018-02-22 04:54:28 -06:00
userId := cmd . UserId
if userId == 0 {
userId = - 1
}
2018-02-19 04:12:56 -06:00
if dash . Id > 0 {
var existing m . Dashboard
dashWithIdExists , err := sess . Where ( "id=? AND org_id=?" , dash . Id , dash . OrgId ) . Get ( & existing )
if err != nil {
return err
}
if ! dashWithIdExists {
return m . ErrDashboardNotFound
}
2015-05-04 01:19:29 -05:00
2018-02-19 04:12:56 -06:00
// check for is someone else has written in between
if dash . Version != existing . Version {
2018-02-08 06:43:19 -06:00
if cmd . Overwrite {
2018-02-19 04:12:56 -06:00
dash . SetVersion ( existing . Version )
2018-02-08 06:43:19 -06:00
} else {
2018-02-19 04:12:56 -06:00
return m . ErrDashboardVersionMismatch
2015-05-04 01:19:29 -05:00
}
}
2018-02-19 04:12:56 -06:00
// do not allow plugin dashboard updates without overwrite flag
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
if existing . PluginId != "" && ! cmd . Overwrite {
2018-02-19 04:12:56 -06:00
return m . UpdatePluginDashboardError { PluginId : existing . PluginId }
}
2018-01-23 05:28:56 -06:00
}
2015-05-04 01:19:29 -05:00
2018-02-08 04:01:09 -06:00
if dash . Uid == "" {
uid , err := generateNewDashboardUid ( sess , dash . OrgId )
2018-01-31 06:47:28 -06:00
if err != nil {
return err
2015-05-04 01:19:29 -05:00
}
2018-02-19 04:12:56 -06:00
dash . SetUid ( uid )
2018-01-23 05:28:56 -06:00
}
parentVersion := dash . Version
affectedRows := int64 ( 0 )
2018-02-19 04:12:56 -06:00
var err error
2018-01-23 05:28:56 -06:00
if dash . Id == 0 {
2018-02-19 04:12:56 -06:00
dash . SetVersion ( 1 )
2018-02-22 04:54:28 -06:00
dash . Created = time . Now ( )
dash . CreatedBy = userId
dash . Updated = time . Now ( )
dash . UpdatedBy = userId
2018-01-23 05:28:56 -06:00
metrics . M_Api_Dashboard_Insert . Inc ( )
affectedRows , err = sess . Insert ( dash )
} else {
2018-02-22 04:54:28 -06:00
dash . SetVersion ( dash . Version + 1 )
2018-01-23 05:28:56 -06:00
if ! cmd . UpdatedAt . IsZero ( ) {
dash . Updated = cmd . UpdatedAt
2018-02-22 04:54:28 -06:00
} else {
dash . Updated = time . Now ( )
2017-06-23 16:22:09 -05:00
}
2018-02-22 04:54:28 -06:00
dash . UpdatedBy = userId
2018-02-14 08:04:26 -06:00
affectedRows , err = sess . MustCols ( "folder_id" ) . ID ( dash . Id ) . Update ( dash )
2018-01-23 05:28:56 -06:00
}
2017-06-05 09:34:32 -05:00
2018-01-23 05:28:56 -06:00
if err != nil {
return err
}
2017-11-23 04:29:06 -06:00
2018-01-23 05:28:56 -06:00
if affectedRows == 0 {
return m . ErrDashboardNotFound
}
dashVersion := & m . DashboardVersion {
DashboardId : dash . Id ,
ParentVersion : parentVersion ,
RestoredFrom : cmd . RestoredFrom ,
Version : dash . Version ,
Created : time . Now ( ) ,
CreatedBy : dash . UpdatedBy ,
Message : cmd . Message ,
Data : dash . Data ,
}
2017-11-23 04:29:06 -06:00
2018-01-23 05:28:56 -06:00
// insert version entry
if affectedRows , err = sess . Insert ( dashVersion ) ; err != nil {
return err
} else if affectedRows == 0 {
return m . ErrDashboardNotFound
}
2014-12-22 05:25:08 -06:00
2018-01-23 05:28:56 -06:00
// delete existing tags
_ , err = sess . Exec ( "DELETE FROM dashboard_tag WHERE dashboard_id=?" , dash . Id )
if err != nil {
return err
}
2015-01-07 05:37:24 -06:00
2018-01-23 05:28:56 -06:00
// insert new tags
tags := dash . GetTags ( )
if len ( tags ) > 0 {
for _ , tag := range tags {
if _ , err := sess . Insert ( & DashboardTag { DashboardId : dash . Id , Term : tag } ) ; err != nil {
return err
2015-01-07 05:37:24 -06:00
}
2015-05-04 00:46:46 -05:00
}
2018-01-23 05:28:56 -06:00
}
2014-12-22 05:25:08 -06:00
2018-01-23 05:28:56 -06:00
cmd . Result = dash
2017-06-05 09:34:32 -05:00
2018-01-23 05:28:56 -06:00
return err
2014-12-22 05:25:08 -06:00
}
2018-01-31 10:27:28 -06:00
func generateNewDashboardUid ( sess * DBSession , orgId int64 ) ( string , error ) {
for i := 0 ; i < 3 ; i ++ {
uid := generateNewUid ( )
exists , err := sess . Where ( "org_id=? AND uid=?" , orgId , uid ) . Get ( & m . Dashboard { } )
if err != nil {
return "" , err
}
if ! exists {
return uid , nil
}
}
return "" , m . ErrDashboardFailedGenerateUniqueUid
}
2014-12-22 05:25:08 -06:00
2014-12-29 06:58:06 -06:00
func GetDashboard ( query * m . GetDashboardQuery ) error {
2018-01-29 14:23:07 -06:00
dashboard := m . Dashboard { Slug : query . Slug , OrgId : query . OrgId , Id : query . Id , Uid : query . Uid }
2014-12-22 05:25:08 -06:00
has , err := x . Get ( & dashboard )
2017-06-05 10:45:27 -05:00
2014-12-22 05:25:08 -06:00
if err != nil {
2014-12-29 06:58:06 -06:00
return err
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
} else if ! has {
2014-12-29 06:58:06 -06:00
return m . ErrDashboardNotFound
2014-12-22 05:25:08 -06:00
}
2018-02-19 04:12:56 -06:00
dashboard . SetId ( dashboard . Id )
dashboard . SetUid ( dashboard . Uid )
2014-12-29 06:58:06 -06:00
query . Result = & dashboard
return nil
2014-12-22 05:25:08 -06:00
}
2015-01-07 05:37:24 -06:00
type DashboardSearchProjection struct {
2017-06-16 20:00:13 -05:00
Id int64
2018-01-30 08:24:14 -06:00
Uid string
2017-06-16 20:00:13 -05:00
Title string
Slug string
Term string
IsFolder bool
2017-06-23 15:00:26 -05:00
FolderId int64
2018-02-05 06:23:24 -06:00
FolderUid string
2017-06-16 20:00:13 -05:00
FolderSlug string
FolderTitle string
2015-01-07 05:37:24 -06:00
}
2017-03-27 07:36:28 -05:00
func findDashboards ( query * search . FindPersistedDashboardsQuery ) ( [ ] DashboardSearchProjection , error ) {
2017-06-23 16:13:58 -05:00
limit := query . Limit
if limit == 0 {
limit = 1000
}
2018-02-08 10:11:01 -06:00
sb := NewSearchBuilder ( query . SignedInUser , limit , query . Permission ) .
2017-11-17 08:30:21 -06:00
WithTags ( query . Tags ) .
WithDashboardIdsIn ( query . DashboardIds )
2015-01-06 10:15:52 -06:00
2015-02-04 04:35:59 -06:00
if query . IsStarred {
2017-11-16 17:16:33 -06:00
sb . IsStarred ( )
2017-06-16 19:33:53 -05:00
}
2015-02-04 04:35:59 -06:00
if len ( query . Title ) > 0 {
2017-11-16 17:16:33 -06:00
sb . WithTitle ( query . Title )
2015-02-04 04:35:59 -06:00
}
2014-12-22 05:25:08 -06:00
2017-11-16 17:16:33 -06:00
if len ( query . Type ) > 0 {
sb . WithType ( query . Type )
2017-05-24 11:28:13 -05:00
}
2017-11-20 05:47:03 -06:00
if len ( query . FolderIds ) > 0 {
sb . WithFolderIds ( query . FolderIds )
2017-11-17 08:30:21 -06:00
}
2017-11-16 17:16:33 -06:00
var res [ ] DashboardSearchProjection
sql , params := sb . ToSql ( )
err := x . Sql ( sql , params ... ) . Find ( & res )
if err != nil {
return nil , err
2017-06-01 16:30:31 -05:00
}
2017-11-16 17:16:33 -06:00
return res , nil
2017-03-27 07:36:28 -05:00
}
func SearchDashboards ( query * search . FindPersistedDashboardsQuery ) error {
res , err := findDashboards ( query )
2015-01-07 05:37:24 -06:00
if err != nil {
return err
}
2017-06-01 16:30:31 -05:00
makeQueryResult ( query , res )
2015-01-07 05:37:24 -06:00
2017-06-01 16:30:31 -05:00
return nil
2014-12-22 05:25:08 -06:00
}
2017-03-27 07:36:28 -05:00
func getHitType ( item DashboardSearchProjection ) search . HitType {
var hitType search . HitType
if item . IsFolder {
hitType = search . DashHitFolder
} else {
hitType = search . DashHitDB
}
return hitType
}
2017-06-01 16:30:31 -05:00
func makeQueryResult ( query * search . FindPersistedDashboardsQuery , res [ ] DashboardSearchProjection ) {
query . Result = make ( [ ] * search . Hit , 0 )
hits := make ( map [ int64 ] * search . Hit )
for _ , item := range res {
hit , exists := hits [ item . Id ]
if ! exists {
hit = & search . Hit {
2017-06-23 15:00:26 -05:00
Id : item . Id ,
2018-01-31 10:15:00 -06:00
Uid : item . Uid ,
2017-06-23 15:00:26 -05:00
Title : item . Title ,
Uri : "db/" + item . Slug ,
2018-01-31 16:14:48 -06:00
Url : m . GetDashboardFolderUrl ( item . IsFolder , item . Uid , item . Slug ) ,
2017-06-23 15:00:26 -05:00
Type : getHitType ( item ) ,
FolderId : item . FolderId ,
2018-02-05 06:23:24 -06:00
FolderUid : item . FolderUid ,
2017-06-23 15:00:26 -05:00
FolderTitle : item . FolderTitle ,
Tags : [ ] string { } ,
2017-06-01 16:30:31 -05:00
}
2018-01-30 08:24:14 -06:00
2018-02-05 06:23:24 -06:00
if item . FolderId > 0 {
hit . FolderUrl = m . GetFolderUrl ( item . FolderUid , item . FolderSlug )
}
2017-06-01 16:30:31 -05:00
query . Result = append ( query . Result , hit )
hits [ item . Id ] = hit
}
if len ( item . Term ) > 0 {
hit . Tags = append ( hit . Tags , item . Term )
}
}
}
2015-01-06 11:39:26 -06:00
func GetDashboardTags ( query * m . GetDashboardTagsQuery ) error {
2015-01-20 08:23:14 -06:00
sql := ` SELECT
COUNT ( * ) as count ,
term
FROM dashboard
INNER JOIN dashboard_tag on dashboard_tag . dashboard_id = dashboard . id
2015-02-23 13:07:49 -06:00
WHERE dashboard . org_id = ?
2015-01-20 08:23:14 -06:00
GROUP BY term `
query . Result = make ( [ ] * m . DashboardTagCloudItem , 0 )
2015-02-23 13:07:49 -06:00
sess := x . Sql ( sql , query . OrgId )
2015-01-07 05:37:24 -06:00
err := sess . Find ( & query . Result )
return err
2015-01-06 11:39:26 -06:00
}
2014-12-29 06:58:06 -06:00
func DeleteDashboard ( cmd * m . DeleteDashboardCommand ) error {
2017-05-23 03:56:23 -05:00
return inTransaction ( func ( sess * DBSession ) error {
2017-06-17 17:24:38 -05:00
dashboard := m . Dashboard { Id : cmd . Id , OrgId : cmd . OrgId }
2016-04-25 04:22:13 -05:00
has , err := sess . Get ( & dashboard )
2015-08-12 02:23:46 -05:00
if err != nil {
return err
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
} else if ! has {
2015-08-12 02:23:46 -05:00
return m . ErrDashboardNotFound
}
2014-12-22 05:25:08 -06:00
2015-08-12 02:23:46 -05:00
deletes := [ ] string {
"DELETE FROM dashboard_tag WHERE dashboard_id = ? " ,
"DELETE FROM star WHERE dashboard_id = ? " ,
"DELETE FROM dashboard WHERE id = ?" ,
2016-11-06 03:49:43 -06:00
"DELETE FROM playlist_item WHERE type = 'dashboard_by_id' AND value = ?" ,
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-24 18:14:39 -05:00
"DELETE FROM dashboard_version WHERE dashboard_id = ?" ,
2017-06-23 15:00:26 -05:00
"DELETE FROM dashboard WHERE folder_id = ?" ,
2017-10-07 03:31:39 -05:00
"DELETE FROM annotation WHERE dashboard_id = ?" ,
2018-01-25 08:25:07 -06:00
"DELETE FROM dashboard_provisioning WHERE dashboard_id = ?" ,
2015-08-12 02:23:46 -05:00
}
2014-12-22 05:25:08 -06:00
2015-08-12 02:23:46 -05:00
for _ , sql := range deletes {
_ , err := sess . Exec ( sql , dashboard . Id )
if err != nil {
return err
}
}
2018-03-13 05:23:44 -05:00
if err := deleteAlertDefinition ( dashboard . Id , sess ) ; err != nil {
2016-04-26 08:48:29 -05:00
return nil
}
2015-08-12 02:23:46 -05:00
return nil
} )
2014-12-22 05:25:08 -06:00
}
2016-01-28 18:41:23 -06:00
func GetDashboards ( query * m . GetDashboardsQuery ) error {
if len ( query . DashboardIds ) == 0 {
return m . ErrCommandValidationFailed
}
2016-06-23 09:30:12 -05:00
var dashboards = make ( [ ] * m . Dashboard , 0 )
2016-01-28 18:41:23 -06:00
err := x . In ( "id" , query . DashboardIds ) . Find ( & dashboards )
2016-06-23 09:30:12 -05:00
query . Result = dashboards
2018-04-16 12:54:23 -05:00
return err
2016-01-28 18:41:23 -06:00
}
2016-03-17 03:01:58 -05:00
2018-01-30 16:31:02 -06:00
// GetDashboardPermissionsForUser returns the maximum permission the specified user has for a dashboard(s)
// The function takes in a list of dashboard ids and the user id and role
func GetDashboardPermissionsForUser ( query * m . GetDashboardPermissionsForUserQuery ) error {
if len ( query . DashboardIds ) == 0 {
return m . ErrCommandValidationFailed
}
if query . OrgRole == m . ROLE_ADMIN {
var permissions = make ( [ ] * m . DashboardPermissionForUser , 0 )
for _ , d := range query . DashboardIds {
permissions = append ( permissions , & m . DashboardPermissionForUser {
DashboardId : d ,
Permission : m . PERMISSION_ADMIN ,
PermissionName : m . PERMISSION_ADMIN . String ( ) ,
} )
}
query . Result = permissions
return nil
}
params := make ( [ ] interface { } , 0 )
// check dashboards that have ACLs via user id, team id or role
sql := ` SELECT d . id AS dashboard_id , MAX ( COALESCE ( da . permission , pt . permission ) ) AS permission
FROM dashboard AS d
LEFT JOIN dashboard_acl as da on d . folder_id = da . dashboard_id or d . id = da . dashboard_id
LEFT JOIN team_member as ugm on ugm . team_id = da . team_id
LEFT JOIN org_user ou ON ou . role = da . role AND ou . user_id = ?
`
params = append ( params , query . UserId )
//check the user's role for dashboards that do not have hasAcl set
sql += ` LEFT JOIN org_user ouRole ON ouRole.user_id = ? AND ouRole.org_id = ? `
params = append ( params , query . UserId )
params = append ( params , query . OrgId )
sql += `
2018-02-01 10:27:29 -06:00
LEFT JOIN ( SELECT 1 AS permission , ' Viewer ' AS role
UNION SELECT 2 AS permission , ' Editor ' AS role
UNION SELECT 4 AS permission , ' Admin ' AS role ) pt ON ouRole . role = pt . role
2018-01-30 16:31:02 -06:00
WHERE
d . Id IN ( ? ` + strings.Repeat(",?", len(query.DashboardIds)-1) + ` ) `
for _ , id := range query . DashboardIds {
params = append ( params , id )
}
sql += ` AND
d . org_id = ? AND
(
( d . has_acl = ? AND ( da . user_id = ? OR ugm . user_id = ? OR ou . id IS NOT NULL ) )
OR ( d . has_acl = ? AND ouRole . id IS NOT NULL )
)
group by d . id
order by d . id asc `
params = append ( params , query . OrgId )
2018-02-01 10:27:29 -06:00
params = append ( params , dialect . BooleanStr ( true ) )
2018-01-30 16:31:02 -06:00
params = append ( params , query . UserId )
params = append ( params , query . UserId )
params = append ( params , dialect . BooleanStr ( false ) )
err := x . Sql ( sql , params ... ) . Find ( & query . Result )
for _ , p := range query . Result {
p . PermissionName = p . Permission . String ( )
}
return err
}
2016-07-08 02:35:06 -05:00
func GetDashboardsByPluginId ( query * m . GetDashboardsByPluginIdQuery ) error {
var dashboards = make ( [ ] * m . Dashboard , 0 )
2017-12-20 05:15:49 -06:00
whereExpr := "org_id=? AND plugin_id=? AND is_folder=" + dialect . BooleanStr ( false )
2016-07-08 02:35:06 -05:00
2017-12-20 05:15:49 -06:00
err := x . Where ( whereExpr , query . OrgId , query . PluginId ) . Find ( & dashboards )
2016-07-08 02:35:06 -05:00
query . Result = dashboards
2018-04-16 12:54:23 -05:00
return err
2016-01-28 18:41:23 -06:00
}
2016-03-17 03:01:58 -05:00
2016-03-20 05:52:19 -05:00
type DashboardSlugDTO struct {
Slug string
}
2016-03-17 03:01:58 -05:00
func GetDashboardSlugById ( query * m . GetDashboardSlugByIdQuery ) error {
2016-03-20 05:52:19 -05:00
var rawSql = ` SELECT slug from dashboard WHERE Id=? `
var slug = DashboardSlugDTO { }
2018-02-01 06:32:00 -06:00
exists , err := x . SQL ( rawSql , query . Id ) . Get ( & slug )
2016-03-17 03:01:58 -05:00
if err != nil {
return err
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
} else if ! exists {
2016-03-17 03:01:58 -05:00
return m . ErrDashboardNotFound
}
2016-03-20 05:52:19 -05:00
query . Result = slug . Slug
2016-03-17 03:01:58 -05:00
return nil
}
2018-01-31 09:51:06 -06:00
func GetDashboardsBySlug ( query * m . GetDashboardsBySlugQuery ) error {
2018-02-01 07:13:42 -06:00
var dashboards [ ] * m . Dashboard
2018-01-31 09:51:06 -06:00
if err := x . Where ( "org_id=? AND slug=?" , query . OrgId , query . Slug ) . Find ( & dashboards ) ; err != nil {
return err
}
query . Result = dashboards
return nil
}
2018-02-01 06:32:00 -06:00
2018-02-05 03:24:48 -06:00
func GetDashboardUIDById ( query * m . GetDashboardRefByIdQuery ) error {
2018-02-01 06:32:00 -06:00
var rawSql = ` SELECT uid, slug from dashboard WHERE Id=? `
us := & m . DashboardRef { }
exists , err := x . SQL ( rawSql , query . Id ) . Get ( us )
if err != nil {
return err
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
} else if ! exists {
2018-02-01 06:32:00 -06:00
return m . ErrDashboardNotFound
}
query . Result = us
return nil
}
2018-02-19 04:12:56 -06:00
func getExistingDashboardByIdOrUidForUpdate ( sess * DBSession , cmd * m . ValidateDashboardBeforeSaveCommand ) ( err error ) {
dash := cmd . Dashboard
dashWithIdExists := false
var existingById m . Dashboard
if dash . Id > 0 {
dashWithIdExists , err = sess . Where ( "id=? AND org_id=?" , dash . Id , dash . OrgId ) . Get ( & existingById )
if err != nil {
return err
}
if ! dashWithIdExists {
return m . ErrDashboardNotFound
}
if dash . Uid == "" {
dash . SetUid ( existingById . Uid )
}
}
dashWithUidExists := false
var existingByUid m . Dashboard
if dash . Uid != "" {
dashWithUidExists , err = sess . Where ( "org_id=? AND uid=?" , dash . OrgId , dash . Uid ) . Get ( & existingByUid )
if err != nil {
return err
}
}
if dash . FolderId > 0 {
var existingFolder m . Dashboard
folderExists , folderErr := sess . Where ( "org_id=? AND id=? AND is_folder=?" , dash . OrgId , dash . FolderId , dialect . BooleanStr ( true ) ) . Get ( & existingFolder )
if folderErr != nil {
return folderErr
}
if ! folderExists {
2018-02-19 06:32:45 -06:00
return m . ErrDashboardFolderNotFound
2018-02-19 04:12:56 -06:00
}
}
if ! dashWithIdExists && ! dashWithUidExists {
return nil
}
if dashWithIdExists && dashWithUidExists && existingById . Id != existingByUid . Id {
return m . ErrDashboardWithSameUIDExists
}
existing := existingById
if ! dashWithIdExists && dashWithUidExists {
dash . SetId ( existingByUid . Id )
dash . SetUid ( existingByUid . Uid )
existing = existingByUid
2018-04-10 17:23:50 -05:00
if ! dash . IsFolder {
cmd . Result . IsParentFolderChanged = true
}
2018-02-19 04:12:56 -06:00
}
if ( existing . IsFolder && ! dash . IsFolder ) ||
( ! existing . IsFolder && dash . IsFolder ) {
return m . ErrDashboardTypeMismatch
}
2018-04-10 17:23:50 -05:00
if ! dash . IsFolder && dash . FolderId != existing . FolderId {
cmd . Result . IsParentFolderChanged = true
}
2018-02-19 04:12:56 -06:00
// check for is someone else has written in between
if dash . Version != existing . Version {
if cmd . Overwrite {
dash . SetVersion ( existing . Version )
} else {
return m . ErrDashboardVersionMismatch
}
}
// do not allow plugin dashboard updates without overwrite flag
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
if existing . PluginId != "" && ! cmd . Overwrite {
2018-02-19 04:12:56 -06:00
return m . UpdatePluginDashboardError { PluginId : existing . PluginId }
}
return nil
}
func getExistingDashboardByTitleAndFolder ( sess * DBSession , cmd * m . ValidateDashboardBeforeSaveCommand ) error {
dash := cmd . Dashboard
var existing m . Dashboard
exists , err := sess . Where ( "org_id=? AND slug=? AND (is_folder=? OR folder_id=?)" , dash . OrgId , dash . Slug , dialect . BooleanStr ( true ) , dash . FolderId ) . Get ( & existing )
if err != nil {
return err
}
if exists && dash . Id != existing . Id {
if existing . IsFolder && ! dash . IsFolder {
return m . ErrDashboardWithSameNameAsFolder
}
if ! existing . IsFolder && dash . IsFolder {
return m . ErrDashboardFolderWithSameNameAsDashboard
}
2018-04-10 17:23:50 -05:00
if ! dash . IsFolder && ( dash . FolderId != existing . FolderId || dash . Id == 0 ) {
cmd . Result . IsParentFolderChanged = true
}
2018-02-19 04:12:56 -06:00
if cmd . Overwrite {
dash . SetId ( existing . Id )
dash . SetUid ( existing . Uid )
dash . SetVersion ( existing . Version )
} else {
return m . ErrDashboardWithSameNameInFolderExists
}
}
return nil
}
func ValidateDashboardBeforeSave ( cmd * m . ValidateDashboardBeforeSaveCommand ) ( err error ) {
2018-04-10 17:23:50 -05:00
cmd . Result = & m . ValidateDashboardBeforeSaveResult { }
2018-02-19 04:12:56 -06:00
return inTransaction ( func ( sess * DBSession ) error {
if err = getExistingDashboardByIdOrUidForUpdate ( sess , cmd ) ; err != nil {
return err
}
if err = getExistingDashboardByTitleAndFolder ( sess , cmd ) ; err != nil {
return err
}
return nil
} )
}