K8s/DataSource: Introduce PluginConfigProvider (#80928)

This commit is contained in:
Ryan McKinley 2024-01-22 11:32:25 -08:00 committed by GitHub
parent ce84f7c540
commit c7c594dba0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 252 additions and 222 deletions

View File

@ -20,9 +20,10 @@ var (
)
type connectionAccess struct {
pluginID string
resourceInfo common.ResourceInfo
tableConverter rest.TableConvertor
builder Querier
configs PluginConfigProvider
}
func (s *connectionAccess) New() runtime.Object {
@ -52,9 +53,9 @@ func (s *connectionAccess) ConvertToTable(ctx context.Context, object runtime.Ob
}
func (s *connectionAccess) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
return s.builder.Datasource(ctx, name)
return s.configs.GetDataSource(ctx, s.pluginID, name)
}
func (s *connectionAccess) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
return s.builder.Datasources(ctx)
return s.configs.ListDatasources(ctx, s.pluginID)
}

View File

@ -2,10 +2,122 @@ package datasource
import (
"context"
"fmt"
"github.com/grafana/grafana-plugin-sdk-go/backend"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
"github.com/grafana/grafana/pkg/infra/appcontext"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
)
type PluginContextProvider interface {
PluginContextForDataSource(ctx context.Context, pluginID, name string) (backend.PluginContext, error)
// This provides access to settings saved in the database.
// Authorization checks will happen within each function, and the user in ctx will
// limit which namespace/tenant/org we are talking to
type PluginConfigProvider interface {
// GetDataSource gets a specific datasource (that the user in context can see)
GetDataSource(ctx context.Context, pluginID, uid string) (*v0alpha1.DataSourceConnection, error)
// ListDatasources lists all data sources the user in context can see
ListDatasources(ctx context.Context, pluginID string) (*v0alpha1.DataSourceConnectionList, error)
// Return settings (decrypted!) for a specific plugin
// This will require "query" permission for the user in context
GetDataSourceInstanceSettings(ctx context.Context, pluginID, uid string) (*backend.DataSourceInstanceSettings, error)
}
// PluginContext requires adding system settings (feature flags, etc) to the datasource config
type PluginContextWrapper interface {
PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error)
}
func ProvideDefaultPluginConfigs(
dsService datasources.DataSourceService,
dsCache datasources.CacheService,
contextProvider *plugincontext.Provider) PluginConfigProvider {
return &defaultPluginConfigProvider{
dsService: dsService,
dsCache: dsCache,
contextProvider: contextProvider,
}
}
type defaultPluginConfigProvider struct {
dsService datasources.DataSourceService
dsCache datasources.CacheService
contextProvider *plugincontext.Provider
}
var (
_ PluginConfigProvider = (*defaultPluginConfigProvider)(nil)
)
func (q *defaultPluginConfigProvider) GetDataSource(ctx context.Context, pluginID, uid string) (*v0alpha1.DataSourceConnection, error) {
info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
user, err := appcontext.User(ctx)
if err != nil {
return nil, err
}
ds, err := q.dsCache.GetDatasourceByUID(ctx, uid, user, false)
if err != nil {
return nil, err
}
return asConnection(ds, info.Value)
}
func (q *defaultPluginConfigProvider) ListDatasources(ctx context.Context, pluginID string) (*v0alpha1.DataSourceConnectionList, error) {
info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
dss, err := q.dsService.GetDataSourcesByType(ctx, &datasources.GetDataSourcesByTypeQuery{
OrgID: info.OrgID,
Type: pluginID,
})
if err != nil {
return nil, err
}
result := &v0alpha1.DataSourceConnectionList{
Items: []v0alpha1.DataSourceConnection{},
}
for _, ds := range dss {
v, _ := asConnection(ds, info.Value)
result.Items = append(result.Items, *v)
}
return result, nil
}
func (q *defaultPluginConfigProvider) GetDataSourceInstanceSettings(ctx context.Context, pluginID, uid string) (*backend.DataSourceInstanceSettings, error) {
if q.contextProvider == nil {
// NOTE!!! this is only here for the standalone example
// if we cleanup imports this can throw an error
return nil, nil
}
return q.contextProvider.GetDataSourceInstanceSettings(ctx, uid)
}
func asConnection(ds *datasources.DataSource, ns string) (*v0alpha1.DataSourceConnection, error) {
v := &v0alpha1.DataSourceConnection{
ObjectMeta: metav1.ObjectMeta{
Name: ds.UID,
Namespace: ns,
CreationTimestamp: metav1.NewTime(ds.Created),
ResourceVersion: fmt.Sprintf("%d", ds.Updated.UnixMilli()),
},
Title: ds.Name,
}
v.UID = utils.CalculateClusterWideUID(v) // indicates if the value changed on the server
meta, err := utils.MetaAccessor(v)
if err != nil {
meta.SetUpdatedTimestamp(&ds.Updated)
}
return v, err
}

