diff --git a/pkg/apimachinery/apis/common/v0alpha1/types.go b/pkg/apimachinery/apis/common/v0alpha1/types.go index 94f5670a89a..9cb6f958a87 100644 --- a/pkg/apimachinery/apis/common/v0alpha1/types.go +++ b/pkg/apimachinery/apis/common/v0alpha1/types.go @@ -42,46 +42,3 @@ func (r ObjectReference) ToOwnerReference() metav1.OwnerReference { UID: r.UID, } } - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type Scope struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ScopeSpec `json:"spec,omitempty"` -} - -type ScopeSpec struct { - Title string `json:"title"` - // Provides a default path for the scope. This refers to a list of nodes in the selector. This is used to display the title next to the selected scope and expand the selector to the proper path. - // This will override whichever is selected from in the selector. - // The path is a list of node ids, starting at the direct parent of the selected node towards the root. - // +listType=atomic - DefaultPath []string `json:"defaultPath,omitempty"` - - // +listType=atomic - Filters []ScopeFilter `json:"filters,omitempty"` -} - -type ScopeFilter struct { - Key string `json:"key"` - Value string `json:"value"` - // Values is used for operators that require multiple values (e.g. one-of and not-one-of). - // +listType=atomic - Values []string `json:"values,omitempty"` - Operator FilterOperator `json:"operator"` -} - -// Type of the filter operator. -// +enum -type FilterOperator string - -// Defines values for FilterOperator. -const ( - FilterOperatorEquals FilterOperator = "equals" - FilterOperatorNotEquals FilterOperator = "not-equals" - FilterOperatorRegexMatch FilterOperator = "regex-match" - FilterOperatorRegexNotMatch FilterOperator = "regex-not-match" - FilterOperatorOneOf FilterOperator = "one-of" - FilterOperatorNotOneOf FilterOperator = "not-one-of" -) diff --git a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go index 41c6e53441b..ce8cef02c51 100644 --- a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go +++ b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.deepcopy.go @@ -7,10 +7,6 @@ package v0alpha1 -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InlineSecureValue) DeepCopyInto(out *InlineSecureValue) { *out = *in @@ -42,79 +38,3 @@ func (in *ObjectReference) DeepCopy() *ObjectReference { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Scope) DeepCopyInto(out *Scope) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scope. -func (in *Scope) DeepCopy() *Scope { - if in == nil { - return nil - } - out := new(Scope) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Scope) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ScopeFilter) DeepCopyInto(out *ScopeFilter) { - *out = *in - if in.Values != nil { - in, out := &in.Values, &out.Values - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeFilter. -func (in *ScopeFilter) DeepCopy() *ScopeFilter { - if in == nil { - return nil - } - out := new(ScopeFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ScopeSpec) DeepCopyInto(out *ScopeSpec) { - *out = *in - if in.DefaultPath != nil { - in, out := &in.DefaultPath, &out.DefaultPath - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Filters != nil { - in, out := &in.Filters, &out.Filters - *out = make([]ScopeFilter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScopeSpec. -func (in *ScopeSpec) DeepCopy() *ScopeSpec { - if in == nil { - return nil - } - out := new(ScopeSpec) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go index b3042736e0c..da02bcce8ac 100644 --- a/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go +++ b/pkg/apimachinery/apis/common/v0alpha1/zz_generated.openapi.go @@ -17,9 +17,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA return map[string]common.OpenAPIDefinition{ "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue": InlineSecureValue{}.OpenAPIDefinition(), "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ObjectReference": schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref), - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Scope": schema_apimachinery_apis_common_v0alpha1_Scope(ref), - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter": schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref), - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec": schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref), "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": Unstructured{}.OpenAPIDefinition(), "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), @@ -139,162 +136,6 @@ func schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref common.Referen } } -func schema_apimachinery_apis_common_v0alpha1_Scope(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_apimachinery_apis_common_v0alpha1_ScopeFilter(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "key": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "value": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "values": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "operator": { - SchemaProps: spec.SchemaProps{ - Description: "Possible enum values:\n - `\"equals\"`\n - `\"not-equals\"`\n - `\"not-one-of\"`\n - `\"one-of\"`\n - `\"regex-match\"`\n - `\"regex-not-match\"`", - Default: "", - Type: []string{"string"}, - Format: "", - Enum: []interface{}{"equals", "not-equals", "not-one-of", "one-of", "regex-match", "regex-not-match"}, - }, - }, - }, - Required: []string{"key", "value", "operator"}, - }, - }, - } -} - -func schema_apimachinery_apis_common_v0alpha1_ScopeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "defaultPath": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Provides a default path for the scope. This refers to a list of nodes in the selector. This is used to display the title next to the selected scope and expand the selector to the proper path. This will override whichever is selected from in the selector. The path is a list of node ids, starting at the direct parent of the selected node towards the root.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "filters": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter"), - }, - }, - }, - }, - }, - }, - Required: []string{"title"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.ScopeFilter"}, - } -} - func schema_pkg_apis_meta_v1_APIGroup(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod index e28af53a841..cc2420b2223 100644 --- a/pkg/promlib/go.mod +++ b/pkg/promlib/go.mod @@ -5,6 +5,7 @@ go 1.25.2 require ( github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 github.com/grafana/grafana-plugin-sdk-go v0.279.0 + github.com/grafana/grafana/apps/scope v0.0.0-20251007093103-792853df9134 github.com/json-iterator/go v1.1.12 github.com/prometheus/client_golang v1.23.2 github.com/prometheus/common v0.66.1 @@ -54,6 +55,7 @@ require ( github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect + github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect @@ -91,10 +93,9 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/smartystreets/goconvey v1.8.1 // indirect - github.com/spf13/pflag v1.0.10 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect github.com/unknwon/com v1.0.1 // indirect diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum index 59f48deaaba..3351c0f7097 100644 --- a/pkg/promlib/go.sum +++ b/pkg/promlib/go.sum @@ -134,6 +134,10 @@ github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz2 github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4/go.mod h1:VahT+GtfQIM+o8ht2StR6J9g+Ef+C2Vokh5uuSmOD/4= github.com/grafana/grafana-plugin-sdk-go v0.279.0 h1:/KCrsZkj9pEGwIGovqAz1A8rjI2A2YT+ZpvgfZN0LAA= github.com/grafana/grafana-plugin-sdk-go v0.279.0/go.mod h1:/7oGN6Z7DGTGaLHhgIYrRr6Wvmdsb3BLw5hL4Kbjy88= +github.com/grafana/grafana/apps/scope v0.0.0-20251007093103-792853df9134 h1:xly75v5lFNR37q+wXnwA5yU/fPW9IOSYbhFpt4tQyt8= +github.com/grafana/grafana/apps/scope v0.0.0-20251007093103-792853df9134/go.mod h1:zijsUNa1zi476JJIR2Lcm/Paz1nRCno9XCp6hbS6G9o= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a h1:L7xgV9mP6MRF3L2/vDOjNR7heaBPbXPMGTDN9/jXSFQ= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a/go.mod h1:OK8NwS87D5YphchOcAsiIWk/feMZ0EzfAGME1Kff860= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= @@ -278,6 +282,7 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/pkg/promlib/models/query.go b/pkg/promlib/models/query.go index ec32b7bc3cd..a34c1b6aea9 100644 --- a/pkg/promlib/models/query.go +++ b/pkg/promlib/models/query.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/gtime" sdkapi "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -68,47 +69,15 @@ type PrometheusQueryProperties struct { LegendFormat string `json:"legendFormat,omitempty"` // A set of filters applied to apply to the query - Scopes []ScopeSpec `json:"scopes,omitempty"` + Scopes []scope.ScopeSpec `json:"scopes,omitempty"` // Additional Ad-hoc filters that take precedence over Scope on conflict. - AdhocFilters []ScopeFilter `json:"adhocFilters,omitempty"` + AdhocFilters []scope.ScopeFilter `json:"adhocFilters,omitempty"` // Group By parameters to apply to aggregate expressions in the query GroupByKeys []string `json:"groupByKeys,omitempty"` } -// ScopeSpec is a hand copy of the ScopeSpec struct from pkg/apis/scope/v0alpha1/types.go -// to avoid import (temp fix). This also has metadata.name inlined. -type ScopeSpec struct { - Name string `json:"name"` // This is the identifier from metadata.name of the scope model. - Title string `json:"title"` - DefaultPath []string `json:"defaultPath,omitempty"` - Filters []ScopeFilter `json:"filters,omitempty"` -} - -// ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go -// to avoid import (temp fix) -type ScopeFilter struct { - Key string `json:"key"` - Value string `json:"value"` - // Values is used for operators that require multiple values (e.g. one-of and not-one-of). - Values []string `json:"values,omitempty"` - Operator FilterOperator `json:"operator"` -} - -// FilterOperator is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go -type FilterOperator string - -// Hand copy of enum from pkg/apis/scope/v0alpha1/types.go -const ( - FilterOperatorEquals FilterOperator = "equals" - FilterOperatorNotEquals FilterOperator = "not-equals" - FilterOperatorRegexMatch FilterOperator = "regex-match" - FilterOperatorRegexNotMatch FilterOperator = "regex-not-match" - FilterOperatorOneOf FilterOperator = "one-of" - FilterOperatorNotOneOf FilterOperator = "not-one-of" -) - // Internal interval and range variables const ( varInterval = "$__interval" @@ -175,7 +144,7 @@ type Query struct { ExemplarQuery bool UtcOffsetSec int64 - Scopes []ScopeSpec + Scopes []scope.ScopeSpec } // This internal query struct is just like QueryModel, except it does not include: @@ -217,7 +186,7 @@ func Parse(ctx context.Context, log glog.Logger, span trace.Span, query backend. ) if enableScope { - var scopeFilters []ScopeFilter + var scopeFilters []scope.ScopeFilter for _, scope := range model.Scopes { scopeFilters = append(scopeFilters, scope.Filters...) } diff --git a/pkg/promlib/models/query.panel.schema.json b/pkg/promlib/models/query.panel.schema.json index c6ca6a172b8..e787ba10a20 100644 --- a/pkg/promlib/models/query.panel.schema.json +++ b/pkg/promlib/models/query.panel.schema.json @@ -18,7 +18,6 @@ "description": "Additional Ad-hoc filters that take precedence over Scope on conflict.", "type": "array", "items": { - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "type": "object", "required": [ "key", @@ -36,7 +35,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "type": "array", "items": { "type": "string" @@ -184,10 +182,8 @@ "description": "A set of filters applied to apply to the query", "type": "array", "items": { - "description": "ScopeSpec is a hand copy of the ScopeSpec struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix).", "type": "object", "required": [ - "name", "title" ], "properties": { @@ -200,7 +196,6 @@ "filters": { "type": "array", "items": { - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "type": "object", "required": [ "key", @@ -218,7 +213,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "type": "array", "items": { "type": "string" @@ -228,10 +222,6 @@ "additionalProperties": false } }, - "name": { - "description": "This is the identifier from metadata.name of the scope model.", - "type": "string" - }, "title": { "type": "string" } diff --git a/pkg/promlib/models/query.request.schema.json b/pkg/promlib/models/query.request.schema.json index 0e533b8e5c7..899197c97bd 100644 --- a/pkg/promlib/models/query.request.schema.json +++ b/pkg/promlib/models/query.request.schema.json @@ -28,7 +28,6 @@ "description": "Additional Ad-hoc filters that take precedence over Scope on conflict.", "type": "array", "items": { - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "type": "object", "required": [ "key", @@ -46,7 +45,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "type": "array", "items": { "type": "string" @@ -194,10 +192,8 @@ "description": "A set of filters applied to apply to the query", "type": "array", "items": { - "description": "ScopeSpec is a hand copy of the ScopeSpec struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix).", "type": "object", "required": [ - "name", "title" ], "properties": { @@ -210,7 +206,6 @@ "filters": { "type": "array", "items": { - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "type": "object", "required": [ "key", @@ -228,7 +223,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "type": "array", "items": { "type": "string" @@ -238,10 +232,6 @@ "additionalProperties": false } }, - "name": { - "description": "This is the identifier from metadata.name of the scope model.", - "type": "string" - }, "title": { "type": "string" } diff --git a/pkg/promlib/models/query.types.json b/pkg/promlib/models/query.types.json index 6d29e934973..1a30ec82503 100644 --- a/pkg/promlib/models/query.types.json +++ b/pkg/promlib/models/query.types.json @@ -8,7 +8,7 @@ { "metadata": { "name": "default", - "resourceVersion": "1758739325095", + "resourceVersion": "1759831574256", "creationTimestamp": "2024-03-25T13:19:04Z" }, "spec": { @@ -21,7 +21,6 @@ "description": "Additional Ad-hoc filters that take precedence over Scope on conflict.", "items": { "additionalProperties": false, - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "properties": { "key": { "type": "string" @@ -33,7 +32,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "items": { "type": "string" }, @@ -103,7 +101,6 @@ "description": "A set of filters applied to apply to the query", "items": { "additionalProperties": false, - "description": "ScopeSpec is a hand copy of the ScopeSpec struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix).", "properties": { "defaultPath": { "items": { @@ -114,7 +111,6 @@ "filters": { "items": { "additionalProperties": false, - "description": "ScopeFilter is a hand copy of the ScopeFilter struct from pkg/apis/scope/v0alpha1/types.go to avoid import (temp fix)", "properties": { "key": { "type": "string" @@ -126,7 +122,6 @@ "type": "string" }, "values": { - "description": "Values is used for operators that require multiple values (e.g. one-of and not-one-of).", "items": { "type": "string" }, @@ -142,16 +137,11 @@ }, "type": "array" }, - "name": { - "description": "This is the identifier from metadata.name of the scope model.", - "type": "string" - }, "title": { "type": "string" } }, "required": [ - "name", "title" ], "type": "object" diff --git a/pkg/promlib/models/scope.go b/pkg/promlib/models/scope.go index bc2aeb24535..13e9c3c082d 100644 --- a/pkg/promlib/models/scope.go +++ b/pkg/promlib/models/scope.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/promql/parser" @@ -15,7 +16,7 @@ func init() { } // ApplyFiltersAndGroupBy takes a raw promQL expression, converts the filters into PromQL matchers, and applies these matchers to the parsed expression. It also applies the group by clause to any aggregate expressions in the parsed expression. -func ApplyFiltersAndGroupBy(rawExpr string, scopeFilters, adHocFilters []ScopeFilter, groupBy []string) (string, error) { +func ApplyFiltersAndGroupBy(rawExpr string, scopeFilters, adHocFilters []scope.ScopeFilter, groupBy []string) (string, error) { expr, err := parser.ParseExpr(rawExpr) if err != nil { return "", err @@ -76,7 +77,7 @@ func ApplyFiltersAndGroupBy(rawExpr string, scopeFilters, adHocFilters []ScopeFi return expr.String(), nil } -func FiltersToMatchers(scopeFilters, adhocFilters []ScopeFilter) ([]*labels.Matcher, error) { +func FiltersToMatchers(scopeFilters, adhocFilters []scope.ScopeFilter) ([]*labels.Matcher, error) { filterMap := make(map[string]*labels.Matcher) // scope filters are applied first @@ -115,25 +116,25 @@ func FiltersToMatchers(scopeFilters, adhocFilters []ScopeFilter) ([]*labels.Matc return matchers, nil } -func filterToMatcher(f ScopeFilter) (*labels.Matcher, error) { +func filterToMatcher(f scope.ScopeFilter) (*labels.Matcher, error) { var mt labels.MatchType switch f.Operator { - case FilterOperatorEquals: + case scope.FilterOperatorEquals: mt = labels.MatchEqual - case FilterOperatorNotEquals: + case scope.FilterOperatorNotEquals: mt = labels.MatchNotEqual - case FilterOperatorRegexMatch: + case scope.FilterOperatorRegexMatch: mt = labels.MatchRegexp - case FilterOperatorRegexNotMatch: + case scope.FilterOperatorRegexNotMatch: mt = labels.MatchNotRegexp - case FilterOperatorOneOf: + case scope.FilterOperatorOneOf: mt = labels.MatchRegexp - case FilterOperatorNotOneOf: + case scope.FilterOperatorNotOneOf: mt = labels.MatchNotRegexp default: return nil, fmt.Errorf("unknown operator %q", f.Operator) } - if f.Operator == FilterOperatorOneOf || f.Operator == FilterOperatorNotOneOf { + if f.Operator == scope.FilterOperatorOneOf || f.Operator == scope.FilterOperatorNotOneOf { if len(f.Values) > 0 { return labels.NewMatcher(mt, f.Key, strings.Join(f.Values, "|")) } diff --git a/pkg/promlib/models/scope_test.go b/pkg/promlib/models/scope_test.go index fb6d5f4c1a3..3fa1a7a36e5 100644 --- a/pkg/promlib/models/scope_test.go +++ b/pkg/promlib/models/scope_test.go @@ -3,6 +3,7 @@ package models import ( "testing" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/stretchr/testify/require" ) @@ -10,8 +11,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { tests := []struct { name string query string - adhocFilters []ScopeFilter - scopeFilters []ScopeFilter + adhocFilters []scope.ScopeFilter + scopeFilters []scope.ScopeFilter expected string expectErr bool }{ @@ -30,8 +31,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Adhoc filter with existing filter", query: `http_requests_total{job="prometheus"}`, - adhocFilters: []ScopeFilter{ - {Key: "method", Value: "get", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "method", Value: "get", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{job="prometheus",method="get"}`, expectErr: false, @@ -39,9 +40,9 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Adhoc filter with no existing filter", query: `http_requests_total`, - adhocFilters: []ScopeFilter{ - {Key: "method", Value: "get", Operator: FilterOperatorEquals}, - {Key: "job", Value: "prometheus", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "method", Value: "get", Operator: scope.FilterOperatorEquals}, + {Key: "job", Value: "prometheus", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{job="prometheus",method="get"}`, expectErr: false, @@ -49,8 +50,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Scope filter", query: `http_requests_total{job="prometheus"}`, - scopeFilters: []ScopeFilter{ - {Key: "status", Value: "200", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "status", Value: "200", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{job="prometheus",status="200"}`, expectErr: false, @@ -58,11 +59,11 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Adhoc and Scope filter no existing filter", query: `http_requests_total`, - scopeFilters: []ScopeFilter{ - {Key: "status", Value: "200", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "status", Value: "200", Operator: scope.FilterOperatorEquals}, }, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "prometheus", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "prometheus", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{job="prometheus",status="200"}`, expectErr: false, @@ -70,11 +71,11 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Adhoc and Scope filter conflict - adhoc wins (if not oneOf or notOneOf)", query: `http_requests_total{job="prometheus"}`, - scopeFilters: []ScopeFilter{ - {Key: "status", Value: "404", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "status", Value: "404", Operator: scope.FilterOperatorEquals}, }, - adhocFilters: []ScopeFilter{ - {Key: "status", Value: "200", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "status", Value: "200", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{job="prometheus",status="200"}`, expectErr: false, @@ -82,8 +83,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "Adhoc filters with more complex expression", query: `capacity_bytes{job="prometheus"} + available_bytes{job="grafana"} / 1024`, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "alloy", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "alloy", Operator: scope.FilterOperatorEquals}, }, expected: `capacity_bytes{job="alloy"} + available_bytes{job="alloy"} / 1024`, expectErr: false, @@ -91,8 +92,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "OneOf Operator is combined into a single regex filter", query: `http_requests_total{job="prometheus"}`, - scopeFilters: []ScopeFilter{ - {Key: "status", Values: []string{"404", "400"}, Operator: FilterOperatorOneOf}, + scopeFilters: []scope.ScopeFilter{ + {Key: "status", Values: []string{"404", "400"}, Operator: scope.FilterOperatorOneOf}, }, expected: `http_requests_total{job="prometheus",status=~"404|400"}`, expectErr: false, @@ -100,8 +101,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "using __name__ as part of the query", query: `{__name__="http_requests_total"}`, - scopeFilters: []ScopeFilter{ - {Key: "namespace", Value: "istio", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "namespace", Value: "istio", Operator: scope.FilterOperatorEquals}, }, expected: `{__name__="http_requests_total",namespace="istio"}`, expectErr: false, @@ -109,9 +110,9 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "merge scopes filters into using OR if they share filter key", query: `http_requests_total{}`, - scopeFilters: []ScopeFilter{ - {Key: "namespace", Value: "default", Operator: FilterOperatorEquals}, - {Key: "namespace", Value: "kube-system", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, + {Key: "namespace", Value: "kube-system", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{namespace=~"default|kube-system"}`, expectErr: false, @@ -119,12 +120,12 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) { { name: "adhoc filters win over scope filters if they share filter key", query: `http_requests_total{}`, - scopeFilters: []ScopeFilter{ - {Key: "namespace", Value: "default", Operator: FilterOperatorEquals}, - {Key: "namespace", Value: "kube-system", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, + {Key: "namespace", Value: "kube-system", Operator: scope.FilterOperatorEquals}, }, - adhocFilters: []ScopeFilter{ - {Key: "namespace", Value: "adhoc-wins", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "namespace", Value: "adhoc-wins", Operator: scope.FilterOperatorEquals}, }, expected: `http_requests_total{namespace="adhoc-wins"}`, expectErr: false, @@ -149,8 +150,8 @@ func TestApplyQueryFiltersAndGroupBy_Filters_utf8(t *testing.T) { tests := []struct { name string query string - adhocFilters []ScopeFilter - scopeFilters []ScopeFilter + adhocFilters []scope.ScopeFilter + scopeFilters []scope.ScopeFilter expected string expectErr bool }{ @@ -276,8 +277,8 @@ func TestApplyQueryFiltersAndGroupBy(t *testing.T) { tests := []struct { name string query string - adhocFilters []ScopeFilter - scopeFilters []ScopeFilter + adhocFilters []scope.ScopeFilter + scopeFilters []scope.ScopeFilter groupby []string expected string expectErr bool @@ -286,11 +287,11 @@ func TestApplyQueryFiltersAndGroupBy(t *testing.T) { { name: "Adhoc filters with more complex expression", query: `sum(capacity_bytes{job="prometheus"} + available_bytes{job="grafana"}) / 1024`, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "alloy", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "alloy", Operator: scope.FilterOperatorEquals}, }, - scopeFilters: []ScopeFilter{ - {Key: "vol", Value: "/", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "vol", Value: "/", Operator: scope.FilterOperatorEquals}, }, groupby: []string{"job"}, expected: `sum by (job) (capacity_bytes{job="alloy",vol="/"} + available_bytes{job="alloy",vol="/"}) / 1024`, @@ -316,8 +317,8 @@ func TestApplyQueryFiltersAndGroupBy_utf8(t *testing.T) { tests := []struct { name string query string - adhocFilters []ScopeFilter - scopeFilters []ScopeFilter + adhocFilters []scope.ScopeFilter + scopeFilters []scope.ScopeFilter groupby []string expected string expectErr bool @@ -325,11 +326,11 @@ func TestApplyQueryFiltersAndGroupBy_utf8(t *testing.T) { { name: "Adhoc filters with more complex expression and utf8 metric name", query: `sum({"capacity_bytes", job="prometheus"} + {"available_bytes", job="grafana"}) / 1024`, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "alloy", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "alloy", Operator: scope.FilterOperatorEquals}, }, - scopeFilters: []ScopeFilter{ - {Key: "vol", Value: "/", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "vol", Value: "/", Operator: scope.FilterOperatorEquals}, }, groupby: []string{"job"}, expected: `sum by (job) ({__name__="capacity_bytes",job="alloy",vol="/"} + {__name__="available_bytes",job="alloy",vol="/"}) / 1024`, @@ -338,11 +339,11 @@ func TestApplyQueryFiltersAndGroupBy_utf8(t *testing.T) { { name: "Adhoc filters with more complex expression with utf8 label", query: `sum(capacity_bytes{job="prometheus", "utf8.label"="value"} + available_bytes{job="grafana"}) / 1024`, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "alloy", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "alloy", Operator: scope.FilterOperatorEquals}, }, - scopeFilters: []ScopeFilter{ - {Key: "vol", Value: "/", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "vol", Value: "/", Operator: scope.FilterOperatorEquals}, }, groupby: []string{"job"}, expected: `sum by (job) (capacity_bytes{"utf8.label"="value",job="alloy",vol="/"} + available_bytes{job="alloy",vol="/"}) / 1024`, @@ -351,11 +352,11 @@ func TestApplyQueryFiltersAndGroupBy_utf8(t *testing.T) { { name: "Adhoc filters with more complex expression with utf8 metric and label", query: `sum({"capacity_bytes", job="prometheus", "utf8.label"="value"} + available_bytes{job="grafana"}) / 1024`, - adhocFilters: []ScopeFilter{ - {Key: "job", Value: "alloy", Operator: FilterOperatorEquals}, + adhocFilters: []scope.ScopeFilter{ + {Key: "job", Value: "alloy", Operator: scope.FilterOperatorEquals}, }, - scopeFilters: []ScopeFilter{ - {Key: "vol", Value: "/", Operator: FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "vol", Value: "/", Operator: scope.FilterOperatorEquals}, }, groupby: []string{"job"}, expected: `sum by (job) ({"utf8.label"="value",__name__="capacity_bytes",job="alloy",vol="/"} + available_bytes{job="alloy",vol="/"}) / 1024`, diff --git a/pkg/promlib/resource/resource.go b/pkg/promlib/resource/resource.go index 93846c1074f..c2c6b977b01 100644 --- a/pkg/promlib/resource/resource.go +++ b/pkg/promlib/resource/resource.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/data/utils/maputil" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/prometheus/prometheus/promql/parser" "github.com/grafana/grafana/pkg/promlib/client" @@ -116,8 +117,8 @@ type SuggestionRequest struct { Queries []string `json:"queries"` - Scopes []models.ScopeFilter `json:"scopes"` - AdhocFilters []models.ScopeFilter `json:"adhocFilters"` + Scopes []scope.ScopeFilter `json:"scopes"` + AdhocFilters []scope.ScopeFilter `json:"adhocFilters"` // Start and End are proxied directly to the prometheus endpoint (which is rfc3339 | unix_timestamp) Start string `json:"start"` diff --git a/pkg/promlib/resource/resource_test.go b/pkg/promlib/resource/resource_test.go index b569e0004c9..442367fe900 100644 --- a/pkg/promlib/resource/resource_test.go +++ b/pkg/promlib/resource/resource_test.go @@ -11,10 +11,10 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/log" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/grafana/grafana/pkg/promlib/models" "github.com/grafana/grafana/pkg/promlib/resource" ) @@ -151,11 +151,11 @@ func TestResource_GetSuggestionsWithEmptyQueriesButFilters(t *testing.T) { // Create a request with empty queries but with filters suggestionReq := resource.SuggestionRequest{ Queries: []string{}, // Empty queries - Scopes: []models.ScopeFilter{ - {Key: "job", Operator: models.FilterOperatorEquals, Value: "testjob"}, + Scopes: []scope.ScopeFilter{ + {Key: "job", Operator: scope.FilterOperatorEquals, Value: "testjob"}, }, - AdhocFilters: []models.ScopeFilter{ - {Key: "instance", Operator: models.FilterOperatorEquals, Value: "localhost:9090"}, + AdhocFilters: []scope.ScopeFilter{ + {Key: "instance", Operator: scope.FilterOperatorEquals, Value: "localhost:9090"}, }, } diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index 5626ca94ee5..4c07b9e8199 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -21,8 +21,8 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" - "github.com/grafana/grafana/pkg/promlib/models" "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery" ) @@ -73,9 +73,9 @@ type datasourceInfo struct { type QueryJSONModel struct { dataquery.LokiDataQuery - Direction *string `json:"direction,omitempty"` - SupportingQueryType *string `json:"supportingQueryType"` - Scopes []models.ScopeFilter `json:"scopes"` + Direction *string `json:"direction,omitempty"` + SupportingQueryType *string `json:"supportingQueryType"` + Scopes []scope.ScopeFilter `json:"scopes"` } type ResponseOpts struct { diff --git a/pkg/tsdb/loki/scopes.go b/pkg/tsdb/loki/scopes.go index c9f502a780b..2728489d3ff 100644 --- a/pkg/tsdb/loki/scopes.go +++ b/pkg/tsdb/loki/scopes.go @@ -8,6 +8,7 @@ import ( "time" "github.com/grafana/grafana-plugin-sdk-go/backend" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/grafana/grafana/pkg/promlib/models" "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery" "github.com/grafana/loki/v3/pkg/logql/syntax" @@ -21,8 +22,8 @@ type SuggestionRequest struct { Query string `json:"query"` - Scopes []models.ScopeFilter `json:"scopes"` - AdhocFilters []models.ScopeFilter `json:"adhocFilters"` + Scopes []scope.ScopeFilter `json:"scopes"` + AdhocFilters []scope.ScopeFilter `json:"adhocFilters"` // Start and End are proxied directly to the prometheus endpoint (which is rfc3339 | unix_timestamp) Start string `json:"start"` @@ -79,7 +80,7 @@ func GetSuggestions(ctx context.Context, lokiAPI *LokiAPI, req *backend.CallReso } // ApplyScopes applies the given scope filters to the given raw expression. -func ApplyScopes(rawExpr string, scopeFilters []models.ScopeFilter) (string, error) { +func ApplyScopes(rawExpr string, scopeFilters []scope.ScopeFilter) (string, error) { if len(scopeFilters) == 0 { return rawExpr, nil } diff --git a/pkg/tsdb/loki/scopes_test.go b/pkg/tsdb/loki/scopes_test.go index 76c51f0ec73..74c967cadec 100644 --- a/pkg/tsdb/loki/scopes_test.go +++ b/pkg/tsdb/loki/scopes_test.go @@ -3,7 +3,7 @@ package loki import ( "testing" - "github.com/grafana/grafana/pkg/promlib/models" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "github.com/stretchr/testify/require" ) @@ -14,7 +14,7 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { tests := []struct { name string query string - scopeFilters []models.ScopeFilter + scopeFilters []scope.ScopeFilter expected string expectErr bool }{ @@ -33,8 +33,8 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "scopes with existing filter", query: `{namespace="default"} |= "an unexpected error"`, - scopeFilters: []models.ScopeFilter{ - {Key: "cluster", Value: "us-central-1", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "cluster", Value: "us-central-1", Operator: scope.FilterOperatorEquals}, }, expected: `{namespace="default", cluster="us-central-1"} |= "an unexpected error"`, expectErr: false, @@ -42,8 +42,8 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "scopes without existing label matchers", query: `{} |= "an unexpected error"`, - scopeFilters: []models.ScopeFilter{ - {Key: "cluster", Value: "us-central-1", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "cluster", Value: "us-central-1", Operator: scope.FilterOperatorEquals}, }, expected: `{cluster="us-central-1"} |= "an unexpected error"`, expectErr: false, @@ -51,9 +51,9 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "scopes with multiple filters", query: `{} |= "an unexpected error"`, - scopeFilters: []models.ScopeFilter{ - {Key: "cluster", Value: "us-central-1", Operator: models.FilterOperatorEquals}, - {Key: "namespace", Value: "default", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "cluster", Value: "us-central-1", Operator: scope.FilterOperatorEquals}, + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, }, expected: `{cluster="us-central-1", namespace="default"} |= "an unexpected error"`, expectErr: false, @@ -61,8 +61,8 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "metric query with scopes filters", query: `count_over_time({} |= "error" [1m])`, - scopeFilters: []models.ScopeFilter{ - {Key: "namespace", Value: "default", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, }, expected: `count_over_time({namespace="default"} |= "error"[1m])`, expectErr: false, @@ -70,9 +70,9 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "multi range metric query operation", query: `count_over_time({} |= "error" [1m])/count_over_time({} [1m])`, - scopeFilters: []models.ScopeFilter{ - {Key: "cluster", Value: "us-central-1", Operator: models.FilterOperatorEquals}, - {Key: "namespace", Value: "default", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "cluster", Value: "us-central-1", Operator: scope.FilterOperatorEquals}, + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, }, expected: `(count_over_time({cluster="us-central-1", namespace="default"} |= "error"[1m]) / count_over_time({cluster="us-central-1", namespace="default"}[1m]))`, expectErr: false, @@ -80,9 +80,9 @@ func TestInjectScopesIntoLokiQuery(t *testing.T) { { name: "multi range metric query operation with existing label matchers", query: `count_over_time({a="bar"} |= "error" [1m])/count_over_time({a="bar"} [1m])`, - scopeFilters: []models.ScopeFilter{ - {Key: "cluster", Value: "us-central-1", Operator: models.FilterOperatorEquals}, - {Key: "namespace", Value: "default", Operator: models.FilterOperatorEquals}, + scopeFilters: []scope.ScopeFilter{ + {Key: "cluster", Value: "us-central-1", Operator: scope.FilterOperatorEquals}, + {Key: "namespace", Value: "default", Operator: scope.FilterOperatorEquals}, }, expected: `(count_over_time({a="bar", cluster="us-central-1", namespace="default"} |= "error"[1m]) / count_over_time({a="bar", cluster="us-central-1", namespace="default"}[1m]))`, expectErr: false, diff --git a/pkg/tsdb/loki/types.go b/pkg/tsdb/loki/types.go index d6d5d7ce1ca..0d6156ed158 100644 --- a/pkg/tsdb/loki/types.go +++ b/pkg/tsdb/loki/types.go @@ -3,7 +3,8 @@ package loki import ( "time" - "github.com/grafana/grafana/pkg/promlib/models" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" + "github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery" ) @@ -40,5 +41,5 @@ type lokiQuery struct { End time.Time RefID string SupportingQueryType SupportingQueryType - Scopes []models.ScopeFilter + Scopes []scope.ScopeFilter }