refact alert, decision filters: remove unnecessary pointers (#3607)

This commit is contained in:
mmetc 2025-05-06 15:34:50 +02:00 committed by GitHub
parent 4527ad0fa8
commit 0e8b557402
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 128 additions and 227 deletions

View file

@ -104,15 +104,15 @@ func (cli *cliAlerts) alertsToTable(alerts *models.GetAlertsResponse, printMachi
if *alerts == nil { if *alerts == nil {
// avoid returning "null" in json // avoid returning "null" in json
// could be cleaner if we used slice of alerts directly // could be cleaner if we used slice of alerts directly
fmt.Println("[]") fmt.Fprintln(os.Stdout, "[]")
return nil return nil
} }
x, _ := json.MarshalIndent(alerts, "", " ") x, _ := json.MarshalIndent(alerts, "", " ")
fmt.Print(string(x)) fmt.Fprint(os.Stdout, string(x))
case "human": case "human":
if len(*alerts) == 0 { if len(*alerts) == 0 {
fmt.Println("No active alerts") fmt.Fprintln(os.Stdout, "No active alerts")
return nil return nil
} }
@ -156,7 +156,7 @@ func (cli *cliAlerts) displayOneAlert(alert *models.Alert, withDetail bool) erro
alertDecisionsTable(color.Output, cfg.Cscli.Color, alert) alertDecisionsTable(color.Output, cfg.Cscli.Color, alert)
if len(alert.Meta) > 0 { if len(alert.Meta) > 0 {
fmt.Printf("\n - Context :\n") fmt.Fprintf(os.Stdout, "\n - Context :\n")
sort.Slice(alert.Meta, func(i, j int) bool { sort.Slice(alert.Meta, func(i, j int) bool {
return alert.Meta[i].Key < alert.Meta[j].Key return alert.Meta[i].Key < alert.Meta[j].Key
}) })
@ -183,7 +183,7 @@ func (cli *cliAlerts) displayOneAlert(alert *models.Alert, withDetail bool) erro
} }
if withDetail { if withDetail {
fmt.Printf("\n - Events :\n") fmt.Fprintf(os.Stdout, "\n - Events :\n")
for _, event := range alert.Events { for _, event := range alert.Events {
alertEventTable(color.Output, cfg.Cscli.Color, event) alertEventTable(color.Output, cfg.Cscli.Color, event)
@ -240,7 +240,7 @@ func (cli *cliAlerts) NewCommand() *cobra.Command {
func (cli *cliAlerts) list(ctx context.Context, alertListFilter apiclient.AlertsListOpts, limit *int, contained *bool, printMachine bool) error { func (cli *cliAlerts) list(ctx context.Context, alertListFilter apiclient.AlertsListOpts, limit *int, contained *bool, printMachine bool) error {
var err error var err error
*alertListFilter.ScopeEquals, err = SanitizeScope(*alertListFilter.ScopeEquals, *alertListFilter.IPEquals, *alertListFilter.RangeEquals) alertListFilter.ScopeEquals, err = SanitizeScope(alertListFilter.ScopeEquals, alertListFilter.IPEquals, alertListFilter.RangeEquals)
if err != nil { if err != nil {
return err return err
} }
@ -253,34 +253,6 @@ func (cli *cliAlerts) list(ctx context.Context, alertListFilter apiclient.Alerts
*alertListFilter.Limit = 0 *alertListFilter.Limit = 0
} }
if *alertListFilter.TypeEquals == "" {
alertListFilter.TypeEquals = nil
}
if *alertListFilter.ScopeEquals == "" {
alertListFilter.ScopeEquals = nil
}
if *alertListFilter.ValueEquals == "" {
alertListFilter.ValueEquals = nil
}
if *alertListFilter.ScenarioEquals == "" {
alertListFilter.ScenarioEquals = nil
}
if *alertListFilter.IPEquals == "" {
alertListFilter.IPEquals = nil
}
if *alertListFilter.RangeEquals == "" {
alertListFilter.RangeEquals = nil
}
if *alertListFilter.OriginEquals == "" {
alertListFilter.OriginEquals = nil
}
if contained != nil && *contained { if contained != nil && *contained {
alertListFilter.Contains = new(bool) alertListFilter.Contains = new(bool)
} }
@ -299,16 +271,16 @@ func (cli *cliAlerts) list(ctx context.Context, alertListFilter apiclient.Alerts
func (cli *cliAlerts) newListCmd() *cobra.Command { func (cli *cliAlerts) newListCmd() *cobra.Command {
alertListFilter := apiclient.AlertsListOpts{ alertListFilter := apiclient.AlertsListOpts{
ScopeEquals: new(string), ScopeEquals: "",
ValueEquals: new(string), ValueEquals: "",
ScenarioEquals: new(string), ScenarioEquals: "",
IPEquals: new(string), IPEquals: "",
RangeEquals: new(string), RangeEquals: "",
Since: cstime.DurationWithDays(0), Since: cstime.DurationWithDays(0),
Until: cstime.DurationWithDays(0), Until: cstime.DurationWithDays(0),
TypeEquals: new(string), TypeEquals: "",
IncludeCAPI: new(bool), IncludeCAPI: new(bool),
OriginEquals: new(string), OriginEquals: "",
} }
limit := new(int) limit := new(int)
@ -338,13 +310,13 @@ cscli alerts list --type ban`,
flags.BoolVarP(alertListFilter.IncludeCAPI, "all", "a", false, "Include decisions from Central API") flags.BoolVarP(alertListFilter.IncludeCAPI, "all", "a", false, "Include decisions from Central API")
flags.Var(&alertListFilter.Until, "until", "restrict to alerts older than until (ie. 4h, 30d)") flags.Var(&alertListFilter.Until, "until", "restrict to alerts older than until (ie. 4h, 30d)")
flags.Var(&alertListFilter.Since, "since", "restrict to alerts newer than since (ie. 4h, 30d)") flags.Var(&alertListFilter.Since, "since", "restrict to alerts newer than since (ie. 4h, 30d)")
flags.StringVarP(alertListFilter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)") flags.StringVarP(&alertListFilter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)")
flags.StringVarP(alertListFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)") flags.StringVarP(&alertListFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)")
flags.StringVarP(alertListFilter.RangeEquals, "range", "r", "", "restrict to alerts from this range (shorthand for --scope range --value <RANGE/X>)") flags.StringVarP(&alertListFilter.RangeEquals, "range", "r", "", "restrict to alerts from this range (shorthand for --scope range --value <RANGE/X>)")
flags.StringVar(alertListFilter.TypeEquals, "type", "", "restrict to alerts with given decision type (ie. ban, captcha)") flags.StringVar(&alertListFilter.TypeEquals, "type", "", "restrict to alerts with given decision type (ie. ban, captcha)")
flags.StringVar(alertListFilter.ScopeEquals, "scope", "", "restrict to alerts of this scope (ie. ip,range)") flags.StringVar(&alertListFilter.ScopeEquals, "scope", "", "restrict to alerts of this scope (ie. ip,range)")
flags.StringVarP(alertListFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") flags.StringVarP(&alertListFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
flags.StringVar(alertListFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) flags.StringVar(&alertListFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
flags.BoolVar(contained, "contained", false, "query decisions contained by range") flags.BoolVar(contained, "contained", false, "query decisions contained by range")
flags.BoolVarP(&printMachine, "machine", "m", false, "print machines that sent alerts") flags.BoolVarP(&printMachine, "machine", "m", false, "print machines that sent alerts")
flags.IntVarP(limit, "limit", "l", 50, "limit size of alerts list table (0 to view all alerts)") flags.IntVarP(limit, "limit", "l", 50, "limit size of alerts list table (0 to view all alerts)")
@ -356,7 +328,7 @@ func (cli *cliAlerts) delete(ctx context.Context, delFilter apiclient.AlertsDele
var err error var err error
if !deleteAll { if !deleteAll {
*delFilter.ScopeEquals, err = SanitizeScope(*delFilter.ScopeEquals, *delFilter.IPEquals, *delFilter.RangeEquals) delFilter.ScopeEquals, err = SanitizeScope(delFilter.ScopeEquals, delFilter.IPEquals, delFilter.RangeEquals)
if err != nil { if err != nil {
return err return err
} }
@ -365,26 +337,6 @@ func (cli *cliAlerts) delete(ctx context.Context, delFilter apiclient.AlertsDele
delFilter.ActiveDecisionEquals = activeDecision delFilter.ActiveDecisionEquals = activeDecision
} }
if *delFilter.ScopeEquals == "" {
delFilter.ScopeEquals = nil
}
if *delFilter.ValueEquals == "" {
delFilter.ValueEquals = nil
}
if *delFilter.ScenarioEquals == "" {
delFilter.ScenarioEquals = nil
}
if *delFilter.IPEquals == "" {
delFilter.IPEquals = nil
}
if *delFilter.RangeEquals == "" {
delFilter.RangeEquals = nil
}
if contained != nil && *contained { if contained != nil && *contained {
delFilter.Contains = new(bool) delFilter.Contains = new(bool)
} }
@ -422,11 +374,11 @@ func (cli *cliAlerts) newDeleteCmd() *cobra.Command {
) )
delFilter := apiclient.AlertsDeleteOpts{ delFilter := apiclient.AlertsDeleteOpts{
ScopeEquals: new(string), ScopeEquals: "",
ValueEquals: new(string), ValueEquals: "",
ScenarioEquals: new(string), ScenarioEquals: "",
IPEquals: new(string), IPEquals: "",
RangeEquals: new(string), RangeEquals: "",
} }
contained := new(bool) contained := new(bool)
@ -445,9 +397,9 @@ cscli alerts delete -s crowdsecurity/ssh-bf"`,
if deleteAll { if deleteAll {
return nil return nil
} }
if *delFilter.ScopeEquals == "" && *delFilter.ValueEquals == "" && if delFilter.ScopeEquals == "" && delFilter.ValueEquals == "" &&
*delFilter.ScenarioEquals == "" && *delFilter.IPEquals == "" && delFilter.ScenarioEquals == "" && delFilter.IPEquals == "" &&
*delFilter.RangeEquals == "" && delAlertByID == "" { delFilter.RangeEquals == "" && delAlertByID == "" {
_ = cmd.Usage() _ = cmd.Usage()
return errors.New("at least one filter or --all must be specified") return errors.New("at least one filter or --all must be specified")
} }
@ -461,11 +413,11 @@ cscli alerts delete -s crowdsecurity/ssh-bf"`,
flags := cmd.Flags() flags := cmd.Flags()
flags.SortFlags = false flags.SortFlags = false
flags.StringVar(delFilter.ScopeEquals, "scope", "", "the scope (ie. ip,range)") flags.StringVar(&delFilter.ScopeEquals, "scope", "", "the scope (ie. ip,range)")
flags.StringVarP(delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") flags.StringVarP(&delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
flags.StringVarP(delFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)") flags.StringVarP(&delFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)")
flags.StringVarP(delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)") flags.StringVarP(&delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)")
flags.StringVarP(delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)") flags.StringVarP(&delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)")
flags.StringVar(&delAlertByID, "id", "", "alert ID") flags.StringVar(&delAlertByID, "id", "", "alert ID")
flags.BoolVarP(&deleteAll, "all", "a", false, "delete all alerts") flags.BoolVarP(&deleteAll, "all", "a", false, "delete all alerts")
flags.BoolVar(contained, "contained", false, "query decisions contained by range") flags.BoolVar(contained, "contained", false, "query decisions contained by range")
@ -499,14 +451,14 @@ func (cli *cliAlerts) inspect(ctx context.Context, details bool, alertIDs ...str
return fmt.Errorf("unable to serialize alert with id %s: %w", alertID, err) return fmt.Errorf("unable to serialize alert with id %s: %w", alertID, err)
} }
fmt.Printf("%s\n", string(data)) fmt.Fprintln(os.Stdout, string(data))
case "raw": case "raw":
data, err := yaml.Marshal(alert) data, err := yaml.Marshal(alert)
if err != nil { if err != nil {
return fmt.Errorf("unable to serialize alert with id %s: %w", alertID, err) return fmt.Errorf("unable to serialize alert with id %s: %w", alertID, err)
} }
fmt.Println(string(data)) fmt.Fprintln(os.Stdout, string(data))
} }
} }
@ -536,7 +488,7 @@ func (cli *cliAlerts) newInspectCmd() *cobra.Command {
func (cli *cliAlerts) newFlushCmd() *cobra.Command { func (cli *cliAlerts) newFlushCmd() *cobra.Command {
var maxItems int var maxItems int
maxAge := cstime.DurationWithDays(7*24*time.Hour) maxAge := cstime.DurationWithDays(7 * 24 * time.Hour)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: `flush`, Use: `flush`,

View file

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/url" "net/url"
"os"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
@ -283,7 +284,7 @@ func (cli *cliAllowLists) create(ctx context.Context, db *database.Client, name
return err return err
} }
fmt.Printf("allowlist '%s' created successfully\n", name) fmt.Fprintf(os.Stdout, "allowlist '%s' created successfully\n", name)
return nil return nil
} }
@ -392,7 +393,7 @@ func (cli *cliAllowLists) delete(ctx context.Context, db *database.Client, name
return err return err
} }
fmt.Printf("allowlist '%s' deleted successfully\n", name) fmt.Fprintf(os.Stdout, "allowlist '%s' deleted successfully\n", name)
return nil return nil
} }
@ -475,7 +476,7 @@ func (cli *cliAllowLists) add(ctx context.Context, db *database.Client, name str
} }
if len(toAdd) == 0 { if len(toAdd) == 0 {
fmt.Println("no new values for allowlist") fmt.Fprintln(os.Stdout, "no new values for allowlist")
return nil return nil
} }
@ -485,7 +486,7 @@ func (cli *cliAllowLists) add(ctx context.Context, db *database.Client, name str
} }
if added > 0 { if added > 0 {
fmt.Printf("added %d values to allowlist %s\n", added, name) fmt.Fprintf(os.Stdout, "added %d values to allowlist %s\n", added, name)
} }
deleted, err := db.ApplyAllowlistsToExistingDecisions(ctx) deleted, err := db.ApplyAllowlistsToExistingDecisions(ctx)
@ -622,7 +623,7 @@ func (cli *cliAllowLists) remove(ctx context.Context, db *database.Client, name
} }
if len(toRemove) == 0 { if len(toRemove) == 0 {
fmt.Println("no value to remove from allowlist") fmt.Fprintln(os.Stdout, "no value to remove from allowlist")
return nil return nil
} }
@ -632,7 +633,7 @@ func (cli *cliAllowLists) remove(ctx context.Context, db *database.Client, name
} }
if deleted > 0 { if deleted > 0 {
fmt.Printf("removed %d values from allowlist %s", deleted, name) fmt.Fprintf(os.Stdout, "removed %d values from allowlist %s", deleted, name)
} }
return nil return nil

