merge main
This commit is contained in:
@@ -456,7 +456,6 @@ require (
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jaegertracing/jaeger v1.67.0 // indirect
|
||||
github.com/jaegertracing/jaeger-idl v0.5.0 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
@@ -518,9 +517,6 @@ require (
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.0 // indirect
|
||||
github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.5 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect
|
||||
@@ -586,7 +582,6 @@ require (
|
||||
go.etcd.io/etcd/client/v3 v3.5.21 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.3 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.124.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 // indirect
|
||||
|
||||
@@ -1793,8 +1793,6 @@ github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jaegertracing/jaeger v1.67.0 h1:t0BiJZVW9D3Z16y3uHqKzV9bKFTusooTH1Kgr77xF2Q=
|
||||
github.com/jaegertracing/jaeger v1.67.0/go.mod h1:tE/FEQfybCSdUbBgel51YaCSkc58O+Njih8oTl6j8vw=
|
||||
github.com/jaegertracing/jaeger-idl v0.5.0 h1:zFXR5NL3Utu7MhPg8ZorxtCBjHrL3ReM1VoB65FOFGE=
|
||||
github.com/jaegertracing/jaeger-idl v0.5.0/go.mod h1:ON90zFo9eoyXrt9F/KN8YeF3zxcnujaisMweFY/rg5k=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
@@ -2107,12 +2105,6 @@ github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.3 h1:6jpO6
|
||||
github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.3/go.mod h1:dPUHjAIFzg+ci/wt6XxlNiiMkOh5Yw4SGyeRY0AFT0g=
|
||||
github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.5 h1:ZdqlGnNwhWf3luhBQlIpbglvcCzjkcuEgOEhYhr5Emc=
|
||||
github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.5/go.mod h1:jrD4UG3ZCzuwImKHlyuIN2iWeYjlOX5+zJ/sX45efuE=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1 h1:NrjsoVPxI6lmV8jPImDcMeqYh+97Y71f/HB5Sfpfe3I=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1/go.mod h1:AFMryJmht7dZxcAwc2sx/r4gxbriElWw49ugxKp2mcA=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1 h1:E1e96GTHmiAfIfeYfA5ZVnOxud3+vbisGp0gE1tfd4s=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1/go.mod h1:MOhFATtYSLad9nKunjh6uGf8nQUcWje2LPlhD2uu3do=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1 h1:9c6L4xlAMqhOg5y54Bc2B5t0i49yz7v2I6I8RY4Z0/o=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1/go.mod h1:6f0N58o0cOHC0ApSM/qrooVmQza1eQ7L53PDE91uO1Q=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
@@ -2554,13 +2546,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/collector v0.124.0 h1:g/dfdGFhBcQI0ggGxTmGlJnJ6Yl6T2gVxQoIj4UfXCc=
|
||||
go.opentelemetry.io/collector/pdata v1.30.0 h1:j3jyq9um436r6WzWySzexP2nLnFdmL5uVBYAlyr9nDM=
|
||||
go.opentelemetry.io/collector/pdata v1.30.0/go.mod h1:0Bxu1ktuj4wE7PIASNSvd0SdBscQ1PLtYasymJ13/Cs=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.124.0 h1:ZjL9wKqzP4BHj0/F1jfGxs1Va8B7xmYayipZeNVoWJE=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.124.0/go.mod h1:1EN3Gw5LSI4fSVma/Yfv/6nqeuYgRTm1/kmG5nE5Oyo=
|
||||
go.opentelemetry.io/collector/semconv v0.124.0 h1:YTdo3UFwNyDQCh9DiSm2rbzAgBuwn/9dNZ0rv454goA=
|
||||
go.opentelemetry.io/collector/semconv v0.124.0/go.mod h1:te6VQ4zZJO5Lp8dM2XIhDxDiL45mwX0YAQQWRQ0Qr9U=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 h1:RyrtJzu5MAmIcbRrwg75b+w3RlZCP0vJByDVzcpAe3M=
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.61.0/go.mod h1:tirr4p9NXbzjlbruiRGp53IzlYrDk5CO2fdHj0sSSaY=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.36.0 h1:F7q2tNlCaHY9nMKHR6XH9/qkp8FktLnIcy6jJNyOCQw=
|
||||
|
||||
@@ -301,6 +301,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
queryService?: boolean;
|
||||
/**
|
||||
* Adds datasource connections to the query service
|
||||
*/
|
||||
queryServiceWithConnections?: boolean;
|
||||
/**
|
||||
* Rewrite requests targeting /ds/query to the query service
|
||||
*/
|
||||
queryServiceRewrite?: boolean;
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
aggregationv0alpha1 "github.com/grafana/grafana/pkg/aggregator/apis/aggregation/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/aggregator/apiserver/plugin/admission"
|
||||
)
|
||||
@@ -64,7 +64,7 @@ func (h *PluginHandler) registerRoutes() {
|
||||
case aggregationv0alpha1.DataSourceProxyServiceType:
|
||||
// TODO: implement in future PR
|
||||
case aggregationv0alpha1.QueryServiceType:
|
||||
h.mux.Handle(proxyPath("/namespaces/{namespace}/connections/{uid}/query"), h.QueryDataHandler())
|
||||
h.mux.Handle(proxyPath("/namespaces/{namespace}/datasources/{uid}/query"), h.QueryDataHandler())
|
||||
case aggregationv0alpha1.RouteServiceType:
|
||||
// TODO: implement in future PR
|
||||
case aggregationv0alpha1.StreamServiceType:
|
||||
|
||||
@@ -6,15 +6,15 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
||||
grafanasemconv "github.com/grafana/grafana/pkg/semconv"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
||||
"k8s.io/component-base/tracing"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
||||
aggregationv0alpha1 "github.com/grafana/grafana/pkg/aggregator/apis/aggregation/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/aggregator/apiserver/util"
|
||||
grafanasemconv "github.com/grafana/grafana/pkg/semconv"
|
||||
)
|
||||
|
||||
func (h *PluginHandler) QueryDataHandler() http.HandlerFunc {
|
||||
|
||||
@@ -10,13 +10,14 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
datav0alpha1 "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/aggregator/apis/aggregation/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/aggregator/apiserver/plugin/fakes"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestQueryDataHandler(t *testing.T) {
|
||||
@@ -87,7 +88,7 @@ func TestQueryDataHandler(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
||||
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/123/query", buf)
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/datasources/123/query", buf)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -113,7 +114,7 @@ func TestQueryDataHandler(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
||||
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/123/query", buf)
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/datasources/123/query", buf)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -141,7 +142,7 @@ func TestQueryDataHandler(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
assert.NoError(t, json.NewEncoder(buf).Encode(qdr))
|
||||
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/connections/abc/query", buf)
|
||||
req, err := http.NewRequest("POST", "/apis/testds.example.com/v1/namespaces/default/datasources/abc/query", buf)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
@@ -165,7 +166,7 @@ func TestQueryDataHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should return delegate response if group does not match", func(t *testing.T) {
|
||||
req, err := http.NewRequest("POST", "/apis/wrongds.example.com/v1/namespaces/default/connections/abc/query", bytes.NewBuffer(nil))
|
||||
req, err := http.NewRequest("POST", "/apis/wrongds.example.com/v1/namespaces/default/datasources/abc/query", bytes.NewBuffer(nil))
|
||||
assert.NoError(t, err)
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
@@ -53,5 +53,4 @@ import (
|
||||
_ "github.com/grafana/e2e"
|
||||
_ "github.com/grafana/gofpdf"
|
||||
_ "github.com/grafana/gomemcache/memcache"
|
||||
_ "github.com/grafana/tempo/pkg/traceql"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package datasource
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
query "github.com/grafana/grafana/pkg/apis/query/v0alpha1"
|
||||
)
|
||||
|
||||
// Temporary noop storage that lets us map /connections/{name}/query
|
||||
type noopREST struct{}
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*noopREST)(nil)
|
||||
_ rest.Scoper = (*noopREST)(nil)
|
||||
_ rest.Getter = (*noopREST)(nil)
|
||||
_ rest.SingularNameProvider = (*noopREST)(nil)
|
||||
)
|
||||
|
||||
func (r *noopREST) New() runtime.Object {
|
||||
return &query.QueryDataResponse{}
|
||||
}
|
||||
|
||||
func (r *noopREST) Destroy() {}
|
||||
|
||||
func (r *noopREST) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *noopREST) GetSingularName() string {
|
||||
return "noop"
|
||||
}
|
||||
|
||||
func (r *noopREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
return &metav1.Status{
|
||||
Status: metav1.StatusSuccess,
|
||||
Message: "noop",
|
||||
}, nil
|
||||
}
|
||||
@@ -54,6 +54,26 @@ func (b *DataSourceAPIBuilder) PostProcessOpenAPI(oas *spec3.OpenAPI) (*spec3.Op
|
||||
ds.Properties["apiVersion"] = *spec.StringProperty().WithEnum(b.GetGroupVersion().String())
|
||||
ds.Properties["kind"] = *spec.StringProperty().WithEnum("DataSource")
|
||||
|
||||
// Mark connections as deprecated
|
||||
delete(oas.Paths.Paths, root+"namespaces/{namespace}/connections/{name}")
|
||||
query := oas.Paths.Paths[root+"namespaces/{namespace}/connections/{name}/query"]
|
||||
for query == nil || query.Post == nil {
|
||||
return nil, fmt.Errorf("missing temporary connection path")
|
||||
}
|
||||
query.Post.Tags = []string{"Connections (deprecated)"}
|
||||
query.Post.Deprecated = true
|
||||
query.Post.RequestBody = &spec3.RequestBody{
|
||||
RequestBodyProps: spec3.RequestBodyProps{
|
||||
Content: map[string]*spec3.MediaType{
|
||||
"application/json": {
|
||||
MediaTypeProps: spec3.MediaTypeProps{
|
||||
Schema: spec.MapProperty(nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if b.schemaProvider == nil {
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package datasource
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"maps"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -230,10 +231,14 @@ func (b *DataSourceAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver
|
||||
|
||||
storage[ds.StoragePath("query")] = &subQueryREST{builder: b}
|
||||
storage[ds.StoragePath("health")] = &subHealthREST{builder: b}
|
||||
|
||||
// TODO! only setup this endpoint if it is implemented
|
||||
storage[ds.StoragePath("resource")] = &subResourceREST{builder: b}
|
||||
|
||||
// FIXME: temporarily register both "datasources" and "connections" query paths
|
||||
// This lets us deploy both datasources/{uid}/query and connections/{uid}/query
|
||||
// while we transition requests to the new path
|
||||
storage["connections"] = &noopREST{} // hidden from openapi
|
||||
storage["connections/query"] = storage[ds.StoragePath("query")] // deprecated in openapi
|
||||
|
||||
// Frontend proxy
|
||||
if len(b.pluginJSON.Routes) > 0 {
|
||||
storage[ds.StoragePath("proxy")] = &subProxyREST{pluginJSON: b.pluginJSON}
|
||||
@@ -262,9 +267,7 @@ func (b *DataSourceAPIBuilder) getPluginContext(ctx context.Context, uid string)
|
||||
func (b *DataSourceAPIBuilder) GetOpenAPIDefinitions() openapi.GetOpenAPIDefinitions {
|
||||
return func(ref openapi.ReferenceCallback) map[string]openapi.OpenAPIDefinition {
|
||||
defs := queryV0.GetOpenAPIDefinitions(ref) // required when running standalone
|
||||
for k, v := range datasourceV0.GetOpenAPIDefinitions(ref) {
|
||||
defs[k] = v
|
||||
}
|
||||
maps.Copy(defs, datasourceV0.GetOpenAPIDefinitions(ref))
|
||||
return defs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ var (
|
||||
_ rest.Storage = (*subQueryREST)(nil)
|
||||
_ rest.Connecter = (*subQueryREST)(nil)
|
||||
_ rest.StorageMetadata = (*subQueryREST)(nil)
|
||||
_ rest.Scoper = (*subQueryREST)(nil)
|
||||
)
|
||||
|
||||
func (r *subQueryREST) New() runtime.Object {
|
||||
@@ -35,6 +36,10 @@ func (r *subQueryREST) New() runtime.Object {
|
||||
|
||||
func (r *subQueryREST) Destroy() {}
|
||||
|
||||
func (r *subQueryREST) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *subQueryREST) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"} // and parquet!
|
||||
}
|
||||
|
||||
@@ -18,36 +18,36 @@ func TestResourceRequest(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "no resource path",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc",
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
desc: "root resource path",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc/resource",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc/resource",
|
||||
expectedPath: "",
|
||||
expectedURL: "",
|
||||
},
|
||||
{
|
||||
desc: "root resource path",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc/resource/",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc/resource/",
|
||||
expectedPath: "",
|
||||
expectedURL: "",
|
||||
},
|
||||
{
|
||||
desc: "resource sub path",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc/resource/test",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc/resource/test",
|
||||
expectedPath: "test",
|
||||
expectedURL: "test",
|
||||
},
|
||||
{
|
||||
desc: "resource sub path with colon",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc/resource/test-*,*:test-*/_mapping",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc/resource/test-*,*:test-*/_mapping",
|
||||
expectedPath: "test-*,*:test-*/_mapping",
|
||||
expectedURL: "./test-%2A,%2A:test-%2A/_mapping",
|
||||
},
|
||||
{
|
||||
desc: "resource sub path with query params",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/connections/abc/resource/test?k1=v1&k2=v2",
|
||||
url: "http://localhost:6443/apis/test.datasource.grafana.app/v0alpha1/namespaces/default/datasources/abc/resource/test?k1=v1&k2=v2",
|
||||
expectedPath: "test",
|
||||
expectedURL: "test?k1=v1&k2=v2",
|
||||
},
|
||||
|
||||
@@ -66,21 +66,8 @@ func AddQueriesToOpenAPI(options OASQueryOptions) error {
|
||||
// Rewrite the query path
|
||||
query := oas.Paths.Paths[root+options.QueryPath]
|
||||
if query != nil && query.Post != nil {
|
||||
query.Post.Tags = []string{"Query"}
|
||||
query.Parameters = []*spec3.Parameter{
|
||||
{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: "namespace",
|
||||
In: "path",
|
||||
Description: "object name and auth scope, such as for teams and projects",
|
||||
Example: "default",
|
||||
Required: true,
|
||||
Schema: spec.StringProperty().UniqueValues(),
|
||||
},
|
||||
},
|
||||
}
|
||||
query.Post.Tags = []string{"DataSource"}
|
||||
query.Post.Description = options.QueryDescription
|
||||
query.Post.Parameters = nil //
|
||||
query.Post.RequestBody = &spec3.RequestBody{
|
||||
RequestBodyProps: spec3.RequestBodyProps{
|
||||
Content: map[string]*spec3.MediaType{
|
||||
|
||||
@@ -179,7 +179,7 @@ func (b *QueryAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIG
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
// Get a list of all datasource instances
|
||||
if b.features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
|
||||
if b.features.IsEnabledGlobally(featuremgmt.FlagQueryServiceWithConnections) {
|
||||
// Eventually this would be backed either by search or reconciler pattern
|
||||
storage[query.ConnectionResourceInfo.StoragePath()] = &connectionAccess{
|
||||
connections: b.connections,
|
||||
|
||||
@@ -499,6 +499,13 @@ var (
|
||||
Owner: grafanaDatasourcesCoreServicesSquad,
|
||||
RequiresRestart: true, // Adds a route at startup
|
||||
},
|
||||
{
|
||||
Name: "queryServiceWithConnections",
|
||||
Description: "Adds datasource connections to the query service",
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaDatasourcesCoreServicesSquad,
|
||||
RequiresRestart: true, // Adds a route at startup
|
||||
},
|
||||
{
|
||||
Name: "queryServiceRewrite",
|
||||
Description: "Rewrite requests targeting /ds/query to the query service",
|
||||
|
||||
@@ -65,6 +65,7 @@ dashboardSchemaValidationLogging,experimental,@grafana/grafana-app-platform-squa
|
||||
scanRowInvalidDashboardParseFallbackEnabled,experimental,@grafana/search-and-storage,false,false,false
|
||||
datasourceQueryTypes,experimental,@grafana/grafana-app-platform-squad,false,true,false
|
||||
queryService,experimental,@grafana/grafana-datasources-core-services,false,true,false
|
||||
queryServiceWithConnections,experimental,@grafana/grafana-datasources-core-services,false,true,false
|
||||
queryServiceRewrite,experimental,@grafana/grafana-datasources-core-services,false,true,false
|
||||
queryServiceFromUI,experimental,@grafana/grafana-datasources-core-services,false,false,true
|
||||
queryServiceFromExplore,experimental,@grafana/grafana-datasources-core-services,false,false,true
|
||||
|
||||
|
@@ -271,6 +271,10 @@ const (
|
||||
// Register /apis/query.grafana.app/ -- will eventually replace /api/ds/query
|
||||
FlagQueryService = "queryService"
|
||||
|
||||
// FlagQueryServiceWithConnections
|
||||
// Adds datasource connections to the query service
|
||||
FlagQueryServiceWithConnections = "queryServiceWithConnections"
|
||||
|
||||
// FlagQueryServiceRewrite
|
||||
// Rewrite requests targeting /ds/query to the query service
|
||||
FlagQueryServiceRewrite = "queryServiceRewrite"
|
||||
|
||||
@@ -2765,6 +2765,19 @@
|
||||
"requiresRestart": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "queryServiceWithConnections",
|
||||
"resourceVersion": "1756367172351",
|
||||
"creationTimestamp": "2025-08-28T07:46:12Z"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Adds datasource connections to the query service",
|
||||
"stage": "experimental",
|
||||
"codeowner": "@grafana/grafana-datasources-core-services",
|
||||
"requiresRestart": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "recordedQueriesMulti",
|
||||
|
||||
Reference in New Issue
Block a user