mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
66 lines
2.1 KiB
Go
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)
|
|
}
|