diff --git a/router/config.go b/router/config.go index d34642442..45b37afe4 100644 --- a/router/config.go +++ b/router/config.go @@ -96,7 +96,8 @@ type Config struct { InitialDelay time.Duration } } - src map[interface{}]interface{} + Plugins []string + src map[interface{}]interface{} } func (config *Config) Configure(sub config.Subconfig) error { @@ -375,6 +376,20 @@ func LoadConfig(path string) (*Config, error) { } } + if value, found := cfgmap["plugins"]; found { + if list, ok := value.([]interface{}); ok { + for _, v := range list { + if plugin, ok := v.(string); ok { + cfg.Plugins = append(cfg.Plugins, plugin) + } else { + pfxlog.Logger().Warnf("invalid plugin value: '%v'", plugin) + } + } + } else { + pfxlog.Logger().Warn("invalid plugins value") + } + } + return cfg, nil } diff --git a/router/router.go b/router/router.go index d74e7ccef..6820fefab 100644 --- a/router/router.go +++ b/router/router.go @@ -53,6 +53,7 @@ import ( "github.com/sirupsen/logrus" "io" "math/rand" + "plugin" "time" ) @@ -136,6 +137,18 @@ func (self *Router) RegisterXctrl(x xctrl.Xctrl) error { return nil } +func (self *Router) GetVersionInfo() common.VersionProvider { + return self.versionProvider +} + +func (self *Router) GetConfig() *Config { + return self.config +} + +func (self *Router) GetMetricsRegistry() metrics.UsageRegistry { + return self.metricsRegistry +} + func (self *Router) Start() error { rand.Seed(info.NowInMilliseconds()) @@ -156,6 +169,10 @@ func (self *Router) Start() error { return err } + if err := self.registerPlugins(); err != nil { + return err + } + self.startXlinkDialers() self.startXlinkListeners() self.startXgressListeners() @@ -266,6 +283,27 @@ func (self *Router) registerComponents() error { return nil } +func (self *Router) registerPlugins() error { + for _, pluginPath := range self.config.Plugins { + goPlugin, err := plugin.Open(pluginPath) + if err != nil { + return errors.Wrapf(err, "router unable to load plugin at path %v", pluginPath) + } + initializeSymbol, err := goPlugin.Lookup("Initialize") + if err != nil { + return errors.Wrapf(err, "router plugin at %v does not contain Initialize symbol", pluginPath) + } + initialize, ok := initializeSymbol.(func(*Router) error) + if !ok { + return errors.Errorf("router plugin at %v exports Initialize symbol, but it is not of type 'func(router *router.Router) error'", pluginPath) + } + if err := initialize(self); err != nil { + return errors.Wrapf(err, "error initializing router plugin at %v", pluginPath) + } + } + return nil +} + func (self *Router) startXlinkDialers() { for _, lmap := range self.config.Link.Dialers { binding := lmap["binding"].(string)