View File

@ -1,169 +0,0 @@
package datasource
import (
"context"
"fmt"
"github.com/grafana/grafana-plugin-sdk-go/backend"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
common "github.com/grafana/grafana/pkg/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
"github.com/grafana/grafana/pkg/infra/appcontext"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
)
type QuerierFactoryFunc func(ctx context.Context, ri common.ResourceInfo, pj plugins.JSONData) (Querier, error)
type QuerierProvider interface {
Querier(ctx context.Context, ri common.ResourceInfo, pj plugins.JSONData) (Querier, error)
}
type DefaultQuerierProvider struct {
factory QuerierFactoryFunc
}
func ProvideDefaultQuerierProvider(pluginClient plugins.Client, dsService datasources.DataSourceService,
dsCache datasources.CacheService) *DefaultQuerierProvider {
return NewQuerierProvider(func(ctx context.Context, ri common.ResourceInfo, pj plugins.JSONData) (Querier, error) {
return NewDefaultQuerier(ri, pj, pluginClient, dsService, dsCache), nil
})
}
func NewQuerierProvider(factory QuerierFactoryFunc) *DefaultQuerierProvider {
return &DefaultQuerierProvider{
factory: factory,
}
}
func (p *DefaultQuerierProvider) Querier(ctx context.Context, ri common.ResourceInfo, pj plugins.JSONData) (Querier, error) {
return p.factory(ctx, ri, pj)
}
// Querier is the interface that wraps the Query method.
type Querier interface {
// Query runs the query on behalf of the user in context.
Query(ctx context.Context, query *backend.QueryDataRequest) (*backend.QueryDataResponse, error)
// Health checks the health of the plugin.
Health(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error)
// Resource gets a resource plugin.
Resource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error
// Datasource gets all data source plugins (with elevated permissions).
Datasource(ctx context.Context, name string) (*v0alpha1.DataSourceConnection, error)
// Datasources lists all data sources (with elevated permissions).
Datasources(ctx context.Context) (*v0alpha1.DataSourceConnectionList, error)
}
type DefaultQuerier struct {
connectionResourceInfo common.ResourceInfo
pluginJSON plugins.JSONData
pluginClient plugins.Client
dsService datasources.DataSourceService
dsCache datasources.CacheService
}
func NewDefaultQuerier(
connectionResourceInfo common.ResourceInfo,
pluginJSON plugins.JSONData,
pluginClient plugins.Client,
dsService datasources.DataSourceService,
dsCache datasources.CacheService,
) *DefaultQuerier {
return &DefaultQuerier{
connectionResourceInfo: connectionResourceInfo,
pluginJSON: pluginJSON,
pluginClient: pluginClient,
dsService: dsService,
dsCache: dsCache,
}
}
func (q *DefaultQuerier) Query(ctx context.Context, query *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
_, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
return q.pluginClient.QueryData(ctx, query)
}
func (q *DefaultQuerier) Resource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
_, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return err
}
return q.pluginClient.CallResource(ctx, req, sender)
}
func (q *DefaultQuerier) Health(ctx context.Context, query *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
_, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
return q.pluginClient.CheckHealth(ctx, query)
}
func (q *DefaultQuerier) Datasource(ctx context.Context, name string) (*v0alpha1.DataSourceConnection, error) {
info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
user, err := appcontext.User(ctx)
if err != nil {
return nil, err
}
ds, err := q.dsCache.GetDatasourceByUID(ctx, name, user, false)
if err != nil {
return nil, err
}
return asConnection(q.connectionResourceInfo.TypeMeta(), ds, info.Value)
}
func (q *DefaultQuerier) Datasources(ctx context.Context) (*v0alpha1.DataSourceConnectionList, error) {
info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
ds, err := q.dsService.GetDataSourcesByType(ctx, &datasources.GetDataSourcesByTypeQuery{
OrgID: info.OrgID,
Type: q.pluginJSON.ID,
})
if err != nil {
return nil, err
}
return asConnectionList(q.connectionResourceInfo.TypeMeta(), ds, info.Value)
}
func asConnection(typeMeta metav1.TypeMeta, ds *datasources.DataSource, ns string) (*v0alpha1.DataSourceConnection, error) {
v := &v0alpha1.DataSourceConnection{
TypeMeta: typeMeta,
ObjectMeta: metav1.ObjectMeta{
Name: ds.UID,
Namespace: ns,
CreationTimestamp: metav1.NewTime(ds.Created),
ResourceVersion: fmt.Sprintf("%d", ds.Updated.UnixMilli()),
},
Title: ds.Name,
}
v.UID = utils.CalculateClusterWideUID(v) // indicates if the value changed on the server
meta, err := utils.MetaAccessor(v)
if err != nil {
meta.SetUpdatedTimestamp(&ds.Updated)
}
return v, err
}
func asConnectionList(typeMeta metav1.TypeMeta, dss []*datasources.DataSource, ns string) (*v0alpha1.DataSourceConnectionList, error) {
result := &v0alpha1.DataSourceConnectionList{
Items: []v0alpha1.DataSourceConnection{},
}
for _, ds := range dss {
v, _ := asConnection(typeMeta, ds, ns)
result.Items = append(result.Items, *v)
}
return result, nil
}

