Skip to content

Commit

Permalink
cscli refact - encapsulation with types (#2643)
Browse files Browse the repository at this point in the history
* refactor type cliHub, cliBouncers, cliMachines, cliPapi, cliNotifications, cliSupport, type cliExplain
  • Loading branch information
mmetc authored Dec 7, 2023
1 parent 8cca434 commit 3e86f52
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 255 deletions.
108 changes: 57 additions & 51 deletions cmd/crowdsec-cli/bouncers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand All @@ -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()
Expand Down Expand Up @@ -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 <random-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 {
Expand All @@ -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),
Expand All @@ -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,
Expand Down Expand Up @@ -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
}
152 changes: 79 additions & 73 deletions cmd/crowdsec-cli/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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
}
Loading

0 comments on commit 3e86f52

Please sign in to comment.