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()
|
||||
|
||||
@@ -43,3 +43,18 @@ func (m *baseMiddleware) PublishStream(ctx context.Context, req *backend.Publish
|
||||
func (m *baseMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
|
||||
return m.next.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *baseMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
return m.next.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *baseMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
return m.next.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *baseMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
return m.next.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
@@ -70,3 +70,21 @@ func (m *ContextualLoggerMiddleware) RunStream(ctx context.Context, req *backend
|
||||
ctx = instrumentContext(ctx, endpointRunStream, req.PluginContext)
|
||||
return m.next.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointValidateAdmission, req.PluginContext)
|
||||
return m.next.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointMutateAdmission, req.PluginContext)
|
||||
return m.next.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *ContextualLoggerMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
ctx = instrumentContext(ctx, endpointConvertObject, req.PluginContext)
|
||||
return m.next.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
@@ -185,3 +185,33 @@ func (m *MetricsMiddleware) CollectMetrics(ctx context.Context, req *backend.Col
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
var result *backend.ValidationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.ValidateAdmission(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
var result *backend.MutationResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.MutateAdmission(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (m *MetricsMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
var result *backend.ConversionResponse
|
||||
err := m.instrumentPluginRequest(ctx, req.PluginContext, endpointMutateAdmission, func(ctx context.Context) (status requestStatus, innerErr error) {
|
||||
result, innerErr = m.next.ConvertObject(ctx, req)
|
||||
return requestStatusFromError(innerErr), innerErr
|
||||
})
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -67,3 +67,21 @@ func (m *PluginRequestMetaMiddleware) RunStream(ctx context.Context, req *backen
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.next.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.next.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.next.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *PluginRequestMetaMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
ctx = m.withDefaultPluginRequestMeta(ctx)
|
||||
return m.next.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
@@ -135,3 +135,30 @@ func (m *TracingMiddleware) RunStream(ctx context.Context, req *backend.RunStrea
|
||||
err = m.next.RunStream(ctx, req, sender)
|
||||
return err
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointValidateAdmission)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.ValidateAdmission(ctx, req)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointMutateAdmission)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.MutateAdmission(ctx, req)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *TracingMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
var err error
|
||||
ctx, end := m.traceWrap(ctx, req.PluginContext, endpointConvertObject)
|
||||
defer func() { end(err) }()
|
||||
resp, err := m.next.ConvertObject(ctx, req)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -387,6 +387,21 @@ func (m *alwaysErrorFuncMiddleware) RunStream(ctx context.Context, req *backend.
|
||||
return m.f()
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (m *alwaysErrorFuncMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
return nil, m.f()
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (m *alwaysErrorFuncMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
return nil, m.f()
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (m *alwaysErrorFuncMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
return nil, m.f()
|
||||
}
|
||||
|
||||
// newAlwaysErrorMiddleware returns a new middleware that always returns the specified error.
|
||||
func newAlwaysErrorMiddleware(err error) plugins.ClientMiddleware {
|
||||
return plugins.ClientMiddlewareFunc(func(next plugins.Client) plugins.Client {
|
||||
@@ -401,7 +416,6 @@ func newAlwaysPanicMiddleware(message string) plugins.ClientMiddleware {
|
||||
return plugins.ClientMiddlewareFunc(func(next plugins.Client) plugins.Client {
|
||||
return &alwaysErrorFuncMiddleware{func() error {
|
||||
panic(message)
|
||||
return nil // nolint:govet
|
||||
}}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -25,13 +25,16 @@ func (status requestStatus) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
endpointCallResource = "callResource"
|
||||
endpointCheckHealth = "checkHealth"
|
||||
endpointCollectMetrics = "collectMetrics"
|
||||
endpointQueryData = "queryData"
|
||||
endpointSubscribeStream = "subscribeStream"
|
||||
endpointPublishStream = "publishStream"
|
||||
endpointRunStream = "runStream"
|
||||
endpointCallResource = "callResource"
|
||||
endpointCheckHealth = "checkHealth"
|
||||
endpointCollectMetrics = "collectMetrics"
|
||||
endpointQueryData = "queryData"
|
||||
endpointSubscribeStream = "subscribeStream"
|
||||
endpointPublishStream = "publishStream"
|
||||
endpointRunStream = "runStream"
|
||||
endpointValidateAdmission = "validateAdmission"
|
||||
endpointMutateAdmission = "mutateAdmission"
|
||||
endpointConvertObject = "convertObject"
|
||||
)
|
||||
|
||||
type callResourceResponseSenderFunc func(res *backend.CallResourceResponse) error
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
pluginfakes "github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
|
||||
@@ -484,7 +485,8 @@ func setupEnv(t *testing.T, sqlStore db.DB, cfg *setting.Cfg, b bus.Bus, quotaSe
|
||||
require.NoError(t, err)
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||
_, err = dsservice.ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
_, err = dsservice.ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(),
|
||||
quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
m := metrics.NewNGAlert(prometheus.NewRegistry())
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
pluginfakes "github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
dsservice "github.com/grafana/grafana/pkg/services/datasources/service"
|
||||
@@ -36,7 +37,8 @@ func SetupTestDataSourceSecretMigrationService(t *testing.T, sqlStore db.DB, kvS
|
||||
}
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dsService, err := dsservice.ProvideService(sqlStore, secretsService, secretsStore, cfg, features, acmock.New(), acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{})
|
||||
dsService, err := dsservice.ProvideService(sqlStore, secretsService, secretsStore, cfg, features, acmock.New(),
|
||||
acmock.NewMockedPermissionsService(), quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{})
|
||||
require.NoError(t, err)
|
||||
migService := ProvideDataSourceMigrationService(dsService, kvStore, features)
|
||||
return migService
|
||||
|
||||
Reference in New Issue
Block a user