Alerting: Improve rule validation to check if rule uses backend datasources (#58986)

* validate if rule uses backend datasources

* add backend datasource to test

* fix tests

* another forgotten import

* remove unused var
This commit is contained in:
Yuri Tseretyan
2022-12-08 10:44:02 +01:00
committed by GitHub
parent 75cceec62c
commit c5ee4e4ae1
6 changed files with 160 additions and 38 deletions
+27 -2
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/expr/classic"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/setting"
@@ -83,16 +84,20 @@ type evaluatorImpl struct {
evaluationTimeout time.Duration
dataSourceCache datasources.CacheService
expressionService *expr.Service
pluginsStore plugins.Store
}
func NewEvaluatorFactory(
cfg setting.UnifiedAlertingSettings,
datasourceCache datasources.CacheService,
expressionService *expr.Service) EvaluatorFactory {
expressionService *expr.Service,
pluginsStore plugins.Store,
) EvaluatorFactory {
return &evaluatorImpl{
evaluationTimeout: cfg.EvaluationTimeout,
dataSourceCache: datasourceCache,
expressionService: expressionService,
pluginsStore: pluginsStore,
}
}
@@ -591,7 +596,23 @@ func (evalResults Results) AsDataFrame() data.Frame {
}
func (e *evaluatorImpl) Validate(ctx EvaluationContext, condition models.Condition) error {
_, err := e.Create(ctx, condition)
req, err := getExprRequest(ctx, condition.Data, e.dataSourceCache)
if err != nil {
return err
}
for _, query := range req.Queries {
if query.DataSource == nil || expr.IsDataSource(query.DataSource.Uid) {
continue
}
p, found := e.pluginsStore.Plugin(ctx.Ctx, query.DataSource.Type)
if !found { // technically this should fail earlier during datasource resolution phase.
return fmt.Errorf("datasource refID %s could not be found: %w", query.RefID, plugins.ErrPluginUnavailable)
}
if !p.Backend {
return fmt.Errorf("datasource refID %s is not a backend datasource", query.RefID)
}
}
_, err = e.create(condition, req)
return err
}
@@ -606,6 +627,10 @@ func (e *evaluatorImpl) Create(ctx EvaluationContext, condition models.Condition
if err != nil {
return nil, err
}
return e.create(condition, req)
}
func (e *evaluatorImpl) create(condition models.Condition, req *expr.Request) (ConditionEvaluator, error) {
pipeline, err := e.expressionService.BuildPipeline(req)
if err != nil {
return nil, err