mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Support Admission validation hooks (#87718)
This commit is contained in:
@@ -18,6 +18,7 @@ type corePlugin struct {
|
||||
backend.CallResourceHandler
|
||||
backend.QueryDataHandler
|
||||
backend.StreamHandler
|
||||
backend.AdmissionHandler
|
||||
}
|
||||
|
||||
// New returns a new backendplugin.PluginFactoryFunc for creating a core (built-in) backendplugin.Plugin.
|
||||
@@ -29,6 +30,7 @@ func New(opts backend.ServeOpts) backendplugin.PluginFactoryFunc {
|
||||
CheckHealthHandler: opts.CheckHealthHandler,
|
||||
CallResourceHandler: opts.CallResourceHandler,
|
||||
QueryDataHandler: opts.QueryDataHandler,
|
||||
AdmissionHandler: opts.AdmissionHandler,
|
||||
StreamHandler: opts.StreamHandler,
|
||||
}, nil
|
||||
}
|
||||
@@ -124,3 +126,27 @@ func (cp *corePlugin) RunStream(ctx context.Context, req *backend.RunStreamReque
|
||||
}
|
||||
return plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (cp *corePlugin) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if cp.AdmissionHandler != nil {
|
||||
ctx = backend.WithGrafanaConfig(ctx, req.PluginContext.GrafanaConfig)
|
||||
return cp.AdmissionHandler.MutateAdmission(ctx, req)
|
||||
}
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (cp *corePlugin) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if cp.AdmissionHandler != nil {
|
||||
ctx = backend.WithGrafanaConfig(ctx, req.PluginContext.GrafanaConfig)
|
||||
return cp.AdmissionHandler.ValidateAdmission(ctx, req)
|
||||
}
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (cp *corePlugin) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if cp.AdmissionHandler != nil {
|
||||
ctx = backend.WithGrafanaConfig(ctx, req.PluginContext.GrafanaConfig)
|
||||
return cp.AdmissionHandler.ConvertObject(ctx, req)
|
||||
}
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
sdktracing "github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
@@ -145,6 +146,9 @@ func asBackendPlugin(svc any) backendplugin.PluginFactoryFunc {
|
||||
if healthHandler, ok := svc.(backend.CheckHealthHandler); ok {
|
||||
opts.CheckHealthHandler = healthHandler
|
||||
}
|
||||
if storageHandler, ok := svc.(backend.AdmissionHandler); ok {
|
||||
opts.AdmissionHandler = storageHandler
|
||||
}
|
||||
|
||||
if opts.QueryDataHandler != nil || opts.CallResourceHandler != nil ||
|
||||
opts.CheckHealthHandler != nil || opts.StreamHandler != nil {
|
||||
|
||||
@@ -33,6 +33,7 @@ var pluginSet = map[int]goplugin.PluginSet{
|
||||
"resource": &grpcplugin.ResourceGRPCPlugin{},
|
||||
"data": &grpcplugin.DataGRPCPlugin{},
|
||||
"stream": &grpcplugin.StreamGRPCPlugin{},
|
||||
"admission": &grpcplugin.AdmissionGRPCPlugin{},
|
||||
"renderer": &pluginextensionv2.RendererGRPCPlugin{},
|
||||
"secretsmanager": &secretsmanagerplugin.SecretsManagerGRPCPlugin{},
|
||||
},
|
||||
|
||||
@@ -24,6 +24,7 @@ type ClientV2 struct {
|
||||
grpcplugin.ResourceClient
|
||||
grpcplugin.DataClient
|
||||
grpcplugin.StreamClient
|
||||
grpcplugin.AdmissionClient
|
||||
pluginextensionv2.RendererPlugin
|
||||
secretsmanagerplugin.SecretsManagerPlugin
|
||||
}
|
||||
@@ -44,6 +45,11 @@ func newClientV2(descriptor PluginDescriptor, logger log.Logger, rpcClient plugi
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawAdmission, err := rpcClient.Dispense("admission")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawStream, err := rpcClient.Dispense("stream")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,6 +84,12 @@ func newClientV2(descriptor PluginDescriptor, logger log.Logger, rpcClient plugi
|
||||
}
|
||||
}
|
||||
|
||||
if rawAdmission != nil {
|
||||
if admissionClient, ok := rawAdmission.(grpcplugin.AdmissionClient); ok {
|
||||
c.AdmissionClient = admissionClient
|
||||
}
|
||||
}
|
||||
|
||||
if rawStream != nil {
|
||||
if streamClient, ok := rawStream.(grpcplugin.StreamClient); ok {
|
||||
c.StreamClient = streamClient
|
||||
@@ -257,3 +269,60 @@ func (c *ClientV2) RunStream(ctx context.Context, req *backend.RunStreamRequest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClientV2) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if c.AdmissionClient == nil {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
protoReq := backend.ToProto().AdmissionRequest(req)
|
||||
protoResp, err := c.AdmissionClient.ValidateAdmission(ctx, protoReq)
|
||||
|
||||
if err != nil {
|
||||
if status.Code(err) == codes.Unimplemented {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%v: %w", "Failed to ValidateAdmission", err)
|
||||
}
|
||||
|
||||
return backend.FromProto().ValidationResponse(protoResp), nil
|
||||
}
|
||||
|
||||
func (c *ClientV2) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if c.AdmissionClient == nil {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
protoReq := backend.ToProto().AdmissionRequest(req)
|
||||
protoResp, err := c.AdmissionClient.MutateAdmission(ctx, protoReq)
|
||||
|
||||
if err != nil {
|
||||
if status.Code(err) == codes.Unimplemented {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%v: %w", "Failed to MutateAdmission", err)
|
||||
}
|
||||
|
||||
return backend.FromProto().MutationResponse(protoResp), nil
|
||||
}
|
||||
|
||||
func (c *ClientV2) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if c.AdmissionClient == nil {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
protoReq := backend.ToProto().ConversionRequest(req)
|
||||
protoResp, err := c.AdmissionClient.ConvertObject(ctx, protoReq)
|
||||
|
||||
if err != nil {
|
||||
if status.Code(err) == codes.Unimplemented {
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%v: %w", "Failed to ConvertObject", err)
|
||||
}
|
||||
|
||||
return backend.FromProto().ConversionResponse(protoResp), nil
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ type pluginClient interface {
|
||||
backend.CheckHealthHandler
|
||||
backend.QueryDataHandler
|
||||
backend.CallResourceHandler
|
||||
backend.AdmissionHandler
|
||||
backend.StreamHandler
|
||||
}
|
||||
|
||||
@@ -199,3 +200,27 @@ func (p *grpcPlugin) RunStream(ctx context.Context, req *backend.RunStreamReques
|
||||
}
|
||||
return pluginClient.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
func (p *grpcPlugin) ValidateAdmission(ctx context.Context, request *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
pluginClient, ok := p.getPluginClient()
|
||||
if !ok {
|
||||
return nil, plugins.ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.ValidateAdmission(ctx, request)
|
||||
}
|
||||
|
||||
func (p *grpcPlugin) MutateAdmission(ctx context.Context, request *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
pluginClient, ok := p.getPluginClient()
|
||||
if !ok {
|
||||
return nil, plugins.ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.MutateAdmission(ctx, request)
|
||||
}
|
||||
|
||||
func (p *grpcPlugin) ConvertObject(ctx context.Context, request *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
pluginClient, ok := p.getPluginClient()
|
||||
if !ok {
|
||||
return nil, plugins.ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.ConvertObject(ctx, request)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type Plugin interface {
|
||||
backend.CheckHealthHandler
|
||||
backend.QueryDataHandler
|
||||
backend.CallResourceHandler
|
||||
backend.AdmissionHandler
|
||||
backend.StreamHandler
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ type Client interface {
|
||||
backend.QueryDataHandler
|
||||
backend.CheckHealthHandler
|
||||
backend.StreamHandler
|
||||
backend.AdmissionHandler
|
||||
backend.CallResourceHandler
|
||||
backend.CollectMetricsHandler
|
||||
}
|
||||
|
||||
@@ -217,6 +217,48 @@ func (s *Service) RunStream(ctx context.Context, req *backend.RunStreamRequest,
|
||||
return plugin.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ConvertObject implements plugins.Client.
|
||||
func (s *Service) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
plugin, exists := s.plugin(ctx, req.PluginContext.PluginID, req.PluginContext.PluginVersion)
|
||||
if !exists {
|
||||
return nil, plugins.ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
return plugin.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements plugins.Client.
|
||||
func (s *Service) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
plugin, exists := s.plugin(ctx, req.PluginContext.PluginID, req.PluginContext.PluginVersion)
|
||||
if !exists {
|
||||
return nil, plugins.ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
return plugin.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements plugins.Client.
|
||||
func (s *Service) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
plugin, exists := s.plugin(ctx, req.PluginContext.PluginID, req.PluginContext.PluginVersion)
|
||||
if !exists {
|
||||
return nil, plugins.ErrPluginNotRegistered
|
||||
}
|
||||
|
||||
return plugin.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// plugin finds a plugin with `pluginID` from the registry that is not decommissioned
|
||||
func (s *Service) plugin(ctx context.Context, pluginID, pluginVersion string) (*plugins.Plugin, bool) {
|
||||
p, exists := s.pluginRegistry.Plugin(ctx, pluginID, pluginVersion)
|
||||
|
||||
@@ -20,13 +20,16 @@ import (
|
||||
|
||||
type TestClient struct {
|
||||
plugins.Client
|
||||
QueryDataFunc backend.QueryDataHandlerFunc
|
||||
CallResourceFunc backend.CallResourceHandlerFunc
|
||||
CheckHealthFunc backend.CheckHealthHandlerFunc
|
||||
CollectMetricsFunc backend.CollectMetricsHandlerFunc
|
||||
SubscribeStreamFunc func(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error)
|
||||
PublishStreamFunc func(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error)
|
||||
RunStreamFunc func(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error
|
||||
QueryDataFunc backend.QueryDataHandlerFunc
|
||||
CallResourceFunc backend.CallResourceHandlerFunc
|
||||
CheckHealthFunc backend.CheckHealthHandlerFunc
|
||||
CollectMetricsFunc backend.CollectMetricsHandlerFunc
|
||||
SubscribeStreamFunc func(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error)
|
||||
PublishStreamFunc func(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error)
|
||||
RunStreamFunc func(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error
|
||||
ValidateAdmissionFunc backend.ValidateAdmissionFunc
|
||||
MutateAdmissionFunc backend.MutateAdmissionFunc
|
||||
ConvertObjectFunc backend.ConvertObjectFunc
|
||||
}
|
||||
|
||||
func (c *TestClient) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
@@ -84,14 +87,39 @@ func (c *TestClient) RunStream(ctx context.Context, req *backend.RunStreamReques
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *TestClient) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if c.ValidateAdmissionFunc != nil {
|
||||
return c.ValidateAdmissionFunc(ctx, req)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *TestClient) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if c.MutateAdmissionFunc != nil {
|
||||
return c.MutateAdmissionFunc(ctx, req)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *TestClient) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if c.ConvertObjectFunc != nil {
|
||||
return c.ConvertObjectFunc(ctx, req)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type MiddlewareScenarioContext struct {
|
||||
QueryDataCallChain []string
|
||||
CallResourceCallChain []string
|
||||
CollectMetricsCallChain []string
|
||||
CheckHealthCallChain []string
|
||||
SubscribeStreamCallChain []string
|
||||
PublishStreamCallChain []string
|
||||
RunStreamCallChain []string
|
||||
QueryDataCallChain []string
|
||||
CallResourceCallChain []string
|
||||
CollectMetricsCallChain []string
|
||||
CheckHealthCallChain []string
|
||||
SubscribeStreamCallChain []string
|
||||
PublishStreamCallChain []string
|
||||
RunStreamCallChain []string
|
||||
InstanceSettingsCallChain []string
|
||||
ValidateAdmissionCallChain []string
|
||||
MutateAdmissionCallChain []string
|
||||
ConvertObjectCallChain []string
|
||||
}
|
||||
|
||||
func (ctx *MiddlewareScenarioContext) NewMiddleware(name string) plugins.ClientMiddleware {
|
||||
@@ -131,6 +159,27 @@ func (m *TestMiddleware) CollectMetrics(ctx context.Context, req *backend.Collec
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
m.sCtx.ValidateAdmissionCallChain = append(m.sCtx.ValidateAdmissionCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.ValidateAdmission(ctx, req)
|
||||
m.sCtx.ValidateAdmissionCallChain = append(m.sCtx.ValidateAdmissionCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
m.sCtx.MutateAdmissionCallChain = append(m.sCtx.MutateAdmissionCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.MutateAdmission(ctx, req)
|
||||
m.sCtx.MutateAdmissionCallChain = append(m.sCtx.MutateAdmissionCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
m.sCtx.ConvertObjectCallChain = append(m.sCtx.ConvertObjectCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.ConvertObject(ctx, req)
|
||||
m.sCtx.ConvertObjectCallChain = append(m.sCtx.ConvertObjectCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
|
||||
m.sCtx.CheckHealthCallChain = append(m.sCtx.CheckHealthCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.CheckHealth(ctx, req)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
||||
@@ -14,6 +15,10 @@ type Decorator struct {
|
||||
middlewares []plugins.ClientMiddleware
|
||||
}
|
||||
|
||||
var (
|
||||
_ = plugins.Client(&Decorator{})
|
||||
)
|
||||
|
||||
// NewDecorator creates a new plugins.client decorator.
|
||||
func NewDecorator(client plugins.Client, middlewares ...plugins.ClientMiddleware) (*Decorator, error) {
|
||||
if client == nil {
|
||||
@@ -98,6 +103,33 @@ func (d *Decorator) RunStream(ctx context.Context, req *backend.RunStreamRequest
|
||||
return client.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
func (d *Decorator) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
func (d *Decorator) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
func (d *Decorator) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if req == nil {
|
||||
return nil, errNilRequest
|
||||
}
|
||||
|
||||
client := clientFromMiddlewares(d.middlewares, d.client)
|
||||
return client.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
func clientFromMiddlewares(middlewares []plugins.ClientMiddleware, finalClient plugins.Client) plugins.Client {
|
||||
if len(middlewares) == 0 {
|
||||
return finalClient
|
||||
@@ -123,5 +155,3 @@ func reverseMiddlewares(middlewares []plugins.ClientMiddleware) []plugins.Client
|
||||
|
||||
return reversed
|
||||
}
|
||||
|
||||
var _ plugins.Client = &Decorator{}
|
||||
|
||||
@@ -6,8 +6,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
)
|
||||
|
||||
func TestDecorator(t *testing.T) {
|
||||
@@ -146,13 +147,17 @@ func (c *TestClient) CheckHealth(ctx context.Context, req *backend.CheckHealthRe
|
||||
}
|
||||
|
||||
type MiddlewareScenarioContext struct {
|
||||
QueryDataCallChain []string
|
||||
CallResourceCallChain []string
|
||||
CollectMetricsCallChain []string
|
||||
CheckHealthCallChain []string
|
||||
SubscribeStreamCallChain []string
|
||||
PublishStreamCallChain []string
|
||||
RunStreamCallChain []string
|
||||
QueryDataCallChain []string
|
||||
CallResourceCallChain []string
|
||||
CollectMetricsCallChain []string
|
||||
CheckHealthCallChain []string
|
||||
SubscribeStreamCallChain []string
|
||||
PublishStreamCallChain []string
|
||||
RunStreamCallChain []string
|
||||
InstanceSettingsCallChain []string
|
||||
ValidateAdmissionCallChain []string
|
||||
MutateAdmissionCallChain []string
|
||||
ConvertObjectCallChain []string
|
||||
}
|
||||
|
||||
func (ctx *MiddlewareScenarioContext) NewMiddleware(name string) plugins.ClientMiddleware {
|
||||
@@ -220,4 +225,25 @@ func (m *TestMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRe
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
m.sCtx.ValidateAdmissionCallChain = append(m.sCtx.ValidateAdmissionCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.ValidateAdmission(ctx, req)
|
||||
m.sCtx.ValidateAdmissionCallChain = append(m.sCtx.ValidateAdmissionCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
m.sCtx.MutateAdmissionCallChain = append(m.sCtx.MutateAdmissionCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.MutateAdmission(ctx, req)
|
||||
m.sCtx.MutateAdmissionCallChain = append(m.sCtx.MutateAdmissionCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *TestMiddleware) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
m.sCtx.ConvertObjectCallChain = append(m.sCtx.ConvertObjectCallChain, fmt.Sprintf("before %s", m.Name))
|
||||
res, err := m.next.ConvertObject(ctx, req)
|
||||
m.sCtx.ConvertObjectCallChain = append(m.sCtx.ConvertObjectCallChain, fmt.Sprintf("after %s", m.Name))
|
||||
return res, err
|
||||
}
|
||||
|
||||
var _ plugins.Client = &TestClient{}
|
||||
|
||||
@@ -70,6 +70,9 @@ type FakePluginClient struct {
|
||||
backend.CheckHealthHandlerFunc
|
||||
backend.QueryDataHandlerFunc
|
||||
backend.CallResourceHandlerFunc
|
||||
backend.MutateAdmissionFunc
|
||||
backend.ValidateAdmissionFunc
|
||||
backend.ConvertObjectFunc
|
||||
mutex sync.RWMutex
|
||||
|
||||
backendplugin.Plugin
|
||||
@@ -166,6 +169,30 @@ func (pc *FakePluginClient) RunStream(_ context.Context, _ *backend.RunStreamReq
|
||||
return plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (pc *FakePluginClient) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
if pc.ValidateAdmissionFunc != nil {
|
||||
return pc.ValidateAdmissionFunc(ctx, req)
|
||||
}
|
||||
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (pc *FakePluginClient) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
if pc.MutateAdmissionFunc != nil {
|
||||
return pc.MutateAdmissionFunc(ctx, req)
|
||||
}
|
||||
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
func (pc *FakePluginClient) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
if pc.ConvertObjectFunc != nil {
|
||||
return pc.ConvertObjectFunc(ctx, req)
|
||||
}
|
||||
|
||||
return nil, plugins.ErrMethodNotImplemented
|
||||
}
|
||||
|
||||
type FakePluginRegistry struct {
|
||||
Store map[string]*plugins.Plugin
|
||||
}
|
||||
|
||||
@@ -69,6 +69,15 @@ type Plugin struct {
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
_ = backend.CollectMetricsHandler(&Plugin{})
|
||||
_ = backend.CheckHealthHandler(&Plugin{})
|
||||
_ = backend.QueryDataHandler(&Plugin{})
|
||||
_ = backend.CallResourceHandler(&Plugin{})
|
||||
_ = backend.StreamHandler(&Plugin{})
|
||||
_ = backend.AdmissionHandler(&Plugin{})
|
||||
)
|
||||
|
||||
type AngularMeta struct {
|
||||
Detected bool `json:"detected"`
|
||||
HideDeprecation bool `json:"hideDeprecation"`
|
||||
@@ -360,6 +369,33 @@ func (p *Plugin) RunStream(ctx context.Context, req *backend.RunStreamRequest, s
|
||||
return pluginClient.RunStream(ctx, req, sender)
|
||||
}
|
||||
|
||||
// ValidateAdmission implements backend.AdmissionHandler.
|
||||
func (p *Plugin) ValidateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.ValidationResponse, error) {
|
||||
pluginClient, ok := p.Client()
|
||||
if !ok {
|
||||
return nil, ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.ValidateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// MutateAdmission implements backend.AdmissionHandler.
|
||||
func (p *Plugin) MutateAdmission(ctx context.Context, req *backend.AdmissionRequest) (*backend.MutationResponse, error) {
|
||||
pluginClient, ok := p.Client()
|
||||
if !ok {
|
||||
return nil, ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.MutateAdmission(ctx, req)
|
||||
}
|
||||
|
||||
// ConvertObject implements backend.AdmissionHandler.
|
||||
func (p *Plugin) ConvertObject(ctx context.Context, req *backend.ConversionRequest) (*backend.ConversionResponse, error) {
|
||||
pluginClient, ok := p.Client()
|
||||
if !ok {
|
||||
return nil, ErrPluginUnavailable
|
||||
}
|
||||
return pluginClient.ConvertObject(ctx, req)
|
||||
}
|
||||
|
||||
func (p *Plugin) File(name string) (fs.File, error) {
|
||||
cleanPath, err := util.CleanRelativePath(name)
|
||||
if err != nil {
|
||||
@@ -418,6 +454,7 @@ type PluginClient interface {
|
||||
backend.CollectMetricsHandler
|
||||
backend.CheckHealthHandler
|
||||
backend.CallResourceHandler
|
||||
backend.AdmissionHandler
|
||||
backend.StreamHandler
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user