mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-11 20:36:12 +02:00
cscli: add option --ignore-missing to "bouncers delete", "machines delete" (#3177)
* cscli: add option --ignore-missing to "bouncers delete", "machines delete" * lint
This commit is contained in:
parent
71a253aea6
commit
48e3f51954
6 changed files with 69 additions and 16 deletions
|
@ -344,11 +344,15 @@ func (cli *cliBouncers) validBouncerID(cmd *cobra.Command, args []string, toComp
|
|||
return ret, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
func (cli *cliBouncers) delete(bouncers []string) error {
|
||||
func (cli *cliBouncers) delete(bouncers []string, ignoreMissing bool) error {
|
||||
for _, bouncerID := range bouncers {
|
||||
err := cli.db.DeleteBouncer(bouncerID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to delete bouncer '%s': %w", bouncerID, err)
|
||||
if err := cli.db.DeleteBouncer(bouncerID); err != nil {
|
||||
var notFoundErr *database.BouncerNotFoundError
|
||||
if ignoreMissing && errors.As(err, ¬FoundErr) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("unable to delete bouncer: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("bouncer '%s' deleted successfully", bouncerID)
|
||||
|
@ -358,18 +362,24 @@ func (cli *cliBouncers) delete(bouncers []string) error {
|
|||
}
|
||||
|
||||
func (cli *cliBouncers) newDeleteCmd() *cobra.Command {
|
||||
var ignoreMissing bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete MyBouncerName",
|
||||
Short: "delete bouncer(s) from the database",
|
||||
Example: `cscli bouncers delete "bouncer1" "bouncer2"`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Aliases: []string{"remove"},
|
||||
DisableAutoGenTag: true,
|
||||
ValidArgsFunction: cli.validBouncerID,
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
return cli.delete(args)
|
||||
return cli.delete(args, ignoreMissing)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&ignoreMissing, "ignore-missing", false, "don't print errors if one or more bouncers don't exist")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -488,10 +488,16 @@ func (cli *cliMachines) validMachineID(cmd *cobra.Command, args []string, toComp
|
|||
return ret, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
func (cli *cliMachines) delete(machines []string) error {
|
||||
func (cli *cliMachines) delete(machines []string, ignoreMissing bool) error {
|
||||
for _, machineID := range machines {
|
||||
if err := cli.db.DeleteWatcher(machineID); err != nil {
|
||||
log.Errorf("unable to delete machine '%s': %s", machineID, err)
|
||||
var notFoundErr *database.MachineNotFoundError
|
||||
if ignoreMissing && errors.As(err, ¬FoundErr) {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Errorf("unable to delete machine: %s", err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -502,6 +508,8 @@ func (cli *cliMachines) delete(machines []string) error {
|
|||
}
|
||||
|
||||
func (cli *cliMachines) newDeleteCmd() *cobra.Command {
|
||||
var ignoreMissing bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete [machine_name]...",
|
||||
Short: "delete machine(s) by name",
|
||||
|
@ -511,10 +519,13 @@ func (cli *cliMachines) newDeleteCmd() *cobra.Command {
|
|||
DisableAutoGenTag: true,
|
||||
ValidArgsFunction: cli.validMachineID,
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
return cli.delete(args)
|
||||
return cli.delete(args, ignoreMissing)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&ignoreMissing, "ignore-missing", false, "don't print errors if one or more machines don't exist")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,14 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||
)
|
||||
|
||||
type BouncerNotFoundError struct {
|
||||
BouncerName string
|
||||
}
|
||||
|
||||
func (e *BouncerNotFoundError) Error() string {
|
||||
return fmt.Sprintf("'%s' does not exist", e.BouncerName)
|
||||
}
|
||||
|
||||
func (c *Client) BouncerUpdateBaseMetrics(bouncerName string, bouncerType string, baseMetrics models.BaseMetrics) error {
|
||||
os := baseMetrics.Os
|
||||
features := strings.Join(baseMetrics.FeatureFlags, ",")
|
||||
|
@ -88,7 +96,7 @@ func (c *Client) DeleteBouncer(name string) error {
|
|||
}
|
||||
|
||||
if nbDeleted == 0 {
|
||||
return errors.New("bouncer doesn't exist")
|
||||
return &BouncerNotFoundError{BouncerName: name}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -21,6 +21,14 @@ const (
|
|||
CapiListsMachineID = types.ListOrigin
|
||||
)
|
||||
|
||||
type MachineNotFoundError struct {
|
||||
MachineID string
|
||||
}
|
||||
|
||||
func (e *MachineNotFoundError) Error() string {
|
||||
return fmt.Sprintf("'%s' does not exist", e.MachineID)
|
||||
}
|
||||
|
||||
func (c *Client) MachineUpdateBaseMetrics(machineID string, baseMetrics models.BaseMetrics, hubItems models.HubItems, datasources map[string]int64) error {
|
||||
os := baseMetrics.Os
|
||||
features := strings.Join(baseMetrics.FeatureFlags, ",")
|
||||
|
@ -168,7 +176,7 @@ func (c *Client) DeleteWatcher(name string) error {
|
|||
}
|
||||
|
||||
if nbDeleted == 0 {
|
||||
return errors.New("machine doesn't exist")
|
||||
return &MachineNotFoundError{MachineID: name}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -197,8 +205,8 @@ func (c *Client) UpdateMachineLastHeartBeat(machineID string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) UpdateMachineScenarios(scenarios string, ID int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(ID).
|
||||
func (c *Client) UpdateMachineScenarios(scenarios string, id int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(id).
|
||||
SetUpdatedAt(time.Now().UTC()).
|
||||
SetScenarios(scenarios).
|
||||
Save(c.CTX)
|
||||
|
@ -209,8 +217,8 @@ func (c *Client) UpdateMachineScenarios(scenarios string, ID int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) UpdateMachineIP(ipAddr string, ID int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(ID).
|
||||
func (c *Client) UpdateMachineIP(ipAddr string, id int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(id).
|
||||
SetIpAddress(ipAddr).
|
||||
Save(c.CTX)
|
||||
if err != nil {
|
||||
|
@ -220,8 +228,8 @@ func (c *Client) UpdateMachineIP(ipAddr string, ID int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) UpdateMachineVersion(ipAddr string, ID int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(ID).
|
||||
func (c *Client) UpdateMachineVersion(ipAddr string, id int) error {
|
||||
_, err := c.Ent.Machine.UpdateOneID(id).
|
||||
SetVersion(ipAddr).
|
||||
Save(c.CTX)
|
||||
if err != nil {
|
||||
|
|
|
@ -60,6 +60,14 @@ teardown() {
|
|||
assert_json '{message:"access forbidden"}'
|
||||
}
|
||||
|
||||
@test "delete non-existent bouncer" {
|
||||
# this is a fatal error, which is not consistent with "machines delete"
|
||||
rune -1 cscli bouncers delete something
|
||||
assert_stderr --partial "unable to delete bouncer: 'something' does not exist"
|
||||
rune -0 cscli bouncers delete something --ignore-missing
|
||||
refute_stderr
|
||||
}
|
||||
|
||||
@test "bouncers delete has autocompletion" {
|
||||
rune -0 cscli bouncers add foo1
|
||||
rune -0 cscli bouncers add foo2
|
||||
|
|
|
@ -62,6 +62,14 @@ teardown() {
|
|||
assert_output 1
|
||||
}
|
||||
|
||||
@test "delete non-existent machine" {
|
||||
# this is not a fatal error, won't halt a script with -e
|
||||
rune -0 cscli machines delete something
|
||||
assert_stderr --partial "unable to delete machine: 'something' does not exist"
|
||||
rune -0 cscli machines delete something --ignore-missing
|
||||
refute_stderr
|
||||
}
|
||||
|
||||
@test "machines [delete|inspect] has autocompletion" {
|
||||
rune -0 cscli machines add -a -f /dev/null foo1
|
||||
rune -0 cscli machines add -a -f /dev/null foo2
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue