Make plugin runner configurable and run only registered plugins (#944)

* Make plugin runner configurable and run only registered plugins
This commit is contained in:
Shivam Sandbhor 2021-09-08 15:06:42 +05:30 committed by GitHub
parent 1d955f4258
commit b8e24a1e0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 25 additions and 6 deletions

View file

@ -18,7 +18,7 @@ func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) {
if hasPlugins(cConfig.API.Server.Profiles) { if hasPlugins(cConfig.API.Server.Profiles) {
log.Info("initiating plugin broker") log.Info("initiating plugin broker")
err = pluginBroker.Init(cConfig.API.Server.Profiles, cConfig.ConfigPaths) err = pluginBroker.Init(cConfig.PluginConfig, cConfig.API.Server.Profiles, cConfig.ConfigPaths)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to run local API: %s", err) return nil, fmt.Errorf("unable to run local API: %s", err)
} }

View file

@ -30,6 +30,9 @@ db_config:
flush: flush:
max_items: 5000 max_items: 5000
max_age: 7d max_age: 7d
plugin_config:
user: nobody # plugin process would be ran on behalf of this user
group: nogroup # plugin process would be ran on behalf of this group
api: api:
client: client:
insecure_skip_verify: false insecure_skip_verify: false

View file

@ -22,6 +22,7 @@ type Config struct {
DbConfig *DatabaseCfg `yaml:"db_config,omitempty"` DbConfig *DatabaseCfg `yaml:"db_config,omitempty"`
API *APICfg `yaml:"api,omitempty"` API *APICfg `yaml:"api,omitempty"`
ConfigPaths *ConfigurationPaths `yaml:"config_paths,omitempty"` ConfigPaths *ConfigurationPaths `yaml:"config_paths,omitempty"`
PluginConfig *PluginCfg `yaml:"plugin_config,omitempty"`
DisableAPI bool `yaml:"-"` DisableAPI bool `yaml:"-"`
DisableAgent bool `yaml:"-"` DisableAgent bool `yaml:"-"`
Hub *Hub `yaml:"-"` Hub *Hub `yaml:"-"`

View file

@ -0,0 +1,6 @@
package csconfig
type PluginCfg struct {
User string
Group string
}

View file

@ -47,6 +47,8 @@ type PluginBroker struct {
notificationPluginByName map[string]Notifier notificationPluginByName map[string]Notifier
watcher PluginWatcher watcher PluginWatcher
pluginKillMethods []func() pluginKillMethods []func()
pluginProcConfig *csconfig.PluginCfg
pluginsTypesToDispatch map[string]struct{}
} }
// holder to determine where to dispatch config and how to format messages // holder to determine where to dispatch config and how to format messages
@ -69,7 +71,7 @@ type ProfileAlert struct {
Alert *models.Alert Alert *models.Alert
} }
func (pb *PluginBroker) Init(profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error { func (pb *PluginBroker) Init(pluginCfg *csconfig.PluginCfg, profileConfigs []*csconfig.ProfileCfg, configPaths *csconfig.ConfigurationPaths) error {
pb.PluginChannel = make(chan ProfileAlert) pb.PluginChannel = make(chan ProfileAlert)
pb.notificationConfigsByPluginType = make(map[string][][]byte) pb.notificationConfigsByPluginType = make(map[string][][]byte)
pb.notificationPluginByName = make(map[string]Notifier) pb.notificationPluginByName = make(map[string]Notifier)
@ -77,6 +79,8 @@ func (pb *PluginBroker) Init(profileConfigs []*csconfig.ProfileCfg, configPaths
pb.pluginConfigByName = make(map[string]PluginConfig) pb.pluginConfigByName = make(map[string]PluginConfig)
pb.alertsByPluginName = make(map[string][]*models.Alert) pb.alertsByPluginName = make(map[string][]*models.Alert)
pb.profileConfigs = profileConfigs pb.profileConfigs = profileConfigs
pb.pluginProcConfig = pluginCfg
pb.pluginsTypesToDispatch = make(map[string]struct{})
if err := pb.loadConfig(configPaths.NotificationDir); err != nil { if err := pb.loadConfig(configPaths.NotificationDir); err != nil {
return errors.Wrap(err, "while loading plugin config") return errors.Wrap(err, "while loading plugin config")
} }
@ -178,6 +182,7 @@ func (pb *PluginBroker) verifyPluginConfigsWithProfile() error {
if _, ok := pb.pluginConfigByName[pluginName]; !ok { if _, ok := pb.pluginConfigByName[pluginName]; !ok {
return fmt.Errorf("config file for plugin %s not found", pluginName) return fmt.Errorf("config file for plugin %s not found", pluginName)
} }
pb.pluginsTypesToDispatch[pb.pluginConfigByName[pluginName].Type] = struct{}{}
} }
} }
return nil return nil
@ -200,6 +205,10 @@ func (pb *PluginBroker) loadPlugins(path string) error {
continue continue
} }
if _, ok := pb.pluginsTypesToDispatch[pSubtype]; !ok {
continue
}
pluginClient, err := pb.loadNotificationPlugin(pSubtype, binaryPath) pluginClient, err := pb.loadNotificationPlugin(pSubtype, binaryPath)
if err != nil { if err != nil {
return err return err
@ -231,7 +240,7 @@ func (pb *PluginBroker) loadNotificationPlugin(name string, binaryPath string) (
return nil, err return nil, err
} }
cmd := exec.Command(binaryPath) cmd := exec.Command(binaryPath)
cmd.SysProcAttr, err = getProccessAtr() cmd.SysProcAttr, err = getProccessAtr(pb.pluginProcConfig.User, pb.pluginProcConfig.Group)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "while getting process attributes") return nil, errors.Wrap(err, "while getting process attributes")
} }
@ -378,12 +387,12 @@ func getPluginTypeAndSubtypeFromPath(path string) (string, string, error) {
return strings.Join(parts[:len(parts)-1], "-"), parts[len(parts)-1], nil return strings.Join(parts[:len(parts)-1], "-"), parts[len(parts)-1], nil
} }
func getProccessAtr() (*syscall.SysProcAttr, error) { func getProccessAtr(username string, groupname string) (*syscall.SysProcAttr, error) {
u, err := user.Lookup("nobody") u, err := user.Lookup(username)
if err != nil { if err != nil {
return nil, err return nil, err
} }
g, err := user.LookupGroup("nogroup") g, err := user.LookupGroup(groupname)
if err != nil { if err != nil {
return nil, err return nil, err
} }