public dashboards: move into into its own service (#51358)

This PR moves public dashboards into its own self contained service including API, Service, Database, and Models. Routes are mounted on the Grafana HTTPServer by the API service at injection time with wire.go. The main  route that loads the frontend for public dashboards is still handled by the API package.

Co-authored-by: Jesse Weaver <jesse.weaver@grafana.com>
Co-authored-by: Owen Smallwood <owen.smallwood@grafana.com>
This commit is contained in:
Jeff Levin
2022-07-06 17:51:44 -06:00
committed by GitHub
co-authored by Jesse Weaver Owen Smallwood
parent ba2d8cd838
commit eacee08135
23 changed files with 1632 additions and 1198 deletions
-11
View File
@@ -3,15 +3,12 @@ package dashboards
import (
"context"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
)
//go:generate mockery --name DashboardService --structname FakeDashboardService --inpackage --filename dashboard_service_mock.go
// DashboardService is a service for operating on dashboards.
type DashboardService interface {
BuildPublicDashboardMetricRequest(ctx context.Context, dashboard *models.Dashboard, publicDashboard *models.PublicDashboard, panelId int64) (dtos.MetricRequest, error)
BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error)
BuildSaveDashboardCommand(ctx context.Context, dto *SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error)
DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error
FindDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) ([]DashboardSearchProjection, error)
@@ -20,14 +17,11 @@ type DashboardService interface {
GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error
GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
GetPublicDashboard(ctx context.Context, accessToken string) (*models.Dashboard, error)
GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error)
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error
HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error
ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*models.Dashboard, error)
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error)
SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboard, error)
SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
}
@@ -66,18 +60,13 @@ type Store interface {
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error)
GetPublicDashboard(ctx context.Context, accessToken string) (*models.PublicDashboard, *models.Dashboard, error)
GenerateNewPublicDashboardUid(ctx context.Context) (string, error)
HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error
HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error
// SaveAlerts saves dashboard alerts.
SaveAlerts(ctx context.Context, dashID int64, alerts []*models.Alert) error
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
SavePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboard, error)
UnprovisionDashboard(ctx context.Context, id int64) error
UpdatePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) error
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
// ValidateDashboardBeforeSave validates a dashboard before save.
ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error)
@@ -1,14 +1,12 @@
// Code generated by mockery v2.12.1. DO NOT EDIT.
// Code generated by mockery v2.12.2. DO NOT EDIT.
package dashboards
import (
context "context"
dtos "github.com/grafana/grafana/pkg/api/dtos"
mock "github.com/stretchr/testify/mock"
models "github.com/grafana/grafana/pkg/models"
mock "github.com/stretchr/testify/mock"
testing "testing"
)
@@ -18,50 +16,6 @@ type FakeDashboardService struct {
mock.Mock
}
// BuildAnonymousUser provides a mock function with given fields: ctx, dashboard
func (_m *FakeDashboardService) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error) {
ret := _m.Called(ctx, dashboard)
var r0 *models.SignedInUser
if rf, ok := ret.Get(0).(func(context.Context, *models.Dashboard) *models.SignedInUser); ok {
r0 = rf(ctx, dashboard)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.SignedInUser)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.Dashboard) error); ok {
r1 = rf(ctx, dashboard)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// BuildPublicDashboardMetricRequest provides a mock function with given fields: ctx, dashboard, publicDashboard, panelId
func (_m *FakeDashboardService) BuildPublicDashboardMetricRequest(ctx context.Context, dashboard *models.Dashboard, publicDashboard *models.PublicDashboard, panelId int64) (dtos.MetricRequest, error) {
ret := _m.Called(ctx, dashboard, publicDashboard, panelId)
var r0 dtos.MetricRequest
if rf, ok := ret.Get(0).(func(context.Context, *models.Dashboard, *models.PublicDashboard, int64) dtos.MetricRequest); ok {
r0 = rf(ctx, dashboard, publicDashboard, panelId)
} else {
r0 = ret.Get(0).(dtos.MetricRequest)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.Dashboard, *models.PublicDashboard, int64) error); ok {
r1 = rf(ctx, dashboard, publicDashboard, panelId)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// BuildSaveDashboardCommand provides a mock function with given fields: ctx, dto, shouldValidateAlerts, validateProvisionedDashboard
func (_m *FakeDashboardService) BuildSaveDashboardCommand(ctx context.Context, dto *SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error) {
ret := _m.Called(ctx, dto, shouldValidateAlerts, validateProvisionedDashboard)
@@ -192,52 +146,6 @@ func (_m *FakeDashboardService) GetDashboards(ctx context.Context, query *models
return r0
}
// GetPublicDashboard provides a mock function with given fields: ctx, accessToken
func (_m *FakeDashboardService) GetPublicDashboard(ctx context.Context, accessToken string) (*models.Dashboard, error) {
ret := _m.Called(ctx, accessToken)
var r0 *models.Dashboard
if rf, ok := ret.Get(0).(func(context.Context, string) *models.Dashboard); ok {
r0 = rf(ctx, accessToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Dashboard)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, accessToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetPublicDashboardConfig provides a mock function with given fields: ctx, orgId, dashboardUid
func (_m *FakeDashboardService) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
ret := _m.Called(ctx, orgId, dashboardUid)
var r0 *models.PublicDashboard
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *models.PublicDashboard); ok {
r0 = rf(ctx, orgId, dashboardUid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboard)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, orgId, dashboardUid)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HasAdminPermissionInDashboardsOrFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardService) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
ret := _m.Called(ctx, query)
@@ -326,29 +234,6 @@ func (_m *FakeDashboardService) SaveDashboard(ctx context.Context, dto *SaveDash
return r0, r1
}
// SavePublicDashboardConfig provides a mock function with given fields: ctx, dto
func (_m *FakeDashboardService) SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboard, error) {
ret := _m.Called(ctx, dto)
var r0 *models.PublicDashboard
if rf, ok := ret.Get(0).(func(context.Context, *SavePublicDashboardConfigDTO) *models.PublicDashboard); ok {
r0 = rf(ctx, dto)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboard)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *SavePublicDashboardConfigDTO) error); ok {
r1 = rf(ctx, dto)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// SearchDashboards provides a mock function with given fields: ctx, query
func (_m *FakeDashboardService) SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error {
ret := _m.Called(ctx, query)
@@ -1,148 +0,0 @@
package database
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/util"
)
// retrieves public dashboard configuration
func (d *DashboardStore) GetPublicDashboard(ctx context.Context, accessToken string) (*models.PublicDashboard, *models.Dashboard, error) {
if accessToken == "" {
return nil, nil, dashboards.ErrPublicDashboardIdentifierNotSet
}
// get public dashboard
pdRes := &models.PublicDashboard{AccessToken: accessToken}
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
has, err := sess.Get(pdRes)
if err != nil {
return err
}
if !has {
return dashboards.ErrPublicDashboardNotFound
}
return nil
})
if err != nil {
return nil, nil, err
}
// find dashboard
dashRes := &models.Dashboard{OrgId: pdRes.OrgId, Uid: pdRes.DashboardUid}
err = d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
has, err := sess.Get(dashRes)
if err != nil {
return err
}
if !has {
return dashboards.ErrPublicDashboardNotFound
}
return nil
})
if err != nil {
return nil, nil, err
}
return pdRes, dashRes, err
}
// generates a new unique uid to retrieve a public dashboard
func (d *DashboardStore) GenerateNewPublicDashboardUid(ctx context.Context) (string, error) {
var uid string
err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
for i := 0; i < 3; i++ {
uid = util.GenerateShortUID()
exists, err := sess.Get(&models.PublicDashboard{Uid: uid})
if err != nil {
return err
}
if !exists {
return nil
}
}
return dashboards.ErrPublicDashboardFailedGenerateUniqueUid
})
if err != nil {
return "", err
}
return uid, nil
}
// retrieves public dashboard configuration
func (d *DashboardStore) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
if dashboardUid == "" {
return nil, dashboards.ErrDashboardIdentifierNotSet
}
pdRes := &models.PublicDashboard{OrgId: orgId, DashboardUid: dashboardUid}
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
// publicDashboard
_, err := sess.Get(pdRes)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return pdRes, err
}
// persists public dashboard configuration
func (d *DashboardStore) SavePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboard, error) {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.UseBool("is_enabled").Insert(&cmd.PublicDashboard)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &cmd.PublicDashboard, nil
}
// updates existing public dashboard configuration
func (d *DashboardStore) UpdatePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) error {
err := d.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
timeSettingsJSON, err := cmd.PublicDashboard.TimeSettings.MarshalJSON()
if err != nil {
return err
}
_, err = sess.Exec("UPDATE dashboard_public SET is_enabled = ?, time_settings = ?, updated_by = ?, updated_at = ? WHERE uid = ?",
cmd.PublicDashboard.IsEnabled,
string(timeSettingsJSON),
cmd.PublicDashboard.UpdatedBy,
cmd.PublicDashboard.UpdatedAt.UTC().Format("2006-01-02 15:04:05"),
cmd.PublicDashboard.Uid)
if err != nil {
return err
}
return nil
})
return err
}
@@ -1,273 +0,0 @@
package database
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/util"
)
// This is what the db sets empty time settings to
var DefaultTimeSettings, _ = simplejson.NewJson([]byte(`{}`))
// Default time to pass in with seconds rounded
var DefaultTime = time.Now().UTC().Round(time.Second)
// GetPublicDashboard
func TestIntegrationGetPublicDashboard(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var dashboardStore *DashboardStore
var savedDashboard *models.Dashboard
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = ProvideDashboardStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
}
t.Run("returns PublicDashboard and Dashboard", func(t *testing.T) {
setup()
pubdash, err := dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
PublicDashboard: models.PublicDashboard{
IsEnabled: true,
Uid: "abc1234",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
})
require.NoError(t, err)
pd, d, err := dashboardStore.GetPublicDashboard(context.Background(), "NOTAREALUUID")
require.NoError(t, err)
assert.Equal(t, pd, pubdash)
assert.Equal(t, d.Uid, pubdash.DashboardUid)
})
t.Run("returns ErrPublicDashboardNotFound with empty uid", func(t *testing.T) {
setup()
_, _, err := dashboardStore.GetPublicDashboard(context.Background(), "")
require.Error(t, dashboards.ErrPublicDashboardIdentifierNotSet, err)
})
t.Run("returns ErrPublicDashboardNotFound when PublicDashboard not found", func(t *testing.T) {
setup()
_, _, err := dashboardStore.GetPublicDashboard(context.Background(), "zzzzzz")
require.Error(t, dashboards.ErrPublicDashboardNotFound, err)
})
t.Run("returns ErrDashboardNotFound when Dashboard not found", func(t *testing.T) {
setup()
_, err := dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
PublicDashboard: models.PublicDashboard{
IsEnabled: true,
Uid: "abc1234",
DashboardUid: "nevergonnafindme",
OrgId: savedDashboard.OrgId,
CreatedAt: DefaultTime,
CreatedBy: 7,
},
})
require.NoError(t, err)
_, _, err = dashboardStore.GetPublicDashboard(context.Background(), "abc1234")
require.Error(t, dashboards.ErrDashboardNotFound, err)
})
}
// GetPublicDashboardConfig
func TestIntegrationGetPublicDashboardConfig(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var dashboardStore *DashboardStore
var savedDashboard *models.Dashboard
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
dashboardStore = ProvideDashboardStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
}
t.Run("returns isPublic and set dashboardUid and orgId", func(t *testing.T) {
setup()
pubdash, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
require.NoError(t, err)
assert.Equal(t, &models.PublicDashboard{IsEnabled: false, DashboardUid: savedDashboard.Uid, OrgId: savedDashboard.OrgId}, pubdash)
})
t.Run("returns dashboard errDashboardIdentifierNotSet", func(t *testing.T) {
setup()
_, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, "")
require.Error(t, dashboards.ErrDashboardIdentifierNotSet, err)
})
t.Run("returns isPublic along with public dashboard when exists", func(t *testing.T) {
setup()
// insert test public dashboard
resp, err := dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
PublicDashboard: models.PublicDashboard{
IsEnabled: true,
Uid: "pubdash-uid",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
},
})
require.NoError(t, err)
pubdash, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
require.NoError(t, err)
assert.True(t, assert.ObjectsAreEqualValues(resp, pubdash))
assert.True(t, assert.ObjectsAreEqual(resp, pubdash))
})
}
// SavePublicDashboardConfig
func TestIntegrationSavePublicDashboardConfig(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var dashboardStore *DashboardStore
var savedDashboard *models.Dashboard
var savedDashboard2 *models.Dashboard
setup := func() {
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
dashboardStore = ProvideDashboardStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, true)
}
t.Run("saves new public dashboard", func(t *testing.T) {
setup()
resp, err := dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
PublicDashboard: models.PublicDashboard{
IsEnabled: true,
Uid: "pubdash-uid",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
})
require.NoError(t, err)
pubdash, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
require.NoError(t, err)
//verify saved response and queried response are the same
assert.Equal(t, resp, pubdash)
// verify we have a valid uid
assert.True(t, util.IsValidShortUID(pubdash.Uid))
// verify we didn't update all dashboards
pubdash2, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard2.OrgId, savedDashboard2.Uid)
require.NoError(t, err)
assert.False(t, pubdash2.IsEnabled)
})
}
func TestIntegrationUpdatePublicDashboard(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var dashboardStore *DashboardStore
var savedDashboard *models.Dashboard
var anotherSavedDashboard *models.Dashboard
setup := func() {
sqlStore = sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
dashboardStore = ProvideDashboardStore(sqlStore)
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
anotherSavedDashboard = insertTestDashboard(t, dashboardStore, "test another Dashie", 1, 0, true)
}
t.Run("updates an existing dashboard", func(t *testing.T) {
setup()
// inserting two different public dashboards to test update works and only affect the desired pd by uid
anotherPdUid := "anotherUid"
_, err := dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: anotherSavedDashboard.Uid,
OrgId: anotherSavedDashboard.OrgId,
PublicDashboard: models.PublicDashboard{
Uid: anotherPdUid,
DashboardUid: anotherSavedDashboard.Uid,
OrgId: anotherSavedDashboard.OrgId,
IsEnabled: true,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "fakeaccesstoken",
},
})
require.NoError(t, err)
pdUid := "asdf1234"
_, err = dashboardStore.SavePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
PublicDashboard: models.PublicDashboard{
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: true,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
})
require.NoError(t, err)
updatedPublicDashboard := models.PublicDashboard{
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: false,
TimeSettings: simplejson.NewFromAny(map[string]interface{}{"from": "now-8", "to": "now"}),
UpdatedAt: time.Now().UTC().Round(time.Second),
UpdatedBy: 8,
}
// update initial record
err = dashboardStore.UpdatePublicDashboardConfig(context.Background(), models.SavePublicDashboardConfigCommand{
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
PublicDashboard: updatedPublicDashboard,
})
require.NoError(t, err)
// updated dashboard should have changed
pdRetrieved, err := dashboardStore.GetPublicDashboardConfig(context.Background(), savedDashboard.OrgId, savedDashboard.Uid)
require.NoError(t, err)
assert.Equal(t, updatedPublicDashboard.UpdatedAt, pdRetrieved.UpdatedAt)
// make sure we're correctly updated IsEnabled because we have to call
// UseBool with xorm
assert.Equal(t, updatedPublicDashboard.IsEnabled, pdRetrieved.IsEnabled)
// not updated dashboard shouldn't have changed
pdNotUpdatedRetrieved, err := dashboardStore.GetPublicDashboardConfig(context.Background(), anotherSavedDashboard.OrgId, anotherSavedDashboard.Uid)
require.NoError(t, err)
assert.NotEqual(t, updatedPublicDashboard.UpdatedAt, pdNotUpdatedRetrieved.UpdatedAt)
assert.NotEqual(t, updatedPublicDashboard.IsEnabled, pdNotUpdatedRetrieved.IsEnabled)
})
}
-7
View File
@@ -15,13 +15,6 @@ type SaveDashboardDTO struct {
Dashboard *models.Dashboard
}
type SavePublicDashboardConfigDTO struct {
DashboardUid string
OrgId int64
UserId int64
PublicDashboard *models.PublicDashboard
}
type DashboardSearchProjection struct {
ID int64 `xorm:"id"`
UID string `xorm:"uid"`
@@ -1,171 +0,0 @@
package service
import (
"context"
"fmt"
"time"
"github.com/google/uuid"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
)
// Gets public dashboard via access token
func (dr *DashboardServiceImpl) GetPublicDashboard(ctx context.Context, accessToken string) (*models.Dashboard, error) {
pubdash, d, err := dr.dashboardStore.GetPublicDashboard(ctx, accessToken)
if err != nil {
return nil, err
}
if pubdash == nil || d == nil {
return nil, dashboards.ErrPublicDashboardNotFound
}
if !pubdash.IsEnabled {
return nil, dashboards.ErrPublicDashboardNotFound
}
ts := pubdash.BuildTimeSettings(d)
d.Data.SetPath([]string{"time", "from"}, ts.From)
d.Data.SetPath([]string{"time", "to"}, ts.To)
return d, nil
}
// GetPublicDashboardConfig is a helper method to retrieve the public dashboard configuration for a given dashboard from the database
func (dr *DashboardServiceImpl) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
pdc, err := dr.dashboardStore.GetPublicDashboardConfig(ctx, orgId, dashboardUid)
if err != nil {
return nil, err
}
return pdc, nil
}
// SavePublicDashboardConfig is a helper method to persist the sharing config
// to the database. It handles validations for sharing config and persistence
func (dr *DashboardServiceImpl) SavePublicDashboardConfig(ctx context.Context, dto *dashboards.SavePublicDashboardConfigDTO) (*models.PublicDashboard, error) {
if len(dto.DashboardUid) == 0 {
return nil, dashboards.ErrDashboardIdentifierNotSet
}
// set default value for time settings
if dto.PublicDashboard.TimeSettings == nil {
dto.PublicDashboard.TimeSettings = simplejson.New()
}
if dto.PublicDashboard.Uid == "" {
return dr.savePublicDashboardConfig(ctx, dto)
}
return dr.updatePublicDashboardConfig(ctx, dto)
}
func (dr *DashboardServiceImpl) savePublicDashboardConfig(ctx context.Context, dto *dashboards.SavePublicDashboardConfigDTO) (*models.PublicDashboard, error) {
uid, err := dr.dashboardStore.GenerateNewPublicDashboardUid(ctx)
if err != nil {
return nil, err
}
accessToken, err := GenerateAccessToken()
if err != nil {
return nil, err
}
cmd := models.SavePublicDashboardConfigCommand{
DashboardUid: dto.DashboardUid,
OrgId: dto.OrgId,
PublicDashboard: models.PublicDashboard{
Uid: uid,
DashboardUid: dto.DashboardUid,
OrgId: dto.OrgId,
IsEnabled: dto.PublicDashboard.IsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
CreatedBy: dto.UserId,
CreatedAt: time.Now(),
AccessToken: accessToken,
},
}
return dr.dashboardStore.SavePublicDashboardConfig(ctx, cmd)
}
func (dr *DashboardServiceImpl) updatePublicDashboardConfig(ctx context.Context, dto *dashboards.SavePublicDashboardConfigDTO) (*models.PublicDashboard, error) {
cmd := models.SavePublicDashboardConfigCommand{
PublicDashboard: models.PublicDashboard{
Uid: dto.PublicDashboard.Uid,
IsEnabled: dto.PublicDashboard.IsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
UpdatedBy: dto.UserId,
UpdatedAt: time.Now(),
},
}
err := dr.dashboardStore.UpdatePublicDashboardConfig(ctx, cmd)
if err != nil {
return nil, err
}
publicDashboard, err := dr.dashboardStore.GetPublicDashboardConfig(ctx, dto.OrgId, dto.DashboardUid)
if err != nil {
return nil, err
}
return publicDashboard, nil
}
// BuildPublicDashboardMetricRequest merges public dashboard parameters with
// dashboard and returns a metrics request to be sent to query backend
func (dr *DashboardServiceImpl) BuildPublicDashboardMetricRequest(ctx context.Context, dashboard *models.Dashboard, publicDashboard *models.PublicDashboard, panelId int64) (dtos.MetricRequest, error) {
if !publicDashboard.IsEnabled {
return dtos.MetricRequest{}, dashboards.ErrPublicDashboardNotFound
}
queriesByPanel := models.GroupQueriesByPanelId(dashboard.Data)
if _, ok := queriesByPanel[panelId]; !ok {
return dtos.MetricRequest{}, dashboards.ErrPublicDashboardPanelNotFound
}
ts := publicDashboard.BuildTimeSettings(dashboard)
return dtos.MetricRequest{
From: ts.From,
To: ts.To,
Queries: queriesByPanel[panelId],
}, nil
}
// BuildAnonymousUser creates a user with permissions to read from all datasources used in the dashboard
func (dr *DashboardServiceImpl) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*models.SignedInUser, error) {
datasourceUids := models.GetUniqueDashboardDatasourceUids(dashboard.Data)
// Create a temp user with read-only datasource permissions
anonymousUser := &models.SignedInUser{OrgId: dashboard.OrgId, Permissions: make(map[int64]map[string][]string)}
permissions := make(map[string][]string)
queryScopes := make([]string, 0)
readScopes := make([]string, 0)
for _, uid := range datasourceUids {
queryScopes = append(queryScopes, fmt.Sprintf("datasources:uid:%s", uid))
readScopes = append(readScopes, fmt.Sprintf("datasources:uid:%s", uid))
}
permissions[datasources.ActionQuery] = queryScopes
permissions[datasources.ActionRead] = readScopes
anonymousUser.Permissions[dashboard.OrgId] = permissions
return anonymousUser, nil
}
// generates a uuid formatted without dashes to use as access token
func GenerateAccessToken() (string, error) {
token, err := uuid.NewRandom()
if err != nil {
return "", err
}
return fmt.Sprintf("%x", token[:]), nil
}
@@ -1,492 +0,0 @@
package service
import (
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/database"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
var timeSettings, _ = simplejson.NewJson([]byte(`{"from": "now-12", "to": "now"}`))
var defaultPubdashTimeSettings, _ = simplejson.NewJson([]byte(`{}`))
var dashboardData = simplejson.NewFromAny(map[string]interface{}{"time": map[string]interface{}{"from": "now-8", "to": "now"}})
var mergedDashboardData = simplejson.NewFromAny(map[string]interface{}{"time": map[string]interface{}{"from": "now-12", "to": "now"}})
func TestGetPublicDashboard(t *testing.T) {
type storeResp struct {
pd *models.PublicDashboard
d *models.Dashboard
err error
}
testCases := []struct {
Name string
AccessToken string
StoreResp *storeResp
ErrResp error
DashResp *models.Dashboard
}{
{
Name: "returns a dashboard",
AccessToken: "abc123",
StoreResp: &storeResp{
pd: &models.PublicDashboard{IsEnabled: true},
d: &models.Dashboard{Uid: "mydashboard", Data: dashboardData},
err: nil,
},
ErrResp: nil,
DashResp: &models.Dashboard{Uid: "mydashboard", Data: dashboardData},
},
{
Name: "puts pubdash time settings into dashboard",
AccessToken: "abc123",
StoreResp: &storeResp{
pd: &models.PublicDashboard{IsEnabled: true, TimeSettings: timeSettings},
d: &models.Dashboard{Data: dashboardData},
err: nil,
},
ErrResp: nil,
DashResp: &models.Dashboard{Data: mergedDashboardData},
},
{
Name: "returns ErrPublicDashboardNotFound when isEnabled is false",
AccessToken: "abc123",
StoreResp: &storeResp{
pd: &models.PublicDashboard{IsEnabled: false},
d: &models.Dashboard{Uid: "mydashboard"},
err: nil,
},
ErrResp: dashboards.ErrPublicDashboardNotFound,
DashResp: nil,
},
{
Name: "returns ErrPublicDashboardNotFound if PublicDashboard missing",
AccessToken: "abc123",
StoreResp: &storeResp{pd: nil, d: nil, err: nil},
ErrResp: dashboards.ErrPublicDashboardNotFound,
DashResp: nil,
},
{
Name: "returns ErrPublicDashboardNotFound if Dashboard missing",
AccessToken: "abc123",
StoreResp: &storeResp{pd: nil, d: nil, err: nil},
ErrResp: dashboards.ErrPublicDashboardNotFound,
DashResp: nil,
},
}
for _, test := range testCases {
t.Run(test.Name, func(t *testing.T) {
fakeStore := dashboards.FakeDashboardStore{}
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: &fakeStore,
}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.Anything).
Return(test.StoreResp.pd, test.StoreResp.d, test.StoreResp.err)
dashboard, err := service.GetPublicDashboard(context.Background(), test.AccessToken)
if test.ErrResp != nil {
assert.Error(t, test.ErrResp, err)
} else {
require.NoError(t, err)
}
assert.Equal(t, test.DashResp, dashboard)
if test.DashResp != nil {
assert.NotNil(t, dashboard.CreatedBy)
}
})
}
}
func TestSavePublicDashboard(t *testing.T) {
t.Run("Saving public dashboard", func(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
dto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &models.PublicDashboard{
IsEnabled: true,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
TimeSettings: timeSettings,
},
}
_, err := service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
pubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
// DashboardUid/OrgId/CreatedBy set by the command, not parameters
assert.Equal(t, dashboard.Uid, pubdash.DashboardUid)
assert.Equal(t, dashboard.OrgId, pubdash.OrgId)
assert.Equal(t, dto.UserId, pubdash.CreatedBy)
// IsEnabled set by parameters
assert.Equal(t, dto.PublicDashboard.IsEnabled, pubdash.IsEnabled)
// CreatedAt set to non-zero time
assert.NotEqual(t, &time.Time{}, pubdash.CreatedAt)
// Time settings set by db
assert.Equal(t, timeSettings, pubdash.TimeSettings)
// accessToken is valid uuid
_, err = uuid.Parse(pubdash.AccessToken)
require.NoError(t, err, "expected a valid UUID, got %s", pubdash.AccessToken)
})
t.Run("Validate pubdash has default time setting value", func(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
dto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &models.PublicDashboard{
IsEnabled: true,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
},
}
_, err := service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
pubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
assert.Equal(t, defaultPubdashTimeSettings, pubdash.TimeSettings)
})
t.Run("PLACEHOLDER - dashboard with template variables cannot be saved", func(t *testing.T) {})
}
func TestUpdatePublicDashboard(t *testing.T) {
t.Run("Updating public dashboard", func(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
dto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &models.PublicDashboard{
IsEnabled: true,
TimeSettings: timeSettings,
},
}
_, err := service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
savedPubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
// attempt to overwrite settings
dto = &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 8,
PublicDashboard: &models.PublicDashboard{
Uid: savedPubdash.Uid,
OrgId: 9,
DashboardUid: "abc1234",
CreatedBy: 9,
CreatedAt: time.Time{},
IsEnabled: true,
TimeSettings: timeSettings,
AccessToken: "NOTAREALUUID",
},
}
// Since the dto.PublicDashboard has a uid, this will call
// service.updatePublicDashboardConfig
_, err = service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
updatedPubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
// don't get updated
assert.Equal(t, savedPubdash.DashboardUid, updatedPubdash.DashboardUid)
assert.Equal(t, savedPubdash.OrgId, updatedPubdash.OrgId)
assert.Equal(t, savedPubdash.CreatedAt, updatedPubdash.CreatedAt)
assert.Equal(t, savedPubdash.CreatedBy, updatedPubdash.CreatedBy)
assert.Equal(t, savedPubdash.AccessToken, updatedPubdash.AccessToken)
// gets updated
assert.Equal(t, dto.PublicDashboard.IsEnabled, updatedPubdash.IsEnabled)
assert.Equal(t, dto.PublicDashboard.TimeSettings, updatedPubdash.TimeSettings)
assert.Equal(t, dto.UserId, updatedPubdash.UpdatedBy)
assert.NotEqual(t, &time.Time{}, updatedPubdash.UpdatedAt)
})
t.Run("Updating set empty time settings", func(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
dto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &models.PublicDashboard{
IsEnabled: true,
TimeSettings: timeSettings,
},
}
// Since the dto.PublicDashboard has a uid, this will call
// service.updatePublicDashboardConfig
_, err := service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
savedPubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
// attempt to overwrite settings
dto = &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: dashboard.Uid,
OrgId: dashboard.OrgId,
UserId: 8,
PublicDashboard: &models.PublicDashboard{
Uid: savedPubdash.Uid,
OrgId: 9,
DashboardUid: "abc1234",
CreatedBy: 9,
CreatedAt: time.Time{},
IsEnabled: true,
AccessToken: "NOTAREALUUID",
},
}
_, err = service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
updatedPubdash, err := service.GetPublicDashboardConfig(context.Background(), dashboard.OrgId, dashboard.Uid)
require.NoError(t, err)
timeSettings, err := simplejson.NewJson([]byte("{}"))
require.NoError(t, err)
assert.Equal(t, timeSettings, updatedPubdash.TimeSettings)
})
}
func TestBuildAnonymousUser(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
dashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
t.Run("will add datasource read and query permissions to user for each datasource in dashboard", func(t *testing.T) {
user, err := service.BuildAnonymousUser(context.Background(), dashboard)
require.NoError(t, err)
require.Equal(t, dashboard.OrgId, user.OrgId)
require.Equal(t, "datasources:uid:ds1", user.Permissions[user.OrgId]["datasources:query"][0])
require.Equal(t, "datasources:uid:ds3", user.Permissions[user.OrgId]["datasources:query"][1])
require.Equal(t, "datasources:uid:ds1", user.Permissions[user.OrgId]["datasources:read"][0])
require.Equal(t, "datasources:uid:ds3", user.Permissions[user.OrgId]["datasources:read"][1])
})
}
func TestBuildPublicDashboardMetricRequest(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore)
publicDashboard := insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
nonPublicDashboard := insertTestDashboard(t, dashboardStore, "testNonPublicDashie", 1, 0, true)
service := &DashboardServiceImpl{
log: log.New("test.logger"),
dashboardStore: dashboardStore,
}
dto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: publicDashboard.Uid,
OrgId: publicDashboard.OrgId,
PublicDashboard: &models.PublicDashboard{
IsEnabled: true,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
TimeSettings: timeSettings,
},
}
publicDashboardPD, err := service.SavePublicDashboardConfig(context.Background(), dto)
require.NoError(t, err)
nonPublicDto := &dashboards.SavePublicDashboardConfigDTO{
DashboardUid: nonPublicDashboard.Uid,
OrgId: nonPublicDashboard.OrgId,
PublicDashboard: &models.PublicDashboard{
IsEnabled: false,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
TimeSettings: defaultPubdashTimeSettings,
},
}
nonPublicDashboardPD, err := service.SavePublicDashboardConfig(context.Background(), nonPublicDto)
require.NoError(t, err)
t.Run("extracts queries from provided dashboard", func(t *testing.T) {
reqDTO, err := service.BuildPublicDashboardMetricRequest(
context.Background(),
publicDashboard,
publicDashboardPD,
1,
)
require.NoError(t, err)
require.Equal(t, timeSettings.Get("from").MustString(), reqDTO.From)
require.Equal(t, timeSettings.Get("to").MustString(), reqDTO.To)
require.Len(t, reqDTO.Queries, 2)
require.Equal(
t,
simplejson.MustJson([]byte(`{
"datasource": {
"type": "mysql",
"uid": "ds1"
},
"refId": "A"
}`)),
reqDTO.Queries[0],
)
require.Equal(
t,
simplejson.MustJson([]byte(`{
"datasource": {
"type": "prometheus",
"uid": "ds2"
},
"refId": "B"
}`)),
reqDTO.Queries[1],
)
})
t.Run("returns an error when panel missing", func(t *testing.T) {
_, err := service.BuildPublicDashboardMetricRequest(
context.Background(),
publicDashboard,
publicDashboardPD,
49,
)
require.ErrorContains(t, err, "Panel not found")
})
t.Run("returns an error when dashboard not public", func(t *testing.T) {
_, err := service.BuildPublicDashboardMetricRequest(
context.Background(),
nonPublicDashboard,
nonPublicDashboardPD,
2,
)
require.ErrorContains(t, err, "Public dashboard not found")
})
}
func insertTestDashboard(t *testing.T, dashboardStore *database.DashboardStore, title string, orgId int64,
folderId int64, isFolder bool, tags ...interface{}) *models.Dashboard {
t.Helper()
cmd := models.SaveDashboardCommand{
OrgId: orgId,
FolderId: folderId,
IsFolder: isFolder,
Dashboard: simplejson.NewFromAny(map[string]interface{}{
"id": nil,
"title": title,
"tags": tags,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"datasource": map[string]interface{}{
"uid": "ds1",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "mysql",
"uid": "ds1",
},
"refId": "A",
},
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "ds2",
},
"refId": "B",
},
},
},
map[string]interface{}{
"id": 2,
"datasource": map[string]interface{}{
"uid": "ds3",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "mysql",
"uid": "ds3",
},
"refId": "C",
},
},
},
},
}),
}
dash, err := dashboardStore.SaveDashboard(cmd)
require.NoError(t, err)
require.NotNil(t, dash)
dash.Data.Set("id", dash.Id)
dash.Data.Set("uid", dash.Uid)
return dash
}
+1 -114
View File
@@ -1,4 +1,4 @@
// Code generated by mockery v2.12.1. DO NOT EDIT.
// Code generated by mockery v2.12.2. DO NOT EDIT.
package dashboards
@@ -67,27 +67,6 @@ func (_m *FakeDashboardStore) FindDashboards(ctx context.Context, query *models.
return r0, r1
}
// GenerateNewPublicDashboardUid provides a mock function with given fields: ctx
func (_m *FakeDashboardStore) GenerateNewPublicDashboardUid(ctx context.Context) (string, error) {
ret := _m.Called(ctx)
var r0 string
if rf, ok := ret.Get(0).(func(context.Context) string); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(string)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetDashboard provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) (*models.Dashboard, error) {
ret := _m.Called(ctx, query)
@@ -319,61 +298,6 @@ func (_m *FakeDashboardStore) GetProvisionedDataByDashboardUID(orgID int64, dash
return r0, r1
}
// GetPublicDashboard provides a mock function with given fields: ctx, accessToken
func (_m *FakeDashboardStore) GetPublicDashboard(ctx context.Context, accessToken string) (*models.PublicDashboard, *models.Dashboard, error) {
ret := _m.Called(ctx, accessToken)
var r0 *models.PublicDashboard
if rf, ok := ret.Get(0).(func(context.Context, string) *models.PublicDashboard); ok {
r0 = rf(ctx, accessToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboard)
}
}
var r1 *models.Dashboard
if rf, ok := ret.Get(1).(func(context.Context, string) *models.Dashboard); ok {
r1 = rf(ctx, accessToken)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*models.Dashboard)
}
}
var r2 error
if rf, ok := ret.Get(2).(func(context.Context, string) error); ok {
r2 = rf(ctx, accessToken)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// GetPublicDashboardConfig provides a mock function with given fields: ctx, orgId, dashboardUid
func (_m *FakeDashboardStore) GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboard, error) {
ret := _m.Called(ctx, orgId, dashboardUid)
var r0 *models.PublicDashboard
if rf, ok := ret.Get(0).(func(context.Context, int64, string) *models.PublicDashboard); ok {
r0 = rf(ctx, orgId, dashboardUid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboard)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int64, string) error); ok {
r1 = rf(ctx, orgId, dashboardUid)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// HasAdminPermissionInDashboardsOrFolders provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
ret := _m.Called(ctx, query)
@@ -462,29 +386,6 @@ func (_m *FakeDashboardStore) SaveProvisionedDashboard(cmd models.SaveDashboardC
return r0, r1
}
// SavePublicDashboardConfig provides a mock function with given fields: ctx, cmd
func (_m *FakeDashboardStore) SavePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboard, error) {
ret := _m.Called(ctx, cmd)
var r0 *models.PublicDashboard
if rf, ok := ret.Get(0).(func(context.Context, models.SavePublicDashboardConfigCommand) *models.PublicDashboard); ok {
r0 = rf(ctx, cmd)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboard)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, models.SavePublicDashboardConfigCommand) error); ok {
r1 = rf(ctx, cmd)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// UnprovisionDashboard provides a mock function with given fields: ctx, id
func (_m *FakeDashboardStore) UnprovisionDashboard(ctx context.Context, id int64) error {
ret := _m.Called(ctx, id)
@@ -513,20 +414,6 @@ func (_m *FakeDashboardStore) UpdateDashboardACL(ctx context.Context, uid int64,
return r0
}
// UpdatePublicDashboardConfig provides a mock function with given fields: ctx, cmd
func (_m *FakeDashboardStore) UpdatePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) error {
ret := _m.Called(ctx, cmd)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, models.SavePublicDashboardConfigCommand) error); ok {
r0 = rf(ctx, cmd)
} else {
r0 = ret.Error(0)
}
return r0
}
// ValidateDashboardBeforeSave provides a mock function with given fields: dashboard, overwrite
func (_m *FakeDashboardStore) ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error) {
ret := _m.Called(dashboard, overwrite)