Dashboard: Add dashboard validation warning to save drawer (#55732)

* add api route for validating a dashboard json

* add feature flag for showDashboardValidationWarnings

* tidy up

* comments and messages

* swagger specs

* fix typo

* more swagger

* tests!

* tidy test a little bit

* no more ioutil

* api will return different status code depending on validation error

* clean up

* handle 4xx errors

* remove console.log

* fix backend tests

* tidy up

* Swagger: Exclude alpha endpoints

Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
This commit is contained in:
Josh Hunt
2022-10-14 14:51:05 +01:00
committed by GitHub
parent e4b1347ca5
commit 2e16d5499e
14 changed files with 324 additions and 3 deletions

View File

@ -752,6 +752,70 @@ func (hs *HTTPServer) GetDashboardVersion(c *models.ReqContext) response.Respons
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 *models.ReqContext) response.Response {
cmd := models.ValidateDashboardCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cm := hs.Coremodels.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 {
v, _ := cuectx.JSONtoCUE("dashboard.json", dashboardBytes)
_, validationErr := cm.CurrentSchema().Validate(v)
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
//
// Perform diff on two dashboards.
@ -1185,3 +1249,9 @@ type DashboardVersionResponse struct {
// in: body
Body *dashver.DashboardVersionMeta `json:"body"`
}
// swagger:response validateDashboardResponse
type ValidateDashboardResponse struct {
IsValid bool `json:"isValid"`
Message string `json:"message,omitempty"`
}