package datasource import ( "context" "fmt" "net/http" "github.com/grafana/grafana-plugin-sdk-go/backend" data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" query "github.com/grafana/grafana/pkg/apis/query/v0alpha1" "github.com/grafana/grafana/pkg/tsdb/legacydata" "github.com/grafana/grafana/pkg/web" ) type subQueryREST struct { builder *DataSourceAPIBuilder } var ( _ rest.Storage = (*subQueryREST)(nil) _ rest.Connecter = (*subQueryREST)(nil) _ rest.StorageMetadata = (*subQueryREST)(nil) ) func (r *subQueryREST) New() runtime.Object { // This is added as the "ResponseType" regarless what ProducesObject() says :) return &query.QueryDataResponse{} } func (r *subQueryREST) Destroy() {} func (r *subQueryREST) ProducesMIMETypes(verb string) []string { return []string{"application/json"} // and parquet! } func (r *subQueryREST) ProducesObject(verb string) interface{} { return &query.QueryDataResponse{} } func (r *subQueryREST) ConnectMethods() []string { return []string{"POST"} } func (r *subQueryREST) NewConnectOptions() (runtime.Object, bool, string) { return nil, false, "" // true means you can use the trailing path as a variable } func (r *subQueryREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { pluginCtx, err := r.builder.getPluginContext(ctx, name) if err != nil { return nil, err } return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { dqr := data.QueryDataRequest{} err := web.Bind(req, &dqr) if err != nil { responder.Error(err) return } queries, dsRef, err := legacydata.ToDataSourceQueries(dqr) if err != nil { responder.Error(err) return } if dsRef != nil && dsRef.UID != name { responder.Error(fmt.Errorf("expected query body datasource and request to match")) return } ctx = backend.WithGrafanaConfig(ctx, pluginCtx.GrafanaConfig) ctx = contextualMiddlewares(ctx) rsp, err := r.builder.client.QueryData(ctx, &backend.QueryDataRequest{ Queries: queries, PluginContext: pluginCtx, }) if err != nil { responder.Error(err) return } responder.Object(query.GetResponseCode(rsp), &query.QueryDataResponse{QueryDataResponse: *rsp}, ) }), nil }