api: Validate dashboards on save via coremodels, behind feature toggle (#48252)

* Add coremodelValidation feature flag

* coremodels: use stubs when feature flag is off

* api: validate dashboards on save

* Need pointer receiver for FeatureManager

* Update dashboard Go model

* Align doc comments

* Include CoremodelRegistry in test

* Wedge coremodel in on all test cases, ugh

* Ugh fix comment again

* Update pkg/framework/coremodel/staticregistry/provide.go

Co-authored-by: Artur Wierzbicki <wierzbicki.artur.94@gmail.com>

* Update Thema (and its deps) for better errs

* omg whitespace

Co-authored-by: Artur Wierzbicki <wierzbicki.artur.94@gmail.com>
This commit is contained in:
sam boyer
2022-05-22 02:44:12 +02:00
committed by GitHub
co-authored by Artur Wierzbicki
parent 03fe1435a0
commit a3402641d6
11 changed files with 111 additions and 15 deletions
+28 -7
View File
@@ -9,6 +9,9 @@ import (
"net/http"
"testing"
"github.com/grafana/grafana/pkg/coremodel/dashboard"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/framework/coremodel"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -23,7 +26,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/dashboards/database"
service "github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/libraryelements"
@@ -51,6 +54,7 @@ func TestGetHomeDashboard(t *testing.T) {
Cfg: cfg,
pluginStore: &fakePluginStore{},
SQLStore: mockstore.NewSQLStoreMock(),
CoremodelRegistry: setupDashboardCoremodel(t),
preferenceService: prefService,
}
@@ -127,12 +131,13 @@ func TestDashboardAPIEndpoint(t *testing.T) {
mockSQLStore := mockstore.NewSQLStoreMock()
hs := &HTTPServer{
Cfg: setting.NewCfg(),
pluginStore: &fakePluginStore{},
SQLStore: mockSQLStore,
AccessControl: accesscontrolmock.New(),
Features: featuremgmt.WithFeatures(),
dashboardService: dashboardService,
Cfg: setting.NewCfg(),
pluginStore: &fakePluginStore{},
SQLStore: mockSQLStore,
CoremodelRegistry: setupDashboardCoremodel(t),
AccessControl: accesscontrolmock.New(),
Features: featuremgmt.WithFeatures(),
dashboardService: dashboardService,
}
setUp := func() {
@@ -235,6 +240,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
Live: newTestLive(t, sql),
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
CoremodelRegistry: setupDashboardCoremodel(t),
SQLStore: mockSQLStore,
AccessControl: accesscontrolmock.New(),
dashboardService: dashboardService,
@@ -914,6 +920,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
dashboardProvisioningService: mockDashboardProvisioningService{},
CoremodelRegistry: setupDashboardCoremodel(t),
SQLStore: mockSQLStore,
AccessControl: accesscontrolmock.New(),
dashboardService: dashboardService,
@@ -958,6 +965,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
LibraryElementService: &libraryElementsService,
SQLStore: sc.sqlStore,
ProvisioningService: provisioningService,
CoremodelRegistry: setupDashboardCoremodel(t),
AccessControl: accesscontrolmock.New(),
dashboardProvisioningService: service.ProvideDashboardService(
cfg, dashboardStore, nil, features,
@@ -1026,6 +1034,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
pluginStore: &fakePluginStore{},
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
CoremodelRegistry: setupDashboardCoremodel(t),
dashboardService: dashboardService,
folderService: folderService,
Features: featuremgmt.WithFeatures(),
@@ -1057,6 +1066,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
QuotaService: &quota.QuotaService{Cfg: cfg},
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
CoremodelRegistry: setupDashboardCoremodel(t),
SQLStore: sqlmock,
}
@@ -1090,6 +1100,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
QuotaService: &quota.QuotaService{Cfg: cfg},
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
CoremodelRegistry: setupDashboardCoremodel(t),
dashboardService: mock,
SQLStore: sqlStore,
Features: featuremgmt.WithFeatures(),
@@ -1116,6 +1127,16 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
})
}
func setupDashboardCoremodel(t *testing.T) *coremodel.Registry {
// TODO abstract and generalize this further for wider reuse
t.Helper()
dcm, err := dashboard.ProvideCoremodel(cuectx.ProvideThemaLibrary())
require.NoError(t, err)
reg, err := coremodel.NewRegistry(dcm)
require.NoError(t, err)
return reg
}
func (sc *scenarioContext) ToJSON() *simplejson.Json {
result := simplejson.New()
err := json.NewDecoder(sc.resp.Body).Decode(result)