Browse Source

refact "cscli notifications"

marco 1 year ago
parent
commit
1b592a6fe6
2 changed files with 64 additions and 56 deletions
  1. 1 1
      cmd/crowdsec-cli/main.go
  2. 63 55
      cmd/crowdsec-cli/notifications.go

+ 1 - 1
cmd/crowdsec-cli/main.go

@@ -246,7 +246,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
 	cmd.AddCommand(NewConsoleCmd())
 	cmd.AddCommand(NewConsoleCmd())
 	cmd.AddCommand(NewCLIExplain().NewCommand())
 	cmd.AddCommand(NewCLIExplain().NewCommand())
 	cmd.AddCommand(NewCLIHubTest().NewCommand())
 	cmd.AddCommand(NewCLIHubTest().NewCommand())
-	cmd.AddCommand(NewCLINotifications().NewCommand())
+	cmd.AddCommand(NewCLINotifications(cli.cfg).NewCommand())
 	cmd.AddCommand(NewCLISupport().NewCommand())
 	cmd.AddCommand(NewCLISupport().NewCommand())
 	cmd.AddCommand(NewCLIPapi(cli.cfg).NewCommand())
 	cmd.AddCommand(NewCLIPapi(cli.cfg).NewCommand())
 	cmd.AddCommand(NewCLICollection().NewCommand())
 	cmd.AddCommand(NewCLICollection().NewCommand())

+ 63 - 55
cmd/crowdsec-cli/notifications.go

@@ -39,13 +39,17 @@ type NotificationsCfg struct {
 	ids      []uint
 	ids      []uint
 }
 }
 
 
-type cliNotifications struct{}
+type cliNotifications struct {
+	cfg configGetter
+}
 
 
-func NewCLINotifications() *cliNotifications {
-	return &cliNotifications{}
+func NewCLINotifications(cfg configGetter) *cliNotifications {
+	return &cliNotifications{
+		cfg: cfg,
+	}
 }
 }
 
 
