From 66548878fe377818fce76b517cfa48032e496a4e Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Wed, 24 Mar 2021 12:12:34 -0400 Subject: [PATCH] ngalert: add addition temp translation endpoint (#32287) spits out new sse condition/data json from old alert id to help with generating UI models also moves this api code into another file --- pkg/services/ngalert/api/api.go | 113 ++--------------- pkg/services/ngalert/api/api_trans_dev.go | 144 ++++++++++++++++++++++ 2 files changed, 153 insertions(+), 104 deletions(-) create mode 100644 pkg/services/ngalert/api/api_trans_dev.go diff --git a/pkg/services/ngalert/api/api.go b/pkg/services/ngalert/api/api.go index 878d0060cba..8d2d1da1858 100644 --- a/pkg/services/ngalert/api/api.go +++ b/pkg/services/ngalert/api/api.go @@ -10,8 +10,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/api/routing" - "github.com/grafana/grafana/pkg/bus" - "github.com/grafana/grafana/pkg/expr/translate" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/models" @@ -78,15 +76,6 @@ func (api *API) RegisterAPIEndpoints() { alertDefinitions.Post("/unpause", middleware.ReqEditorRole, binding.Bind(ngmodels.UpdateAlertDefinitionPausedCommand{}), routing.Wrap(api.alertDefinitionUnpauseEndpoint)) }) - api.RouteRegister.Group("/api/ngalert/", func(schedulerRouter routing.RouteRegister) { - schedulerRouter.Post("/pause", routing.Wrap(api.pauseScheduler)) - schedulerRouter.Post("/unpause", routing.Wrap(api.unpauseScheduler)) - }, middleware.ReqOrgAdmin) - - api.RouteRegister.Group("/api/alert-instances", func(alertInstances routing.RouteRegister) { - alertInstances.Get("", middleware.ReqSignedIn, routing.Wrap(api.listAlertInstancesEndpoint)) - }) - if api.Cfg.Env == setting.Dev { api.RouteRegister.Group("/api/alert-definitions", func(alertDefinitions routing.RouteRegister) { alertDefinitions.Post("/evalOld", middleware.ReqSignedIn, routing.Wrap(api.conditionEvalOldEndpoint)) @@ -94,102 +83,18 @@ func (api *API) RegisterAPIEndpoints() { api.RouteRegister.Group("/api/alert-definitions", func(alertDefinitions routing.RouteRegister) { alertDefinitions.Get("/evalOldByID/:id", middleware.ReqSignedIn, routing.Wrap(api.conditionEvalOldEndpointByID)) }) - } -} - -// conditionEvalEndpoint handles POST /api/alert-definitions/evalOld. -func (api *API) conditionEvalOldEndpoint(c *models.ReqContext) response.Response { - b, err := c.Req.Body().Bytes() - if err != nil { - response.Error(400, "failed to read body", err) - } - evalCond, err := translate.DashboardAlertConditions(b, c.OrgId) - if err != nil { - return response.Error(400, "Failed to translate alert conditions", err) + api.RouteRegister.Group("/api/alert-definitions", func(alertDefinitions routing.RouteRegister) { + alertDefinitions.Get("/oldByID/:id", middleware.ReqSignedIn, routing.Wrap(api.conditionOldEndpointByID)) + }) } - if err := api.validateCondition(*evalCond, c.SignedInUser, c.SkipCache); err != nil { - return response.Error(400, "invalid condition", err) - } + api.RouteRegister.Group("/api/ngalert/", func(schedulerRouter routing.RouteRegister) { + schedulerRouter.Post("/pause", routing.Wrap(api.pauseScheduler)) + schedulerRouter.Post("/unpause", routing.Wrap(api.unpauseScheduler)) + }, middleware.ReqOrgAdmin) - //now := cmd.Now - //if now.IsZero() { - //now := timeNow() - //} - - evaluator := eval.Evaluator{Cfg: api.Cfg} - evalResults, err := evaluator.ConditionEval(evalCond, timeNow(), api.DataService) - if err != nil { - return response.Error(400, "Failed to evaluate conditions", err) - } - - frame := evalResults.AsDataFrame() - df := plugins.NewDecodedDataFrames([]*data.Frame{&frame}) - instances, err := df.Encoded() - if err != nil { - return response.Error(400, "Failed to encode result dataframes", err) - } - - return response.JSON(200, util.DynMap{ - "instances": instances, - }) -} - -// conditionEvalEndpoint handles POST /api/alert-definitions/evalOld. -func (api *API) conditionEvalOldEndpointByID(c *models.ReqContext) response.Response { - id := c.ParamsInt64("id") - if id == 0 { - return response.Error(400, "missing id", nil) - } - - getAlert := &models.GetAlertByIdQuery{ - Id: id, - } - - if err := bus.Dispatch(getAlert); err != nil { - return response.Error(400, fmt.Sprintf("could find alert with id %v", id), err) - } - - if getAlert.Result.OrgId != c.SignedInUser.OrgId { - return response.Error(403, "alert does not match organization of user", nil) - } - - settings := getAlert.Result.Settings - - sb, err := settings.ToDB() - if err != nil { - return response.Error(400, "failed to marshal alert settings", err) - } - - evalCond, err := translate.DashboardAlertConditions(sb, c.OrgId) - if err != nil { - return response.Error(400, "Failed to translate alert conditions", err) - } - - if err := api.validateCondition(*evalCond, c.SignedInUser, c.SkipCache); err != nil { - return response.Error(400, "invalid condition", err) - } - - //now := cmd.Now - //if now.IsZero() { - //now := timeNow() - //} - - evaluator := eval.Evaluator{Cfg: api.Cfg} - evalResults, err := evaluator.ConditionEval(evalCond, timeNow(), api.DataService) - if err != nil { - return response.Error(400, "Failed to evaluate conditions", err) - } - - frame := evalResults.AsDataFrame() - df := plugins.NewDecodedDataFrames([]*data.Frame{&frame}) - instances, err := df.Encoded() - if err != nil { - return response.Error(400, "Failed to encode result dataframes", err) - } - - return response.JSON(200, util.DynMap{ - "instances": instances, + api.RouteRegister.Group("/api/alert-instances", func(alertInstances routing.RouteRegister) { + alertInstances.Get("", middleware.ReqSignedIn, routing.Wrap(api.listAlertInstancesEndpoint)) }) } diff --git a/pkg/services/ngalert/api/api_trans_dev.go b/pkg/services/ngalert/api/api_trans_dev.go new file mode 100644 index 00000000000..265a83559ec --- /dev/null +++ b/pkg/services/ngalert/api/api_trans_dev.go @@ -0,0 +1,144 @@ +package api + +import ( + "fmt" + + "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/grafana/grafana/pkg/api/response" + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/expr/translate" + "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/services/ngalert/eval" + "github.com/grafana/grafana/pkg/util" +) + +// conditionEvalEndpoint handles POST /api/alert-definitions/evalOld. +func (api *API) conditionEvalOldEndpoint(c *models.ReqContext) response.Response { + b, err := c.Req.Body().Bytes() + if err != nil { + response.Error(400, "failed to read body", err) + } + evalCond, err := translate.DashboardAlertConditions(b, c.OrgId) + if err != nil { + return response.Error(400, "Failed to translate alert conditions", err) + } + + if err := api.validateCondition(*evalCond, c.SignedInUser, c.SkipCache); err != nil { + return response.Error(400, "invalid condition", err) + } + + //now := cmd.Now + //if now.IsZero() { + //now := timeNow() + //} + + evaluator := eval.Evaluator{Cfg: api.Cfg} + evalResults, err := evaluator.ConditionEval(evalCond, timeNow(), api.DataService) + if err != nil { + return response.Error(400, "Failed to evaluate conditions", err) + } + + frame := evalResults.AsDataFrame() + df := plugins.NewDecodedDataFrames([]*data.Frame{&frame}) + instances, err := df.Encoded() + if err != nil { + return response.Error(400, "Failed to encode result dataframes", err) + } + + return response.JSON(200, util.DynMap{ + "instances": instances, + }) +} + +// conditionEvalEndpoint handles POST /api/alert-definitions/evalOld. +func (api *API) conditionEvalOldEndpointByID(c *models.ReqContext) response.Response { + id := c.ParamsInt64("id") + if id == 0 { + return response.Error(400, "missing id", nil) + } + + getAlert := &models.GetAlertByIdQuery{ + Id: id, + } + + if err := bus.Dispatch(getAlert); err != nil { + return response.Error(400, fmt.Sprintf("could find alert with id %v", id), err) + } + + if getAlert.Result.OrgId != c.SignedInUser.OrgId { + return response.Error(403, "alert does not match organization of user", nil) + } + + settings := getAlert.Result.Settings + + sb, err := settings.ToDB() + if err != nil { + return response.Error(400, "failed to marshal alert settings", err) + } + + evalCond, err := translate.DashboardAlertConditions(sb, c.OrgId) + if err != nil { + return response.Error(400, "Failed to translate alert conditions", err) + } + + if err := api.validateCondition(*evalCond, c.SignedInUser, c.SkipCache); err != nil { + return response.Error(400, "invalid condition", err) + } + + //now := cmd.Now + //if now.IsZero() { + //now := timeNow() + //} + + evaluator := eval.Evaluator{Cfg: api.Cfg} + evalResults, err := evaluator.ConditionEval(evalCond, timeNow(), api.DataService) + if err != nil { + return response.Error(400, "Failed to evaluate conditions", err) + } + + frame := evalResults.AsDataFrame() + df := plugins.NewDecodedDataFrames([]*data.Frame{&frame}) + instances, err := df.Encoded() + if err != nil { + return response.Error(400, "Failed to encode result dataframes", err) + } + + return response.JSON(200, util.DynMap{ + "instances": instances, + }) +} + +// conditionEvalEndpoint handles POST /api/alert-definitions/evalOld. +func (api *API) conditionOldEndpointByID(c *models.ReqContext) response.Response { + id := c.ParamsInt64("id") + if id == 0 { + return response.Error(400, "missing id", nil) + } + + getAlert := &models.GetAlertByIdQuery{ + Id: id, + } + + if err := bus.Dispatch(getAlert); err != nil { + return response.Error(400, fmt.Sprintf("could find alert with id %v", id), err) + } + + if getAlert.Result.OrgId != c.SignedInUser.OrgId { + return response.Error(403, "alert does not match organization of user", nil) + } + + settings := getAlert.Result.Settings + + sb, err := settings.ToDB() + if err != nil { + return response.Error(400, "failed to marshal alert settings", err) + } + + evalCond, err := translate.DashboardAlertConditions(sb, c.OrgId) + if err != nil { + return response.Error(400, "Failed to translate alert conditions", err) + } + + return response.JSON(200, evalCond) +}