crowdsec/cmd/crowdsec-cli/clibouncer/prune.go
mmetc b12ade27f4
cscli: review/update argument number checking (#3490)
* cscsli: remove unused Command.Args setting

* cscli: review/update argument number checking

cscli will consistently print the help text if the number of arguments is
wrong for the command, but not for other types of errors.

* fix func tests

* lint
2025-03-04 12:21:27 +01:00

86 lines
2.1 KiB
Go

package clibouncer
import (
"context"
"fmt"
"os"
"time"
"github.com/fatih/color"
"github.com/spf13/cobra"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/args"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/ask"
)
func (cli *cliBouncers) prune(ctx context.Context, duration time.Duration, force bool) error {
if duration < 2*time.Minute {
if yes, err := ask.YesNo(
"The duration you provided is less than 2 minutes. "+
"This may remove active bouncers. Continue?", false); err != nil {
return err
} else if !yes {
fmt.Println("User aborted prune. No changes were made.")
return nil
}
}
bouncers, err := cli.db.QueryBouncersInactiveSince(ctx, time.Now().UTC().Add(-duration))
if err != nil {
return fmt.Errorf("unable to query bouncers: %w", err)
}
if len(bouncers) == 0 {
fmt.Println("No bouncers to prune.")
return nil
}
cli.listHuman(color.Output, bouncers)
if !force {
if yes, err := ask.YesNo(
"You are about to PERMANENTLY remove the above bouncers from the database. "+
"These will NOT be recoverable. Continue?", false); err != nil {
return err
} else if !yes {
fmt.Println("User aborted prune. No changes were made.")
return nil
}
}
deleted, err := cli.db.BulkDeleteBouncers(ctx, bouncers)
if err != nil {
return fmt.Errorf("unable to prune bouncers: %w", err)
}
fmt.Fprintf(os.Stderr, "Successfully deleted %d bouncers\n", deleted)
return nil
}
func (cli *cliBouncers) newPruneCmd() *cobra.Command {
var (
duration time.Duration
force bool
)
const defaultDuration = 60 * time.Minute
cmd := &cobra.Command{
Use: "prune",
Short: "prune multiple bouncers from the database",
Args: args.NoArgs,
DisableAutoGenTag: true,
Example: `cscli bouncers prune -d 45m
cscli bouncers prune -d 45m --force`,
RunE: func(cmd *cobra.Command, _ []string) error {
return cli.prune(cmd.Context(), duration, force)
},
}
flags := cmd.Flags()
flags.DurationVarP(&duration, "duration", "d", defaultDuration, "duration of time since last pull")
flags.BoolVar(&force, "force", false, "force prune without asking for confirmation")
return cmd
}