-func (cli cliNotifications) NewCommand() *cobra.Command {
+func (cli *cliNotifications) NewCommand() *cobra.Command {
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
 		Use:               "notifications [action]",
 		Use:               "notifications [action]",
 		Short:             "Helper for notification plugin configuration",
 		Short:             "Helper for notification plugin configuration",
@@ -53,14 +57,15 @@ func (cli cliNotifications) NewCommand() *cobra.Command {
 		Args:              cobra.MinimumNArgs(1),
 		Args:              cobra.MinimumNArgs(1),
 		Aliases:           []string{"notifications", "notification"},
 		Aliases:           []string{"notifications", "notification"},
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
-		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
-			if err := require.LAPI(csConfig); err != nil {
+		PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
+			cfg := cli.cfg()
+			if err := require.LAPI(cfg); err != nil {
 				return err
 				return err
 			}
 			}
-			if err := csConfig.LoadAPIClient(); err != nil {
+			if err := cfg.LoadAPIClient(); err != nil {
 				return fmt.Errorf("loading api client: %w", err)
 				return fmt.Errorf("loading api client: %w", err)
 			}
 			}
-			if err := require.Notifications(csConfig); err != nil {
+			if err := require.Notifications(cfg); err != nil {
 				return err
 				return err
 			}
 			}
 
 
@@ -76,13 +81,14 @@ func (cli cliNotifications) NewCommand() *cobra.Command {
 	return cmd
 	return cmd
 }
 }
 
 
-func getPluginConfigs() (map[string]csplugin.PluginConfig, error) {
+func (cli *cliNotifications) getPluginConfigs() (map[string]csplugin.PluginConfig, error) {
+	cfg := cli.cfg()
 	pcfgs := map[string]csplugin.PluginConfig{}
 	pcfgs := map[string]csplugin.PluginConfig{}
 	wf := func(path string, info fs.FileInfo, err error) error {
 	wf := func(path string, info fs.FileInfo, err error) error {
 		if info == nil {
 		if info == nil {
 			return fmt.Errorf("error while traversing directory %s: %w", path, err)
 			return fmt.Errorf("error while traversing directory %s: %w", path, err)
 		}
 		}
-		name := filepath.Join(csConfig.ConfigPaths.NotificationDir, info.Name()) //Avoid calling info.Name() twice
+		name := filepath.Join(cfg.ConfigPaths.NotificationDir, info.Name()) //Avoid calling info.Name() twice
 		if (strings.HasSuffix(name, "yaml") || strings.HasSuffix(name, "yml")) && !(info.IsDir()) {
 		if (strings.HasSuffix(name, "yaml") || strings.HasSuffix(name, "yml")) && !(info.IsDir()) {
 			ts, err := csplugin.ParsePluginConfigFile(name)
 			ts, err := csplugin.ParsePluginConfigFile(name)
 			if err != nil {
 			if err != nil {
@@ -96,15 +102,16 @@ func getPluginConfigs() (map[string]csplugin.PluginConfig, error) {
 		return nil
 		return nil
 	}
 	}
 
 
-	if err := filepath.Walk(csConfig.ConfigPaths.NotificationDir, wf); err != nil {
+	if err := filepath.Walk(cfg.ConfigPaths.NotificationDir, wf); err != nil {
 		return nil, fmt.Errorf("while loading notifification plugin configuration: %w", err)
 		return nil, fmt.Errorf("while loading notifification plugin configuration: %w", err)
 	}
 	}
 	return pcfgs, nil
 	return pcfgs, nil
 }
 }
 
 
-func getProfilesConfigs() (map[string]NotificationsCfg, error) {
+func (cli *cliNotifications) getProfilesConfigs() (map[string]NotificationsCfg, error) {
+	cfg := cli.cfg()
 	// A bit of a tricky stuf now: reconcile profiles and notification plugins
 	// A bit of a tricky stuf now: reconcile profiles and notification plugins
-	pcfgs, err := getPluginConfigs()
+	pcfgs, err := cli.getPluginConfigs()
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -114,7 +121,7 @@ func getProfilesConfigs() (map[string]NotificationsCfg, error) {
 			Config: pc,
 			Config: pc,
 		}
 		}
 	}
 	}
-	profiles, err := csprofiles.NewProfile(csConfig.API.Server.Profiles)
+	profiles, err := csprofiles.NewProfile(cfg.API.Server.Profiles)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("while extracting profiles from configuration: %w", err)
 		return nil, fmt.Errorf("while extracting profiles from configuration: %w", err)
 	}
 	}
@@ -136,7 +143,7 @@ func getProfilesConfigs() (map[string]NotificationsCfg, error) {
 	return ncfgs, nil
 	return ncfgs, nil
 }
 }
 
 
-func (cli cliNotifications) NewListCmd() *cobra.Command {
+func (cli *cliNotifications) NewListCmd() *cobra.Command {
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
 		Use:               "list",
 		Use:               "list",
 		Short:             "list active notifications plugins",
 		Short:             "list active notifications plugins",
@@ -144,21 +151,22 @@ func (cli cliNotifications) NewListCmd() *cobra.Command {
 		Example:           `cscli notifications list`,
 		Example:           `cscli notifications list`,
 		Args:              cobra.ExactArgs(0),
 		Args:              cobra.ExactArgs(0),
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
-		RunE: func(cmd *cobra.Command, arg []string) error {
-			ncfgs, err := getProfilesConfigs()
+		RunE: func(_ *cobra.Command, _ []string) error {
+			cfg := cli.cfg()
+			ncfgs, err := cli.getProfilesConfigs()
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 			}
 			}
 
 
-			if csConfig.Cscli.Output == "human" {
+			if cfg.Cscli.Output == "human" {
 				notificationListTable(color.Output, ncfgs)
 				notificationListTable(color.Output, ncfgs)
-			} else if csConfig.Cscli.Output == "json" {
+			} else if cfg.Cscli.Output == "json" {
 				x, err := json.MarshalIndent(ncfgs, "", " ")
 				x, err := json.MarshalIndent(ncfgs, "", " ")
 				if err != nil {
 				if err != nil {
 					return fmt.Errorf("failed to marshal notification configuration: %w", err)
 					return fmt.Errorf("failed to marshal notification configuration: %w", err)
 				}
 				}
 				fmt.Printf("%s", string(x))
 				fmt.Printf("%s", string(x))
-			} else if csConfig.Cscli.Output == "raw" {
+			} else if cfg.Cscli.Output == "raw" {
 				csvwriter := csv.NewWriter(os.Stdout)
 				csvwriter := csv.NewWriter(os.Stdout)
 				err := csvwriter.Write([]string{"Name", "Type", "Profile name"})
 				err := csvwriter.Write([]string{"Name", "Type", "Profile name"})
 				if err != nil {
 				if err != nil {
@@ -183,7 +191,7 @@ func (cli cliNotifications) NewListCmd() *cobra.Command {
 	return cmd
 	return cmd
 }
 }
 
 
-func (cli cliNotifications) NewInspectCmd() *cobra.Command {
+func (cli *cliNotifications) NewInspectCmd() *cobra.Command {
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
 		Use:               "inspect",
 		Use:               "inspect",
 		Short:             "Inspect active notifications plugin configuration",
 		Short:             "Inspect active notifications plugin configuration",
@@ -191,30 +199,25 @@ func (cli cliNotifications) NewInspectCmd() *cobra.Command {
 		Example:           `cscli notifications inspect <plugin_name>`,
 		Example:           `cscli notifications inspect <plugin_name>`,
 		Args:              cobra.ExactArgs(1),
 		Args:              cobra.ExactArgs(1),
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
-		PreRunE: func(cmd *cobra.Command, args []string) error {
-			if args[0] == "" {
-				return fmt.Errorf("please provide a plugin name to inspect")
-			}
-			return nil
-		},
-		RunE: func(cmd *cobra.Command, args []string) error {
-			ncfgs, err := getProfilesConfigs()
+		RunE: func(_ *cobra.Command, args []string) error {
+			cfg := cli.cfg()
+			ncfgs, err := cli.getProfilesConfigs()
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 			}
 			}
-			cfg, ok := ncfgs[args[0]]
+			ncfg, ok := ncfgs[args[0]]
 			if !ok {
 			if !ok {
 				return fmt.Errorf("plugin '%s' does not exist or is not active", args[0])
 				return fmt.Errorf("plugin '%s' does not exist or is not active", args[0])
 			}
 			}
-			if csConfig.Cscli.Output == "human" || csConfig.Cscli.Output == "raw" {
-				fmt.Printf(" - %15s: %15s\n", "Type", cfg.Config.Type)
-				fmt.Printf(" - %15s: %15s\n", "Name", cfg.Config.Name)
-				fmt.Printf(" - %15s: %15s\n", "Timeout", cfg.Config.TimeOut)
-				fmt.Printf(" - %15s: %15s\n", "Format", cfg.Config.Format)
-				for k, v := range cfg.Config.Config {
+			if cfg.Cscli.Output == "human" || cfg.Cscli.Output == "raw" {
+				fmt.Printf(" - %15s: %15s\n", "Type", ncfg.Config.Type)
+				fmt.Printf(" - %15s: %15s\n", "Name", ncfg.Config.Name)
+				fmt.Printf(" - %15s: %15s\n", "Timeout", ncfg.Config.TimeOut)
+				fmt.Printf(" - %15s: %15s\n", "Format", ncfg.Config.Format)
+				for k, v := range ncfg.Config.Config {
 					fmt.Printf(" - %15s: %15v\n", k, v)
 					fmt.Printf(" - %15s: %15v\n", k, v)
 				}
 				}
-			} else if csConfig.Cscli.Output == "json" {
+			} else if cfg.Cscli.Output == "json" {
 				x, err := json.MarshalIndent(cfg, "", " ")
 				x, err := json.MarshalIndent(cfg, "", " ")
 				if err != nil {
 				if err != nil {
 					return fmt.Errorf("failed to marshal notification configuration: %w", err)
 					return fmt.Errorf("failed to marshal notification configuration: %w", err)
@@ -228,7 +231,7 @@ func (cli cliNotifications) NewInspectCmd() *cobra.Command {
 	return cmd
 	return cmd
 }
 }
 
 
-func (cli cliNotifications) NewTestCmd() *cobra.Command {
+func (cli *cliNotifications) NewTestCmd() *cobra.Command {
 	var (
 	var (
 		pluginBroker  csplugin.PluginBroker
 		pluginBroker  csplugin.PluginBroker
 		pluginTomb    tomb.Tomb
 		pluginTomb    tomb.Tomb
@@ -241,25 +244,26 @@ func (cli cliNotifications) NewTestCmd() *cobra.Command {
 		Example:           `cscli notifications test [plugin_name]`,
 		Example:           `cscli notifications test [plugin_name]`,
 		Args:              cobra.ExactArgs(1),
 		Args:              cobra.ExactArgs(1),
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
-		PreRunE: func(cmd *cobra.Command, args []string) error {
-			pconfigs, err := getPluginConfigs()
+		PreRunE: func(_ *cobra.Command, args []string) error {
+			cfg := cli.cfg()
+			pconfigs, err := cli.getPluginConfigs()
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 				return fmt.Errorf("can't build profiles configuration: %w", err)
 			}
 			}
-			cfg, ok := pconfigs[args[0]]
+			pcfg, ok := pconfigs[args[0]]
 			if !ok {
 			if !ok {
 				return fmt.Errorf("plugin name: '%s' does not exist", args[0])
 				return fmt.Errorf("plugin name: '%s' does not exist", args[0])
 			}
 			}
 			//Create a single profile with plugin name as notification name
 			//Create a single profile with plugin name as notification name
-			return pluginBroker.Init(csConfig.PluginConfig, []*csconfig.ProfileCfg{
+			return pluginBroker.Init(cfg.PluginConfig, []*csconfig.ProfileCfg{
 				{
 				{
 					Notifications: []string{
 					Notifications: []string{
-						cfg.Name,
+						pcfg.Name,
 					},
 					},
 				},
 				},
-			}, csConfig.ConfigPaths)
+			}, cfg.ConfigPaths)
 		},
 		},
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(_ *cobra.Command, _ []string) error {
 			pluginTomb.Go(func() error {
 			pluginTomb.Go(func() error {
 				pluginBroker.Run(&pluginTomb)
 				pluginBroker.Run(&pluginTomb)
 				return nil
 				return nil
@@ -313,7 +317,7 @@ func (cli cliNotifications) NewTestCmd() *cobra.Command {
 	return cmd
 	return cmd
 }
 }
 
 
-func (cli cliNotifications) NewReinjectCmd() *cobra.Command {
+func (cli *cliNotifications) NewReinjectCmd() *cobra.Command {
 	var alertOverride string
 	var alertOverride string
 	var alert *models.Alert
 	var alert *models.Alert
 
 
@@ -328,25 +332,28 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
 `,
 `,
 		Args:              cobra.ExactArgs(1),
 		Args:              cobra.ExactArgs(1),
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
-		PreRunE: func(cmd *cobra.Command, args []string) error {
+		PreRunE: func(_ *cobra.Command, args []string) error {
 			var err error
 			var err error
-			alert, err = FetchAlertFromArgString(args[0])
+			alert, err = cli.fetchAlertFromArgString(args[0])
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 			return nil
 			return nil
 		},
 		},
-		RunE: func(cmd *cobra.Command, args []string) error {
+		RunE: func(_ *cobra.Command, _ []string) error {
 			var (
 			var (
 				pluginBroker csplugin.PluginBroker
 				pluginBroker csplugin.PluginBroker
 				pluginTomb   tomb.Tomb
 				pluginTomb   tomb.Tomb
 			)
 			)
+
+			cfg := cli.cfg()
+
 			if alertOverride != "" {
 			if alertOverride != "" {
 				if err := json.Unmarshal([]byte(alertOverride), alert); err != nil {
 				if err := json.Unmarshal([]byte(alertOverride), alert); err != nil {
 					return fmt.Errorf("can't unmarshal data in the alert flag: %w", err)
 					return fmt.Errorf("can't unmarshal data in the alert flag: %w", err)
 				}
 				}
 			}
 			}
-			err := pluginBroker.Init(csConfig.PluginConfig, csConfig.API.Server.Profiles, csConfig.ConfigPaths)
+			err := pluginBroker.Init(cfg.PluginConfig, cfg.API.Server.Profiles, cfg.ConfigPaths)
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("can't initialize plugins: %w", err)
 				return fmt.Errorf("can't initialize plugins: %w", err)
 			}
 			}
@@ -356,7 +363,7 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
 				return nil
 				return nil
 			})
 			})
 
 
-			profiles, err := csprofiles.NewProfile(csConfig.API.Server.Profiles)
+			profiles, err := csprofiles.NewProfile(cfg.API.Server.Profiles)
 			if err != nil {
 			if err != nil {
 				return fmt.Errorf("cannot extract profiles from configuration: %w", err)
 				return fmt.Errorf("cannot extract profiles from configuration: %w", err)
 			}
 			}
@@ -401,18 +408,19 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
 	return cmd
 	return cmd
 }
 }
 
 
-func FetchAlertFromArgString(toParse string) (*models.Alert, error) {
+func (cli *cliNotifications) fetchAlertFromArgString(toParse string) (*models.Alert, error) {
+	cfg := cli.cfg()
 	id, err := strconv.Atoi(toParse)
 	id, err := strconv.Atoi(toParse)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("bad alert id %s", toParse)
 		return nil, fmt.Errorf("bad alert id %s", toParse)
 	}
 	}
-	apiURL, err := url.Parse(csConfig.API.Client.Credentials.URL)
+	apiURL, err := url.Parse(cfg.API.Client.Credentials.URL)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("error parsing the URL of the API: %w", err)
 		return nil, fmt.Errorf("error parsing the URL of the API: %w", err)
 	}
 	}
 	client, err := apiclient.NewClient(&apiclient.Config{
 	client, err := apiclient.NewClient(&apiclient.Config{
-		MachineID:     csConfig.API.Client.Credentials.Login,
-		Password:      strfmt.Password(csConfig.API.Client.Credentials.Password),
+		MachineID:     cfg.API.Client.Credentials.Login,
+		Password:      strfmt.Password(cfg.API.Client.Credentials.Password),
 		UserAgent:     fmt.Sprintf("crowdsec/%s", version.String()),
 		UserAgent:     fmt.Sprintf("crowdsec/%s", version.String()),
 		URL:           apiURL,
 		URL:           apiURL,
 		VersionPrefix: "v1",
 		VersionPrefix: "v1",