mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
Perf: Disable core kind registry (#78568)
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
co-authored by
Ryan McKinley
parent
b022ddeee8
commit
529271d7a8
@@ -466,7 +466,6 @@ func (hs *HTTPServer) registerRoutes() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
dashboardRoute.Post("/calculate-diff", authorize(ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.CalculateDashboardDiff))
|
dashboardRoute.Post("/calculate-diff", authorize(ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.CalculateDashboardDiff))
|
||||||
dashboardRoute.Post("/validate", authorize(ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.ValidateDashboard))
|
|
||||||
|
|
||||||
dashboardRoute.Post("/db", authorize(ac.EvalAny(ac.EvalPermission(dashboards.ActionDashboardsCreate), ac.EvalPermission(dashboards.ActionDashboardsWrite))), routing.Wrap(hs.PostDashboard))
|
dashboardRoute.Post("/db", authorize(ac.EvalAny(ac.EvalPermission(dashboards.ActionDashboardsCreate), ac.EvalPermission(dashboards.ActionDashboardsWrite))), routing.Wrap(hs.PostDashboard))
|
||||||
dashboardRoute.Get("/home", routing.Wrap(hs.GetHomeDashboard))
|
dashboardRoute.Get("/home", routing.Wrap(hs.GetHomeDashboard))
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
"github.com/grafana/grafana/pkg/components/dashdiffs"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/kinds/dashboard"
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||||
@@ -792,72 +791,6 @@ func (hs *HTTPServer) GetDashboardVersion(c *contextmodel.ReqContext) response.R
|
|||||||
return response.JSON(http.StatusOK, dashVersionMeta)
|
return response.JSON(http.StatusOK, dashVersionMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
// swagger:route POST /dashboards/validate dashboards alpha validateDashboard
|
|
||||||
//
|
|
||||||
// Validates a dashboard JSON against the schema.
|
|
||||||
//
|
|
||||||
// Produces:
|
|
||||||
// - application/json
|
|
||||||
//
|
|
||||||
// Responses:
|
|
||||||
// 200: validateDashboardResponse
|
|
||||||
// 412: validateDashboardResponse
|
|
||||||
// 422: validateDashboardResponse
|
|
||||||
// 401: unauthorisedError
|
|
||||||
// 403: forbiddenError
|
|
||||||
// 500: internalServerError
|
|
||||||
func (hs *HTTPServer) ValidateDashboard(c *contextmodel.ReqContext) response.Response {
|
|
||||||
cmd := dashboards.ValidateDashboardCommand{}
|
|
||||||
|
|
||||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
|
||||||
return response.Error(http.StatusBadRequest, "Bad request data", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dk := hs.Kinds.Dashboard()
|
|
||||||
dashboardBytes := []byte(cmd.Dashboard)
|
|
||||||
|
|
||||||
// POST api receives dashboard as a string of json (so line numbers for errors stay consistent),
|
|
||||||
// but we need to parse the schema version out of it
|
|
||||||
dashboardJson, err := simplejson.NewJson(dashboardBytes)
|
|
||||||
if err != nil {
|
|
||||||
return response.Error(http.StatusBadRequest, "unable to parse dashboard", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
schemaVersion, err := dashboardJson.Get("schemaVersion").Int()
|
|
||||||
|
|
||||||
isValid := false
|
|
||||||
statusCode := http.StatusOK
|
|
||||||
validationMessage := ""
|
|
||||||
|
|
||||||
// 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 || schemaVersion >= dashboard.HandoffSchemaVersion {
|
|
||||||
// Schemas expect the dashboard to live in the spec field
|
|
||||||
k8sResource := `{"spec": ` + cmd.Dashboard + "}"
|
|
||||||
|
|
||||||
_, _, validationErr := dk.JSONValueMux([]byte(k8sResource))
|
|
||||||
|
|
||||||
if validationErr == nil {
|
|
||||||
isValid = true
|
|
||||||
} else {
|
|
||||||
validationMessage = validationErr.Error()
|
|
||||||
statusCode = http.StatusUnprocessableEntity
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
validationMessage = "invalid schema version"
|
|
||||||
statusCode = http.StatusPreconditionFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
respData := &ValidateDashboardResponse{
|
|
||||||
IsValid: isValid,
|
|
||||||
Message: validationMessage,
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.JSON(statusCode, respData)
|
|
||||||
}
|
|
||||||
|
|
||||||
// swagger:route POST /dashboards/calculate-diff dashboards calculateDashboardDiff
|
// swagger:route POST /dashboards/calculate-diff dashboards calculateDashboardDiff
|
||||||
//
|
//
|
||||||
// Perform diff on two dashboards.
|
// Perform diff on two dashboards.
|
||||||
@@ -1303,9 +1236,3 @@ type DashboardVersionResponse struct {
|
|||||||
// in: body
|
// in: body
|
||||||
Body *dashver.DashboardVersionMeta `json:"body"`
|
Body *dashver.DashboardVersionMeta `json:"body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// swagger:response validateDashboardResponse
|
|
||||||
type ValidateDashboardResponse struct {
|
|
||||||
IsValid bool `json:"isValid"`
|
|
||||||
Message string `json:"message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||||
"github.com/grafana/grafana/pkg/registry/corekind"
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||||
@@ -79,7 +78,6 @@ func TestGetHomeDashboard(t *testing.T) {
|
|||||||
SQLStore: dbtest.NewFakeDB(),
|
SQLStore: dbtest.NewFakeDB(),
|
||||||
preferenceService: prefService,
|
preferenceService: prefService,
|
||||||
dashboardVersionService: dashboardVersionService,
|
dashboardVersionService: dashboardVersionService,
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
log: log.New("test-logger"),
|
log: log.New("test-logger"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,60 +513,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Given a dashboard to validate", func(t *testing.T) {
|
|
||||||
sqlmock := dbtest.NewFakeDB()
|
|
||||||
|
|
||||||
t.Run("When an invalid dashboard json is posted", func(t *testing.T) {
|
|
||||||
cmd := dashboards.ValidateDashboardCommand{
|
|
||||||
Dashboard: "{\"hello\": \"world\"}",
|
|
||||||
}
|
|
||||||
|
|
||||||
role := org.RoleAdmin
|
|
||||||
postValidateScenario(t, "When calling POST on", "/api/dashboards/validate", "/api/dashboards/validate", cmd, role, func(sc *scenarioContext) {
|
|
||||||
callPostDashboard(sc)
|
|
||||||
|
|
||||||
result := sc.ToJSON()
|
|
||||||
assert.Equal(t, http.StatusUnprocessableEntity, sc.resp.Code)
|
|
||||||
assert.False(t, result.Get("isValid").MustBool())
|
|
||||||
assert.NotEmpty(t, result.Get("message").MustString())
|
|
||||||
}, sqlmock)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("When a dashboard with a too-low schema version is posted", func(t *testing.T) {
|
|
||||||
cmd := dashboards.ValidateDashboardCommand{
|
|
||||||
Dashboard: "{\"schemaVersion\": 1}",
|
|
||||||
}
|
|
||||||
|
|
||||||
role := org.RoleAdmin
|
|
||||||
postValidateScenario(t, "When calling POST on", "/api/dashboards/validate", "/api/dashboards/validate", cmd, role, func(sc *scenarioContext) {
|
|
||||||
callPostDashboard(sc)
|
|
||||||
|
|
||||||
result := sc.ToJSON()
|
|
||||||
assert.Equal(t, http.StatusPreconditionFailed, sc.resp.Code)
|
|
||||||
assert.False(t, result.Get("isValid").MustBool())
|
|
||||||
assert.Equal(t, "invalid schema version", result.Get("message").MustString())
|
|
||||||
}, sqlmock)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("When a valid dashboard is posted", func(t *testing.T) {
|
|
||||||
devenvDashboard, readErr := os.ReadFile("../../devenv/dev-dashboards/home.json")
|
|
||||||
assert.Empty(t, readErr)
|
|
||||||
|
|
||||||
cmd := dashboards.ValidateDashboardCommand{
|
|
||||||
Dashboard: string(devenvDashboard),
|
|
||||||
}
|
|
||||||
|
|
||||||
role := org.RoleAdmin
|
|
||||||
postValidateScenario(t, "When calling POST on", "/api/dashboards/validate", "/api/dashboards/validate", cmd, role, func(sc *scenarioContext) {
|
|
||||||
callPostDashboard(sc)
|
|
||||||
|
|
||||||
result := sc.ToJSON()
|
|
||||||
assert.Equal(t, http.StatusOK, sc.resp.Code)
|
|
||||||
assert.True(t, result.Get("isValid").MustBool())
|
|
||||||
}, sqlmock)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Given two dashboards being compared", func(t *testing.T) {
|
t.Run("Given two dashboards being compared", func(t *testing.T) {
|
||||||
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
fakeDashboardVersionService := dashvertest.NewDashboardVersionServiceFake()
|
||||||
fakeDashboardVersionService.ExpectedDashboardVersions = []*dashver.DashboardVersionDTO{
|
fakeDashboardVersionService.ExpectedDashboardVersions = []*dashver.DashboardVersionDTO{
|
||||||
@@ -742,7 +686,6 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
|||||||
AccessControl: accesscontrolmock.New(),
|
AccessControl: accesscontrolmock.New(),
|
||||||
DashboardService: dashboardService,
|
DashboardService: dashboardService,
|
||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
starService: startest.NewStarServiceFake(),
|
starService: startest.NewStarServiceFake(),
|
||||||
}
|
}
|
||||||
hs.callGetDashboard(sc)
|
hs.callGetDashboard(sc)
|
||||||
@@ -781,7 +724,6 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) {
|
|||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
DashboardService: dashboardService,
|
DashboardService: dashboardService,
|
||||||
dashboardVersionService: fakeDashboardVersionService,
|
dashboardVersionService: fakeDashboardVersionService,
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
QuotaService: quotatest.New(false, nil),
|
QuotaService: quotatest.New(false, nil),
|
||||||
userService: userSvc,
|
userService: userSvc,
|
||||||
CacheService: localcache.New(5*time.Minute, 10*time.Minute),
|
CacheService: localcache.New(5*time.Minute, 10*time.Minute),
|
||||||
@@ -922,7 +864,6 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
|||||||
dashboardProvisioningService: dashboardProvisioningService,
|
dashboardProvisioningService: dashboardProvisioningService,
|
||||||
DashboardService: dashboardService,
|
DashboardService: dashboardService,
|
||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
starService: startest.NewStarServiceFake(),
|
starService: startest.NewStarServiceFake(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,7 +916,6 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
|||||||
DashboardService: dashboardService,
|
DashboardService: dashboardService,
|
||||||
folderService: folderService,
|
folderService: folderService,
|
||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
accesscontrolService: actest.FakeService{},
|
accesscontrolService: actest.FakeService{},
|
||||||
log: log.New("test-logger"),
|
log: log.New("test-logger"),
|
||||||
}
|
}
|
||||||
@@ -996,42 +936,6 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func postValidateScenario(t *testing.T, desc string, url string, routePattern string, cmd dashboards.ValidateDashboardCommand,
|
|
||||||
role org.RoleType, fn scenarioFunc, sqlmock db.DB) {
|
|
||||||
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, db.InitTestDB(t)),
|
|
||||||
QuotaService: quotatest.New(false, nil),
|
|
||||||
LibraryPanelService: &mockLibraryPanelService{},
|
|
||||||
LibraryElementService: &mockLibraryElementService{},
|
|
||||||
SQLStore: sqlmock,
|
|
||||||
Features: featuremgmt.WithFeatures(),
|
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
}
|
|
||||||
|
|
||||||
sc := setupScenarioContext(t, url)
|
|
||||||
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
|
||||||
c.Req.Body = mockRequestBody(cmd)
|
|
||||||
c.Req.Header.Add("Content-Type", "application/json")
|
|
||||||
sc.context = c
|
|
||||||
sc.context.SignedInUser = &user.SignedInUser{
|
|
||||||
OrgID: testOrgID,
|
|
||||||
UserID: testUserID,
|
|
||||||
}
|
|
||||||
sc.context.OrgRole = role
|
|
||||||
|
|
||||||
return hs.ValidateDashboard(c)
|
|
||||||
})
|
|
||||||
|
|
||||||
sc.m.Post(routePattern, sc.defaultHandler)
|
|
||||||
|
|
||||||
fn(sc)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions,
|
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions,
|
||||||
role org.RoleType, fn scenarioFunc, sqlmock db.DB, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) {
|
role org.RoleType, fn scenarioFunc, sqlmock db.DB, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) {
|
||||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||||
@@ -1048,7 +952,6 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
|
|||||||
SQLStore: sqlmock,
|
SQLStore: sqlmock,
|
||||||
dashboardVersionService: fakeDashboardVersionService,
|
dashboardVersionService: fakeDashboardVersionService,
|
||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
DashboardService: dashSvc,
|
DashboardService: dashSvc,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1091,7 +994,6 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
|||||||
SQLStore: sqlStore,
|
SQLStore: sqlStore,
|
||||||
Features: featuremgmt.WithFeatures(),
|
Features: featuremgmt.WithFeatures(),
|
||||||
dashboardVersionService: fakeDashboardVersionService,
|
dashboardVersionService: fakeDashboardVersionService,
|
||||||
Kinds: corekind.NewBase(nil),
|
|
||||||
accesscontrolService: actest.FakeService{},
|
accesscontrolService: actest.FakeService{},
|
||||||
folderService: folderSvc,
|
folderService: folderSvc,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
||||||
"github.com/grafana/grafana/pkg/registry/corekind"
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/alerting"
|
"github.com/grafana/grafana/pkg/services/alerting"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations"
|
"github.com/grafana/grafana/pkg/services/annotations"
|
||||||
@@ -187,7 +186,6 @@ type HTTPServer struct {
|
|||||||
dashboardVersionService dashver.Service
|
dashboardVersionService dashver.Service
|
||||||
PublicDashboardsApi *publicdashboardsApi.Api
|
PublicDashboardsApi *publicdashboardsApi.Api
|
||||||
starService star.Service
|
starService star.Service
|
||||||
Kinds *corekind.Base
|
|
||||||
playlistService playlist.Service
|
playlistService playlist.Service
|
||||||
apiKeyService apikey.Service
|
apiKeyService apikey.Service
|
||||||
kvStore kvstore.KVStore
|
kvStore kvstore.KVStore
|
||||||
@@ -240,7 +238,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||||||
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service,
|
avatarCacheServer *avatar.AvatarCacheServer, preferenceService pref.Service,
|
||||||
folderPermissionsService accesscontrol.FolderPermissionsService,
|
folderPermissionsService accesscontrol.FolderPermissionsService,
|
||||||
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service,
|
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service,
|
||||||
starService star.Service, csrfService csrf.Service, basekinds *corekind.Base,
|
starService star.Service, csrfService csrf.Service,
|
||||||
playlistService playlist.Service, apiKeyService apikey.Service, kvStore kvstore.KVStore,
|
playlistService playlist.Service, apiKeyService apikey.Service, kvStore kvstore.KVStore,
|
||||||
secretsMigrator secrets.Migrator, secretsPluginManager plugins.SecretsPluginManager, secretsService secrets.Service,
|
secretsMigrator secrets.Migrator, secretsPluginManager plugins.SecretsPluginManager, secretsService secrets.Service,
|
||||||
secretsPluginMigrator spm.SecretMigrationProvider, secretsStore secretsKV.SecretsKVStore,
|
secretsPluginMigrator spm.SecretMigrationProvider, secretsStore secretsKV.SecretsKVStore,
|
||||||
@@ -329,7 +327,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||||||
dashboardPermissionsService: dashboardPermissionsService,
|
dashboardPermissionsService: dashboardPermissionsService,
|
||||||
dashboardVersionService: dashboardVersionService,
|
dashboardVersionService: dashboardVersionService,
|
||||||
starService: starService,
|
starService: starService,
|
||||||
Kinds: basekinds,
|
|
||||||
playlistService: playlistService,
|
playlistService: playlistService,
|
||||||
apiKeyService: apiKeyService,
|
apiKeyService: apiKeyService,
|
||||||
kvStore: kvStore,
|
kvStore: kvStore,
|
||||||
|
|||||||
+16
-3
@@ -6,6 +6,7 @@ package cuectx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"cuelang.org/go/cue"
|
"cuelang.org/go/cue"
|
||||||
"cuelang.org/go/cue/cuecontext"
|
"cuelang.org/go/cue/cuecontext"
|
||||||
@@ -26,14 +27,25 @@ var GoCoreKindParentPath = filepath.Join("pkg", "kinds")
|
|||||||
// contains one directory per kind, full of generated TS kind output: types and default consts.
|
// contains one directory per kind, full of generated TS kind output: types and default consts.
|
||||||
var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw")
|
var TSCoreKindParentPath = filepath.Join("packages", "grafana-schema", "src", "raw")
|
||||||
|
|
||||||
var ctx = cuecontext.New()
|
var (
|
||||||
var rt = thema.NewRuntime(ctx)
|
ctx *cue.Context
|
||||||
|
rt *thema.Runtime
|
||||||
|
once sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func initContext() {
|
||||||
|
once.Do(func() {
|
||||||
|
ctx = cuecontext.New()
|
||||||
|
rt = thema.NewRuntime(ctx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// GrafanaCUEContext returns Grafana's singleton instance of [cue.Context].
|
// GrafanaCUEContext returns Grafana's singleton instance of [cue.Context].
|
||||||
//
|
//
|
||||||
// All code within grafana/grafana that needs a *cue.Context should get it
|
// All code within grafana/grafana that needs a *cue.Context should get it
|
||||||
// from this function, when one was not otherwise provided.
|
// from this function, when one was not otherwise provided.
|
||||||
func GrafanaCUEContext() *cue.Context {
|
func GrafanaCUEContext() *cue.Context {
|
||||||
|
initContext()
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +54,7 @@ func GrafanaCUEContext() *cue.Context {
|
|||||||
// All code within grafana/grafana that needs a *thema.Runtime should get it
|
// All code within grafana/grafana that needs a *thema.Runtime should get it
|
||||||
// from this function, when one was not otherwise provided.
|
// from this function, when one was not otherwise provided.
|
||||||
func GrafanaThemaRuntime() *thema.Runtime {
|
func GrafanaThemaRuntime() *thema.Runtime {
|
||||||
|
initContext()
|
||||||
return rt
|
return rt
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,5 +69,5 @@ func GrafanaThemaRuntime() *thema.Runtime {
|
|||||||
// call it repeatedly. Most use cases should probably prefer making
|
// call it repeatedly. Most use cases should probably prefer making
|
||||||
// their own Thema/CUE decoders.
|
// their own Thema/CUE decoders.
|
||||||
func JSONtoCUE(path string, b []byte) (cue.Value, error) {
|
func JSONtoCUE(path string, b []byte) (cue.Value, error) {
|
||||||
return vmux.NewJSONCodec(path).Decode(ctx, b)
|
return vmux.NewJSONCodec(path).Decode(GrafanaCUEContext(), b)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,12 @@ package corekind
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/google/wire"
|
|
||||||
"github.com/grafana/kindsys"
|
"github.com/grafana/kindsys"
|
||||||
"github.com/grafana/thema"
|
"github.com/grafana/thema"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/cuectx"
|
"github.com/grafana/grafana/pkg/cuectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// KindSet contains all of the wire-style providers related to kinds.
|
|
||||||
var KindSet = wire.NewSet(
|
|
||||||
NewBase,
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
baseOnce sync.Once
|
baseOnce sync.Once
|
||||||
defaultBase *Base
|
defaultBase *Base
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/middleware/csrf"
|
"github.com/grafana/grafana/pkg/middleware/csrf"
|
||||||
"github.com/grafana/grafana/pkg/middleware/loggermw"
|
"github.com/grafana/grafana/pkg/middleware/loggermw"
|
||||||
apiregistry "github.com/grafana/grafana/pkg/registry/apis"
|
apiregistry "github.com/grafana/grafana/pkg/registry/apis"
|
||||||
"github.com/grafana/grafana/pkg/registry/corekind"
|
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
@@ -314,7 +313,6 @@ var wireBasicSet = wire.NewSet(
|
|||||||
secretsStore.ProvideService,
|
secretsStore.ProvideService,
|
||||||
avatar.ProvideAvatarCacheServer,
|
avatar.ProvideAvatarCacheServer,
|
||||||
statscollector.ProvideService,
|
statscollector.ProvideService,
|
||||||
corekind.KindSet,
|
|
||||||
cuectx.GrafanaCUEContext,
|
cuectx.GrafanaCUEContext,
|
||||||
cuectx.GrafanaThemaRuntime,
|
cuectx.GrafanaThemaRuntime,
|
||||||
csrf.ProvideCSRFFilter,
|
csrf.ProvideCSRFFilter,
|
||||||
|
|||||||
@@ -260,15 +260,6 @@ type SaveDashboardCommand struct {
|
|||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidateDashboardCommand struct {
|
|
||||||
Dashboard string `json:"dashboard" binding:"Required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TrimDashboardCommand struct {
|
|
||||||
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
|
|
||||||
Meta *simplejson.Json `json:"meta"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DashboardProvisioning struct {
|
type DashboardProvisioning struct {
|
||||||
ID int64 `xorm:"pk autoincr 'id'"`
|
ID int64 `xorm:"pk autoincr 'id'"`
|
||||||
DashboardID int64 `xorm:"dashboard_id"`
|
DashboardID int64 `xorm:"dashboard_id"`
|
||||||
|
|||||||
@@ -9158,17 +9158,6 @@
|
|||||||
"$ref": "#/definitions/UserProfileDTO"
|
"$ref": "#/definitions/UserProfileDTO"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"validateDashboardResponse": {
|
|
||||||
"description": "",
|
|
||||||
"headers": {
|
|
||||||
"isValid": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"viewPublicDashboardResponse": {
|
"viewPublicDashboardResponse": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"schema": {
|
"schema": {
|
||||||
|
|||||||
@@ -22312,17 +22312,6 @@
|
|||||||
"$ref": "#/definitions/UserProfileDTO"
|
"$ref": "#/definitions/UserProfileDTO"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"validateDashboardResponse": {
|
|
||||||
"description": "(empty)",
|
|
||||||
"headers": {
|
|
||||||
"isValid": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"viewPublicDashboardResponse": {
|
"viewPublicDashboardResponse": {
|
||||||
"description": "(empty)",
|
"description": "(empty)",
|
||||||
"schema": {
|
"schema": {
|
||||||
|
|||||||
@@ -516,16 +516,13 @@ export class BackendSrv implements BackendService {
|
|||||||
return this.get<DashboardDTO>(`/api/dashboards/uid/${uid}`);
|
return this.get<DashboardDTO>(`/api/dashboards/uid/${uid}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateDashboard(dashboard: DashboardModel) {
|
validateDashboard(dashboard: DashboardModel): Promise<ValidateDashboardResponse> {
|
||||||
// We want to send the dashboard as a JSON string (in the JSON body payload) so we can get accurate error line numbers back
|
// support for this function will be implemented in the k8s flavored api-server
|
||||||
const dashboardJson = JSON.stringify(dashboard, replaceJsonNulls, 2);
|
// hidden by experimental feature flag:
|
||||||
|
// config.featureToggles.showDashboardValidationWarnings
|
||||||
return this.request<ValidateDashboardResponse>({
|
return Promise.resolve({
|
||||||
method: 'POST',
|
isValid: false,
|
||||||
url: `/api/dashboards/validate`,
|
message: 'dashboard validation is supported',
|
||||||
data: { dashboard: dashboardJson },
|
|
||||||
showSuccessAlert: false,
|
|
||||||
showErrorAlert: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,10 +550,3 @@ interface ValidateDashboardResponse {
|
|||||||
isValid: boolean;
|
isValid: boolean;
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceJsonNulls<T extends unknown>(key: string, value: T): T | undefined {
|
|
||||||
if (typeof value === 'number' && !Number.isFinite(value)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1911,21 +1911,6 @@
|
|||||||
},
|
},
|
||||||
"description": "(empty)"
|
"description": "(empty)"
|
||||||
},
|
},
|
||||||
"validateDashboardResponse": {
|
|
||||||
"description": "(empty)",
|
|
||||||
"headers": {
|
|
||||||
"isValid": {
|
|
||||||
"schema": {
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"message": {
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"viewPublicDashboardResponse": {
|
"viewPublicDashboardResponse": {
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
|
|||||||
Reference in New Issue
Block a user