mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 14:22:48 +08:00
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:
@ -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"`
|
||||
}
|
||||
|
Reference in New Issue
Block a user