coremodels: Automatically generate coremodel registries (#50057)

* coremodel: Generate static registry

* Actually make codegen work

Also, remove the per-coremodel assignability test from generator set.

* Make wire gen depend on cue gen

This is necessary now that we're generating a wire set as part of
coremodel registry generation.

* Add wire inject bits to http server

* s/staticregistry/registry/

* move to static and dynamic wording

* Move registry type into registry package

* Use static registry in http handler

* Oi comments
This commit is contained in:
sam boyer
2022-06-15 15:47:04 +02:00
committed by GitHub
parent 8a6ed3d81b
commit 4c4aa95d38
16 changed files with 390 additions and 158 deletions
+13 -13
View File
@@ -303,22 +303,22 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext) response.Response {
}
if hs.Features.IsEnabled(featuremgmt.FlagValidateDashboardsOnSave) {
cm := hs.CoremodelStaticRegistry.Dashboard()
// Ideally, coremodel validation calls would be integrated into the web
// framework. But this does the job for now.
if cm, has := hs.CoremodelRegistry.Get("dashboard"); has {
schv, err := cmd.Dashboard.Get("schemaVersion").Int()
schv, err := cmd.Dashboard.Get("schemaVersion").Int()
// Only try to validate if the schemaVersion is at least the handoff version
// (the minimum schemaVersion against which the dashboard schema is known to
// work), or if schemaVersion is absent (which will happen once the Thema
// schema becomes canonical).
if err != nil || schv >= dashboard.HandoffSchemaVersion {
// Can't fail, web.Bind() already ensured it's valid JSON
b, _ := cmd.Dashboard.Bytes()
v, _ := cuectx.JSONtoCUE("dashboard.json", b)
if _, err := cm.CurrentSchema().Validate(v); err != nil {
return response.Error(http.StatusBadRequest, "invalid dashboard json", err)
}
// Only try to validate if the schemaVersion is at least the handoff version
// (the minimum schemaVersion against which the dashboard schema is known to
// work), or if schemaVersion is absent (which will happen once the Thema
// schema becomes canonical).
if err != nil || schv >= dashboard.HandoffSchemaVersion {
// Can't fail, web.Bind() already ensured it's valid JSON
b, _ := cmd.Dashboard.Bytes()
v, _ := cuectx.JSONtoCUE("dashboard.json", b)
if _, err := cm.CurrentSchema().Validate(v); err != nil {
return response.Error(http.StatusBadRequest, "invalid dashboard json", err)
}
}
}
+13 -15
View File
@@ -9,6 +9,7 @@ import (
"net/http"
"testing"
"github.com/grafana/grafana/pkg/framework/coremodel/registry"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -17,9 +18,6 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/coremodel/dashboard"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/framework/coremodel"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models"
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
@@ -59,8 +57,8 @@ func TestGetHomeDashboard(t *testing.T) {
SQLStore: mockstore.NewSQLStoreMock(),
preferenceService: prefService,
dashboardVersionService: dashboardVersionService,
CoremodelRegistry: setupDashboardCoremodel(t),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
tests := []struct {
name string
@@ -143,8 +141,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
Features: featuremgmt.WithFeatures(),
dashboardService: dashboardService,
dashboardVersionService: fakeDashboardVersionService,
CoremodelRegistry: setupDashboardCoremodel(t),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
setUp := func() {
viewerRole := models.ROLE_VIEWER
@@ -263,8 +261,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
AccessControl: accesscontrolmock.New(),
dashboardService: dashboardService,
dashboardVersionService: fakeDashboardVersionService,
CoremodelRegistry: setupDashboardCoremodel(t),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
setUp := func() {
origCanEdit := setting.ViewersCanEdit
@@ -900,11 +898,11 @@ func TestDashboardAPIEndpoint(t *testing.T) {
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
dashboardProvisioningService: mockDashboardProvisioningService{},
CoremodelRegistry: setupDashboardCoremodel(t),
SQLStore: mockSQLStore,
AccessControl: accesscontrolmock.New(),
dashboardService: dashboardService,
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
hs.callGetDashboard(sc)
assert.Equal(t, 200, sc.resp.Code)
@@ -951,7 +949,6 @@ 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,
@@ -959,6 +956,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
),
dashboardService: dashboardService,
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
hs.callGetDashboard(sc)
@@ -1020,11 +1018,11 @@ 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(),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
sc := setupScenarioContext(t, url)
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
@@ -1055,8 +1053,8 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
LibraryElementService: &mockLibraryElementService{},
SQLStore: sqlmock,
dashboardVersionService: fakeDashboardVersionService,
CoremodelRegistry: setupDashboardCoremodel(t),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
sc := setupScenarioContext(t, url)
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
@@ -1094,8 +1092,8 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
SQLStore: sqlStore,
Features: featuremgmt.WithFeatures(),
dashboardVersionService: fakeDashboardVersionService,
CoremodelRegistry: setupDashboardCoremodel(t),
}
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
sc := setupScenarioContext(t, url)
sc.sqlStore = sqlStore
@@ -1119,14 +1117,14 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
})
}
func setupDashboardCoremodel(t *testing.T) *coremodel.Registry {
func setupDashboardCoremodel(t *testing.T) (*registry.Static, *registry.Generic) {
// TODO abstract and generalize this further for wider reuse
t.Helper()
dcm, err := dashboard.ProvideCoremodel(cuectx.ProvideThemaLibrary())
sreg, err := registry.ProvideStatic()
require.NoError(t, err)
reg, err := coremodel.NewRegistry(dcm)
greg, err := registry.ProvideGeneric()
require.NoError(t, err)
return reg
return sreg, greg
}
func (sc *scenarioContext) ToJSON() *simplejson.Json {
+6 -3
View File
@@ -23,7 +23,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
httpstatic "github.com/grafana/grafana/pkg/api/static"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/framework/coremodel"
"github.com/grafana/grafana/pkg/framework/coremodel/registry"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
@@ -162,7 +162,8 @@ type HTTPServer struct {
dashboardPermissionsService accesscontrol.DashboardPermissionsService
dashboardVersionService dashver.Service
starService star.Service
CoremodelRegistry *coremodel.Registry
CoremodelRegistry *registry.Generic
CoremodelStaticRegistry *registry.Static
kvStore kvstore.KVStore
}
@@ -197,7 +198,8 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service, entityEventsService store.EntityEventsService,
teamsPermissionsService accesscontrol.TeamPermissionsService, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service,
starService star.Service, coremodelRegistry *coremodel.Registry, csrfService csrf.Service, kvStore kvstore.KVStore,
starService star.Service, csrfService csrf.Service, coremodelRegistry *registry.Generic, coremodelStaticRegistry *registry.Static,
kvStore kvstore.KVStore,
) (*HTTPServer, error) {
web.Env = cfg.Env
m := web.New()
@@ -279,6 +281,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
dashboardVersionService: dashboardVersionService,
starService: starService,
CoremodelRegistry: coremodelRegistry,
CoremodelStaticRegistry: coremodelStaticRegistry,
kvStore: kvStore,
}
if hs.Listener != nil {