diff --git a/pkg/apis/peakq/v0alpha1/types.go b/pkg/apis/peakq/v0alpha1/types.go index 18cd54e1742..3e6ab0c937c 100644 --- a/pkg/apis/peakq/v0alpha1/types.go +++ b/pkg/apis/peakq/v0alpha1/types.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" common "github.com/grafana/grafana/pkg/apis/common/v0alpha1" + query "github.com/grafana/grafana/pkg/apis/query/v0alpha1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -40,8 +41,8 @@ type Target struct { // Variables that will be replaced in the query Variables map[string][]VariableReplacement `json:"variables"` - // The raw query: TODO, should be query.GenericQuery - Properties common.Unstructured `json:"properties"` + // Query target + Properties query.GenericDataQuery `json:"properties"` } // TemplateVariable is the definition of a variable that will be interpolated diff --git a/pkg/apis/peakq/v0alpha1/zz_generated.openapi.go b/pkg/apis/peakq/v0alpha1/zz_generated.openapi.go index 0c3c52ebccf..b0edddee0f3 100644 --- a/pkg/apis/peakq/v0alpha1/zz_generated.openapi.go +++ b/pkg/apis/peakq/v0alpha1/zz_generated.openapi.go @@ -291,8 +291,8 @@ func schema_pkg_apis_peakq_v0alpha1_Target(ref common.ReferenceCallback) common. }, "properties": { SchemaProps: spec.SchemaProps{ - Description: "The raw query: TODO, should be query.GenericQuery", - Ref: ref("github.com/grafana/grafana/pkg/apis/common/v0alpha1.Unstructured"), + Description: "Query target", + Ref: ref("github.com/grafana/grafana/pkg/apis/query/v0alpha1.GenericDataQuery"), }, }, }, @@ -300,7 +300,7 @@ func schema_pkg_apis_peakq_v0alpha1_Target(ref common.ReferenceCallback) common. }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/peakq/v0alpha1.VariableReplacement"}, + "github.com/grafana/grafana/pkg/apis/peakq/v0alpha1.VariableReplacement", "github.com/grafana/grafana/pkg/apis/query/v0alpha1.GenericDataQuery"}, } } @@ -377,7 +377,7 @@ func schema_pkg_apis_peakq_v0alpha1_VariableReplacement(ref common.ReferenceCall }, "format": { SchemaProps: spec.SchemaProps{ - Description: "How values should be interpolated See: NOTE: the format parameter is not yet supported!\n\nPossible enum values:\n - `\"csv\"` Formats variables with multiple values as a comma-separated string.\n - `\"doublequote\"` Formats single- and multi-valued variables into a comma-separated string\n - `\"json\"` Formats variables with multiple values as a comma-separated string.\n - `\"pipe\"` Formats variables with multiple values into a pipe-separated string.\n - `\"raw\"` Formats variables with multiple values into comma-separated string. This is the default behavior when no format is specified\n - `\"singlequote\"` Formats single- and multi-valued variables into a comma-separated string", + Description: "How values should be interpolated\n\nPossible enum values:\n - `\"csv\"` Formats variables with multiple values as a comma-separated string.\n - `\"doublequote\"` Formats single- and multi-valued variables into a comma-separated string\n - `\"json\"` Formats variables with multiple values as a comma-separated string.\n - `\"pipe\"` Formats variables with multiple values into a pipe-separated string.\n - `\"raw\"` Formats variables with multiple values into comma-separated string. This is the default behavior when no format is specified\n - `\"singlequote\"` Formats single- and multi-valued variables into a comma-separated string", Type: []string{"string"}, Format: "", Enum: []interface{}{"csv", "doublequote", "json", "pipe", "raw", "singlequote"}, diff --git a/pkg/apis/query/v0alpha1/query.go b/pkg/apis/query/v0alpha1/query.go index 4ae9435f0d3..6c32e8becee 100644 --- a/pkg/apis/query/v0alpha1/query.go +++ b/pkg/apis/query/v0alpha1/query.go @@ -75,6 +75,12 @@ type GenericDataQuery struct { props map[string]any `json:"-"` } +func NewGenericDataQuery(vals map[string]any) GenericDataQuery { + q := GenericDataQuery{} + _ = q.unmarshal(vals) + return q +} + // TimeRange represents a time range for a query and is a property of DataQuery. type TimeRange struct { // From is the start time of the query. @@ -120,7 +126,7 @@ func (g GenericDataQuery) MarshalJSON() ([]byte, error) { } vals["refId"] = g.RefID - if g.Datasource.Type != "" || g.Datasource.UID != "" { + if g.Datasource != nil && (g.Datasource.Type != "" || g.Datasource.UID != "") { vals["datasource"] = g.Datasource } if g.DatasourceId > 0 { @@ -143,6 +149,15 @@ func (g *GenericDataQuery) UnmarshalJSON(b []byte) error { if err != nil { return err } + return g.unmarshal(vals) +} + +func (g *GenericDataQuery) unmarshal(vals map[string]any) error { + if vals == nil { + g.props = nil + return nil + } + key := "refId" v, ok := vals[key] if ok { diff --git a/pkg/registry/apis/peakq/render.go b/pkg/registry/apis/peakq/render.go index 5f084c2037f..efa54389ffc 100644 --- a/pkg/registry/apis/peakq/render.go +++ b/pkg/registry/apis/peakq/render.go @@ -14,8 +14,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" - common "github.com/grafana/grafana/pkg/apis/common/v0alpha1" peakq "github.com/grafana/grafana/pkg/apis/peakq/v0alpha1" + query "github.com/grafana/grafana/pkg/apis/query/v0alpha1" ) type renderREST struct { @@ -198,7 +198,7 @@ func Render(qt peakq.QueryTemplateSpec, selectedValues map[string][]string) (*pe if err != nil { return nil, err } - u := common.Unstructured{} + u := query.GenericDataQuery{} err = u.UnmarshalJSON(raw) if err != nil { return nil, err diff --git a/pkg/registry/apis/peakq/render_examples.go b/pkg/registry/apis/peakq/render_examples.go index 289bfde7864..c1b5ff75e5c 100644 --- a/pkg/registry/apis/peakq/render_examples.go +++ b/pkg/registry/apis/peakq/render_examples.go @@ -3,8 +3,8 @@ package peakq import ( "github.com/grafana/grafana-plugin-sdk-go/data" - common "github.com/grafana/grafana/pkg/apis/common/v0alpha1" peakq "github.com/grafana/grafana/pkg/apis/peakq/v0alpha1" + query "github.com/grafana/grafana/pkg/apis/query/v0alpha1" ) var basicTemplateSpec = peakq.QueryTemplateSpec{ @@ -38,20 +38,18 @@ var basicTemplateSpec = peakq.QueryTemplateSpec{ }, }, - Properties: common.Unstructured{ - Object: map[string]any{ - "refId": "A", // TODO: Set when Where? - "datasource": map[string]any{ - "type": "prometheus", - "uid": "foo", // TODO: Probably a default templating thing to set this. - }, - "editorMode": "builder", - "expr": "metricName + metricName + 42", - "instant": true, - "range": false, - "exemplar": false, + Properties: query.NewGenericDataQuery(map[string]any{ + "refId": "A", // TODO: Set when Where? + "datasource": map[string]any{ + "type": "prometheus", + "uid": "foo", // TODO: Probably a default templating thing to set this. }, - }, + "editorMode": "builder", + "expr": "metricName + metricName + 42", + "instant": true, + "range": false, + "exemplar": false, + }), }, }, } @@ -60,19 +58,17 @@ var basicTemplateRenderedTargets = []peakq.Target{ { DataType: data.FrameTypeUnknown, //DataTypeVersion: data.FrameTypeVersion{0, 0}, - Properties: common.Unstructured{ - Object: map[string]any{ - "refId": "A", // TODO: Set when Where? - "datasource": map[string]any{ - "type": "prometheus", - "uid": "foo", // TODO: Probably a default templating thing to set this. - }, - "editorMode": "builder", - "expr": "up + up + 42", - "instant": true, - "range": false, - "exemplar": false, + Properties: query.NewGenericDataQuery(map[string]any{ + "refId": "A", // TODO: Set when Where? + "datasource": map[string]any{ + "type": "prometheus", + "uid": "foo", // TODO: Probably a default templating thing to set this. }, - }, + "editorMode": "builder", + "expr": "up + up + 42", + "instant": true, + "range": false, + "exemplar": false, + }), }, } diff --git a/pkg/registry/apis/peakq/render_examples_test.go b/pkg/registry/apis/peakq/render_examples_test.go index bdcbfc43eb0..22bd71e1459 100644 --- a/pkg/registry/apis/peakq/render_examples_test.go +++ b/pkg/registry/apis/peakq/render_examples_test.go @@ -11,7 +11,9 @@ import ( func TestRender(t *testing.T) { rT, err := Render(basicTemplateSpec, map[string][]string{"metricName": {"up"}}) require.NoError(t, err) - require.Equal(t, basicTemplateRenderedTargets[0].Properties.Object["expr"], rT.Targets[0].Properties.Object["expr"]) + require.Equal(t, + basicTemplateRenderedTargets[0].Properties.AdditionalProperties()["expr"], + rT.Targets[0].Properties.AdditionalProperties()["expr"]) b, _ := json.MarshalIndent(basicTemplateSpec, "", " ") fmt.Println(string(b)) } diff --git a/pkg/registry/apis/peakq/render_test.go b/pkg/registry/apis/peakq/render_test.go index 0e4d5f49013..30b7a1403a2 100644 --- a/pkg/registry/apis/peakq/render_test.go +++ b/pkg/registry/apis/peakq/render_test.go @@ -6,8 +6,8 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/stretchr/testify/require" - common "github.com/grafana/grafana/pkg/apis/common/v0alpha1" peakq "github.com/grafana/grafana/pkg/apis/peakq/v0alpha1" + query "github.com/grafana/grafana/pkg/apis/query/v0alpha1" ) var nestedFieldRender = peakq.QueryTemplateSpec{ @@ -33,13 +33,11 @@ var nestedFieldRender = peakq.QueryTemplateSpec{ }, }, }, - Properties: common.Unstructured{ - Object: map[string]any{ - "nestedObject": map[string]any{ - "anArray": []any{"foo", .2}, - }, + Properties: query.NewGenericDataQuery(map[string]any{ + "nestedObject": map[string]any{ + "anArray": []any{"foo", .2}, }, - }, + }), }, }, } @@ -59,13 +57,12 @@ var nestedFieldRenderedTargets = []peakq.Target{ }, }, //DataTypeVersion: data.FrameTypeVersion{0, 0}, - Properties: common.Unstructured{ - Object: map[string]any{ + Properties: query.NewGenericDataQuery( + map[string]any{ "nestedObject": map[string]any{ "anArray": []any{"up", .2}, }, - }, - }, + }), }, } @@ -121,11 +118,9 @@ var multiVarTemplate = peakq.QueryTemplateSpec{ }, }, - Properties: common.Unstructured{ - Object: map[string]any{ - "expr": "1 + metricName + 1 + anotherMetric + metricName", - }, - }, + Properties: query.NewGenericDataQuery(map[string]any{ + "expr": "1 + metricName + 1 + anotherMetric + metricName", + }), }, }, } @@ -161,11 +156,9 @@ var multiVarRenderedTargets = []peakq.Target{ }, }, //DataTypeVersion: data.FrameTypeVersion{0, 0}, - Properties: common.Unstructured{ - Object: map[string]any{ - "expr": "1 + up + 1 + sloths_do_like_a_good_nap + up", - }, - }, + Properties: query.NewGenericDataQuery(map[string]any{ + "expr": "1 + up + 1 + sloths_do_like_a_good_nap + up", + }), }, } @@ -190,11 +183,9 @@ func TestRenderWithRune(t *testing.T) { }, Targets: []peakq.Target{ { - Properties: common.Unstructured{ - Object: map[string]any{ - "message": "🐦 name!", - }, - }, + Properties: query.NewGenericDataQuery(map[string]any{ + "message": "🐦 name!", + }), Variables: map[string][]peakq.VariableReplacement{ "name": { { @@ -217,5 +208,5 @@ func TestRenderWithRune(t *testing.T) { rq, err := Render(qt, selectedValues) require.NoError(t, err) - require.Equal(t, "🐦 🦥!", rq.Targets[0].Properties.Object["message"]) + require.Equal(t, "🐦 🦥!", rq.Targets[0].Properties.AdditionalProperties()["message"]) }