diff --git a/pkg/services/ngalert/api/api_ruler.go b/pkg/services/ngalert/api/api_ruler.go index ca9aa225a34..fd82c004a57 100644 --- a/pkg/services/ngalert/api/api_ruler.go +++ b/pkg/services/ngalert/api/api_ruler.go @@ -303,7 +303,7 @@ func (srv RulerSrv) RoutePostNameRulesConfig(c *contextmodel.ReqContext, ruleGro } rules, err := validateRuleGroup(&ruleGroupConfig, c.SignedInUser.OrgID, namespace, func(condition ngmodels.Condition) error { - return srv.conditionValidator.Validate(eval.Context(c.Req.Context(), c.SignedInUser), condition) + return srv.conditionValidator.Validate(eval.NewContext(c.Req.Context(), c.SignedInUser), condition) }, srv.cfg) if err != nil { return ErrResp(http.StatusBadRequest, err, "") diff --git a/pkg/services/ngalert/api/api_testing.go b/pkg/services/ngalert/api/api_testing.go index 83728417e80..f5dd34c03b2 100644 --- a/pkg/services/ngalert/api/api_testing.go +++ b/pkg/services/ngalert/api/api_testing.go @@ -52,7 +52,7 @@ func (srv TestingApiSrv) RouteTestGrafanaRuleConfig(c *contextmodel.ReqContext, Condition: body.GrafanaManagedCondition.Condition, Data: queries, } - ctx := eval.Context(c.Req.Context(), c.SignedInUser) + ctx := eval.NewContext(c.Req.Context(), c.SignedInUser) conditionEval, err := srv.evaluator.Create(ctx, evalCond) if err != nil { @@ -128,7 +128,7 @@ func (srv TestingApiSrv) RouteEvalQueries(c *contextmodel.ReqContext, cmd apimod if len(cmd.Data) > 0 { cond.Condition = cmd.Data[0].RefID } - evaluator, err := srv.evaluator.Create(eval.Context(c.Req.Context(), c.SignedInUser), cond) + evaluator, err := srv.evaluator.Create(eval.NewContext(c.Req.Context(), c.SignedInUser), cond) if err != nil { return ErrResp(http.StatusBadRequest, err, "Failed to build evaluator for queries and expressions") diff --git a/pkg/services/ngalert/eval/context.go b/pkg/services/ngalert/eval/context.go index f84a0e607f6..3cdaefceb22 100644 --- a/pkg/services/ngalert/eval/context.go +++ b/pkg/services/ngalert/eval/context.go @@ -12,7 +12,7 @@ type EvaluationContext struct { User *user.SignedInUser } -func Context(ctx context.Context, user *user.SignedInUser) EvaluationContext { +func NewContext(ctx context.Context, user *user.SignedInUser) EvaluationContext { return EvaluationContext{ Ctx: ctx, User: user, diff --git a/pkg/services/ngalert/eval/eval.go b/pkg/services/ngalert/eval/eval.go index c08bbec75e0..fd9f4b6084b 100644 --- a/pkg/services/ngalert/eval/eval.go +++ b/pkg/services/ngalert/eval/eval.go @@ -220,7 +220,7 @@ func (s State) String() string { return [...]string{"Normal", "Alerting", "Pending", "NoData", "Error"}[s] } -func buildDatasourceHeaders(ctx EvaluationContext) map[string]string { +func buildDatasourceHeaders(ctx context.Context) map[string]string { headers := map[string]string{ // Many data sources check this in query method as sometimes alerting needs special considerations. // Several existing systems also compare against the value of this header. Altering this constitutes a breaking change. @@ -233,7 +233,7 @@ func buildDatasourceHeaders(ctx EvaluationContext) map[string]string { models.CacheSkipHeaderName: "true", } - key, ok := models.RuleKeyFromContext(ctx.Ctx) + key, ok := models.RuleKeyFromContext(ctx) if ok { headers["X-Rule-Uid"] = key.UID headers["X-Grafana-Org-Id"] = strconv.FormatInt(key.OrgID, 10) @@ -246,7 +246,7 @@ func buildDatasourceHeaders(ctx EvaluationContext) map[string]string { func getExprRequest(ctx EvaluationContext, data []models.AlertQuery, dsCacheService datasources.CacheService) (*expr.Request, error) { req := &expr.Request{ OrgId: ctx.User.OrgID, - Headers: buildDatasourceHeaders(ctx), + Headers: buildDatasourceHeaders(ctx.Ctx), } datasources := make(map[string]*datasources.DataSource, len(data)) @@ -295,7 +295,8 @@ func getExprRequest(ctx EvaluationContext, data []models.AlertQuery, dsCacheServ type NumberValueCapture struct { Var string // RefID Labels data.Labels - Value *float64 + + Value *float64 } func queryDataResponseToExecutionResults(c models.Condition, execResp *backend.QueryDataResponse) ExecutionResults { diff --git a/pkg/services/ngalert/eval/eval_test.go b/pkg/services/ngalert/eval/eval_test.go index 14fdd65cb54..a69c54e31e7 100644 --- a/pkg/services/ngalert/eval/eval_test.go +++ b/pkg/services/ngalert/eval/eval_test.go @@ -533,7 +533,7 @@ func TestValidate(t *testing.T) { }) evaluator := NewEvaluatorFactory(setting.UnifiedAlertingSettings{}, cacheService, expr.ProvideService(&setting.Cfg{ExpressionsEnabled: true}, nil, nil), store) - evalCtx := Context(context.Background(), u) + evalCtx := NewContext(context.Background(), u) err := evaluator.Validate(evalCtx, condition) if testCase.error { diff --git a/pkg/services/ngalert/models/alert_query.go b/pkg/services/ngalert/models/alert_query.go index 0d4d1410a9f..6f6c437e72a 100644 --- a/pkg/services/ngalert/models/alert_query.go +++ b/pkg/services/ngalert/models/alert_query.go @@ -97,6 +97,10 @@ type AlertQuery struct { modelProps map[string]interface{} } +func (aq *AlertQuery) String() string { + return fmt.Sprintf("refID: %s, queryType: %s, datasourceUID: %s", aq.RefID, aq.QueryType, aq.DatasourceUID) +} + func (aq *AlertQuery) setModelProps() error { aq.modelProps = make(map[string]interface{}) err := json.Unmarshal(aq.Model, &aq.modelProps) diff --git a/pkg/services/ngalert/schedule/schedule.go b/pkg/services/ngalert/schedule/schedule.go index a57bf6c133d..eefed6e9a4c 100644 --- a/pkg/services/ngalert/schedule/schedule.go +++ b/pkg/services/ngalert/schedule/schedule.go @@ -373,21 +373,7 @@ func (sch *schedule) ruleRoutine(grafanaCtx context.Context, key ngmodels.AlertR logger := logger.New("version", e.rule.Version, "attempt", attempt, "now", e.scheduledAt) start := sch.clock.Now() - schedulerUser := &user.SignedInUser{ - UserID: -1, - IsServiceAccount: true, - Login: "grafana_scheduler", - OrgID: e.rule.OrgID, - OrgRole: org.RoleAdmin, - Permissions: map[int64]map[string][]string{ - e.rule.OrgID: { - datasources.ActionQuery: []string{ - datasources.ScopeAll, - }, - }, - }, - } - evalCtx := eval.Context(ctx, schedulerUser) + evalCtx := eval.NewContext(ctx, SchedulerUserFor(e.rule.OrgID)) ruleEval, err := sch.evaluatorFactory.Create(evalCtx, e.rule.GetEvalCondition()) var results eval.Results var dur time.Duration @@ -580,3 +566,20 @@ func (sch *schedule) getRuleExtraLabels(evalCtx *evaluation) map[string]string { } return extraLabels } + +func SchedulerUserFor(orgID int64) *user.SignedInUser { + return &user.SignedInUser{ + UserID: -1, + IsServiceAccount: true, + Login: "grafana_scheduler", + OrgID: orgID, + OrgRole: org.RoleAdmin, + Permissions: map[int64]map[string][]string{ + orgID: { + datasources.ActionQuery: []string{ + datasources.ScopeAll, + }, + }, + }, + } +}