View File

@ -16,6 +16,8 @@ import (
openapi "k8s.io/kube-openapi/pkg/common"
"k8s.io/utils/strings/slices"
"github.com/grafana/grafana-plugin-sdk-go/backend"
common "github.com/grafana/grafana/pkg/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
"github.com/grafana/grafana/pkg/plugins"
@ -32,17 +34,19 @@ var _ grafanaapiserver.APIGroupBuilder = (*DataSourceAPIBuilder)(nil)
type DataSourceAPIBuilder struct {
connectionResourceInfo common.ResourceInfo
pluginJSON plugins.JSONData
querier Querier
pluginContext PluginContextProvider
accessControl accesscontrol.AccessControl
pluginJSON plugins.JSONData
client plugins.Client // will only ever be called with the same pluginid!
pluginsConfig PluginConfigProvider
contextProvider PluginContextWrapper
accessControl accesscontrol.AccessControl
}
func RegisterAPIService(
querierProvider QuerierProvider,
features featuremgmt.FeatureToggles,
apiRegistrar grafanaapiserver.APIRegistrar,
pluginContext PluginContextProvider,
pluginClient plugins.Client, // access to everything
pluginConfigs PluginConfigProvider,
contextProvider PluginContextWrapper,
pluginStore pluginstore.Store,
accessControl accesscontrol.AccessControl,
) (*DataSourceAPIBuilder, error) {
@ -63,7 +67,12 @@ func RegisterAPIService(
continue // skip this one
}
builder, err = NewDataSourceAPIBuilder(ds.JSONData, querierProvider, pluginContext, accessControl)
builder, err = NewDataSourceAPIBuilder(ds.JSONData,
pluginClient,
pluginConfigs,
contextProvider,
accessControl,
)
if err != nil {
return nil, err
}
@ -74,24 +83,21 @@ func RegisterAPIService(
func NewDataSourceAPIBuilder(
plugin plugins.JSONData,
querierProvider QuerierProvider,
pluginContext PluginContextProvider,
client plugins.Client,
pluginsConfig PluginConfigProvider,
contextProvider PluginContextWrapper,
accessControl accesscontrol.AccessControl) (*DataSourceAPIBuilder, error) {
ri, err := resourceFromPluginID(plugin.ID)
if err != nil {
return nil, err
}
querier, err := querierProvider.Querier(context.Background(), ri, plugin)
if err != nil {
return nil, err
}
return &DataSourceAPIBuilder{
connectionResourceInfo: ri,
pluginJSON: plugin,
querier: querier,
pluginContext: pluginContext,
client: client,
pluginsConfig: pluginsConfig,
contextProvider: contextProvider,
accessControl: accessControl,
}, nil
}
@ -148,7 +154,8 @@ func (b *DataSourceAPIBuilder) GetAPIGroupInfo(
conn := b.connectionResourceInfo
storage[conn.StoragePath()] = &connectionAccess{
builder: b.querier,
pluginID: b.pluginJSON.ID,
configs: b.pluginsConfig,
resourceInfo: conn,
tableConverter: utils.NewTableConverter(
conn.GroupResource(),
@ -191,6 +198,14 @@ func (b *DataSourceAPIBuilder) GetAPIGroupInfo(
return &apiGroupInfo, nil
}
func (b *DataSourceAPIBuilder) getPluginContext(ctx context.Context, uid string) (backend.PluginContext, error) {
instance, err := b.pluginsConfig.GetDataSourceInstanceSettings(ctx, b.pluginJSON.ID, uid)
if err != nil {
return backend.PluginContext{}, err
}
return b.contextProvider.PluginContextForDataSource(ctx, instance)
}
func (b *DataSourceAPIBuilder) GetOpenAPIDefinitions() openapi.GetOpenAPIDefinitions {
return v0alpha1.GetOpenAPIDefinitions
}

View File

@ -5,9 +5,12 @@ import (
"fmt"
"github.com/grafana/grafana-plugin-sdk-go/backend"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
common "github.com/grafana/grafana/pkg/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/apis/datasource/v0alpha1"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/setting"
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
)
@ -21,6 +24,22 @@ func NewTestDataAPIServer(group string) (*DataSourceAPIBuilder, error) {
return nil, fmt.Errorf("only %s is currently supported", pluginID)
}
// Run standalone with zero dependencies
if true {
return NewDataSourceAPIBuilder(
plugins.JSONData{
ID: pluginID,
},
testdatasource.ProvideService(), // the client
&testdataPluginConfigProvider{
startup: v1.Now(),
},
&testdataPluginConfigProvider{}, // stub
&actest.FakeAccessControl{ExpectedEvaluate: true},
)
}
// Otherwise manually wire up access to testdata
cfg, err := setting.NewCfgFromArgs(setting.CommandLineArgs{
// TODO: Add support for args?
})
@ -37,21 +56,69 @@ func NewTestDataAPIServer(group string) (*DataSourceAPIBuilder, error) {
if !exists {
return nil, fmt.Errorf("plugin %s not found", pluginID)
}
var testsDataQuerierFactory QuerierFactoryFunc = func(ctx context.Context, ri common.ResourceInfo, pj plugins.JSONData) (Querier, error) {
return NewDefaultQuerier(ri, td.JSONData, testdatasource.ProvideService(), dsService, dsCache), nil
}
return NewDataSourceAPIBuilder(
td.JSONData,
NewQuerierProvider(testsDataQuerierFactory),
&TestDataPluginContextProvider{},
testdatasource.ProvideService(), // the client
&defaultPluginConfigProvider{
dsService: dsService,
dsCache: dsCache,
},
&testdataPluginConfigProvider{}, // stub
accessControl,
)
}
type TestDataPluginContextProvider struct{}
func (p *TestDataPluginContextProvider) PluginContextForDataSource(_ context.Context, _, _ string) (backend.PluginContext, error) {
return backend.PluginContext{}, nil
// Simple stub for standalone testing
type testdataPluginConfigProvider struct {
startup v1.Time
}
var (
_ PluginConfigProvider = (*testdataPluginConfigProvider)(nil)
)
// GetDataSource implements PluginConfigProvider.
func (p *testdataPluginConfigProvider) GetDataSource(ctx context.Context, pluginID string, uid string) (*v0alpha1.DataSourceConnection, error) {
all, err := p.ListDatasources(ctx, pluginID)
if err != nil {
return nil, err
}
for idx, v := range all.Items {
if v.Name == uid {
return &all.Items[idx], nil
}
}
return nil, fmt.Errorf("not found")
}
// ListDatasources implements PluginConfigProvider.
func (p *testdataPluginConfigProvider) ListDatasources(ctx context.Context, pluginID string) (*v0alpha1.DataSourceConnectionList, error) {
info, err := request.NamespaceInfoFrom(ctx, true)
if err != nil {
return nil, err
}
return &v0alpha1.DataSourceConnectionList{
TypeMeta: v0alpha1.GenericConnectionResourceInfo.TypeMeta(),
Items: []v0alpha1.DataSourceConnection{
{
ObjectMeta: v1.ObjectMeta{
Name: "PD8C576611E62080A",
Namespace: info.Value, // the raw namespace value
CreationTimestamp: p.startup,
},
Title: "gdev-testdata",
},
},
}, nil
}
// PluginContextForDataSource implements PluginConfigProvider.
func (*testdataPluginConfigProvider) GetDataSourceInstanceSettings(ctx context.Context, pluginID, uid string) (*backend.DataSourceInstanceSettings, error) {
return &backend.DataSourceInstanceSettings{}, nil
}
// PluginContextWrapper
func (*testdataPluginConfigProvider) PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error) {
return backend.PluginContext{DataSourceInstanceSettings: datasourceSettings}, nil
}

View File

@ -35,13 +35,13 @@ func (r *subHealthREST) NewConnectOptions() (runtime.Object, bool, string) {
func (r *subHealthREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
pluginCtx, err := r.builder.pluginContext.PluginContextForDataSource(ctx, r.builder.pluginJSON.ID, name)
pluginCtx, err := r.builder.getPluginContext(ctx, name)
if err != nil {
responder.Error(err)
return
}
healthResponse, err := r.builder.querier.Health(ctx, &backend.CheckHealthRequest{
healthResponse, err := r.builder.client.CheckHealth(ctx, &backend.CheckHealthRequest{
PluginContext: pluginCtx,
})
if err != nil {

View File

@ -71,7 +71,7 @@ func (r *subQueryREST) readQueries(req *http.Request) ([]backend.DataQuery, erro
}
func (r *subQueryREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
pluginCtx, err := r.builder.pluginContext.PluginContextForDataSource(ctx, r.builder.pluginJSON.ID, name)
pluginCtx, err := r.builder.getPluginContext(ctx, name)
if err != nil {
return nil, err
}
@ -83,7 +83,7 @@ func (r *subQueryREST) Connect(ctx context.Context, name string, opts runtime.Ob
return
}
queryResponse, err := r.builder.querier.Query(ctx, &backend.QueryDataRequest{
queryResponse, err := r.builder.client.QueryData(ctx, &backend.QueryDataRequest{
PluginContext: pluginCtx,
Queries: queries,
// Headers: // from context

View File

@ -46,7 +46,7 @@ func (r *subResourceREST) NewConnectOptions() (runtime.Object, bool, string) {
}
func (r *subResourceREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) {
pluginCtx, err := r.builder.pluginContext.PluginContextForDataSource(ctx, r.builder.pluginJSON.ID, name)
pluginCtx, err := r.builder.getPluginContext(ctx, name)
if err != nil {
return nil, err
}
@ -65,7 +65,7 @@ func (r *subResourceREST) Connect(ctx context.Context, name string, opts runtime
}
path := req.URL.Path[idx+len("/resource"):]
err = r.builder.querier.Resource(ctx, &backend.CallResourceRequest{
err = r.builder.client.CallResource(ctx, &backend.CallResourceRequest{
PluginContext: pluginCtx,
Path: path,
Method: req.Method,

View File

@ -15,10 +15,10 @@ import (
var WireSet = wire.NewSet(
ProvideRegistryServiceSink, // dummy background service that forces registration
wire.Bind(new(datasource.QuerierProvider), new(*datasource.DefaultQuerierProvider)),
datasource.ProvideDefaultQuerierProvider,
// read-only datasource abstractions
plugincontext.ProvideService,
wire.Bind(new(datasource.PluginContextProvider), new(*plugincontext.Provider)),
wire.Bind(new(datasource.PluginContextWrapper), new(*plugincontext.Provider)),
datasource.ProvideDefaultPluginConfigs,
// Each must be added here *and* in the ServiceSink above
playlist.RegisterAPIService,

View File

@ -132,9 +132,22 @@ func (p *Provider) GetWithDataSource(ctx context.Context, pluginID string, user
return pCtx, nil
}
func (p *Provider) GetDataSourceInstanceSettings(ctx context.Context, uid string) (*backend.DataSourceInstanceSettings, error) {
user, err := appcontext.User(ctx)
if err != nil {
return nil, err
}
ds, err := p.dataSourceCache.GetDatasourceByUID(ctx, uid, user, false)
if err != nil {
return nil, err
}
return adapters.ModelToInstanceSettings(ds, p.decryptSecureJsonDataFn(ctx))
}
// PluginContextForDataSource will retrieve plugin context by the provided pluginID and datasource UID / K8s name.
// This is intended to be used for datasource API server plugin requests.
func (p *Provider) PluginContextForDataSource(ctx context.Context, pluginID, name string) (backend.PluginContext, error) {
func (p *Provider) PluginContextForDataSource(ctx context.Context, datasourceSettings *backend.DataSourceInstanceSettings) (backend.PluginContext, error) {
pluginID := datasourceSettings.Type
plugin, exists := p.pluginStore.Plugin(ctx, pluginID)
if !exists {
return backend.PluginContext{}, plugins.ErrPluginNotRegistered
@ -144,11 +157,6 @@ func (p *Provider) PluginContextForDataSource(ctx context.Context, pluginID, nam
if err != nil {
return backend.PluginContext{}, err
}
ds, err := p.dataSourceCache.GetDatasourceByUID(ctx, name, user, false)
if err != nil {
return backend.PluginContext{}, err
}
pCtx := backend.PluginContext{
PluginID: plugin.ID,
PluginVersion: plugin.Info.Version,
@ -158,10 +166,6 @@ func (p *Provider) PluginContextForDataSource(ctx context.Context, pluginID, nam
pCtx.User = adapters.BackendUserFromSignedInUser(user)
}
datasourceSettings, err := adapters.ModelToInstanceSettings(ds, p.decryptSecureJsonDataFn(ctx))
if err != nil {
return pCtx, err
}
pCtx.DataSourceInstanceSettings = datasourceSettings
settings := p.pluginEnvVars.GetConfigMap(ctx, pluginID, plugin.ExternalService)