Plugins: Support Admission validation hooks (#87718)
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
|
||||
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
@@ -26,6 +28,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/kvstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -44,6 +47,7 @@ type Service struct {
|
||||
logger log.Logger
|
||||
db db.DB
|
||||
pluginStore pluginstore.Store
|
||||
pluginClient plugins.Client // access to everything
|
||||
|
||||
ptc proxyTransportCache
|
||||
}
|
||||
@@ -61,7 +65,7 @@ type cachedRoundTripper struct {
|
||||
func ProvideService(
|
||||
db db.DB, secretsService secrets.Service, secretsStore kvstore.SecretsKVStore, cfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, datasourcePermissionsService accesscontrol.DatasourcePermissionsService,
|
||||
quotaService quota.Service, pluginStore pluginstore.Store,
|
||||
quotaService quota.Service, pluginStore pluginstore.Store, pluginClient plugins.Client,
|
||||
) (*Service, error) {
|
||||
dslogger := log.New("datasources")
|
||||
store := &SqlStore{db: db, logger: dslogger, features: features}
|
||||
@@ -79,6 +83,7 @@ func ProvideService(
|
||||
logger: dslogger,
|
||||
db: db,
|
||||
pluginStore: pluginStore,
|
||||
pluginClient: pluginClient,
|
||||
}
|
||||
|
||||
ac.RegisterScopeAttributeResolver(NewNameScopeResolver(store))
|
||||
@@ -205,10 +210,48 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *datasources.AddDataSou
|
||||
cmd.Name = getAvailableName(cmd.Type, dataSources)
|
||||
}
|
||||
|
||||
if err := s.validateFields(ctx, cmd.Name, cmd.URL, cmd.Type, cmd.APIVersion); err != nil {
|
||||
// Validate the command
|
||||
jd, err := cmd.JsonData.ToDB()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid jsonData")
|
||||
}
|
||||
|
||||
settings, err := s.prepareInstanceSettings(ctx, backend.PluginContext{
|
||||
OrgID: cmd.OrgID,
|
||||
PluginID: cmd.Type,
|
||||
}, &backend.DataSourceInstanceSettings{
|
||||
UID: cmd.UID,
|
||||
Name: cmd.Name,
|
||||
URL: cmd.URL,
|
||||
Database: cmd.Database,
|
||||
JSONData: jd,
|
||||
DecryptedSecureJSONData: cmd.SecureJsonData,
|
||||
Type: cmd.Type,
|
||||
User: cmd.User,
|
||||
BasicAuthEnabled: cmd.BasicAuth,
|
||||
BasicAuthUser: cmd.BasicAuthUser,
|
||||
APIVersion: cmd.APIVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The mutable properties
|
||||
cmd.URL = settings.URL
|
||||
cmd.User = settings.User
|
||||
cmd.BasicAuth = settings.BasicAuthEnabled
|
||||
cmd.BasicAuthUser = settings.BasicAuthUser
|
||||
cmd.Database = settings.Database
|
||||
cmd.SecureJsonData = settings.DecryptedSecureJSONData
|
||||
cmd.JsonData = nil
|
||||
if settings.JSONData != nil {
|
||||
cmd.JsonData = simplejson.New()
|
||||
err := cmd.JsonData.FromDB(settings.JSONData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var dataSource *datasources.DataSource
|
||||
return dataSource, s.db.InTransaction(ctx, func(ctx context.Context) error {
|
||||
var err error
|
||||
@@ -252,6 +295,122 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *datasources.AddDataSou
|
||||
})
|
||||
}
|
||||
|
||||
// This will valid validate the instance settings return a version that is safe to be saved
|
||||
func (s *Service) prepareInstanceSettings(ctx context.Context, pluginContext backend.PluginContext, settings *backend.DataSourceInstanceSettings) (*backend.DataSourceInstanceSettings, error) {
|
||||
operation := backend.AdmissionRequestCreate
|
||||
|
||||
// First apply global validation rules -- these are required regardless which plugin we are talking to
|
||||
if len(settings.Name) > maxDatasourceNameLen {
|
||||
return nil, datasources.ErrDataSourceNameInvalid.Errorf("max length is %d", maxDatasourceNameLen)
|
||||
}
|
||||
|
||||
if len(settings.URL) > maxDatasourceUrlLen {
|
||||
return nil, datasources.ErrDataSourceURLInvalid.Errorf("max length is %d", maxDatasourceUrlLen)
|
||||
}
|
||||
|
||||
if settings.Type == "" {
|
||||
return settings, nil // NOOP used in tests
|
||||
}
|
||||
|
||||
// Make sure it is a known plugin type
|
||||
p, found := s.pluginStore.Plugin(ctx, settings.Type)
|
||||
if !found {
|
||||
return nil, errutil.BadRequest("datasource.unknownPlugin",
|
||||
errutil.WithPublicMessage(fmt.Sprintf("plugin '%s' not found", settings.Type)))
|
||||
}
|
||||
|
||||
// When the APIVersion is set, the client must also implement AdmissionHandler
|
||||
if p.APIVersion == "" {
|
||||
if settings.APIVersion != "" {
|
||||
return nil, fmt.Errorf("invalid request apiVersion (datasource does not have one configured)")
|
||||
}
|
||||
return settings, nil // NOOP
|
||||
}
|
||||
|
||||
pb, err := backend.DataSourceInstanceSettingsToProtoBytes(settings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := &backend.AdmissionRequest{
|
||||
Operation: backend.AdmissionRequestCreate,
|
||||
PluginContext: pluginContext,
|
||||
Kind: settings.GVK(),
|
||||
ObjectBytes: pb,
|
||||
}
|
||||
|
||||
// Set the old bytes and change the operation
|
||||
if pluginContext.DataSourceInstanceSettings != nil {
|
||||
req.Operation = backend.AdmissionRequestUpdate
|
||||
req.OldObjectBytes, err = backend.DataSourceInstanceSettingsToProtoBytes(settings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
{ // As an example, this will first call validate (then mutate)
|
||||
// Implementations may vary, but typically validation is
|
||||
// more strict because it does not have the option to fix anything
|
||||
// that has reasonable fixes.
|
||||
rsp, err := s.pluginClient.ValidateAdmission(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
||||
return nil, errutil.Internal("plugin.unimplemented").
|
||||
Errorf("plugin (%s) with apiVersion=%s must implement ValidateAdmission", p.ID, p.APIVersion)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if rsp == nil {
|
||||
return nil, fmt.Errorf("expected response (%v)", operation)
|
||||
}
|
||||
if !rsp.Allowed {
|
||||
if rsp.Result != nil {
|
||||
return nil, toError(rsp.Result)
|
||||
}
|
||||
return nil, fmt.Errorf("not allowed")
|
||||
}
|
||||
// payload is OK, but now lets do the mutate version...
|
||||
}
|
||||
|
||||
// Next calling mutation -- this will try to get the input into an acceptable form
|
||||
rsp, err := s.pluginClient.MutateAdmission(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Is(err, plugins.ErrMethodNotImplemented) {
|
||||
return nil, errutil.Internal("plugin.unimplemented").
|
||||
Errorf("plugin (%s) with apiVersion=%s must implement MutateAdmission", p.ID, p.APIVersion)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if rsp == nil {
|
||||
return nil, fmt.Errorf("expected response (%v)", operation)
|
||||
}
|
||||
if !rsp.Allowed {
|
||||
if rsp.Result != nil {
|
||||
return nil, toError(rsp.Result)
|
||||
}
|
||||
return nil, fmt.Errorf("not allowed")
|
||||
}
|
||||
if rsp.ObjectBytes == nil {
|
||||
return nil, fmt.Errorf("mutation response is missing value")
|
||||
}
|
||||
return backend.DataSourceInstanceSettingsFromProto(rsp.ObjectBytes, pluginContext.PluginID)
|
||||
}
|
||||
|
||||
func toError(status *backend.StatusResult) error {
|
||||
if status == nil {
|
||||
return fmt.Errorf("error converting status")
|
||||
}
|
||||
// hymm -- no way to pass the raw http status along!!
|
||||
// Looks like it must be based on the reason string
|
||||
return errutil.Error{
|
||||
Reason: errutil.CoreStatus(status.Reason),
|
||||
MessageID: "datasource.config.mutate",
|
||||
LogMessage: status.Message,
|
||||
PublicMessage: status.Message,
|
||||
Source: errutil.SourceDownstream,
|
||||
}
|
||||
}
|
||||
|
||||
// getAvailableName finds the first available name for a datasource of the given type.
|
||||
func getAvailableName(dsType string, dataSources []*datasources.DataSource) string {
|
||||
dsNames := make(map[string]bool)
|
||||
@@ -284,13 +443,40 @@ func (s *Service) DeleteDataSource(ctx context.Context, cmd *datasources.DeleteD
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Service) getPluginContext(ctx context.Context, orgID int64, pluginID string, ds *datasources.DataSource) (backend.PluginContext, error) {
|
||||
var err error
|
||||
if ds == nil {
|
||||
return backend.PluginContext{
|
||||
OrgID: orgID,
|
||||
PluginID: pluginID,
|
||||
}, err
|
||||
}
|
||||
pctx := backend.PluginContext{
|
||||
OrgID: orgID,
|
||||
PluginID: pluginID,
|
||||
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
|
||||
UID: ds.UID,
|
||||
Type: pluginID,
|
||||
Name: ds.Name,
|
||||
URL: ds.URL,
|
||||
Database: ds.Database,
|
||||
BasicAuthEnabled: ds.BasicAuth,
|
||||
BasicAuthUser: ds.BasicAuthUser,
|
||||
Updated: ds.Updated,
|
||||
APIVersion: ds.APIVersion,
|
||||
User: ds.User,
|
||||
},
|
||||
}
|
||||
pctx.DataSourceInstanceSettings.JSONData, err = ds.JsonData.ToDB()
|
||||
if err == nil && len(ds.SecureJsonData) > 0 {
|
||||
pctx.DataSourceInstanceSettings.DecryptedSecureJSONData, err = s.DecryptedValues(ctx, ds)
|
||||
}
|
||||
return pctx, err
|
||||
}
|
||||
|
||||
func (s *Service) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateDataSourceCommand) (*datasources.DataSource, error) {
|
||||
var dataSource *datasources.DataSource
|
||||
|
||||
if err := s.validateFields(ctx, cmd.Name, cmd.URL, cmd.Type, cmd.APIVersion); err != nil {
|
||||
return dataSource, err
|
||||
}
|
||||
|
||||
return dataSource, s.db.InTransaction(ctx, func(ctx context.Context) error {
|
||||
var err error
|
||||
|
||||
@@ -303,6 +489,54 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateD
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate the command
|
||||
jd, err := cmd.JsonData.ToDB()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid jsonData")
|
||||
}
|
||||
pctx, err := s.getPluginContext(ctx, cmd.OrgID, cmd.Type, dataSource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings, err := s.prepareInstanceSettings(ctx, pctx,
|
||||
&backend.DataSourceInstanceSettings{
|
||||
UID: cmd.UID,
|
||||
Name: cmd.Name,
|
||||
URL: cmd.URL,
|
||||
Database: cmd.Database,
|
||||
JSONData: jd,
|
||||
DecryptedSecureJSONData: cmd.SecureJsonData,
|
||||
Type: cmd.Type,
|
||||
User: cmd.User,
|
||||
BasicAuthEnabled: cmd.BasicAuth,
|
||||
BasicAuthUser: cmd.BasicAuthUser,
|
||||
APIVersion: cmd.APIVersion,
|
||||
Updated: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if settings == nil {
|
||||
return fmt.Errorf("settings or an error is required")
|
||||
}
|
||||
|
||||
// The mutable properties
|
||||
cmd.URL = settings.URL
|
||||
cmd.User = settings.User
|
||||
cmd.BasicAuth = settings.BasicAuthEnabled
|
||||
cmd.BasicAuthUser = settings.BasicAuthUser
|
||||
cmd.Database = settings.Database
|
||||
cmd.SecureJsonData = settings.DecryptedSecureJSONData
|
||||
cmd.JsonData = nil
|
||||
if settings.JSONData != nil {
|
||||
cmd.JsonData = simplejson.New()
|
||||
err := cmd.JsonData.FromDB(settings.JSONData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if cmd.Name != "" && cmd.Name != dataSource.Name {
|
||||
query := &datasources.GetDataSourceQuery{
|
||||
Name: cmd.Name,
|
||||
@@ -716,32 +950,6 @@ func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *datasources.U
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) validateFields(ctx context.Context, name, url, pluginID, apiVersion string) error {
|
||||
if len(name) > maxDatasourceNameLen {
|
||||
return datasources.ErrDataSourceNameInvalid.Errorf("max length is %d", maxDatasourceNameLen)
|
||||
}
|
||||
|
||||
if len(url) > maxDatasourceUrlLen {
|
||||
return datasources.ErrDataSourceURLInvalid.Errorf("max length is %d", maxDatasourceUrlLen)
|
||||
}
|
||||
|
||||
if apiVersion == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
p, found := s.pluginStore.Plugin(context.Background(), pluginID)
|
||||
if !found {
|
||||
// Plugin not installed, ignore apiVersion check
|
||||
return nil
|
||||
}
|
||||
|
||||
if p.APIVersion != "" && p.APIVersion != apiVersion {
|
||||
return datasources.ErrDataSourceAPIVersionInvalid.Errorf("expected %s, got %s", p.APIVersion, apiVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) {
|
||||
limits := "a.Map{}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
pluginfakes "github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
@@ -33,6 +35,8 @@ import (
|
||||
secretsmng "github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
|
||||
"github.com/grafana/grafana/pkg/util/errutil"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -59,6 +63,7 @@ func TestService_AddDataSource(t *testing.T) {
|
||||
cfg := &setting.Cfg{}
|
||||
|
||||
t.Run("should return validation error if command validation failed", func(t *testing.T) {
|
||||
dsplugin := &testdatasource.Service{}
|
||||
sqlStore := db.InitTestDB(t)
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
@@ -67,10 +72,16 @@ func TestService_AddDataSource(t *testing.T) {
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{
|
||||
PluginList: []pluginstore.Plugin{{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test",
|
||||
Type: plugins.TypeDataSource,
|
||||
Name: "test",
|
||||
APIVersion: "v0alpha1",
|
||||
APIVersion: "v0alpha1", // When a value exists in plugin.json, the callback will be executed
|
||||
},
|
||||
}},
|
||||
}, &pluginfakes.FakePluginClient{
|
||||
ValidateAdmissionFunc: dsplugin.ValidateAdmission,
|
||||
MutateAdmissionFunc: dsplugin.MutateAdmission,
|
||||
ConvertObjectFunc: dsplugin.ConvertObject,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -92,12 +103,17 @@ func TestService_AddDataSource(t *testing.T) {
|
||||
|
||||
cmd = &datasources.AddDataSourceCommand{
|
||||
OrgID: 1,
|
||||
Type: "test", // required to validate apiserver
|
||||
Name: "test",
|
||||
APIVersion: "v0alpha2",
|
||||
APIVersion: "v123", // invalid apiVersion
|
||||
}
|
||||
|
||||
_, err = dsService.AddDataSource(context.Background(), cmd)
|
||||
require.EqualError(t, err, "[datasource.apiVersionInvalid] expected v0alpha1, got v0alpha2")
|
||||
|
||||
var gErr errutil.Error
|
||||
require.True(t, errors.As(err, &gErr))
|
||||
require.Equal(t, "expected apiVersion: v0alpha1, found: v123", gErr.PublicMessage)
|
||||
require.Equal(t, 400, gErr.Public().StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -189,7 +205,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := &datasources.UpdateDataSourceCommand{
|
||||
@@ -208,11 +224,31 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService,
|
||||
&pluginstore.FakePluginStore{
|
||||
PluginList: []pluginstore.Plugin{
|
||||
{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// First add the datasource
|
||||
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||
OrgID: 1,
|
||||
Name: "test",
|
||||
Type: "test",
|
||||
UserID: 0,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := &datasources.UpdateDataSourceCommand{
|
||||
ID: 1,
|
||||
ID: ds.ID,
|
||||
UID: ds.UID,
|
||||
OrgID: 1,
|
||||
Name: string(make([]byte, 256)),
|
||||
}
|
||||
@@ -221,7 +257,8 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
require.EqualError(t, err, "[datasource.nameInvalid] max length is 190")
|
||||
|
||||
cmd = &datasources.UpdateDataSourceCommand{
|
||||
ID: 1,
|
||||
ID: ds.ID,
|
||||
UID: ds.UID,
|
||||
OrgID: 1,
|
||||
URL: string(make([]byte, 256)),
|
||||
}
|
||||
@@ -236,7 +273,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
@@ -263,7 +300,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
@@ -296,7 +333,7 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
@@ -340,7 +377,8 @@ func TestService_UpdateDataSource(t *testing.T) {
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
mockPermission := acmock.NewMockedPermissionsService()
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{},
|
||||
mockPermission, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
@@ -602,7 +640,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
rt1, err := dsService.GetHTTPTransport(context.Background(), &ds, provider)
|
||||
@@ -639,7 +677,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -690,7 +728,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -738,7 +776,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -794,7 +832,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -829,7 +867,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -898,7 +936,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -977,7 +1015,7 @@ func TestService_GetHttpTransport(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := datasources.DataSource{
|
||||
@@ -998,7 +1036,7 @@ func TestService_getProxySettings(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, &setting.Cfg{}, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, &setting.Cfg{}, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("Should default to disabled", func(t *testing.T) {
|
||||
@@ -1094,7 +1132,7 @@ func TestService_getTimeout(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -1117,7 +1155,7 @@ func TestService_GetDecryptedValues(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
jsonData := map[string]string{
|
||||
@@ -1145,7 +1183,7 @@ func TestService_GetDecryptedValues(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
jsonData := map[string]string{
|
||||
@@ -1169,7 +1207,7 @@ func TestDataSource_CustomHeaders(t *testing.T) {
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, nil, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
|
||||
dsService.cfg = setting.NewCfg()
|
||||
|
||||
Reference in New Issue
Block a user