mirror of
https://github.com/grafana/grafana.git
synced 2026-08-18 17:15:08 -05:00
Add store split for Get Dashboard version method (#49138)
* Add store split for Get Dashboard version method * Implement dashboard version service * Fix api tests * Remove GetDashboarVersion from sqlstore * Add fakes for Get dashboard version * Fix sqlstore test * Add Get Dashboard store test * Add dashver service test * Remove useless comments
This commit is contained in:
+14
-12
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
dashboardsstore "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/ldap"
|
||||
"github.com/grafana/grafana/pkg/services/login/loginservice"
|
||||
@@ -154,18 +155,19 @@ func (sc *scenarioContext) fakeReqNoAssertionsWithCookie(method, url string, coo
|
||||
}
|
||||
|
||||
type scenarioContext struct {
|
||||
t *testing.T
|
||||
cfg *setting.Cfg
|
||||
m *web.Mux
|
||||
context *models.ReqContext
|
||||
resp *httptest.ResponseRecorder
|
||||
handlerFunc handlerFunc
|
||||
defaultHandler web.Handler
|
||||
req *http.Request
|
||||
url string
|
||||
userAuthTokenService *auth.FakeUserAuthTokenService
|
||||
sqlStore sqlstore.Store
|
||||
authInfoService *logintest.AuthInfoServiceFake
|
||||
t *testing.T
|
||||
cfg *setting.Cfg
|
||||
m *web.Mux
|
||||
context *models.ReqContext
|
||||
resp *httptest.ResponseRecorder
|
||||
handlerFunc handlerFunc
|
||||
defaultHandler web.Handler
|
||||
req *http.Request
|
||||
url string
|
||||
userAuthTokenService *auth.FakeUserAuthTokenService
|
||||
sqlStore sqlstore.Store
|
||||
authInfoService *logintest.AuthInfoServiceFake
|
||||
dashboardVersionService dashver.Service
|
||||
}
|
||||
|
||||
func (sc *scenarioContext) exec() {
|
||||
|
||||
+31
-28
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
@@ -624,31 +625,32 @@ func (hs *HTTPServer) GetDashboardVersion(c *models.ReqContext) response.Respons
|
||||
}
|
||||
|
||||
version, _ := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 32)
|
||||
query := models.GetDashboardVersionQuery{
|
||||
OrgId: c.OrgId,
|
||||
DashboardId: dashID,
|
||||
query := dashver.GetDashboardVersionQuery{
|
||||
OrgID: c.OrgId,
|
||||
DashboardID: dashID,
|
||||
Version: int(version),
|
||||
}
|
||||
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &query); err != nil {
|
||||
res, err := hs.dashboardVersionService.Get(c.Req.Context(), &query)
|
||||
if err != nil {
|
||||
return response.Error(500, fmt.Sprintf("Dashboard version %d not found for dashboardId %d", query.Version, dashID), err)
|
||||
}
|
||||
|
||||
creator := anonString
|
||||
if query.Result.CreatedBy > 0 {
|
||||
creator = hs.getUserLogin(c.Req.Context(), query.Result.CreatedBy)
|
||||
if res.CreatedBy > 0 {
|
||||
creator = hs.getUserLogin(c.Req.Context(), res.CreatedBy)
|
||||
}
|
||||
|
||||
dashVersionMeta := &models.DashboardVersionMeta{
|
||||
Id: query.Result.Id,
|
||||
DashboardId: query.Result.DashboardId,
|
||||
Id: res.ID,
|
||||
DashboardId: res.DashboardID,
|
||||
DashboardUID: dashUID,
|
||||
Data: query.Result.Data,
|
||||
ParentVersion: query.Result.ParentVersion,
|
||||
RestoredFrom: query.Result.RestoredFrom,
|
||||
Version: query.Result.Version,
|
||||
Created: query.Result.Created,
|
||||
Message: query.Result.Message,
|
||||
Data: res.Data,
|
||||
ParentVersion: res.ParentVersion,
|
||||
RestoredFrom: res.RestoredFrom,
|
||||
Version: res.Version,
|
||||
Created: res.Created,
|
||||
Message: res.Message,
|
||||
CreatedBy: creator,
|
||||
}
|
||||
|
||||
@@ -688,34 +690,36 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *models.ReqContext) response.Resp
|
||||
},
|
||||
}
|
||||
|
||||
baseVersionQuery := models.GetDashboardVersionQuery{
|
||||
DashboardId: options.Base.DashboardId,
|
||||
baseVersionQuery := dashver.GetDashboardVersionQuery{
|
||||
DashboardID: options.Base.DashboardId,
|
||||
Version: options.Base.Version,
|
||||
OrgId: options.OrgId,
|
||||
OrgID: options.OrgId,
|
||||
}
|
||||
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &baseVersionQuery); err != nil {
|
||||
baseVersionRes, err := hs.dashboardVersionService.Get(c.Req.Context(), &baseVersionQuery)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDashboardVersionNotFound) {
|
||||
return response.Error(404, "Dashboard version not found", err)
|
||||
}
|
||||
return response.Error(500, "Unable to compute diff", err)
|
||||
}
|
||||
|
||||
newVersionQuery := models.GetDashboardVersionQuery{
|
||||
DashboardId: options.New.DashboardId,
|
||||
newVersionQuery := dashver.GetDashboardVersionQuery{
|
||||
DashboardID: options.New.DashboardId,
|
||||
Version: options.New.Version,
|
||||
OrgId: options.OrgId,
|
||||
OrgID: options.OrgId,
|
||||
}
|
||||
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &newVersionQuery); err != nil {
|
||||
newVersionRes, err := hs.dashboardVersionService.Get(c.Req.Context(), &newVersionQuery)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrDashboardVersionNotFound) {
|
||||
return response.Error(404, "Dashboard version not found", err)
|
||||
}
|
||||
return response.Error(500, "Unable to compute diff", err)
|
||||
}
|
||||
|
||||
baseData := baseVersionQuery.Result.Data
|
||||
newData := newVersionQuery.Result.Data
|
||||
baseData := baseVersionRes.Data
|
||||
newData := newVersionRes.Data
|
||||
|
||||
result, err := dashdiffs.CalculateDiff(c.Req.Context(), &options, baseData, newData)
|
||||
|
||||
@@ -765,13 +769,12 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext) response.Res
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
||||
versionQuery := models.GetDashboardVersionQuery{DashboardId: dashID, Version: apiCmd.Version, OrgId: c.OrgId}
|
||||
if err := hs.SQLStore.GetDashboardVersion(c.Req.Context(), &versionQuery); err != nil {
|
||||
versionQuery := dashver.GetDashboardVersionQuery{DashboardID: dashID, Version: apiCmd.Version, OrgID: c.OrgId}
|
||||
version, err := hs.dashboardVersionService.Get(c.Req.Context(), &versionQuery)
|
||||
if err != nil {
|
||||
return response.Error(404, "Dashboard version not found", nil)
|
||||
}
|
||||
|
||||
version := versionQuery.Result
|
||||
|
||||
saveCmd := models.SaveDashboardCommand{}
|
||||
saveCmd.RestoredFrom = version.Version
|
||||
saveCmd.OrgId = c.OrgId
|
||||
|
||||
+93
-48
@@ -27,6 +27,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/service"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/dashboardversion/dashvertest"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||
@@ -49,13 +51,15 @@ func TestGetHomeDashboard(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
cfg.StaticRootPath = "../../public/"
|
||||
prefService := preftest.NewPreferenceServiceFake()
|
||||
dashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
preferenceService: prefService,
|
||||
Cfg: cfg,
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockstore.NewSQLStoreMock(),
|
||||
preferenceService: prefService,
|
||||
dashboardVersionService: dashboardVersionService,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -122,6 +126,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = false
|
||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
fakeDashboardVersionService.ExpectedDashboardVersion = &dashver.DashboardVersion{}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
@@ -131,13 +137,14 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockSQLStore,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
dashboardService: dashboardService,
|
||||
Cfg: setting.NewCfg(),
|
||||
pluginStore: &fakePluginStore{},
|
||||
SQLStore: mockSQLStore,
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
dashboardService: dashboardService,
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
}
|
||||
|
||||
setUp := func() {
|
||||
@@ -225,6 +232,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
fakeDash.Id = 1
|
||||
fakeDash.FolderId = 1
|
||||
fakeDash.HasAcl = true
|
||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
fakeDashboardVersionService.ExpectedDashboardVersion = &dashver.DashboardVersion{}
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
dashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*models.GetDashboardQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*models.GetDashboardQuery)
|
||||
@@ -236,14 +245,15 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
sql := sqlstore.InitTestDB(t)
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
Live: newTestLive(t, sql),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
SQLStore: mockSQLStore,
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
dashboardService: dashboardService,
|
||||
Cfg: cfg,
|
||||
Live: newTestLive(t, sql),
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: mockSQLStore,
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
dashboardService: dashboardService,
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
}
|
||||
|
||||
setUp := func() {
|
||||
@@ -389,6 +399,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
loggedInUserScenarioWithRole(t, "When calling GET on", "GET", "/api/dashboards/id/2/versions/1", "/api/dashboards/id/:dashboardId/versions/:id", role, func(sc *scenarioContext) {
|
||||
setUpInner()
|
||||
sc.sqlStore = mockSQLStore
|
||||
sc.dashboardVersionService = fakeDashboardVersionService
|
||||
hs.callGetDashboardVersion(sc)
|
||||
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
@@ -705,6 +716,23 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
"title": "Dash2",
|
||||
})},
|
||||
}
|
||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
fakeDashboardVersionService.ExpectedDashboardVersions = []*dashver.DashboardVersion{
|
||||
{
|
||||
DashboardID: 1,
|
||||
Version: 1,
|
||||
Data: simplejson.NewFromAny(map[string]interface{}{
|
||||
"title": "Dash1",
|
||||
}),
|
||||
},
|
||||
{
|
||||
DashboardID: 2,
|
||||
Version: 2,
|
||||
Data: simplejson.NewFromAny(map[string]interface{}{
|
||||
"title": "Dash2",
|
||||
}),
|
||||
},
|
||||
}
|
||||
sqlmock := mockstore.SQLStoreMock{ExpectedDashboardVersions: dashboardvs}
|
||||
setUp := func() {
|
||||
mockResult := []*models.DashboardAclInfoDTO{}
|
||||
@@ -730,7 +758,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, 403, sc.resp.Code)
|
||||
}, &sqlmock)
|
||||
}, &sqlmock, fakeDashboardVersionService)
|
||||
})
|
||||
|
||||
t.Run("when user does have permission", func(t *testing.T) {
|
||||
@@ -739,9 +767,10 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
postDiffScenario(t, "When calling POST on", "/api/dashboards/calculate-diff", "/api/dashboards/calculate-diff", cmd, role, func(sc *scenarioContext) {
|
||||
setUp()
|
||||
|
||||
sc.dashboardVersionService = fakeDashboardVersionService
|
||||
callPostDashboard(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, &sqlmock)
|
||||
}, &sqlmock, fakeDashboardVersionService)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -767,16 +796,18 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
}
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
mockSQLStore.ExpectedDashboardVersions = []*models.DashboardVersion{
|
||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
fakeDashboardVersionService.ExpectedDashboardVersions = []*dashver.DashboardVersion{
|
||||
{
|
||||
DashboardId: 2,
|
||||
DashboardID: 2,
|
||||
Version: 1,
|
||||
Data: fakeDash.Data,
|
||||
}}
|
||||
|
||||
mockSQLStore := mockstore.NewSQLStoreMock()
|
||||
restoreDashboardVersionScenario(t, "When calling POST on", "/api/dashboards/id/1/restore",
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, cmd, func(sc *scenarioContext) {
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, fakeDashboardVersionService, cmd, func(sc *scenarioContext) {
|
||||
sc.dashboardVersionService = fakeDashboardVersionService
|
||||
|
||||
callRestoreDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@@ -799,6 +830,14 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
}
|
||||
}).Return(nil, nil)
|
||||
|
||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||
fakeDashboardVersionService.ExpectedDashboardVersions = []*dashver.DashboardVersion{
|
||||
{
|
||||
DashboardID: 2,
|
||||
Version: 1,
|
||||
Data: fakeDash.Data,
|
||||
}}
|
||||
|
||||
cmd := dtos.RestoreDashboardVersionCommand{
|
||||
Version: 1,
|
||||
}
|
||||
@@ -810,7 +849,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
Data: fakeDash.Data,
|
||||
}}
|
||||
restoreDashboardVersionScenario(t, "When calling POST on", "/api/dashboards/id/1/restore",
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, cmd, func(sc *scenarioContext) {
|
||||
"/api/dashboards/id/:dashboardId/restore", dashboardService, fakeDashboardVersionService, cmd, func(sc *scenarioContext) {
|
||||
callRestoreDashboardVersion(sc)
|
||||
assert.Equal(t, 200, sc.resp.Code)
|
||||
}, mockSQLStore)
|
||||
@@ -1003,18 +1042,20 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
||||
})
|
||||
}
|
||||
|
||||
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions, role models.RoleType, fn scenarioFunc, sqlmock sqlstore.Store) {
|
||||
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions,
|
||||
role models.RoleType, fn scenarioFunc, sqlmock sqlstore.Store, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
hs := HTTPServer{
|
||||
Cfg: cfg,
|
||||
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
|
||||
Live: newTestLive(t, sqlstore.InitTestDB(t)),
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
SQLStore: sqlmock,
|
||||
Cfg: cfg,
|
||||
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
|
||||
Live: newTestLive(t, sqlstore.InitTestDB(t)),
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: sqlmock,
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
@@ -1037,24 +1078,28 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
|
||||
})
|
||||
}
|
||||
|
||||
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string, mock *dashboards.FakeDashboardService, cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc, sqlStore sqlstore.Store) {
|
||||
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string,
|
||||
mock *dashboards.FakeDashboardService, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService,
|
||||
cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc, sqlStore sqlstore.Store) {
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
hs := HTTPServer{
|
||||
Cfg: cfg,
|
||||
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
|
||||
Live: newTestLive(t, sqlstore.InitTestDB(t)),
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
dashboardService: mock,
|
||||
SQLStore: sqlStore,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
Cfg: cfg,
|
||||
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
|
||||
Live: newTestLive(t, sqlstore.InitTestDB(t)),
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
LibraryPanelService: &mockLibraryPanelService{},
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
dashboardService: mock,
|
||||
SQLStore: sqlStore,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
CoremodelRegistry: setupDashboardCoremodel(t),
|
||||
}
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.sqlStore = sqlStore
|
||||
sc.dashboardVersionService = fakeDashboardVersionService
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
c.Req.Body = mockRequestBody(cmd)
|
||||
c.Req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/datasourceproxy"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
||||
@@ -154,6 +155,7 @@ type HTTPServer struct {
|
||||
entityEventsService store.EntityEventsService
|
||||
folderPermissionsService accesscontrol.FolderPermissionsService
|
||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService
|
||||
dashboardVersionService dashver.Service
|
||||
starService star.Service
|
||||
CoremodelRegistry *coremodel.Registry
|
||||
}
|
||||
@@ -189,7 +191,8 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
dashboardsnapshotsService *dashboardsnapshots.Service, commentsService *comments.Service, pluginSettings *pluginSettings.Service,
|
||||
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service, entityEventsService store.EntityEventsService,
|
||||
teamsPermissionsService accesscontrol.TeamPermissionsService, folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService, starService star.Service, coremodelRegistry *coremodel.Registry,
|
||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service,
|
||||
starService star.Service, coremodelRegistry *coremodel.Registry,
|
||||
) (*HTTPServer, error) {
|
||||
web.Env = cfg.Env
|
||||
m := web.New()
|
||||
@@ -266,6 +269,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
entityEventsService: entityEventsService,
|
||||
folderPermissionsService: folderPermissionsService,
|
||||
dashboardPermissionsService: dashboardPermissionsService,
|
||||
dashboardVersionService: dashboardVersionService,
|
||||
starService: starService,
|
||||
CoremodelRegistry: coremodelRegistry,
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import (
|
||||
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
|
||||
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
||||
"github.com/grafana/grafana/pkg/services/dashboardversion/dashverimpl"
|
||||
"github.com/grafana/grafana/pkg/services/datasourceproxy"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service"
|
||||
@@ -260,6 +261,7 @@ var wireBasicSet = wire.NewSet(
|
||||
ossaccesscontrol.ProvideDashboardPermissions,
|
||||
wire.Bind(new(accesscontrol.DashboardPermissionsService), new(*ossaccesscontrol.DashboardPermissionsService)),
|
||||
starimpl.ProvideService,
|
||||
dashverimpl.ProvideService,
|
||||
)
|
||||
|
||||
var wireSet = wire.NewSet(
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package dashver
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Get(ctx context.Context, query *GetDashboardVersionQuery) (*DashboardVersion, error)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dashverimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
store store
|
||||
}
|
||||
|
||||
func ProvideService(db db.DB, cfg *setting.Cfg) dashver.Service {
|
||||
return &Service{
|
||||
store: &sqlStore{
|
||||
db: db,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error) {
|
||||
version, err := s.store.Get(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
version.Data.Set("id", version.DashboardID)
|
||||
return version, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package dashverimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDashboardVersionService(t *testing.T) {
|
||||
dashboardVersionStore := newDashboardVersionStoreFake()
|
||||
dashboardVersionService := Service{store: dashboardVersionStore}
|
||||
|
||||
t.Run("Get dashboard version", func(t *testing.T) {
|
||||
dashboard := &dashver.DashboardVersion{
|
||||
ID: 11,
|
||||
Data: &simplejson.Json{},
|
||||
}
|
||||
dashboardVersionStore.ExpectedDashboardVersion = dashboard
|
||||
dashboardVersion, err := dashboardVersionService.Get(context.Background(), &dashver.GetDashboardVersionQuery{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dashboardVersion, dashboard)
|
||||
})
|
||||
}
|
||||
|
||||
type FakeDashboardVersionStroe struct {
|
||||
ExpectedDashboardVersion *dashver.DashboardVersion
|
||||
ExpectedError error
|
||||
}
|
||||
|
||||
func newDashboardVersionStoreFake() *FakeDashboardVersionStroe {
|
||||
return &FakeDashboardVersionStroe{}
|
||||
}
|
||||
|
||||
func (f *FakeDashboardVersionStroe) Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error) {
|
||||
return f.ExpectedDashboardVersion, f.ExpectedError
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package dashverimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||
)
|
||||
|
||||
type store interface {
|
||||
Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error)
|
||||
}
|
||||
|
||||
type sqlStore struct {
|
||||
db db.DB
|
||||
}
|
||||
|
||||
func (s *sqlStore) Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error) {
|
||||
var version dashver.DashboardVersion
|
||||
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
has, err := sess.Where("dashboard_version.dashboard_id=? AND dashboard_version.version=? AND dashboard.org_id=?", query.DashboardID, query.Version, query.OrgID).
|
||||
Join("LEFT", "dashboard", `dashboard.id = dashboard_version.dashboard_id`).
|
||||
Get(&version)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !has {
|
||||
return models.ErrDashboardVersionNotFound
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &version, nil
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
package dashverimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIntegrationDashboardVersion(t *testing.T) {
|
||||
ss := sqlstore.InitTestDB(t)
|
||||
dashVerStore := sqlStore{db: ss}
|
||||
|
||||
t.Run("Get a Dashboard ID and version ID", func(t *testing.T) {
|
||||
savedDash := insertTestDashboard(t, ss, "test dash 26", 1, 0, false, "diff")
|
||||
|
||||
query := dashver.GetDashboardVersionQuery{
|
||||
DashboardID: savedDash.Id,
|
||||
Version: savedDash.Version,
|
||||
OrgID: 1,
|
||||
}
|
||||
|
||||
res, err := dashVerStore.Get(context.Background(), &query)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, query.DashboardID, savedDash.Id)
|
||||
require.Equal(t, query.Version, savedDash.Version)
|
||||
|
||||
dashCmd := &models.Dashboard{
|
||||
Id: res.ID,
|
||||
Uid: savedDash.Uid,
|
||||
OrgId: savedDash.OrgId,
|
||||
}
|
||||
err = getDashboard(t, ss, dashCmd)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.EqualValues(t, dashCmd.Data.Get("uid"), res.Data.Get("uid"))
|
||||
require.EqualValues(t, dashCmd.Data.Get("orgId"), res.Data.Get("orgId"))
|
||||
})
|
||||
|
||||
t.Run("Attempt to get a version that doesn't exist", func(t *testing.T) {
|
||||
query := dashver.GetDashboardVersionQuery{
|
||||
DashboardID: int64(999),
|
||||
Version: 123,
|
||||
OrgID: 1,
|
||||
}
|
||||
|
||||
_, err := dashVerStore.Get(context.Background(), &query)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, models.ErrDashboardVersionNotFound, err)
|
||||
})
|
||||
}
|
||||
|
||||
func getDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, dashboard *models.Dashboard) error {
|
||||
t.Helper()
|
||||
return sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
has, err := sess.Get(dashboard)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return models.ErrDashboardNotFound
|
||||
}
|
||||
|
||||
dashboard.SetId(dashboard.Id)
|
||||
dashboard.SetUid(dashboard.Uid)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
func insertTestDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, 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,
|
||||
}),
|
||||
}
|
||||
|
||||
var dash *models.Dashboard
|
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
dash = cmd.GetDashboardModel()
|
||||
dash.SetVersion(1)
|
||||
dash.Created = time.Now()
|
||||
dash.Updated = time.Now()
|
||||
dash.Uid = util.GenerateShortUID()
|
||||
_, err := sess.Insert(dash)
|
||||
return err
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dash)
|
||||
dash.Data.Set("id", dash.Id)
|
||||
dash.Data.Set("uid", dash.Uid)
|
||||
|
||||
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
dashVersion := &models.DashboardVersion{
|
||||
DashboardId: dash.Id,
|
||||
ParentVersion: dash.Version,
|
||||
RestoredFrom: cmd.RestoredFrom,
|
||||
Version: dash.Version,
|
||||
Created: time.Now(),
|
||||
CreatedBy: dash.UpdatedBy,
|
||||
Message: cmd.Message,
|
||||
Data: dash.Data,
|
||||
}
|
||||
|
||||
if affectedRows, err := sess.Insert(dashVersion); err != nil {
|
||||
return err
|
||||
} else if affectedRows == 0 {
|
||||
return models.ErrDashboardNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return dash
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package dashvertest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||
)
|
||||
|
||||
type FakeDashboardVersionService struct {
|
||||
ExpectedDashboardVersion *dashver.DashboardVersion
|
||||
ExpectedDashboardVersions []*dashver.DashboardVersion
|
||||
counter int
|
||||
ExpectedError error
|
||||
}
|
||||
|
||||
func NewDashboardVersionServiceFake() *FakeDashboardVersionService {
|
||||
return &FakeDashboardVersionService{}
|
||||
}
|
||||
|
||||
func (f *FakeDashboardVersionService) Get(ctx context.Context, query *dashver.GetDashboardVersionQuery) (*dashver.DashboardVersion, error) {
|
||||
if len(f.ExpectedDashboardVersions) == 0 {
|
||||
return f.ExpectedDashboardVersion, f.ExpectedError
|
||||
}
|
||||
f.counter++
|
||||
return f.ExpectedDashboardVersions[f.counter-1], f.ExpectedError
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dashver
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
)
|
||||
|
||||
type DashboardVersion struct {
|
||||
ID int64 `json:"id"`
|
||||
DashboardID int64 `json:"dashboardId"`
|
||||
ParentVersion int `json:"parentVersion"`
|
||||
RestoredFrom int `json:"restoredFrom"`
|
||||
Version int `json:"version"`
|
||||
|
||||
Created time.Time `json:"created"`
|
||||
CreatedBy int64 `json:"createdBy"`
|
||||
|
||||
Message string `json:"message"`
|
||||
Data *simplejson.Json `json:"data"`
|
||||
}
|
||||
|
||||
type GetDashboardVersionQuery struct {
|
||||
DashboardID int64
|
||||
OrgID int64
|
||||
Version int
|
||||
}
|
||||
@@ -8,28 +8,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
// GetDashboardVersion gets the dashboard version for the given dashboard ID and version number.
|
||||
func (ss *SQLStore) GetDashboardVersion(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
return ss.WithDbSession(ctx, func(sess *DBSession) error {
|
||||
version := models.DashboardVersion{}
|
||||
has, err := sess.Where("dashboard_version.dashboard_id=? AND dashboard_version.version=? AND dashboard.org_id=?", query.DashboardId, query.Version, query.OrgId).
|
||||
Join("LEFT", "dashboard", `dashboard.id = dashboard_version.dashboard_id`).
|
||||
Get(&version)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !has {
|
||||
return models.ErrDashboardVersionNotFound
|
||||
}
|
||||
|
||||
version.Data.Set("id", version.DashboardId)
|
||||
query.Result = &version
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetDashboardVersions gets all dashboard versions for the given dashboard ID.
|
||||
func (ss *SQLStore) GetDashboardVersions(ctx context.Context, query *models.GetDashboardVersionsQuery) error {
|
||||
return ss.WithDbSession(ctx, func(sess *DBSession) error {
|
||||
|
||||
@@ -5,7 +5,6 @@ package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -78,46 +77,6 @@ func updateTestDashboard(t *testing.T, sqlStore *SQLStore, dashboard *models.Das
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIntegrationGetDashboardVersion(t *testing.T) {
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
t.Run("Get a Dashboard ID and version ID", func(t *testing.T) {
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 26", 1, 0, false, "diff")
|
||||
|
||||
query := models.GetDashboardVersionQuery{
|
||||
DashboardId: savedDash.Id,
|
||||
Version: savedDash.Version,
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := sqlStore.GetDashboardVersion(context.Background(), &query)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, query.DashboardId, savedDash.Id)
|
||||
require.Equal(t, query.Version, savedDash.Version)
|
||||
|
||||
dashCmd := &models.Dashboard{
|
||||
Uid: savedDash.Uid,
|
||||
OrgId: savedDash.OrgId,
|
||||
}
|
||||
err = getDashboard(t, sqlStore, dashCmd)
|
||||
require.Nil(t, err)
|
||||
eq := reflect.DeepEqual(dashCmd.Data, query.Result.Data)
|
||||
require.Equal(t, true, eq)
|
||||
})
|
||||
|
||||
t.Run("Attempt to get a version that doesn't exist", func(t *testing.T) {
|
||||
query := models.GetDashboardVersionQuery{
|
||||
DashboardId: int64(999),
|
||||
Version: 123,
|
||||
OrgId: 1,
|
||||
}
|
||||
|
||||
err := sqlStore.GetDashboardVersion(context.Background(), &query)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, models.ErrDashboardVersionNotFound, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationGetDashboardVersions(t *testing.T) {
|
||||
sqlStore := InitTestDB(t)
|
||||
savedDash := insertTestDashboard(t, sqlStore, "test dash 43", 1, 0, false, "diff-all")
|
||||
|
||||
@@ -344,16 +344,6 @@ func (m *SQLStoreMock) InTransaction(ctx context.Context, fn func(ctx context.Co
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboardVersion(ctx context.Context, query *models.GetDashboardVersionQuery) error {
|
||||
query.Result = &models.DashboardVersion{}
|
||||
for _, dashboardversion := range m.ExpectedDashboardVersions {
|
||||
if dashboardversion.DashboardId == query.DashboardId && dashboardversion.Version == query.Version {
|
||||
query.Result = dashboardversion
|
||||
}
|
||||
}
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
func (m *SQLStoreMock) GetDashboardVersions(ctx context.Context, query *models.GetDashboardVersionsQuery) error {
|
||||
return m.ExpectedError
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ type Store interface {
|
||||
GetGlobalQuotaByTarget(ctx context.Context, query *models.GetGlobalQuotaByTargetQuery) error
|
||||
WithTransactionalDbSession(ctx context.Context, callback DBTransactionFunc) error
|
||||
InTransaction(ctx context.Context, fn func(ctx context.Context) error) error
|
||||
GetDashboardVersion(ctx context.Context, query *models.GetDashboardVersionQuery) error
|
||||
GetDashboardVersions(ctx context.Context, query *models.GetDashboardVersionsQuery) error
|
||||
DeleteExpiredVersions(ctx context.Context, cmd *models.DeleteExpiredVersionsCommand) error
|
||||
GetDashboardAclInfoList(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error
|
||||
|
||||
Reference in New Issue
Block a user