grafana/pkg/services/ngalert/eval/validate.go
Alexander Weaver 4c71cadd5f
Alerting: Detach condition validator from condition evaluator (#91150)
* Detach validator from evaluator

* Drop unnecessary interface and type
2024-07-30 10:55:37 -05:00

66 lines
2.1 KiB
Go

package eval
import (
"fmt"
"github.com/grafana/grafana/pkg/expr"
"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/services/pluginsintegration/pluginstore"
)
type ConditionValidator struct {
dataSourceCache datasources.CacheService
pluginsStore pluginstore.Store
expressionService expressionBuilder
}
func NewConditionValidator(datasourceCache datasources.CacheService, expressionService *expr.Service, pluginsStore pluginstore.Store) *ConditionValidator {
return &ConditionValidator{
dataSourceCache: datasourceCache,
expressionService: expressionService,
pluginsStore: pluginsStore,
}
}
func (e *ConditionValidator) Validate(ctx EvaluationContext, condition models.Condition) error {
req, err := getExprRequest(ctx, condition, e.dataSourceCache, ctx.AlertingResultsReader)
if err != nil {
return err
}
for _, query := range req.Queries {
if query.DataSource == nil {
continue
}
switch expr.NodeTypeFromDatasourceUID(query.DataSource.UID) {
case expr.TypeDatasourceNode:
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)
}
case expr.TypeMLNode:
_, found := e.pluginsStore.Plugin(ctx.Ctx, query.DataSource.Type)
if !found {
return fmt.Errorf("datasource refID %s could not be found: %w", query.RefID, plugins.ErrPluginUnavailable)
}
case expr.TypeCMDNode:
}
}
pipeline, err := e.expressionService.BuildPipeline(req)
if err != nil {
return err
}
refIDs := make([]string, 0, len(pipeline))
for _, node := range pipeline {
if node.RefID() == condition.Condition {
return nil
}
refIDs = append(refIDs, node.RefID())
}
return models.ErrConditionNotExist(condition.Condition, refIDs)
}