From a984449747af91dbf77239efea4c5afe2b9dcc71 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 00:50:21 +0100 Subject: [PATCH 01/13] Rename Policy to VerificationPolicy for readability --- config/constants.go | 10 +++++----- config/getters.go | 2 +- plugin/plugin_registry.go | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/constants.go b/config/constants.go index 677f2d2b..9861b4f7 100644 --- a/config/constants.go +++ b/config/constants.go @@ -3,10 +3,10 @@ package config import "time" type ( - Status uint - Policy uint - CompatPolicy uint - LogOutput uint + Status uint + VerificationPolicy uint + CompatPolicy uint + LogOutput uint ) // Status is the status of the server. @@ -18,7 +18,7 @@ const ( // Policy is the policy for hook verification. const ( // Non-strict (permissive) mode. - PassDown Policy = iota // Pass down the extra keys/values in result to the next plugins + PassDown VerificationPolicy = iota // Pass down the extra keys/values in result to the next plugins // Strict mode. Ignore // Ignore errors and continue Abort // Abort on first error and return results diff --git a/config/getters.go b/config/getters.go index 4ab949f0..80e67d6a 100644 --- a/config/getters.go +++ b/config/getters.go @@ -6,7 +6,7 @@ import ( ) // GetVerificationPolicy returns the hook verification policy from plugin config file. -func (p PluginConfig) GetVerificationPolicy() Policy { +func (p PluginConfig) GetVerificationPolicy() VerificationPolicy { switch p.VerificationPolicy { case "ignore": return Ignore diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 57c2b03d..926278f1 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -36,7 +36,7 @@ type IRegistry interface { ctx context.Context, args map[string]interface{}, hookName string, - verification config.Policy, + verification config.VerificationPolicy, opts ...grpc.CallOption, ) (map[string]interface{}, *gerr.GatewayDError) } @@ -47,7 +47,7 @@ type Registry struct { Logger zerolog.Logger CompatPolicy config.CompatPolicy - Verification config.Policy + Verification config.VerificationPolicy } var _ IRegistry = &Registry{} @@ -55,7 +55,7 @@ var _ IRegistry = &Registry{} // NewRegistry creates a new plugin registry. func NewRegistry( compatPolicy config.CompatPolicy, - verification config.Policy, + verification config.VerificationPolicy, logger zerolog.Logger, ) *Registry { return &Registry{ @@ -191,7 +191,7 @@ func (reg *Registry) Run( ctx context.Context, args map[string]interface{}, hookName string, - verification config.Policy, + verification config.VerificationPolicy, opts ...grpc.CallOption, ) (map[string]interface{}, *gerr.GatewayDError) { if ctx == nil { From 7924725a9c62d026c7eab70ea75657d6d3c7f9db Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 00:55:36 +0100 Subject: [PATCH 02/13] Rename CompatPolicy to CompatibilityPolicy --- cmd/run.go | 2 +- config/constants.go | 14 +++++++------- config/getters.go | 4 ++-- plugin/plugin_registry.go | 20 ++++++++++---------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 790cbc07..f8ea0095 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -64,7 +64,7 @@ var runCmd = &cobra.Command{ } // Set the plugin compatibility policy. - pluginRegistry.CompatPolicy = pConfig.GetPluginCompatPolicy() + pluginRegistry.CompatibilityPolicy = pConfig.GetPluginCompatibilityPolicy() // Load plugins and register their hooks. pluginRegistry.LoadPlugins(pConfig.Plugins) diff --git a/config/constants.go b/config/constants.go index 9861b4f7..05962928 100644 --- a/config/constants.go +++ b/config/constants.go @@ -3,10 +3,10 @@ package config import "time" type ( - Status uint - VerificationPolicy uint - CompatPolicy uint - LogOutput uint + Status uint + VerificationPolicy uint + CompatibilityPolicy uint + LogOutput uint ) // Status is the status of the server. @@ -25,10 +25,10 @@ const ( Remove // Remove the hook from the list on error and continue ) -// CompatPolicy is the compatibility policy for plugins. +// CompatibilityPolicy is the compatibility policy for plugins. const ( - Strict CompatPolicy = iota - Loose + Strict CompatibilityPolicy = iota // Expect all required plugins to be loaded and present + Loose // Load the plugin, even if the requirements are not met ) // LogOutput is the output type for the logger. diff --git a/config/getters.go b/config/getters.go index 80e67d6a..5bff22f7 100644 --- a/config/getters.go +++ b/config/getters.go @@ -19,8 +19,8 @@ func (p PluginConfig) GetVerificationPolicy() VerificationPolicy { } } -// GetPluginCompatPolicy returns the plugin compatibility policy from plugin config file. -func (p PluginConfig) GetPluginCompatPolicy() CompatPolicy { +// GetPluginCompatibilityPolicy returns the plugin compatibility policy from plugin config file. +func (p PluginConfig) GetPluginCompatibilityPolicy() CompatibilityPolicy { switch p.CompatibilityPolicy { case "strict": return Strict diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 926278f1..020229cb 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -45,25 +45,25 @@ type Registry struct { plugins pool.IPool hooks map[string]map[Priority]Method - Logger zerolog.Logger - CompatPolicy config.CompatPolicy - Verification config.VerificationPolicy + Logger zerolog.Logger + CompatibilityPolicy config.CompatibilityPolicy + Verification config.VerificationPolicy } var _ IRegistry = &Registry{} // NewRegistry creates a new plugin registry. func NewRegistry( - compatPolicy config.CompatPolicy, + compatibilityPolicy config.CompatibilityPolicy, verification config.VerificationPolicy, logger zerolog.Logger, ) *Registry { return &Registry{ - plugins: pool.NewPool(config.EmptyPoolCapacity), - hooks: map[string]map[Priority]Method{}, - Logger: logger, - CompatPolicy: compatPolicy, - Verification: verification, + plugins: pool.NewPool(config.EmptyPoolCapacity), + hooks: map[string]map[Priority]Method{}, + Logger: logger, + CompatibilityPolicy: compatibilityPolicy, + Verification: verification, } } @@ -437,7 +437,7 @@ func (reg *Registry) LoadPlugins(plugins []config.Plugin) { "requirement": req.Name, }, ).Msg("The plugin requirement is not met, so it won't work properly") - if reg.CompatPolicy == config.Strict { + if reg.CompatibilityPolicy == config.Strict { reg.Logger.Debug().Str("name", plugin.ID.Name).Msg( "Registry is in strict compatibility mode, so the plugin won't be loaded") plugin.Stop() // Stop the plugin. From e16ecedad89f500948a0cb99df71d45d2062bd8d Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:02:51 +0100 Subject: [PATCH 03/13] Rename struct field --- cmd/run.go | 2 +- plugin/plugin_registry.go | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index f8ea0095..2a9142ee 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -64,7 +64,7 @@ var runCmd = &cobra.Command{ } // Set the plugin compatibility policy. - pluginRegistry.CompatibilityPolicy = pConfig.GetPluginCompatibilityPolicy() + pluginRegistry.Compatibility = pConfig.GetPluginCompatibilityPolicy() // Load plugins and register their hooks. pluginRegistry.LoadPlugins(pConfig.Plugins) diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 020229cb..68f66a49 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -45,25 +45,25 @@ type Registry struct { plugins pool.IPool hooks map[string]map[Priority]Method - Logger zerolog.Logger - CompatibilityPolicy config.CompatibilityPolicy - Verification config.VerificationPolicy + Logger zerolog.Logger + Compatibility config.CompatibilityPolicy + Verification config.VerificationPolicy } var _ IRegistry = &Registry{} // NewRegistry creates a new plugin registry. func NewRegistry( - compatibilityPolicy config.CompatibilityPolicy, + compatibility config.CompatibilityPolicy, verification config.VerificationPolicy, logger zerolog.Logger, ) *Registry { return &Registry{ - plugins: pool.NewPool(config.EmptyPoolCapacity), - hooks: map[string]map[Priority]Method{}, - Logger: logger, - CompatibilityPolicy: compatibilityPolicy, - Verification: verification, + plugins: pool.NewPool(config.EmptyPoolCapacity), + hooks: map[string]map[Priority]Method{}, + Logger: logger, + Compatibility: compatibility, + Verification: verification, } } @@ -437,7 +437,7 @@ func (reg *Registry) LoadPlugins(plugins []config.Plugin) { "requirement": req.Name, }, ).Msg("The plugin requirement is not met, so it won't work properly") - if reg.CompatibilityPolicy == config.Strict { + if reg.Compatibility == config.Strict { reg.Logger.Debug().Str("name", plugin.ID.Name).Msg( "Registry is in strict compatibility mode, so the plugin won't be loaded") plugin.Stop() // Stop the plugin. From 6adafc6aa5578e5443306932452a5265c6af9dd2 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:23:09 +0100 Subject: [PATCH 04/13] Add acceptance policy for custom hooks --- config/constants.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/constants.go b/config/constants.go index 05962928..03d9b254 100644 --- a/config/constants.go +++ b/config/constants.go @@ -6,6 +6,7 @@ type ( Status uint VerificationPolicy uint CompatibilityPolicy uint + AcceptancePolicy uint LogOutput uint ) @@ -31,6 +32,12 @@ const ( Loose // Load the plugin, even if the requirements are not met ) +// AcceptancePolicy is the acceptance policy for custom hooks. +const ( + Accept AcceptancePolicy = iota // Accept all custom hooks + Reject // Reject all custom hooks +) + // LogOutput is the output type for the logger. const ( Console LogOutput = iota From 7fa90134e6b97751f6f381293f55b1c41b1431a1 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:23:56 +0100 Subject: [PATCH 05/13] Add acceptance policy and its getter to the plugin config struct --- config/getters.go | 12 ++++++++++++ config/types.go | 1 + 2 files changed, 13 insertions(+) diff --git a/config/getters.go b/config/getters.go index 5bff22f7..c1e2d2d7 100644 --- a/config/getters.go +++ b/config/getters.go @@ -31,6 +31,18 @@ func (p PluginConfig) GetPluginCompatibilityPolicy() CompatibilityPolicy { } } +// GetAcceptancePolicy returns the acceptance policy from plugin config file. +func (p PluginConfig) GetAcceptancePolicy() AcceptancePolicy { + switch p.AcceptancePolicy { + case "accept": + return Accept + case "reject": + return Reject + default: + return Accept + } +} + // GetLoadBalancer returns the load balancing algorithm to use. func (s Server) GetLoadBalancer() gnet.LoadBalancing { switch s.LoadBalancer { diff --git a/config/types.go b/config/types.go index cc1c74b3..2f9a644f 100644 --- a/config/types.go +++ b/config/types.go @@ -32,6 +32,7 @@ type Plugin struct { type PluginConfig struct { VerificationPolicy string `koanf:"verificationPolicy"` CompatibilityPolicy string `koanf:"compatibilityPolicy"` + AcceptancePolicy string `koanf:"acceptancePolicy"` Plugins []Plugin `koanf:"plugins"` } From b8c57a88707df75d3bfb812f857d4bd06a852257 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:25:20 +0100 Subject: [PATCH 06/13] Implement custom hook acceptance policy --- cmd/run.go | 11 ++++--- plugin/plugin_registry.go | 26 +++++++++++---- plugin/v1/plugin.pb.go | 66 ++++++++++++++++++++----------------- plugin/v1/plugin.proto | 1 + plugin/v1/plugin_grpc.pb.go | 36 ++++++++++++++++++++ 5 files changed, 99 insertions(+), 41 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 2a9142ee..0fbbb732 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -30,7 +30,7 @@ var ( }, ) // The plugins are loaded and hooks registered before the configuration is loaded. - pluginRegistry = plugin.NewRegistry(config.Loose, config.PassDown, DefaultLogger) + pluginRegistry = plugin.NewRegistry(config.Loose, config.PassDown, config.Accept, DefaultLogger) // Global koanf instance. Using "." as the key path delimiter. globalConfig = koanf.New(".") // Plugin koanf instance. Using "." as the key path delimiter. @@ -63,8 +63,12 @@ var runCmd = &cobra.Command{ os.Exit(gerr.FailedToLoadPluginConfig) } - // Set the plugin compatibility policy. + // Set the plugin requirement's compatibility policy. pluginRegistry.Compatibility = pConfig.GetPluginCompatibilityPolicy() + // Set hooks' signature verification policy. + pluginRegistry.Verification = pConfig.GetVerificationPolicy() + // Set custom hook acceptance policy. + pluginRegistry.Acceptance = pConfig.GetAcceptancePolicy() // Load plugins and register their hooks. pluginRegistry.LoadPlugins(pConfig.Plugins) @@ -84,9 +88,6 @@ var runCmd = &cobra.Command{ // Load environment variables for the global configuration. config.LoadEnvVars(globalConfig) - // Get hooks signature verification policy. - pluginRegistry.Verification = pConfig.GetVerificationPolicy() - // Unmarshal the global configuration for easier access. var gConfig config.GlobalConfig if err := globalConfig.Unmarshal("", &gConfig); err != nil { diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 68f66a49..c8374f0e 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -48,6 +48,7 @@ type Registry struct { Logger zerolog.Logger Compatibility config.CompatibilityPolicy Verification config.VerificationPolicy + Acceptance config.AcceptancePolicy } var _ IRegistry = &Registry{} @@ -56,6 +57,7 @@ var _ IRegistry = &Registry{} func NewRegistry( compatibility config.CompatibilityPolicy, verification config.VerificationPolicy, + acceptance config.AcceptancePolicy, logger zerolog.Logger, ) *Registry { return &Registry{ @@ -64,6 +66,7 @@ func NewRegistry( Logger: logger, Compatibility: compatibility, Verification: verification, + Acceptance: acceptance, } } @@ -552,14 +555,25 @@ func (reg *Registry) RegisterHooks(id Identifier) { case OnNewClient: hookMethod = pluginV1.OnNewClient default: - reg.Logger.Warn().Fields(map[string]interface{}{ - "hook": hookName, - "priority": pluginImpl.Priority, - "name": pluginImpl.ID.Name, - }).Msg( - "Unknown hook, skipping") + switch reg.Acceptance { + case config.Reject: + reg.Logger.Warn().Fields(map[string]interface{}{ + "hook": hookName, + "priority": pluginImpl.Priority, + "name": pluginImpl.ID.Name, + }).Msg("Unknown hook, skipping") + default: + // Default is to accept custom hooks. + reg.Logger.Warn().Fields(map[string]interface{}{ + "hook": hookName, + "priority": pluginImpl.Priority, + "name": pluginImpl.ID.Name, + }).Msg("Registering a custom hook") + reg.AddHook(hookName, pluginImpl.Priority, pluginV1.OnHook) + } continue } + reg.Logger.Debug().Fields(map[string]interface{}{ "hook": hookName, "priority": pluginImpl.Priority, diff --git a/plugin/v1/plugin.pb.go b/plugin/v1/plugin.pb.go index e7c71a4a..874d3891 100644 --- a/plugin/v1/plugin.pb.go +++ b/plugin/v1/plugin.pb.go @@ -259,7 +259,7 @@ var file_plugin_v1_plugin_proto_rawDesc = []byte{ 0x69, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xad, 0x0b, 0x0a, 0x15, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xe9, 0x0b, 0x0a, 0x15, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, @@ -350,11 +350,15 @@ var file_plugin_v1_plugin_proto_rawDesc = []byte{ 0x65, 0x6e, 0x74, 0x12, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x64, 0x2d, 0x69, 0x6f, 0x2f, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x64, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3a, 0x0a, 0x06, 0x4f, 0x6e, 0x48, 0x6f, 0x6f, 0x6b, 0x12, + 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x64, 0x2d, 0x69, 0x6f, 0x2f, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x64, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -403,30 +407,32 @@ var file_plugin_v1_plugin_proto_depIdxs = []int32{ 4, // 22: plugin.v1.GatewayDPluginService.OnShutdown:input_type -> google.protobuf.Struct 4, // 23: plugin.v1.GatewayDPluginService.OnTick:input_type -> google.protobuf.Struct 4, // 24: plugin.v1.GatewayDPluginService.OnNewClient:input_type -> google.protobuf.Struct - 4, // 25: plugin.v1.GatewayDPluginService.GetPluginConfig:output_type -> google.protobuf.Struct - 4, // 26: plugin.v1.GatewayDPluginService.OnConfigLoaded:output_type -> google.protobuf.Struct - 4, // 27: plugin.v1.GatewayDPluginService.OnNewLogger:output_type -> google.protobuf.Struct - 4, // 28: plugin.v1.GatewayDPluginService.OnNewPool:output_type -> google.protobuf.Struct - 4, // 29: plugin.v1.GatewayDPluginService.OnNewProxy:output_type -> google.protobuf.Struct - 4, // 30: plugin.v1.GatewayDPluginService.OnNewServer:output_type -> google.protobuf.Struct - 4, // 31: plugin.v1.GatewayDPluginService.OnSignal:output_type -> google.protobuf.Struct - 4, // 32: plugin.v1.GatewayDPluginService.OnRun:output_type -> google.protobuf.Struct - 4, // 33: plugin.v1.GatewayDPluginService.OnBooting:output_type -> google.protobuf.Struct - 4, // 34: plugin.v1.GatewayDPluginService.OnBooted:output_type -> google.protobuf.Struct - 4, // 35: plugin.v1.GatewayDPluginService.OnOpening:output_type -> google.protobuf.Struct - 4, // 36: plugin.v1.GatewayDPluginService.OnOpened:output_type -> google.protobuf.Struct - 4, // 37: plugin.v1.GatewayDPluginService.OnClosing:output_type -> google.protobuf.Struct - 4, // 38: plugin.v1.GatewayDPluginService.OnClosed:output_type -> google.protobuf.Struct - 4, // 39: plugin.v1.GatewayDPluginService.OnTraffic:output_type -> google.protobuf.Struct - 4, // 40: plugin.v1.GatewayDPluginService.OnTrafficFromClient:output_type -> google.protobuf.Struct - 4, // 41: plugin.v1.GatewayDPluginService.OnTrafficToServer:output_type -> google.protobuf.Struct - 4, // 42: plugin.v1.GatewayDPluginService.OnTrafficFromServer:output_type -> google.protobuf.Struct - 4, // 43: plugin.v1.GatewayDPluginService.OnTrafficToClient:output_type -> google.protobuf.Struct - 4, // 44: plugin.v1.GatewayDPluginService.OnShutdown:output_type -> google.protobuf.Struct - 4, // 45: plugin.v1.GatewayDPluginService.OnTick:output_type -> google.protobuf.Struct - 4, // 46: plugin.v1.GatewayDPluginService.OnNewClient:output_type -> google.protobuf.Struct - 25, // [25:47] is the sub-list for method output_type - 3, // [3:25] is the sub-list for method input_type + 4, // 25: plugin.v1.GatewayDPluginService.OnHook:input_type -> google.protobuf.Struct + 4, // 26: plugin.v1.GatewayDPluginService.GetPluginConfig:output_type -> google.protobuf.Struct + 4, // 27: plugin.v1.GatewayDPluginService.OnConfigLoaded:output_type -> google.protobuf.Struct + 4, // 28: plugin.v1.GatewayDPluginService.OnNewLogger:output_type -> google.protobuf.Struct + 4, // 29: plugin.v1.GatewayDPluginService.OnNewPool:output_type -> google.protobuf.Struct + 4, // 30: plugin.v1.GatewayDPluginService.OnNewProxy:output_type -> google.protobuf.Struct + 4, // 31: plugin.v1.GatewayDPluginService.OnNewServer:output_type -> google.protobuf.Struct + 4, // 32: plugin.v1.GatewayDPluginService.OnSignal:output_type -> google.protobuf.Struct + 4, // 33: plugin.v1.GatewayDPluginService.OnRun:output_type -> google.protobuf.Struct + 4, // 34: plugin.v1.GatewayDPluginService.OnBooting:output_type -> google.protobuf.Struct + 4, // 35: plugin.v1.GatewayDPluginService.OnBooted:output_type -> google.protobuf.Struct + 4, // 36: plugin.v1.GatewayDPluginService.OnOpening:output_type -> google.protobuf.Struct + 4, // 37: plugin.v1.GatewayDPluginService.OnOpened:output_type -> google.protobuf.Struct + 4, // 38: plugin.v1.GatewayDPluginService.OnClosing:output_type -> google.protobuf.Struct + 4, // 39: plugin.v1.GatewayDPluginService.OnClosed:output_type -> google.protobuf.Struct + 4, // 40: plugin.v1.GatewayDPluginService.OnTraffic:output_type -> google.protobuf.Struct + 4, // 41: plugin.v1.GatewayDPluginService.OnTrafficFromClient:output_type -> google.protobuf.Struct + 4, // 42: plugin.v1.GatewayDPluginService.OnTrafficToServer:output_type -> google.protobuf.Struct + 4, // 43: plugin.v1.GatewayDPluginService.OnTrafficFromServer:output_type -> google.protobuf.Struct + 4, // 44: plugin.v1.GatewayDPluginService.OnTrafficToClient:output_type -> google.protobuf.Struct + 4, // 45: plugin.v1.GatewayDPluginService.OnShutdown:output_type -> google.protobuf.Struct + 4, // 46: plugin.v1.GatewayDPluginService.OnTick:output_type -> google.protobuf.Struct + 4, // 47: plugin.v1.GatewayDPluginService.OnNewClient:output_type -> google.protobuf.Struct + 4, // 48: plugin.v1.GatewayDPluginService.OnHook:output_type -> google.protobuf.Struct + 26, // [26:49] is the sub-list for method output_type + 3, // [3:26] is the sub-list for method input_type 3, // [3:3] is the sub-list for extension type_name 3, // [3:3] is the sub-list for extension extendee 0, // [0:3] is the sub-list for field type_name diff --git a/plugin/v1/plugin.proto b/plugin/v1/plugin.proto index 5c370b62..a487a0cd 100644 --- a/plugin/v1/plugin.proto +++ b/plugin/v1/plugin.proto @@ -32,6 +32,7 @@ service GatewayDPluginService { rpc OnShutdown (google.protobuf.Struct) returns (google.protobuf.Struct); rpc OnTick (google.protobuf.Struct) returns (google.protobuf.Struct); rpc OnNewClient (google.protobuf.Struct) returns (google.protobuf.Struct); + rpc OnHook (google.protobuf.Struct) returns (google.protobuf.Struct); // Custom hook } message PluginID { diff --git a/plugin/v1/plugin_grpc.pb.go b/plugin/v1/plugin_grpc.pb.go index 1a21da26..3b85d40a 100644 --- a/plugin/v1/plugin_grpc.pb.go +++ b/plugin/v1/plugin_grpc.pb.go @@ -47,6 +47,7 @@ type GatewayDPluginServiceClient interface { OnShutdown(ctx context.Context, in *structpb.Struct, opts ...grpc.CallOption) (*structpb.Struct, error) OnTick(ctx context.Context, in *structpb.Struct, opts ...grpc.CallOption) (*structpb.Struct, error) OnNewClient(ctx context.Context, in *structpb.Struct, opts ...grpc.CallOption) (*structpb.Struct, error) + OnHook(ctx context.Context, in *structpb.Struct, opts ...grpc.CallOption) (*structpb.Struct, error) } type gatewayDPluginServiceClient struct { @@ -255,6 +256,15 @@ func (c *gatewayDPluginServiceClient) OnNewClient(ctx context.Context, in *struc return out, nil } +func (c *gatewayDPluginServiceClient) OnHook(ctx context.Context, in *structpb.Struct, opts ...grpc.CallOption) (*structpb.Struct, error) { + out := new(structpb.Struct) + err := c.cc.Invoke(ctx, "/plugin.v1.GatewayDPluginService/OnHook", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // GatewayDPluginServiceServer is the server API for GatewayDPluginService service. // All implementations must embed UnimplementedGatewayDPluginServiceServer // for forward compatibility @@ -283,6 +293,7 @@ type GatewayDPluginServiceServer interface { OnShutdown(context.Context, *structpb.Struct) (*structpb.Struct, error) OnTick(context.Context, *structpb.Struct) (*structpb.Struct, error) OnNewClient(context.Context, *structpb.Struct) (*structpb.Struct, error) + OnHook(context.Context, *structpb.Struct) (*structpb.Struct, error) mustEmbedUnimplementedGatewayDPluginServiceServer() } @@ -356,6 +367,9 @@ func (UnimplementedGatewayDPluginServiceServer) OnTick(context.Context, *structp func (UnimplementedGatewayDPluginServiceServer) OnNewClient(context.Context, *structpb.Struct) (*structpb.Struct, error) { return nil, status.Errorf(codes.Unimplemented, "method OnNewClient not implemented") } +func (UnimplementedGatewayDPluginServiceServer) OnHook(context.Context, *structpb.Struct) (*structpb.Struct, error) { + return nil, status.Errorf(codes.Unimplemented, "method OnHook not implemented") +} func (UnimplementedGatewayDPluginServiceServer) mustEmbedUnimplementedGatewayDPluginServiceServer() {} // UnsafeGatewayDPluginServiceServer may be embedded to opt out of forward compatibility for this service. @@ -765,6 +779,24 @@ func _GatewayDPluginService_OnNewClient_Handler(srv interface{}, ctx context.Con return interceptor(ctx, in, info, handler) } +func _GatewayDPluginService_OnHook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(structpb.Struct) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayDPluginServiceServer).OnHook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/plugin.v1.GatewayDPluginService/OnHook", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayDPluginServiceServer).OnHook(ctx, req.(*structpb.Struct)) + } + return interceptor(ctx, in, info, handler) +} + // GatewayDPluginService_ServiceDesc is the grpc.ServiceDesc for GatewayDPluginService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -860,6 +892,10 @@ var GatewayDPluginService_ServiceDesc = grpc.ServiceDesc{ MethodName: "OnNewClient", Handler: _GatewayDPluginService_OnNewClient_Handler, }, + { + MethodName: "OnHook", + Handler: _GatewayDPluginService_OnHook_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "plugin/v1/plugin.proto", From 3e4f6a9a85b59ae1a7596481333c42fc3a9bd518 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:27:00 +0100 Subject: [PATCH 07/13] Add default acceptance policy to the plugin config file --- gatewayd_plugins.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gatewayd_plugins.yaml b/gatewayd_plugins.yaml index 5002d0e2..35d34abc 100644 --- a/gatewayd_plugins.yaml +++ b/gatewayd_plugins.yaml @@ -4,6 +4,8 @@ verificationPolicy: "passdown" # Possible values: "strict" (default) and "loose" compatibilityPolicy: "strict" +# Possible values: "accept" (default) and "reject" +acceptancePolicy: "accept" plugins: # Plugin name From 5f81e6901396c32278aae5f840680faf239263df Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:27:40 +0100 Subject: [PATCH 08/13] Update tests to add hook acceptance policy --- network/proxy_test.go | 4 ++-- network/server_test.go | 2 +- plugin/plugin_registry_test.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/network/proxy_test.go b/network/proxy_test.go index 4d5b4ccc..746cd8a6 100644 --- a/network/proxy_test.go +++ b/network/proxy_test.go @@ -54,7 +54,7 @@ func TestNewProxy(t *testing.T) { // Create a proxy with a fixed buffer pool proxy := NewProxy(pool, - plugin.NewRegistry(config.Loose, config.PassDown, logger), + plugin.NewRegistry(config.Loose, config.PassDown, config.Accept, logger), false, false, config.DefaultHealthCheckPeriod, @@ -89,7 +89,7 @@ func TestNewProxyElastic(t *testing.T) { // Create a proxy with an elastic buffer pool proxy := NewProxy(pool, - plugin.NewRegistry(config.Loose, config.PassDown, logger), + plugin.NewRegistry(config.Loose, config.PassDown, config.Accept, logger), true, false, config.DefaultHealthCheckPeriod, diff --git a/network/server_test.go b/network/server_test.go index 4193f45f..842245d5 100644 --- a/network/server_test.go +++ b/network/server_test.go @@ -39,7 +39,7 @@ func TestRunServer(t *testing.T) { logger := logging.NewLogger(cfg) - pluginRegistry := plugin.NewRegistry(config.Loose, config.PassDown, logger) + pluginRegistry := plugin.NewRegistry(config.Loose, config.PassDown, config.Accept, logger) onTrafficFromClient := func( ctx context.Context, diff --git a/plugin/plugin_registry_test.go b/plugin/plugin_registry_test.go index 48f91ad9..e90eec4d 100644 --- a/plugin/plugin_registry_test.go +++ b/plugin/plugin_registry_test.go @@ -22,7 +22,7 @@ func NewPluginRegistry(t *testing.T) *Registry { NoColor: true, } logger := logging.NewLogger(cfg) - reg := NewRegistry(config.Loose, config.PassDown, logger) + reg := NewRegistry(config.Loose, config.PassDown, config.Accept, logger) return reg } From e2bea9bbb6b837807bf329fb53f64147776665ca Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:32:29 +0100 Subject: [PATCH 09/13] Add missing switch case --- plugin/plugin_registry.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index c8374f0e..889d5cff 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -562,6 +562,7 @@ func (reg *Registry) RegisterHooks(id Identifier) { "priority": pluginImpl.Priority, "name": pluginImpl.ID.Name, }).Msg("Unknown hook, skipping") + case config.Accept: // fallthrough default: // Default is to accept custom hooks. reg.Logger.Warn().Fields(map[string]interface{}{ From 4a2495ff6cdc9cf931adf3122c39407f089312db Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:47:31 +0100 Subject: [PATCH 10/13] Add info log to notify of plugin being ready --- plugin/plugin_registry.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 889d5cff..5135e204 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -491,6 +491,8 @@ func (reg *Registry) LoadPlugins(plugins []config.Plugin) { reg.RegisterHooks(plugin.ID) reg.Logger.Debug().Str("name", plugin.ID.Name).Msg("Plugin hooks registered") + + reg.Logger.Info().Str("name", plugin.ID.Name).Msg("Plugin is ready") } } From a710792e915b52408bbe514e40d29d8128a078d3 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:47:45 +0100 Subject: [PATCH 11/13] Update checksums --- gatewayd_plugins.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gatewayd_plugins.yaml b/gatewayd_plugins.yaml index 35d34abc..3989a758 100644 --- a/gatewayd_plugins.yaml +++ b/gatewayd_plugins.yaml @@ -25,7 +25,7 @@ plugins: - MAGIC_COOKIE_KEY=GATEWAYD_PLUGIN - MAGIC_COOKIE_VALUE=5712b87aa5d7e9f9e9ab643e6603181c5b796015cb1c09d6f5ada882bf2a1872 # Checksum hash to verify the binary before loading - checksum: 8c68bc8ca7a759637579330460a60ca785d659da567b95187f154723b1aa519c + checksum: b1cfe3c6b268d904abe405b106ef737da5373912586ff8a16695939c38caf30d - name: gatewayd-plugin-cache enabled: True localPath: ../gatewayd-plugin-cache/gatewayd-plugin-cache @@ -34,4 +34,4 @@ plugins: - MAGIC_COOKIE_KEY=GATEWAYD_PLUGIN - MAGIC_COOKIE_VALUE=5712b87aa5d7e9f9e9ab643e6603181c5b796015cb1c09d6f5ada882bf2a1872 - REDIS_ADDR=localhost:6379 - checksum: a0b62927f8330638a2b9a36d843580b784b927a12addb76eabb25d0cec7c6b57 + checksum: 0c55ed414432afd6db2fbe284112046b6ce4d70b7beb5b99d3703f4bbbcb5a84 From 329cab8334f8f254487d005b37e60130454c75ac Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 01:49:32 +0100 Subject: [PATCH 12/13] Lower log level --- plugin/plugin_registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 5135e204..9ceb06c5 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -567,7 +567,7 @@ func (reg *Registry) RegisterHooks(id Identifier) { case config.Accept: // fallthrough default: // Default is to accept custom hooks. - reg.Logger.Warn().Fields(map[string]interface{}{ + reg.Logger.Debug().Fields(map[string]interface{}{ "hook": hookName, "priority": pluginImpl.Priority, "name": pluginImpl.ID.Name, From 938296c9617f448fb27da6358d3f1e8e1702ffa5 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 14 Jan 2023 02:07:33 +0100 Subject: [PATCH 13/13] Use plugin registry's verification policy --- cmd/run.go | 22 ++++++---------------- network/proxy.go | 12 ++++-------- network/server.go | 30 ++++++++++-------------------- plugin/plugin_registry.go | 6 ++---- plugin/plugin_registry_test.go | 24 ++++++++++++------------ 5 files changed, 34 insertions(+), 60 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 0fbbb732..461ff3ea 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -101,8 +101,7 @@ var runCmd = &cobra.Command{ updatedGlobalConfig, err := pluginRegistry.Run( context.Background(), globalConfig.All(), - plugin.OnConfigLoaded, - pluginRegistry.Verification) + plugin.OnConfigLoaded) if err != nil { DefaultLogger.Error().Err(err).Msg("Failed to run OnConfigLoaded hooks") } @@ -146,8 +145,7 @@ var runCmd = &cobra.Command{ "fileName": loggerCfg.FileName, } // TODO: Use a context with a timeout - _, err = pluginRegistry.Run( - context.Background(), data, plugin.OnNewLogger, pluginRegistry.Verification) + _, err = pluginRegistry.Run(context.Background(), data, plugin.OnNewLogger) if err != nil { logger.Error().Err(err).Msg("Failed to run OnNewLogger hooks") } @@ -175,11 +173,7 @@ var runCmd = &cobra.Command{ "tcpKeepAlive": client.TCPKeepAlive, "tcpKeepAlivePeriod": client.TCPKeepAlivePeriod.String(), } - _, err := pluginRegistry.Run( - context.Background(), - clientCfg, - plugin.OnNewClient, - pluginRegistry.Verification) + _, err := pluginRegistry.Run(context.Background(), clientCfg, plugin.OnNewClient) if err != nil { logger.Error().Err(err).Msg("Failed to run OnNewClient hooks") } @@ -206,8 +200,7 @@ var runCmd = &cobra.Command{ _, err = pluginRegistry.Run( context.Background(), map[string]interface{}{"size": poolSize}, - plugin.OnNewPool, - pluginRegistry.Verification) + plugin.OnNewPool) if err != nil { logger.Error().Err(err).Msg("Failed to run OnNewPool hooks") } @@ -241,8 +234,7 @@ var runCmd = &cobra.Command{ "tcpKeepAlivePeriod": clientConfig.TCPKeepAlivePeriod.String(), }, } - _, err = pluginRegistry.Run( - context.Background(), proxyCfg, plugin.OnNewProxy, pluginRegistry.Verification) + _, err = pluginRegistry.Run(context.Background(), proxyCfg, plugin.OnNewProxy) if err != nil { logger.Error().Err(err).Msg("Failed to run OnNewProxy hooks") } @@ -303,8 +295,7 @@ var runCmd = &cobra.Command{ "tcpKeepAlive": gConfig.Server.TCPKeepAlive.String(), "tcpNoDelay": gConfig.Server.TCPNoDelay, } - _, err = pluginRegistry.Run( - context.Background(), serverCfg, plugin.OnNewServer, pluginRegistry.Verification) + _, err = pluginRegistry.Run(context.Background(), serverCfg, plugin.OnNewServer) if err != nil { logger.Error().Err(err).Msg("Failed to run OnNewServer hooks") } @@ -331,7 +322,6 @@ var runCmd = &cobra.Command{ context.Background(), map[string]interface{}{"signal": sig.String()}, plugin.OnSignal, - pluginRegistry.Verification, ) if err != nil { logger.Error().Err(err).Msg("Failed to run OnSignal hooks") diff --git a/network/proxy.go b/network/proxy.go index cb3ec7e1..b37155f8 100644 --- a/network/proxy.go +++ b/network/proxy.go @@ -375,8 +375,7 @@ func (pr *Proxy) PassThrough(gconn gnet.Conn) *gerr.GatewayDError { }, }, origErr), - plugin.OnTrafficFromClient, - pr.pluginRegistry.Verification) + plugin.OnTrafficFromClient) if err != nil { pr.logger.Error().Err(err).Msg("Error running hook") } @@ -408,8 +407,7 @@ func (pr *Proxy) PassThrough(gconn gnet.Conn) *gerr.GatewayDError { }, }, err), - plugin.OnTrafficToServer, - pr.pluginRegistry.Verification) + plugin.OnTrafficToServer) if err != nil { pr.logger.Error().Err(err).Msg("Error running hook") } @@ -464,8 +462,7 @@ func (pr *Proxy) PassThrough(gconn gnet.Conn) *gerr.GatewayDError { }, }, err), - plugin.OnTrafficFromServer, - pr.pluginRegistry.Verification) + plugin.OnTrafficFromServer) if err != nil { pr.logger.Error().Err(err).Msg("Error running hook") } @@ -498,8 +495,7 @@ func (pr *Proxy) PassThrough(gconn gnet.Conn) *gerr.GatewayDError { }, err, ), - plugin.OnTrafficToClient, - pr.pluginRegistry.Verification) + plugin.OnTrafficToClient) if err != nil { pr.logger.Error().Err(err).Msg("Error running hook") } diff --git a/network/server.go b/network/server.go index 46215ef8..e3a3b6e2 100644 --- a/network/server.go +++ b/network/server.go @@ -41,8 +41,7 @@ func (s *Server) OnBoot(engine gnet.Engine) gnet.Action { _, err := s.pluginRegistry.Run( context.Background(), map[string]interface{}{"status": fmt.Sprint(s.Status)}, - plugin.OnBooting, - s.pluginRegistry.Verification) + plugin.OnBooting) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnBooting hook") } @@ -56,8 +55,7 @@ func (s *Server) OnBoot(engine gnet.Engine) gnet.Action { _, err = s.pluginRegistry.Run( context.Background(), map[string]interface{}{"status": fmt.Sprint(s.Status)}, - plugin.OnBooted, - s.pluginRegistry.Verification) + plugin.OnBooted) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnBooted hook") } @@ -80,8 +78,7 @@ func (s *Server) OnOpen(gconn gnet.Conn) ([]byte, gnet.Action) { "remote": gconn.RemoteAddr().String(), }, } - _, err := s.pluginRegistry.Run( - context.Background(), onOpeningData, plugin.OnOpening, s.pluginRegistry.Verification) + _, err := s.pluginRegistry.Run(context.Background(), onOpeningData, plugin.OnOpening) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnOpening hook") } @@ -121,8 +118,7 @@ func (s *Server) OnOpen(gconn gnet.Conn) ([]byte, gnet.Action) { "remote": gconn.RemoteAddr().String(), }, } - _, err = s.pluginRegistry.Run( - context.Background(), onOpenedData, plugin.OnOpened, s.pluginRegistry.Verification) + _, err = s.pluginRegistry.Run(context.Background(), onOpenedData, plugin.OnOpened) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnOpened hook") } @@ -148,8 +144,7 @@ func (s *Server) OnClose(gconn gnet.Conn, err error) gnet.Action { if err != nil { data["error"] = err.Error() } - _, gatewaydErr := s.pluginRegistry.Run( - context.Background(), data, plugin.OnClosing, s.pluginRegistry.Verification) + _, gatewaydErr := s.pluginRegistry.Run(context.Background(), data, plugin.OnClosing) if gatewaydErr != nil { s.logger.Error().Err(gatewaydErr).Msg("Failed to run OnClosing hook") } @@ -179,8 +174,7 @@ func (s *Server) OnClose(gconn gnet.Conn, err error) gnet.Action { if err != nil { data["error"] = err.Error() } - _, gatewaydErr = s.pluginRegistry.Run( - context.Background(), data, plugin.OnClosed, s.pluginRegistry.Verification) + _, gatewaydErr = s.pluginRegistry.Run(context.Background(), data, plugin.OnClosed) if gatewaydErr != nil { s.logger.Error().Err(gatewaydErr).Msg("Failed to run OnClosed hook") } @@ -198,8 +192,7 @@ func (s *Server) OnTraffic(gconn gnet.Conn) gnet.Action { "remote": gconn.RemoteAddr().String(), }, } - _, err := s.pluginRegistry.Run( - context.Background(), onTrafficData, plugin.OnTraffic, s.pluginRegistry.Verification) + _, err := s.pluginRegistry.Run(context.Background(), onTrafficData, plugin.OnTraffic) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnTraffic hook") } @@ -234,8 +227,7 @@ func (s *Server) OnShutdown(engine gnet.Engine) { _, err := s.pluginRegistry.Run( context.Background(), map[string]interface{}{"connections": s.engine.CountConnections()}, - plugin.OnShutdown, - s.pluginRegistry.Verification) + plugin.OnShutdown) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnShutdown hook") } @@ -257,8 +249,7 @@ func (s *Server) OnTick() (time.Duration, gnet.Action) { _, err := s.pluginRegistry.Run( context.Background(), map[string]interface{}{"connections": s.engine.CountConnections()}, - plugin.OnTick, - s.pluginRegistry.Verification) + plugin.OnTick) if err != nil { s.logger.Error().Err(err).Msg("Failed to run OnTick hook") } @@ -284,8 +275,7 @@ func (s *Server) Run() error { if err != nil && err.Unwrap() != nil { onRunData["error"] = err.OriginalError.Error() } - result, err := s.pluginRegistry.Run( - context.Background(), onRunData, plugin.OnRun, s.pluginRegistry.Verification) + result, err := s.pluginRegistry.Run(context.Background(), onRunData, plugin.OnRun) if err != nil { s.logger.Error().Err(err).Msg("Failed to run the hook") } diff --git a/plugin/plugin_registry.go b/plugin/plugin_registry.go index 9ceb06c5..54d5b5f8 100644 --- a/plugin/plugin_registry.go +++ b/plugin/plugin_registry.go @@ -36,7 +36,6 @@ type IRegistry interface { ctx context.Context, args map[string]interface{}, hookName string, - verification config.VerificationPolicy, opts ...grpc.CallOption, ) (map[string]interface{}, *gerr.GatewayDError) } @@ -194,7 +193,6 @@ func (reg *Registry) Run( ctx context.Context, args map[string]interface{}, hookName string, - verification config.VerificationPolicy, opts ...grpc.CallOption, ) (map[string]interface{}, *gerr.GatewayDError) { if ctx == nil { @@ -244,7 +242,7 @@ func (reg *Registry) Run( // and that the hook does not return any unexpected values. // If the verification mode is non-strict (permissive), let the plugin pass // extra keys/values to the next plugin in chain. - if Verify(params, result) || verification == config.PassDown { + if Verify(params, result) || reg.Verification == config.PassDown { // Update the last return value with the current result returnVal = result continue @@ -252,7 +250,7 @@ func (reg *Registry) Run( // At this point, the hook returned an invalid value, so we need to handle it. // The result of the current hook will be ignored, regardless of the policy. - switch verification { + switch reg.Verification { // Ignore the result of this plugin, log an error and execute the next case config.Ignore: reg.Logger.Error().Err(err).Fields( diff --git a/plugin/plugin_registry_test.go b/plugin/plugin_registry_test.go index e90eec4d..96a891bb 100644 --- a/plugin/plugin_registry_test.go +++ b/plugin/plugin_registry_test.go @@ -94,6 +94,7 @@ func Test_PluginRegistry_AddHook_Multiple(t *testing.T) { // Test_HookRegistry_Run tests the Run function. func Test_PluginRegistry_Run(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.Ignore reg.AddHook(OnNewLogger, 0, func( ctx context.Context, args *structpb.Struct, @@ -101,8 +102,7 @@ func Test_PluginRegistry_Run(t *testing.T) { ) (*structpb.Struct, error) { return args, nil }) - result, err := reg.Run( - context.Background(), map[string]interface{}{}, OnNewLogger, config.Ignore) + result, err := reg.Run(context.Background(), map[string]interface{}{}, OnNewLogger) assert.NotNil(t, result) assert.Nil(t, err) } @@ -110,6 +110,7 @@ func Test_PluginRegistry_Run(t *testing.T) { // Test_HookRegistry_Run_PassDown tests the Run function with the PassDown option. func Test_PluginRegistry_Run_PassDown(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.PassDown // The result of the hook will be nil and will be passed down to the next reg.AddHook(OnNewLogger, 0, func( ctx context.Context, @@ -137,8 +138,7 @@ func Test_PluginRegistry_Run_PassDown(t *testing.T) { result, err := reg.Run( context.Background(), map[string]interface{}{"test": "test"}, - OnNewLogger, - config.PassDown) + OnNewLogger) assert.Nil(t, err) assert.NotNil(t, result) } @@ -146,6 +146,7 @@ func Test_PluginRegistry_Run_PassDown(t *testing.T) { // Test_HookRegistry_Run_PassDown_2 tests the Run function with the PassDown option. func Test_HookRegistry_Run_PassDown_2(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.PassDown // The result of the hook will be nil and will be passed down to the next reg.AddHook(OnNewLogger, 0, func( ctx context.Context, @@ -178,8 +179,7 @@ func Test_HookRegistry_Run_PassDown_2(t *testing.T) { result, err := reg.Run( context.Background(), map[string]interface{}{"test": "test"}, - OnNewLogger, - config.PassDown) + OnNewLogger) assert.Nil(t, err) assert.NotNil(t, result) } @@ -187,6 +187,7 @@ func Test_HookRegistry_Run_PassDown_2(t *testing.T) { // Test_HookRegistry_Run_Ignore tests the Run function with the Ignore option. func Test_HookRegistry_Run_Ignore(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.Ignore // This should not run, because the return value is not the same as the params reg.AddHook(OnNewLogger, 0, func( ctx context.Context, @@ -214,8 +215,7 @@ func Test_HookRegistry_Run_Ignore(t *testing.T) { result, err := reg.Run( context.Background(), map[string]interface{}{"test": "test"}, - OnNewLogger, - config.Ignore) + OnNewLogger) assert.Nil(t, err) assert.NotNil(t, result) } @@ -223,6 +223,7 @@ func Test_HookRegistry_Run_Ignore(t *testing.T) { // Test_HookRegistry_Run_Abort tests the Run function with the Abort option. func Test_HookRegistry_Run_Abort(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.Abort // This should not run, because the return value is not the same as the params reg.AddHook(OnNewLogger, 0, func( ctx context.Context, @@ -244,8 +245,7 @@ func Test_HookRegistry_Run_Abort(t *testing.T) { return output, nil }) // The first hook returns nil, and it aborts the execution of the rest of the - result, err := reg.Run( - context.Background(), map[string]interface{}{}, OnNewLogger, config.Abort) + result, err := reg.Run(context.Background(), map[string]interface{}{}, OnNewLogger) assert.Nil(t, err) assert.Equal(t, map[string]interface{}{}, result) } @@ -253,6 +253,7 @@ func Test_HookRegistry_Run_Abort(t *testing.T) { // Test_HookRegistry_Run_Remove tests the Run function with the Remove option. func Test_HookRegistry_Run_Remove(t *testing.T) { reg := NewPluginRegistry(t) + reg.Verification = config.Remove // This should not run, because the return value is not the same as the params reg.AddHook(OnNewLogger, 0, func( ctx context.Context, @@ -276,8 +277,7 @@ func Test_HookRegistry_Run_Remove(t *testing.T) { // The first hook returns nil, and its signature doesn't match the params, // so its result is ignored. The failing hook is removed from the list and // the execution continues with the next hook in the list. - result, err := reg.Run( - context.Background(), map[string]interface{}{}, OnNewLogger, config.Remove) + result, err := reg.Run(context.Background(), map[string]interface{}{}, OnNewLogger) assert.Nil(t, err) assert.Equal(t, map[string]interface{}{}, result) assert.Equal(t, 1, len(reg.Hooks()[OnNewLogger]))