Alerting: Add traceability headers for alert queries (#57127)
* Define EvaluationContext * Refactor ConditionEval to use new context struct * Refactor QueriesAndExpressionsEval to use EvaluationContext * Remove dead field from AlertExecCtx * Refactor Validate to use EvaluationContext * Get rid of privately used AlertExecCtx * Move EvaluationContext to new file and add helper * Add builder pattern and bind rule info to context * Extract header logic and add rule UID header * Fix missing call
This commit is contained in:
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
|
||||
type ConditionValidator interface {
|
||||
// Validate validates that the condition is correct. Returns nil if the condition is correct. Otherwise, error that describes the failure
|
||||
Validate(ctx context.Context, user *user.SignedInUser, condition ngmodels.Condition) error
|
||||
Validate(ctx eval.EvaluationContext, condition ngmodels.Condition) error
|
||||
}
|
||||
|
||||
type RulerSrv struct {
|
||||
@@ -308,7 +308,7 @@ func (srv RulerSrv) RoutePostNameRulesConfig(c *models.ReqContext, ruleGroupConf
|
||||
}
|
||||
|
||||
rules, err := validateRuleGroup(&ruleGroupConfig, c.SignedInUser.OrgID, namespace, func(condition ngmodels.Condition) error {
|
||||
return srv.conditionValidator.Validate(c.Req.Context(), c.SignedInUser, condition)
|
||||
return srv.conditionValidator.Validate(eval.Context(c.Req.Context(), c.SignedInUser), condition)
|
||||
}, srv.cfg)
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
|
||||
@@ -42,17 +42,18 @@ func (srv TestingApiSrv) RouteTestGrafanaRuleConfig(c *models.ReqContext, body a
|
||||
Condition: body.GrafanaManagedCondition.Condition,
|
||||
Data: body.GrafanaManagedCondition.Data,
|
||||
}
|
||||
ctx := eval.Context(c.Req.Context(), c.SignedInUser)
|
||||
|
||||
if err := srv.evaluator.Validate(c.Req.Context(), c.SignedInUser, evalCond); err != nil {
|
||||
if err := srv.evaluator.Validate(ctx, evalCond); err != nil {
|
||||
return ErrResp(http.StatusBadRequest, err, "invalid condition")
|
||||
}
|
||||
|
||||
now := body.GrafanaManagedCondition.Now
|
||||
if now.IsZero() {
|
||||
now = timeNow()
|
||||
ctx = ctx.When(body.GrafanaManagedCondition.Now)
|
||||
if ctx.At.IsZero() {
|
||||
ctx = ctx.When(timeNow())
|
||||
}
|
||||
|
||||
evalResults := srv.evaluator.ConditionEval(c.Req.Context(), c.SignedInUser, evalCond, now)
|
||||
evalResults := srv.evaluator.ConditionEval(ctx, evalCond)
|
||||
|
||||
frame := evalResults.AsDataFrame()
|
||||
return response.JSONStreaming(http.StatusOK, util.DynMap{
|
||||
@@ -99,18 +100,18 @@ func (srv TestingApiSrv) RouteTestRuleConfig(c *models.ReqContext, body apimodel
|
||||
}
|
||||
|
||||
func (srv TestingApiSrv) RouteEvalQueries(c *models.ReqContext, cmd apimodels.EvalQueriesPayload) response.Response {
|
||||
now := cmd.Now
|
||||
if now.IsZero() {
|
||||
now = timeNow()
|
||||
}
|
||||
|
||||
if !authorizeDatasourceAccessForRule(&ngmodels.AlertRule{Data: cmd.Data}, func(evaluator accesscontrol.Evaluator) bool {
|
||||
return accesscontrol.HasAccess(srv.accessControl, c)(accesscontrol.ReqSignedIn, evaluator)
|
||||
}) {
|
||||
return ErrResp(http.StatusUnauthorized, fmt.Errorf("%w to query one or many data sources used by the rule", ErrAuthorization), "")
|
||||
}
|
||||
|
||||
evalResults, err := srv.evaluator.QueriesAndExpressionsEval(c.Req.Context(), c.SignedInUser, cmd.Data, now)
|
||||
ctx := eval.Context(c.Req.Context(), c.SignedInUser).When(cmd.Now)
|
||||
if ctx.At.IsZero() {
|
||||
ctx = ctx.When(timeNow())
|
||||
}
|
||||
|
||||
evalResults, err := srv.evaluator.QueriesAndExpressionsEval(ctx, cmd.Data)
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusBadRequest, err, "Failed to evaluate queries and expressions")
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) {
|
||||
|
||||
evaluator := &eval.FakeEvaluator{}
|
||||
var result []eval.Result
|
||||
evaluator.EXPECT().Validate(mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
evaluator.EXPECT().ConditionEval(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(result)
|
||||
evaluator.EXPECT().Validate(mock.Anything, mock.Anything).Return(nil)
|
||||
evaluator.EXPECT().ConditionEval(mock.Anything, mock.Anything).Return(result)
|
||||
|
||||
srv := createTestingApiSrv(ds, ac, evaluator)
|
||||
|
||||
@@ -112,8 +112,8 @@ func TestRouteTestGrafanaRuleConfig(t *testing.T) {
|
||||
|
||||
evaluator := &eval.FakeEvaluator{}
|
||||
var result []eval.Result
|
||||
evaluator.EXPECT().Validate(mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
evaluator.EXPECT().ConditionEval(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(result)
|
||||
evaluator.EXPECT().Validate(mock.Anything, mock.Anything).Return(nil)
|
||||
evaluator.EXPECT().ConditionEval(mock.Anything, mock.Anything).Return(result)
|
||||
|
||||
srv := createTestingApiSrv(ds, ac, evaluator)
|
||||
|
||||
@@ -203,7 +203,7 @@ func TestRouteEvalQueries(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
evaluator.EXPECT().QueriesAndExpressionsEval(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(result, nil)
|
||||
evaluator.EXPECT().QueriesAndExpressionsEval(mock.Anything, mock.Anything).Return(result, nil)
|
||||
|
||||
srv := createTestingApiSrv(ds, ac, evaluator)
|
||||
|
||||
@@ -246,7 +246,7 @@ func TestRouteEvalQueries(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
evaluator.EXPECT().QueriesAndExpressionsEval(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(result, nil)
|
||||
evaluator.EXPECT().QueriesAndExpressionsEval(mock.Anything, mock.Anything).Return(result, nil)
|
||||
|
||||
srv := createTestingApiSrv(ds, ac, evaluator)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user