From aec2ef727a421542873db8d6e7a3573ad721ab76 Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Mon, 18 Mar 2024 09:49:26 -0400 Subject: [PATCH] Prometheus/Scopes: Update to use scopespec type from app (#84593) --- pkg/promlib/models/query.go | 18 +++++------------- pkg/promlib/models/scope.go | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/pkg/promlib/models/query.go b/pkg/promlib/models/query.go index 3c9a96bab91..a22eb5a2bab 100644 --- a/pkg/promlib/models/query.go +++ b/pkg/promlib/models/query.go @@ -2,7 +2,6 @@ package models import ( "encoding/json" - "fmt" "math" "strconv" "strings" @@ -11,8 +10,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/gtime" "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/promql/parser" + "github.com/grafana/grafana/pkg/apis/scope/v0alpha1" "github.com/grafana/grafana/pkg/promlib/intervalv2" ) @@ -64,9 +63,7 @@ type PrometheusQueryProperties struct { LegendFormat string `json:"legendFormat,omitempty"` // ??? - Scope *struct { - Matchers string `json:"matchers"` - } `json:"scope,omitempty"` + Scope *v0alpha1.ScopeSpec `json:"scope,omitempty"` } // Internal interval and range variables @@ -139,7 +136,7 @@ type Query struct { RangeQuery bool ExemplarQuery bool UtcOffsetSec int64 - Scope Scope + Scope *v0alpha1.ScopeSpec } type Scope struct { @@ -168,13 +165,8 @@ func Parse(query backend.DataQuery, dsScrapeInterval string, intervalCalculator dsScrapeInterval, timeRange, ) - var matchers []*labels.Matcher - if enableScope && model.Scope != nil && model.Scope.Matchers != "" { - matchers, err = parser.ParseMetricSelector(model.Scope.Matchers) - if err != nil { - return nil, fmt.Errorf("failed to parse metric selector %v in scope", model.Scope.Matchers) - } - expr, err = ApplyQueryScope(expr, matchers) + if enableScope && model.Scope != nil && len(model.Scope.Filters) > 0 { + expr, err = ApplyQueryScope(expr, *model.Scope) if err != nil { return nil, err } diff --git a/pkg/promlib/models/scope.go b/pkg/promlib/models/scope.go index c14dfdc550b..16e588001bb 100644 --- a/pkg/promlib/models/scope.go +++ b/pkg/promlib/models/scope.go @@ -1,16 +1,24 @@ package models import ( + "fmt" + + "github.com/grafana/grafana/pkg/apis/scope/v0alpha1" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/promql/parser" ) -func ApplyQueryScope(rawExpr string, matchers []*labels.Matcher) (string, error) { +func ApplyQueryScope(rawExpr string, scope v0alpha1.ScopeSpec) (string, error) { expr, err := parser.ParseExpr(rawExpr) if err != nil { return "", err } + matchers, err := scopeFiltersToMatchers(scope.Filters) + if err != nil { + return "", err + } + matcherNamesToIdx := make(map[string]int, len(matchers)) for i, matcher := range matchers { if matcher == nil { @@ -50,3 +58,28 @@ func ApplyQueryScope(rawExpr string, matchers []*labels.Matcher) (string, error) }) return expr.String(), nil } + +func scopeFiltersToMatchers(filters []v0alpha1.ScopeFilter) ([]*labels.Matcher, error) { + matchers := make([]*labels.Matcher, 0, len(filters)) + for _, f := range filters { + var mt labels.MatchType + switch f.Operator { + case "=": + mt = labels.MatchEqual + case "!=": + mt = labels.MatchNotEqual + case "=~": + mt = labels.MatchRegexp + case "!~": + mt = labels.MatchNotRegexp + default: + return nil, fmt.Errorf("unknown operator %q", f.Operator) + } + m, err := labels.NewMatcher(mt, f.Key, f.Value) + if err != nil { + return nil, err + } + matchers = append(matchers, m) + } + return matchers, nil +}