View file

@ -103,22 +103,22 @@ func (cli *cliDecisions) decisionsToTable(alerts *models.GetAlertsResponse, prin
if *alerts == nil { if *alerts == nil {
// avoid returning "null" in `json" // avoid returning "null" in `json"
// could be cleaner if we used slice of alerts directly // could be cleaner if we used slice of alerts directly
fmt.Println("[]") fmt.Fprintln(os.Stdout, "[]")
return nil return nil
} }
x, _ := json.MarshalIndent(alerts, "", " ") x, _ := json.MarshalIndent(alerts, "", " ")
fmt.Printf("%s", string(x)) fmt.Fprintln(os.Stdout, string(x))
case "human": case "human":
if len(*alerts) == 0 { if len(*alerts) == 0 {
fmt.Println("No active decisions") fmt.Fprintln(os.Stdout, "No active decisions")
return nil return nil
} }
cli.decisionsTable(color.Output, alerts, printMachine) cli.decisionsTable(color.Output, alerts, printMachine)
if skipped > 0 { if skipped > 0 {
fmt.Printf("%d duplicated entries skipped\n", skipped) fmt.Fprintf(os.Stdout, "%d duplicated entries skipped\n", skipped)
} }
} }
@ -175,7 +175,7 @@ func (cli *cliDecisions) NewCommand() *cobra.Command {
func (cli *cliDecisions) list(ctx context.Context, filter apiclient.AlertsListOpts, noSimu *bool, contained *bool, printMachine bool) error { func (cli *cliDecisions) list(ctx context.Context, filter apiclient.AlertsListOpts, noSimu *bool, contained *bool, printMachine bool) error {
var err error var err error
*filter.ScopeEquals, err = clialert.SanitizeScope(*filter.ScopeEquals, *filter.IPEquals, *filter.RangeEquals) filter.ScopeEquals, err = clialert.SanitizeScope(filter.ScopeEquals, filter.IPEquals, filter.RangeEquals)
if err != nil { if err != nil {
return err return err
} }
@ -193,34 +193,6 @@ func (cli *cliDecisions) list(ctx context.Context, filter apiclient.AlertsListOp
*filter.Limit = 0 *filter.Limit = 0
} }
if *filter.TypeEquals == "" {
filter.TypeEquals = nil
}
if *filter.ValueEquals == "" {
filter.ValueEquals = nil
}
if *filter.ScopeEquals == "" {
filter.ScopeEquals = nil
}
if *filter.ScenarioEquals == "" {
filter.ScenarioEquals = nil
}
if *filter.IPEquals == "" {
filter.IPEquals = nil
}
if *filter.RangeEquals == "" {
filter.RangeEquals = nil
}
if *filter.OriginEquals == "" {
filter.OriginEquals = nil
}
if contained != nil && *contained { if contained != nil && *contained {
filter.Contains = new(bool) filter.Contains = new(bool)
} }
@ -240,15 +212,15 @@ func (cli *cliDecisions) list(ctx context.Context, filter apiclient.AlertsListOp
func (cli *cliDecisions) newListCmd() *cobra.Command { func (cli *cliDecisions) newListCmd() *cobra.Command {
filter := apiclient.AlertsListOpts{ filter := apiclient.AlertsListOpts{
ValueEquals: new(string), ValueEquals: "",
ScopeEquals: new(string), ScopeEquals: "",
ScenarioEquals: new(string), ScenarioEquals: "",
OriginEquals: new(string), OriginEquals: "",
IPEquals: new(string), IPEquals: "",
RangeEquals: new(string), RangeEquals: "",
Since: cstime.DurationWithDays(0), Since: cstime.DurationWithDays(0),
Until: cstime.DurationWithDays(0), Until: cstime.DurationWithDays(0),
TypeEquals: new(string), TypeEquals: "",
IncludeCAPI: new(bool), IncludeCAPI: new(bool),
Limit: new(int), Limit: new(int),
} }
@ -278,13 +250,13 @@ cscli decisions list --origin lists --scenario list_name
flags.BoolVarP(filter.IncludeCAPI, "all", "a", false, "Include decisions from Central API") flags.BoolVarP(filter.IncludeCAPI, "all", "a", false, "Include decisions from Central API")
flags.Var(&filter.Since, "since", "restrict to alerts newer than since (ie. 4h, 30d)") flags.Var(&filter.Since, "since", "restrict to alerts newer than since (ie. 4h, 30d)")
flags.Var(&filter.Until, "until", "restrict to alerts older than until (ie. 4h, 30d)") flags.Var(&filter.Until, "until", "restrict to alerts older than until (ie. 4h, 30d)")
flags.StringVarP(filter.TypeEquals, "type", "t", "", "restrict to this decision type (ie. ban,captcha)") flags.StringVarP(&filter.TypeEquals, "type", "t", "", "restrict to this decision type (ie. ban,captcha)")
flags.StringVar(filter.ScopeEquals, "scope", "", "restrict to this scope (ie. ip,range,session)") flags.StringVar(&filter.ScopeEquals, "scope", "", "restrict to this scope (ie. ip,range,session)")
flags.StringVar(filter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) flags.StringVar(&filter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
flags.StringVarP(filter.ValueEquals, "value", "v", "", "restrict to this value (ie. 1.2.3.4,userName)") flags.StringVarP(&filter.ValueEquals, "value", "v", "", "restrict to this value (ie. 1.2.3.4,userName)")
flags.StringVarP(filter.ScenarioEquals, "scenario", "s", "", "restrict to this scenario (ie. crowdsecurity/ssh-bf)") flags.StringVarP(&filter.ScenarioEquals, "scenario", "s", "", "restrict to this scenario (ie. crowdsecurity/ssh-bf)")
flags.StringVarP(filter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)") flags.StringVarP(&filter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)")
flags.StringVarP(filter.RangeEquals, "range", "r", "", "restrict to alerts from this source range (shorthand for --scope range --value <RANGE>)") flags.StringVarP(&filter.RangeEquals, "range", "r", "", "restrict to alerts from this source range (shorthand for --scope range --value <RANGE>)")
flags.IntVarP(filter.Limit, "limit", "l", 100, "number of alerts to get (use 0 to remove the limit)") flags.IntVarP(filter.Limit, "limit", "l", 100, "number of alerts to get (use 0 to remove the limit)")
flags.BoolVar(NoSimu, "no-simu", false, "exclude decisions in simulation mode") flags.BoolVar(NoSimu, "no-simu", false, "exclude decisions in simulation mode")
flags.BoolVarP(&printMachine, "machine", "m", false, "print machines that triggered decisions") flags.BoolVarP(&printMachine, "machine", "m", false, "print machines that triggered decisions")
@ -428,39 +400,11 @@ func (cli *cliDecisions) delete(ctx context.Context, delFilter apiclient.Decisio
var err error var err error
/*take care of shorthand options*/ /*take care of shorthand options*/
*delFilter.ScopeEquals, err = clialert.SanitizeScope(*delFilter.ScopeEquals, *delFilter.IPEquals, *delFilter.RangeEquals) delFilter.ScopeEquals, err = clialert.SanitizeScope(delFilter.ScopeEquals, delFilter.IPEquals, delFilter.RangeEquals)
if err != nil { if err != nil {
return err return err
} }
if *delFilter.ScopeEquals == "" {
delFilter.ScopeEquals = nil
}
if *delFilter.OriginEquals == "" {
delFilter.OriginEquals = nil
}
if *delFilter.ValueEquals == "" {
delFilter.ValueEquals = nil
}
if *delFilter.ScenarioEquals == "" {
delFilter.ScenarioEquals = nil
}
if *delFilter.TypeEquals == "" {
delFilter.TypeEquals = nil
}
if *delFilter.IPEquals == "" {
delFilter.IPEquals = nil
}
if *delFilter.RangeEquals == "" {
delFilter.RangeEquals = nil
}
if contained != nil && *contained { if contained != nil && *contained {
delFilter.Contains = new(bool) delFilter.Contains = new(bool)
} }
@ -490,13 +434,13 @@ func (cli *cliDecisions) delete(ctx context.Context, delFilter apiclient.Decisio
func (cli *cliDecisions) newDeleteCmd() *cobra.Command { func (cli *cliDecisions) newDeleteCmd() *cobra.Command {
delFilter := apiclient.DecisionsDeleteOpts{ delFilter := apiclient.DecisionsDeleteOpts{
ScopeEquals: new(string), ScopeEquals: "",
ValueEquals: new(string), ValueEquals: "",
TypeEquals: new(string), TypeEquals: "",
IPEquals: new(string), IPEquals: "",
RangeEquals: new(string), RangeEquals: "",
ScenarioEquals: new(string), ScenarioEquals: "",
OriginEquals: new(string), OriginEquals: "",
} }
var delDecisionID string var delDecisionID string
@ -522,10 +466,10 @@ cscli decisions delete --origin lists --scenario list_name
if delDecisionAll { if delDecisionAll {
return nil return nil
} }
if *delFilter.ScopeEquals == "" && *delFilter.ValueEquals == "" && if delFilter.ScopeEquals == "" && delFilter.ValueEquals == "" &&
*delFilter.TypeEquals == "" && *delFilter.IPEquals == "" && delFilter.TypeEquals == "" && delFilter.IPEquals == "" &&
*delFilter.RangeEquals == "" && *delFilter.ScenarioEquals == "" && delFilter.RangeEquals == "" && delFilter.ScenarioEquals == "" &&
*delFilter.OriginEquals == "" && delDecisionID == "" { delFilter.OriginEquals == "" && delDecisionID == "" {
_ = cmd.Usage() _ = cmd.Usage()
return errors.New("at least one filter or --all must be specified") return errors.New("at least one filter or --all must be specified")
} }
@ -539,12 +483,12 @@ cscli decisions delete --origin lists --scenario list_name
flags := cmd.Flags() flags := cmd.Flags()
flags.SortFlags = false flags.SortFlags = false
flags.StringVarP(delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)") flags.StringVarP(&delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)")
flags.StringVarP(delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)") flags.StringVarP(&delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)")
flags.StringVarP(delFilter.TypeEquals, "type", "t", "", "the decision type (ie. ban,captcha)") flags.StringVarP(&delFilter.TypeEquals, "type", "t", "", "the decision type (ie. ban,captcha)")
flags.StringVarP(delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") flags.StringVarP(&delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
flags.StringVarP(delFilter.ScenarioEquals, "scenario", "s", "", "the scenario name (ie. crowdsecurity/ssh-bf)") flags.StringVarP(&delFilter.ScenarioEquals, "scenario", "s", "", "the scenario name (ie. crowdsecurity/ssh-bf)")
flags.StringVar(delFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) flags.StringVar(&delFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
flags.StringVar(&delDecisionID, "id", "", "decision id") flags.StringVar(&delDecisionID, "id", "", "decision id")
flags.BoolVar(&delDecisionAll, "all", false, "delete all decisions") flags.BoolVar(&delDecisionAll, "all", false, "delete all decisions")

View file

@ -15,14 +15,14 @@ import (
type AlertsService service type AlertsService service
type AlertsListOpts struct { type AlertsListOpts struct {
ScopeEquals *string `url:"scope,omitempty"` ScopeEquals string `url:"scope,omitempty"`
ValueEquals *string `url:"value,omitempty"` ValueEquals string `url:"value,omitempty"`
ScenarioEquals *string `url:"scenario,omitempty"` ScenarioEquals string `url:"scenario,omitempty"`
IPEquals *string `url:"ip,omitempty"` IPEquals string `url:"ip,omitempty"`
RangeEquals *string `url:"range,omitempty"` RangeEquals string `url:"range,omitempty"`
OriginEquals *string `url:"origin,omitempty"` OriginEquals string `url:"origin,omitempty"`
Since cstime.DurationWithDays `url:"since,omitempty"` Since cstime.DurationWithDays `url:"since,omitempty"`
TypeEquals *string `url:"decision_type,omitempty"` TypeEquals string `url:"decision_type,omitempty"`
Until cstime.DurationWithDays `url:"until,omitempty"` Until cstime.DurationWithDays `url:"until,omitempty"`
IncludeSimulated *bool `url:"simulated,omitempty"` IncludeSimulated *bool `url:"simulated,omitempty"`
ActiveDecisionEquals *bool `url:"has_active_decision,omitempty"` ActiveDecisionEquals *bool `url:"has_active_decision,omitempty"`
@ -33,16 +33,16 @@ type AlertsListOpts struct {
} }
type AlertsDeleteOpts struct { type AlertsDeleteOpts struct {
ScopeEquals *string `url:"scope,omitempty"` ScopeEquals string `url:"scope,omitempty"`
ValueEquals *string `url:"value,omitempty"` ValueEquals string `url:"value,omitempty"`
ScenarioEquals *string `url:"scenario,omitempty"` ScenarioEquals string `url:"scenario,omitempty"`
IPEquals *string `url:"ip,omitempty"` IPEquals string `url:"ip,omitempty"`
RangeEquals *string `url:"range,omitempty"` RangeEquals string `url:"range,omitempty"`
Since cstime.DurationWithDays `url:"since,omitempty"` Since cstime.DurationWithDays `url:"since,omitempty"`
Until cstime.DurationWithDays `url:"until,omitempty"` Until cstime.DurationWithDays `url:"until,omitempty"`
OriginEquals *string `url:"origin,omitempty"` OriginEquals string `url:"origin,omitempty"`
ActiveDecisionEquals *bool `url:"has_active_decision,omitempty"` ActiveDecisionEquals *bool `url:"has_active_decision,omitempty"`
SourceEquals *string `url:"alert_source,omitempty"` SourceEquals string `url:"alert_source,omitempty"`
Contains *bool `url:"contains,omitempty"` Contains *bool `url:"contains,omitempty"`
Limit *int `url:"limit,omitempty"` Limit *int `url:"limit,omitempty"`
ListOpts ListOpts

View file

@ -18,6 +18,7 @@ import (
func TestAlertsListAsMachine(t *testing.T) { func TestAlertsListAsMachine(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -189,7 +190,7 @@ func TestAlertsListAsMachine(t *testing.T) {
assert.Equal(t, expected, *alerts) assert.Equal(t, expected, *alerts)
// this one doesn't // this one doesn't
filter := AlertsListOpts{IPEquals: ptr.Of("1.2.3.4")} filter := AlertsListOpts{IPEquals: "1.2.3.4"}
alerts, resp, err = client.Alerts.List(ctx, filter) alerts, resp, err = client.Alerts.List(ctx, filter)
require.NoError(t, err) require.NoError(t, err)
@ -199,6 +200,7 @@ func TestAlertsListAsMachine(t *testing.T) {
func TestAlertsGetAsMachine(t *testing.T) { func TestAlertsGetAsMachine(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -367,6 +369,7 @@ func TestAlertsGetAsMachine(t *testing.T) {
func TestAlertsCreateAsMachine(t *testing.T) { func TestAlertsCreateAsMachine(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -410,6 +413,7 @@ func TestAlertsCreateAsMachine(t *testing.T) {
func TestAlertsDeleteAsMachine(t *testing.T) { func TestAlertsDeleteAsMachine(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -442,7 +446,7 @@ func TestAlertsDeleteAsMachine(t *testing.T) {
defer teardown() defer teardown()
alert := AlertsDeleteOpts{IPEquals: ptr.Of("1.2.3.4")} alert := AlertsDeleteOpts{IPEquals: "1.2.3.4"}
alerts, resp, err := client.Alerts.Delete(ctx, alert) alerts, resp, err := client.Alerts.Delete(ctx, alert)
require.NoError(t, err) require.NoError(t, err)

View file

@ -10,11 +10,11 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/crowdsecurity/go-cs-lib/cstest" "github.com/crowdsecurity/go-cs-lib/cstest"
"github.com/crowdsecurity/go-cs-lib/ptr"
) )
func TestApiAuth(t *testing.T) { func TestApiAuth(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.TraceLevel) log.SetLevel(log.TraceLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -40,7 +40,7 @@ func TestApiAuth(t *testing.T) {
defer teardown() defer teardown()
//ok no answer // ok no answer
auth := &APIKeyTransport{ auth := &APIKeyTransport{
APIKey: "ixu", APIKey: "ixu",
} }
@ -48,12 +48,12 @@ func TestApiAuth(t *testing.T) {
newcli, err := NewDefaultClient(apiURL, "v1", "toto", auth.Client()) newcli, err := NewDefaultClient(apiURL, "v1", "toto", auth.Client())
require.NoError(t, err) require.NoError(t, err)
alert := DecisionsListOpts{IPEquals: ptr.Of("1.2.3.4")} alert := DecisionsListOpts{IPEquals: "1.2.3.4"}
_, resp, err := newcli.Decisions.List(ctx, alert) _, resp, err := newcli.Decisions.List(ctx, alert)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.Response.StatusCode) assert.Equal(t, http.StatusOK, resp.Response.StatusCode)
//ko bad token // ko bad token
auth = &APIKeyTransport{ auth = &APIKeyTransport{
APIKey: "bad", APIKey: "bad",
} }
@ -69,7 +69,7 @@ func TestApiAuth(t *testing.T) {
cstest.RequireErrorMessage(t, err, "API error: access forbidden") cstest.RequireErrorMessage(t, err, "API error: access forbidden")
//ko empty token // ko empty token
auth = &APIKeyTransport{} auth = &APIKeyTransport{}
newcli, err = NewDefaultClient(apiURL, "v1", "toto", auth.Client()) newcli, err = NewDefaultClient(apiURL, "v1", "toto", auth.Client())

View file

@ -20,12 +20,12 @@ import (
type DecisionsService service type DecisionsService service
type DecisionsListOpts struct { type DecisionsListOpts struct {
ScopeEquals *string `url:"scope,omitempty"` ScopeEquals string `url:"scope,omitempty"`
ValueEquals *string `url:"value,omitempty"` ValueEquals string `url:"value,omitempty"`
TypeEquals *string `url:"type,omitempty"` TypeEquals string `url:"type,omitempty"`
IPEquals *string `url:"ip,omitempty"` IPEquals string `url:"ip,omitempty"`
RangeEquals *string `url:"range,omitempty"` RangeEquals string `url:"range,omitempty"`
Contains *bool `url:"contains,omitempty"` Contains *bool `url:"contains,omitempty"`
ListOpts ListOpts
} }
@ -60,15 +60,15 @@ func (o *DecisionsStreamOpts) addQueryParamsToURL(url string) (string, error) {
} }
type DecisionsDeleteOpts struct { type DecisionsDeleteOpts struct {
ScopeEquals *string `url:"scope,omitempty"` ScopeEquals string `url:"scope,omitempty"`
ValueEquals *string `url:"value,omitempty"` ValueEquals string `url:"value,omitempty"`
TypeEquals *string `url:"type,omitempty"` TypeEquals string `url:"type,omitempty"`
IPEquals *string `url:"ip,omitempty"` IPEquals string `url:"ip,omitempty"`
RangeEquals *string `url:"range,omitempty"` RangeEquals string `url:"range,omitempty"`
Contains *bool `url:"contains,omitempty"` Contains *bool `url:"contains,omitempty"`
OriginEquals *string `url:"origin,omitempty"` OriginEquals string `url:"origin,omitempty"`
// //
ScenarioEquals *string `url:"scenario,omitempty"` ScenarioEquals string `url:"scenario,omitempty"`
ListOpts ListOpts
} }

View file

@ -19,6 +19,7 @@ import (
func TestDecisionsList(t *testing.T) { func TestDecisionsList(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -64,15 +65,13 @@ func TestDecisionsList(t *testing.T) {
} }
// OK decisions // OK decisions
decisionsFilter := DecisionsListOpts{IPEquals: ptr.Of("1.2.3.4")} decisions, resp, err := newcli.Decisions.List(ctx, DecisionsListOpts{IPEquals: "1.2.3.4"})
decisions, resp, err := newcli.Decisions.List(ctx, decisionsFilter)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.Response.StatusCode) assert.Equal(t, http.StatusOK, resp.Response.StatusCode)
assert.Equal(t, *expected, *decisions) assert.Equal(t, *expected, *decisions)
// Empty return // Empty return
decisionsFilter = DecisionsListOpts{IPEquals: ptr.Of("1.2.3.5")} decisions, resp, err = newcli.Decisions.List(ctx, DecisionsListOpts{IPEquals: "1.2.3.5"})
decisions, resp, err = newcli.Decisions.List(ctx, decisionsFilter)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.Response.StatusCode) assert.Equal(t, http.StatusOK, resp.Response.StatusCode)
assert.Empty(t, *decisions) assert.Empty(t, *decisions)
@ -80,6 +79,7 @@ func TestDecisionsList(t *testing.T) {
func TestDecisionsStream(t *testing.T) { func TestDecisionsStream(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
@ -156,6 +156,7 @@ func TestDecisionsStream(t *testing.T) {
func TestDecisionsStreamV3Compatibility(t *testing.T) { func TestDecisionsStreamV3Compatibility(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3") mux, urlx, teardown := setupWithPrefix("v3")
@ -224,6 +225,7 @@ func TestDecisionsStreamV3Compatibility(t *testing.T) {
func TestDecisionsStreamV3(t *testing.T) { func TestDecisionsStreamV3(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3") mux, urlx, teardown := setupWithPrefix("v3")
@ -297,6 +299,7 @@ func TestDecisionsStreamV3(t *testing.T) {
func TestDecisionsFromBlocklist(t *testing.T) { func TestDecisionsFromBlocklist(t *testing.T) {
ctx := t.Context() ctx := t.Context()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3") mux, urlx, teardown := setupWithPrefix("v3")
@ -429,10 +432,7 @@ func TestDeleteDecisions(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
filters := DecisionsDeleteOpts{IPEquals: new(string)} deleted, _, err := client.Decisions.Delete(ctx, DecisionsDeleteOpts{IPEquals: "1.2.3.4"})
*filters.IPEquals = "1.2.3.4"
deleted, _, err := client.Decisions.Delete(ctx, filters)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "1", deleted.NbDeleted) assert.Equal(t, "1", deleted.NbDeleted)
} }