From 3e86f52250ad12f74bb06b2aa446c49445024c2f Mon Sep 17 00:00:00 2001 From: mmetc <92726601+mmetc@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:36:35 +0100 Subject: [PATCH] cscli refact - encapsulation with types (#2643) * refactor type cliHub, cliBouncers, cliMachines, cliPapi, cliNotifications, cliSupport, type cliExplain --- cmd/crowdsec-cli/bouncers.go | 108 +++++++++++---------- cmd/crowdsec-cli/explain.go | 152 ++++++++++++++++-------------- cmd/crowdsec-cli/hub.go | 64 +++++++------ cmd/crowdsec-cli/machines.go | 118 ++++++++++++----------- cmd/crowdsec-cli/main.go | 14 +-- cmd/crowdsec-cli/notifications.go | 49 +++++----- cmd/crowdsec-cli/papi.go | 28 +++--- cmd/crowdsec-cli/support.go | 24 +++-- 8 files changed, 302 insertions(+), 255 deletions(-) diff --git a/cmd/crowdsec-cli/bouncers.go b/cmd/crowdsec-cli/bouncers.go index 9ce98d4b6..d6e27ce4a 100644 --- a/cmd/crowdsec-cli/bouncers.go +++ b/cmd/crowdsec-cli/bouncers.go @@ -60,8 +60,46 @@ func getBouncers(out io.Writer, dbClient *database.Client) error { return nil } -func NewBouncersListCmd() *cobra.Command { - cmdBouncersList := &cobra.Command{ +type cliBouncers struct {} + +func NewCLIBouncers() *cliBouncers { + return &cliBouncers{} +} + +func (cli cliBouncers) NewCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "bouncers [action]", + Short: "Manage bouncers [requires local API]", + Long: `To list/add/delete/prune bouncers. +Note: This command requires database direct access, so is intended to be run on Local API/master. +`, + Args: cobra.MinimumNArgs(1), + Aliases: []string{"bouncer"}, + DisableAutoGenTag: true, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + var err error + if err = require.LAPI(csConfig); err != nil { + return err + } + + dbClient, err = database.NewClient(csConfig.DbConfig) + if err != nil { + return fmt.Errorf("unable to create new database client: %s", err) + } + return nil + }, + } + + cmd.AddCommand(cli.NewListCmd()) + cmd.AddCommand(cli.NewAddCmd()) + cmd.AddCommand(cli.NewDeleteCmd()) + cmd.AddCommand(cli.NewPruneCmd()) + + return cmd +} + +func (cli cliBouncers) NewListCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "list", Short: "list all bouncers within the database", Example: `cscli bouncers list`, @@ -76,10 +114,10 @@ func NewBouncersListCmd() *cobra.Command { }, } - return cmdBouncersList + return cmd } -func runBouncersAdd(cmd *cobra.Command, args []string) error { +func (cli cliBouncers) add(cmd *cobra.Command, args []string) error { keyLength := 32 flags := cmd.Flags() @@ -125,26 +163,26 @@ func runBouncersAdd(cmd *cobra.Command, args []string) error { return nil } -func NewBouncersAddCmd() *cobra.Command { - cmdBouncersAdd := &cobra.Command{ +func (cli cliBouncers) NewAddCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "add MyBouncerName", Short: "add a single bouncer to the database", Example: `cscli bouncers add MyBouncerName cscli bouncers add MyBouncerName --key `, Args: cobra.ExactArgs(1), DisableAutoGenTag: true, - RunE: runBouncersAdd, + RunE: cli.add, } - flags := cmdBouncersAdd.Flags() + flags := cmd.Flags() flags.StringP("length", "l", "", "length of the api key") flags.MarkDeprecated("length", "use --key instead") flags.StringP("key", "k", "", "api key for the bouncer") - return cmdBouncersAdd + return cmd } -func runBouncersDelete(cmd *cobra.Command, args []string) error { +func (cli cliBouncers) delete(cmd *cobra.Command, args []string) error { for _, bouncerID := range args { err := dbClient.DeleteBouncer(bouncerID) if err != nil { @@ -156,8 +194,8 @@ func runBouncersDelete(cmd *cobra.Command, args []string) error { return nil } -func NewBouncersDeleteCmd() *cobra.Command { - cmdBouncersDelete := &cobra.Command{ +func (cli cliBouncers) NewDeleteCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "delete MyBouncerName", Short: "delete bouncer(s) from the database", Args: cobra.MinimumNArgs(1), @@ -182,15 +220,15 @@ func NewBouncersDeleteCmd() *cobra.Command { } return ret, cobra.ShellCompDirectiveNoFileComp }, - RunE: runBouncersDelete, + RunE: cli.delete, } - return cmdBouncersDelete + return cmd } -func NewBouncersPruneCmd() *cobra.Command { +func (cli cliBouncers) NewPruneCmd() *cobra.Command { var parsedDuration time.Duration - cmdBouncersPrune := &cobra.Command{ + cmd := &cobra.Command{ Use: "prune", Short: "prune multiple bouncers from the database", Args: cobra.NoArgs, @@ -253,39 +291,7 @@ cscli bouncers prune -d 60m --force`, return nil }, } - cmdBouncersPrune.Flags().StringP("duration", "d", "60m", "duration of time since last pull") - cmdBouncersPrune.Flags().Bool("force", false, "force prune without asking for confirmation") - return cmdBouncersPrune -} - -func NewBouncersCmd() *cobra.Command { - var cmdBouncers = &cobra.Command{ - Use: "bouncers [action]", - Short: "Manage bouncers [requires local API]", - Long: `To list/add/delete/prune bouncers. -Note: This command requires database direct access, so is intended to be run on Local API/master. -`, - Args: cobra.MinimumNArgs(1), - Aliases: []string{"bouncer"}, - DisableAutoGenTag: true, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - var err error - if err = require.LAPI(csConfig); err != nil { - return err - } - - dbClient, err = database.NewClient(csConfig.DbConfig) - if err != nil { - return fmt.Errorf("unable to create new database client: %s", err) - } - return nil - }, - } - - cmdBouncers.AddCommand(NewBouncersListCmd()) - cmdBouncers.AddCommand(NewBouncersAddCmd()) - cmdBouncers.AddCommand(NewBouncersDeleteCmd()) - cmdBouncers.AddCommand(NewBouncersPruneCmd()) - - return cmdBouncers + cmd.Flags().StringP("duration", "d", "60m", "duration of time since last pull") + cmd.Flags().Bool("force", false, "force prune without asking for confirmation") + return cmd } diff --git a/cmd/crowdsec-cli/explain.go b/cmd/crowdsec-cli/explain.go index 1a9d24b85..d3b92c2b5 100644 --- a/cmd/crowdsec-cli/explain.go +++ b/cmd/crowdsec-cli/explain.go @@ -34,7 +34,85 @@ func GetLineCountForFile(filepath string) (int, error) { return lc, nil } -func runExplain(cmd *cobra.Command, args []string) error { +type cliExplain struct {} + +func NewCLIExplain() *cliExplain { + return &cliExplain{} +} + +func (cli cliExplain) NewCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "explain", + Short: "Explain log pipeline", + Long: ` +Explain log pipeline + `, + Example: ` +cscli explain --file ./myfile.log --type nginx +cscli explain --log "Sep 19 18:33:22 scw-d95986 sshd[24347]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=1.2.3.4" --type syslog +cscli explain --dsn "file://myfile.log" --type nginx +tail -n 5 myfile.log | cscli explain --type nginx -f - + `, + Args: cobra.ExactArgs(0), + DisableAutoGenTag: true, + RunE: cli.run, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + flags := cmd.Flags() + + logFile, err := flags.GetString("file") + if err != nil { + return err + } + + dsn, err := flags.GetString("dsn") + if err != nil { + return err + } + + logLine, err := flags.GetString("log") + if err != nil { + return err + } + + logType, err := flags.GetString("type") + if err != nil { + return err + } + + if logLine == "" && logFile == "" && dsn == "" { + printHelp(cmd) + fmt.Println() + return fmt.Errorf("please provide --log, --file or --dsn flag") + } + if logType == "" { + printHelp(cmd) + fmt.Println() + return fmt.Errorf("please provide --type flag") + } + fileInfo, _ := os.Stdin.Stat() + if logFile == "-" && ((fileInfo.Mode() & os.ModeCharDevice) == os.ModeCharDevice) { + return fmt.Errorf("the option -f - is intended to work with pipes") + } + return nil + }, + } + + flags := cmd.Flags() + + flags.StringP("file", "f", "", "Log file to test") + flags.StringP("dsn", "d", "", "DSN to test") + flags.StringP("log", "l", "", "Log line to test") + flags.StringP("type", "t", "", "Type of the acquisition to test") + flags.String("labels", "", "Additional labels to add to the acquisition format (key:value,key2:value2)") + flags.BoolP("verbose", "v", false, "Display individual changes") + flags.Bool("failures", false, "Only show failed lines") + flags.Bool("only-successful-parsers", false, "Only show successful parsers") + flags.String("crowdsec", "crowdsec", "Path to crowdsec") + + return cmd +} + +func (cli cliExplain) run(cmd *cobra.Command, args []string) error { flags := cmd.Flags() logFile, err := flags.GetString("file") @@ -189,75 +267,3 @@ func runExplain(cmd *cobra.Command, args []string) error { return nil } - -func NewExplainCmd() *cobra.Command { - cmdExplain := &cobra.Command{ - Use: "explain", - Short: "Explain log pipeline", - Long: ` -Explain log pipeline - `, - Example: ` -cscli explain --file ./myfile.log --type nginx -cscli explain --log "Sep 19 18:33:22 scw-d95986 sshd[24347]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=1.2.3.4" --type syslog -cscli explain --dsn "file://myfile.log" --type nginx -tail -n 5 myfile.log | cscli explain --type nginx -f - - `, - Args: cobra.ExactArgs(0), - DisableAutoGenTag: true, - RunE: runExplain, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - flags := cmd.Flags() - - logFile, err := flags.GetString("file") - if err != nil { - return err - } - - dsn, err := flags.GetString("dsn") - if err != nil { - return err - } - - logLine, err := flags.GetString("log") - if err != nil { - return err - } - - logType, err := flags.GetString("type") - if err != nil { - return err - } - - if logLine == "" && logFile == "" && dsn == "" { - printHelp(cmd) - fmt.Println() - return fmt.Errorf("please provide --log, --file or --dsn flag") - } - if logType == "" { - printHelp(cmd) - fmt.Println() - return fmt.Errorf("please provide --type flag") - } - fileInfo, _ := os.Stdin.Stat() - if logFile == "-" && ((fileInfo.Mode() & os.ModeCharDevice) == os.ModeCharDevice) { - return fmt.Errorf("the option -f - is intended to work with pipes") - } - return nil - }, - } - - flags := cmdExplain.Flags() - - flags.StringP("file", "f", "", "Log file to test") - flags.StringP("dsn", "d", "", "DSN to test") - flags.StringP("log", "l", "", "Log line to test") - flags.StringP("type", "t", "", "Type of the acquisition to test") - flags.String("labels", "", "Additional labels to add to the acquisition format (key:value,key2:value2)") - flags.BoolP("verbose", "v", false, "Display individual changes") - flags.Bool("failures", false, "Only show failed lines") - flags.Bool("only-successful-parsers", false, "Only show successful parsers") - flags.String("crowdsec", "crowdsec", "Path to crowdsec") - - return cmdExplain -} diff --git a/cmd/crowdsec-cli/hub.go b/cmd/crowdsec-cli/hub.go index 0a48e0231..4d7518143 100644 --- a/cmd/crowdsec-cli/hub.go +++ b/cmd/crowdsec-cli/hub.go @@ -13,8 +13,14 @@ import ( "github.com/crowdsecurity/crowdsec/pkg/cwhub" ) -func NewHubCmd() *cobra.Command { - cmdHub := &cobra.Command{ +type cliHub struct{} + +func NewCLIHub() *cliHub { + return &cliHub{} +} + +func (cli cliHub) NewCommand() *cobra.Command { + cmd := &cobra.Command{ Use: "hub [action]", Short: "Manage hub index", Long: `Hub management @@ -28,15 +34,15 @@ cscli hub upgrade`, DisableAutoGenTag: true, } - cmdHub.AddCommand(NewHubListCmd()) - cmdHub.AddCommand(NewHubUpdateCmd()) - cmdHub.AddCommand(NewHubUpgradeCmd()) - cmdHub.AddCommand(NewHubTypesCmd()) + cmd.AddCommand(cli.NewListCmd()) + cmd.AddCommand(cli.NewUpdateCmd()) + cmd.AddCommand(cli.NewUpgradeCmd()) + cmd.AddCommand(cli.NewTypesCmd()) - return cmdHub + return cmd } -func runHubList(cmd *cobra.Command, args []string) error { +func (cli cliHub) list(cmd *cobra.Command, args []string) error { flags := cmd.Flags() all, err := flags.GetBool("all") @@ -74,22 +80,22 @@ func runHubList(cmd *cobra.Command, args []string) error { return nil } -func NewHubListCmd() *cobra.Command { - cmdHubList := &cobra.Command{ +func (cli cliHub) NewListCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "list [-a]", Short: "List all installed configurations", Args: cobra.ExactArgs(0), DisableAutoGenTag: true, - RunE: runHubList, + RunE: cli.list, } - flags := cmdHubList.Flags() + flags := cmd.Flags() flags.BoolP("all", "a", false, "List disabled items as well") - return cmdHubList + return cmd } -func runHubUpdate(cmd *cobra.Command, args []string) error { +func (cli cliHub) update(cmd *cobra.Command, args []string) error { local := csConfig.Hub remote := require.RemoteHub(csConfig) @@ -106,8 +112,8 @@ func runHubUpdate(cmd *cobra.Command, args []string) error { return nil } -func NewHubUpdateCmd() *cobra.Command { - cmdHubUpdate := &cobra.Command{ +func (cli cliHub) NewUpdateCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "update", Short: "Download the latest index (catalog of available configurations)", Long: ` @@ -115,13 +121,13 @@ Fetches the .index.json file from the hub, containing the list of available conf `, Args: cobra.ExactArgs(0), DisableAutoGenTag: true, - RunE: runHubUpdate, + RunE: cli.update, } - return cmdHubUpdate + return cmd } -func runHubUpgrade(cmd *cobra.Command, args []string) error { +func (cli cliHub) upgrade(cmd *cobra.Command, args []string) error { flags := cmd.Flags() force, err := flags.GetBool("force") @@ -158,8 +164,8 @@ func runHubUpgrade(cmd *cobra.Command, args []string) error { return nil } -func NewHubUpgradeCmd() *cobra.Command { - cmdHubUpgrade := &cobra.Command{ +func (cli cliHub) NewUpgradeCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "upgrade", Short: "Upgrade all configurations to their latest version", Long: ` @@ -167,16 +173,16 @@ Upgrade all configs installed from Crowdsec Hub. Run 'sudo cscli hub update' if `, Args: cobra.ExactArgs(0), DisableAutoGenTag: true, - RunE: runHubUpgrade, + RunE: cli.upgrade, } - flags := cmdHubUpgrade.Flags() + flags := cmd.Flags() flags.Bool("force", false, "Force upgrade: overwrite tainted and outdated files") - return cmdHubUpgrade + return cmd } -func runHubTypes(cmd *cobra.Command, args []string) error { +func (cli cliHub) types(cmd *cobra.Command, args []string) error { switch csConfig.Cscli.Output { case "human": s, err := yaml.Marshal(cwhub.ItemTypes) @@ -198,8 +204,8 @@ func runHubTypes(cmd *cobra.Command, args []string) error { return nil } -func NewHubTypesCmd() *cobra.Command { - cmdHubTypes := &cobra.Command{ +func (cli cliHub) NewTypesCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "types", Short: "List supported item types", Long: ` @@ -207,8 +213,8 @@ List the types of supported hub items. `, Args: cobra.ExactArgs(0), DisableAutoGenTag: true, - RunE: runHubTypes, + RunE: cli.types, } - return cmdHubTypes + return cmd } diff --git a/cmd/crowdsec-cli/machines.go b/cmd/crowdsec-cli/machines.go index 72e6579cc..cfdc2139e 100644 --- a/cmd/crowdsec-cli/machines.go +++ b/cmd/crowdsec-cli/machines.go @@ -142,8 +142,46 @@ func getAgents(out io.Writer, dbClient *database.Client) error { return nil } -func NewMachinesListCmd() *cobra.Command { - cmdMachinesList := &cobra.Command{ +type cliMachines struct {} + +func NewCLIMachines() *cliMachines { + return &cliMachines{} +} + +func (cli cliMachines) NewCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "machines [action]", + Short: "Manage local API machines [requires local API]", + Long: `To list/add/delete/validate/prune machines. +Note: This command requires database direct access, so is intended to be run on the local API machine. +`, + Example: `cscli machines [action]`, + DisableAutoGenTag: true, + Aliases: []string{"machine"}, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + var err error + if err := require.LAPI(csConfig); err != nil { + return err + } + dbClient, err = database.NewClient(csConfig.DbConfig) + if err != nil { + return fmt.Errorf("unable to create new database client: %s", err) + } + return nil + }, + } + + cmd.AddCommand(cli.NewListCmd()) + cmd.AddCommand(cli.NewAddCmd()) + cmd.AddCommand(cli.NewDeleteCmd()) + cmd.AddCommand(cli.NewValidateCmd()) + cmd.AddCommand(cli.NewPruneCmd()) + + return cmd +} + +func (cli cliMachines) NewListCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "list", Short: "list all machines in the database", Long: `list all machines in the database with their status and last heartbeat`, @@ -160,11 +198,11 @@ func NewMachinesListCmd() *cobra.Command { }, } - return cmdMachinesList + return cmd } -func NewMachinesAddCmd() *cobra.Command { - cmdMachinesAdd := &cobra.Command{ +func (cli cliMachines) NewAddCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "add", Short: "add a single machine to the database", DisableAutoGenTag: true, @@ -174,10 +212,10 @@ cscli machines add --auto cscli machines add MyTestMachine --auto cscli machines add MyTestMachine --password MyPassword `, - RunE: runMachinesAdd, + RunE: cli.add, } - flags := cmdMachinesAdd.Flags() + flags := cmd.Flags() flags.StringP("password", "p", "", "machine password to login to the API") flags.StringP("file", "f", "", "output file destination (defaults to "+csconfig.DefaultConfigPath("local_api_credentials.yaml")+")") flags.StringP("url", "u", "", "URL of the local API") @@ -185,12 +223,10 @@ cscli machines add MyTestMachine --password MyPassword flags.BoolP("auto", "a", false, "automatically generate password (and username if not provided)") flags.Bool("force", false, "will force add the machine if it already exist") - return cmdMachinesAdd + return cmd } -func runMachinesAdd(cmd *cobra.Command, args []string) error { - var err error - +func (cli cliMachines) add(cmd *cobra.Command, args []string) error { flags := cmd.Flags() machinePassword, err := flags.GetString("password") @@ -308,8 +344,8 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error { return nil } -func NewMachinesDeleteCmd() *cobra.Command { - cmdMachinesDelete := &cobra.Command{ +func (cli cliMachines) NewDeleteCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "delete [machine_name]...", Short: "delete machine(s) by name", Example: `cscli machines delete "machine1" "machine2"`, @@ -329,13 +365,13 @@ func NewMachinesDeleteCmd() *cobra.Command { } return ret, cobra.ShellCompDirectiveNoFileComp }, - RunE: runMachinesDelete, + RunE: cli.delete, } - return cmdMachinesDelete + return cmd } -func runMachinesDelete(cmd *cobra.Command, args []string) error { +func (cli cliMachines) delete(cmd *cobra.Command, args []string) error { for _, machineID := range args { err := dbClient.DeleteWatcher(machineID) if err != nil { @@ -348,9 +384,9 @@ func runMachinesDelete(cmd *cobra.Command, args []string) error { return nil } -func NewMachinesPruneCmd() *cobra.Command { +func (cli cliMachines) NewPruneCmd() *cobra.Command { var parsedDuration time.Duration - cmdMachinesPrune := &cobra.Command{ + cmd := &cobra.Command{ Use: "prune", Short: "prune multiple machines from the database", Long: `prune multiple machines that are not validated or have not connected to the local API in a given duration.`, @@ -421,15 +457,15 @@ cscli machines prune --not-validated-only --force`, return nil }, } - cmdMachinesPrune.Flags().StringP("duration", "d", "10m", "duration of time since validated machine last heartbeat") - cmdMachinesPrune.Flags().Bool("not-validated-only", false, "only prune machines that are not validated") - cmdMachinesPrune.Flags().Bool("force", false, "force prune without asking for confirmation") + cmd.Flags().StringP("duration", "d", "10m", "duration of time since validated machine last heartbeat") + cmd.Flags().Bool("not-validated-only", false, "only prune machines that are not validated") + cmd.Flags().Bool("force", false, "force prune without asking for confirmation") - return cmdMachinesPrune + return cmd } -func NewMachinesValidateCmd() *cobra.Command { - cmdMachinesValidate := &cobra.Command{ +func (cli cliMachines) NewValidateCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "validate", Short: "validate a machine to access the local API", Long: `validate a machine to access the local API.`, @@ -447,37 +483,5 @@ func NewMachinesValidateCmd() *cobra.Command { }, } - return cmdMachinesValidate -} - -func NewMachinesCmd() *cobra.Command { - var cmdMachines = &cobra.Command{ - Use: "machines [action]", - Short: "Manage local API machines [requires local API]", - Long: `To list/add/delete/validate/prune machines. -Note: This command requires database direct access, so is intended to be run on the local API machine. -`, - Example: `cscli machines [action]`, - DisableAutoGenTag: true, - Aliases: []string{"machine"}, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - var err error - if err := require.LAPI(csConfig); err != nil { - return err - } - dbClient, err = database.NewClient(csConfig.DbConfig) - if err != nil { - return fmt.Errorf("unable to create new database client: %s", err) - } - return nil - }, - } - - cmdMachines.AddCommand(NewMachinesListCmd()) - cmdMachines.AddCommand(NewMachinesAddCmd()) - cmdMachines.AddCommand(NewMachinesDeleteCmd()) - cmdMachines.AddCommand(NewMachinesValidateCmd()) - cmdMachines.AddCommand(NewMachinesPruneCmd()) - - return cmdMachines + return cmd } diff --git a/cmd/crowdsec-cli/main.go b/cmd/crowdsec-cli/main.go index c9b7d7030..7427289bb 100644 --- a/cmd/crowdsec-cli/main.go +++ b/cmd/crowdsec-cli/main.go @@ -225,22 +225,22 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall rootCmd.PersistentFlags().SortFlags = false rootCmd.AddCommand(NewConfigCmd()) - rootCmd.AddCommand(NewHubCmd()) + rootCmd.AddCommand(NewCLIHub().NewCommand()) rootCmd.AddCommand(NewMetricsCmd()) rootCmd.AddCommand(NewDashboardCmd()) rootCmd.AddCommand(NewDecisionsCmd()) rootCmd.AddCommand(NewAlertsCmd()) rootCmd.AddCommand(NewSimulationCmds()) - rootCmd.AddCommand(NewBouncersCmd()) - rootCmd.AddCommand(NewMachinesCmd()) + rootCmd.AddCommand(NewCLIBouncers().NewCommand()) + rootCmd.AddCommand(NewCLIMachines().NewCommand()) rootCmd.AddCommand(NewCapiCmd()) rootCmd.AddCommand(NewLapiCmd()) rootCmd.AddCommand(NewCompletionCmd()) rootCmd.AddCommand(NewConsoleCmd()) - rootCmd.AddCommand(NewExplainCmd()) + rootCmd.AddCommand(NewCLIExplain().NewCommand()) rootCmd.AddCommand(NewHubTestCmd()) - rootCmd.AddCommand(NewNotificationsCmd()) - rootCmd.AddCommand(NewSupportCmd()) + rootCmd.AddCommand(NewCLINotifications().NewCommand()) + rootCmd.AddCommand(NewCLISupport().NewCommand()) rootCmd.AddCommand(NewCollectionCLI().NewCommand()) rootCmd.AddCommand(NewParserCLI().NewCommand()) @@ -254,7 +254,7 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall } if fflag.PapiClient.IsEnabled() { - rootCmd.AddCommand(NewPapiCmd()) + rootCmd.AddCommand(NewCLIPapi().NewCommand()) } if err := rootCmd.Execute(); err != nil { diff --git a/cmd/crowdsec-cli/notifications.go b/cmd/crowdsec-cli/notifications.go index 9f0700bd1..585fd64c6 100644 --- a/cmd/crowdsec-cli/notifications.go +++ b/cmd/crowdsec-cli/notifications.go @@ -39,8 +39,15 @@ type NotificationsCfg struct { ids []uint } -func NewNotificationsCmd() *cobra.Command { - var cmdNotifications = &cobra.Command{ + +type cliNotifications struct {} + +func NewCLINotifications() *cliNotifications { + return &cliNotifications{} +} + +func (cli cliNotifications) NewCommand() *cobra.Command { + cmd := &cobra.Command{ Use: "notifications [action]", Short: "Helper for notification plugin configuration", Long: "To list/inspect/test notification template", @@ -62,12 +69,12 @@ func NewNotificationsCmd() *cobra.Command { }, } - cmdNotifications.AddCommand(NewNotificationsListCmd()) - cmdNotifications.AddCommand(NewNotificationsInspectCmd()) - cmdNotifications.AddCommand(NewNotificationsReinjectCmd()) - cmdNotifications.AddCommand(NewNotificationsTestCmd()) + cmd.AddCommand(cli.NewListCmd()) + cmd.AddCommand(cli.NewInspectCmd()) + cmd.AddCommand(cli.NewReinjectCmd()) + cmd.AddCommand(cli.NewTestCmd()) - return cmdNotifications + return cmd } func getPluginConfigs() (map[string]csplugin.PluginConfig, error) { @@ -141,8 +148,8 @@ func getProfilesConfigs() (map[string]NotificationsCfg, error) { return ncfgs, nil } -func NewNotificationsListCmd() *cobra.Command { - var cmdNotificationsList = &cobra.Command{ +func (cli cliNotifications) NewListCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "list", Short: "list active notifications plugins", Long: `list active notifications plugins`, @@ -185,11 +192,11 @@ func NewNotificationsListCmd() *cobra.Command { }, } - return cmdNotificationsList + return cmd } -func NewNotificationsInspectCmd() *cobra.Command { - var cmdNotificationsInspect = &cobra.Command{ +func (cli cliNotifications) NewInspectCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "inspect", Short: "Inspect active notifications plugin configuration", Long: `Inspect active notifications plugin and show configuration`, @@ -230,16 +237,16 @@ func NewNotificationsInspectCmd() *cobra.Command { }, } - return cmdNotificationsInspect + return cmd } -func NewNotificationsTestCmd() *cobra.Command { +func (cli cliNotifications) NewTestCmd() *cobra.Command { var ( pluginBroker csplugin.PluginBroker pluginTomb tomb.Tomb alertOverride string ) - var cmdNotificationsTest = &cobra.Command{ + cmd := &cobra.Command{ Use: "test [plugin name]", Short: "send a generic test alert to notification plugin", Long: `send a generic test alert to a notification plugin to test configuration even if is not active`, @@ -313,16 +320,16 @@ func NewNotificationsTestCmd() *cobra.Command { return nil }, } - cmdNotificationsTest.Flags().StringVarP(&alertOverride, "alert", "a", "", "JSON string used to override alert fields in the generic alert (see crowdsec/pkg/models/alert.go in the source tree for the full definition of the object)") + cmd.Flags().StringVarP(&alertOverride, "alert", "a", "", "JSON string used to override alert fields in the generic alert (see crowdsec/pkg/models/alert.go in the source tree for the full definition of the object)") - return cmdNotificationsTest + return cmd } -func NewNotificationsReinjectCmd() *cobra.Command { +func (cli cliNotifications) NewReinjectCmd() *cobra.Command { var alertOverride string var alert *models.Alert - var cmdNotificationsReinject = &cobra.Command{ + cmd := &cobra.Command{ Use: "reinject", Short: "reinject an alert into profiles to trigger notifications", Long: `reinject an alert into profiles to be evaluated by the filter and sent to matched notifications plugins`, @@ -401,9 +408,9 @@ cscli notifications reinject -a '{"remediation": true,"scenario":"not return nil }, } - cmdNotificationsReinject.Flags().StringVarP(&alertOverride, "alert", "a", "", "JSON string used to override alert fields in the reinjected alert (see crowdsec/pkg/models/alert.go in the source tree for the full definition of the object)") + cmd.Flags().StringVarP(&alertOverride, "alert", "a", "", "JSON string used to override alert fields in the reinjected alert (see crowdsec/pkg/models/alert.go in the source tree for the full definition of the object)") - return cmdNotificationsReinject + return cmd } func FetchAlertFromArgString(toParse string) (*models.Alert, error) { diff --git a/cmd/crowdsec-cli/papi.go b/cmd/crowdsec-cli/papi.go index a7f36d3f2..606d8b415 100644 --- a/cmd/crowdsec-cli/papi.go +++ b/cmd/crowdsec-cli/papi.go @@ -15,8 +15,14 @@ import ( "github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require" ) -func NewPapiCmd() *cobra.Command { - var cmdLapi = &cobra.Command{ +type cliPapi struct {} + +func NewCLIPapi() *cliPapi { + return &cliPapi{} +} + +func (cli cliPapi) NewCommand() *cobra.Command { + var cmd = &cobra.Command{ Use: "papi [action]", Short: "Manage interaction with Polling API (PAPI)", Args: cobra.MinimumNArgs(1), @@ -35,14 +41,14 @@ func NewPapiCmd() *cobra.Command { }, } - cmdLapi.AddCommand(NewPapiStatusCmd()) - cmdLapi.AddCommand(NewPapiSyncCmd()) + cmd.AddCommand(cli.NewStatusCmd()) + cmd.AddCommand(cli.NewSyncCmd()) - return cmdLapi + return cmd } -func NewPapiStatusCmd() *cobra.Command { - cmdCapiStatus := &cobra.Command{ +func (cli cliPapi) NewStatusCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "status", Short: "Get status of the Polling API", Args: cobra.MinimumNArgs(0), @@ -87,11 +93,11 @@ func NewPapiStatusCmd() *cobra.Command { }, } - return cmdCapiStatus + return cmd } -func NewPapiSyncCmd() *cobra.Command { - cmdCapiSync := &cobra.Command{ +func (cli cliPapi) NewSyncCmd() *cobra.Command { + cmd := &cobra.Command{ Use: "sync", Short: "Sync with the Polling API, pulling all non-expired orders for the instance", Args: cobra.MinimumNArgs(0), @@ -135,5 +141,5 @@ func NewPapiSyncCmd() *cobra.Command { }, } - return cmdCapiSync + return cmd } diff --git a/cmd/crowdsec-cli/support.go b/cmd/crowdsec-cli/support.go index 6395ad6d7..9d5efb7eb 100644 --- a/cmd/crowdsec-cli/support.go +++ b/cmd/crowdsec-cli/support.go @@ -237,8 +237,14 @@ func collectAcquisitionConfig() map[string][]byte { return ret } -func NewSupportCmd() *cobra.Command { - var cmdSupport = &cobra.Command{ +type cliSupport struct {} + +func NewCLISupport() *cliSupport { + return &cliSupport{} +} + +func (cli cliSupport) NewCommand() *cobra.Command { + cmd := &cobra.Command{ Use: "support [action]", Short: "Provide commands to help during support", Args: cobra.MinimumNArgs(1), @@ -248,9 +254,15 @@ func NewSupportCmd() *cobra.Command { }, } + cmd.AddCommand(cli.NewDumpCmd()) + + return cmd +} + +func (cli cliSupport) NewDumpCmd() *cobra.Command { var outFile string - cmdDump := &cobra.Command{ + cmd := &cobra.Command{ Use: "dump", Short: "Dump all your configuration to a zip file for easier support", Long: `Dump the following informations: @@ -415,8 +427,8 @@ cscli support dump -f /tmp/crowdsec-support.zip log.Infof("Written zip file to %s", outFile) }, } - cmdDump.Flags().StringVarP(&outFile, "outFile", "f", "", "File to dump the information to") - cmdSupport.AddCommand(cmdDump) - return cmdSupport + cmd.Flags().StringVarP(&outFile, "outFile", "f", "", "File to dump the information to") + + return cmd }