replace log.Fatal -> fmt.Errorf (#2058)
This commit is contained in:
parent
8fce946850
commit
b7d1e2c483
|
@ -253,13 +253,13 @@ cscli alerts list --range 1.2.3.0/24
|
||||||
cscli alerts list -s crowdsecurity/ssh-bf
|
cscli alerts list -s crowdsecurity/ssh-bf
|
||||||
cscli alerts list --type ban`,
|
cscli alerts list --type ban`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if err := manageCliDecisionAlerts(alertListFilter.IPEquals, alertListFilter.RangeEquals,
|
if err := manageCliDecisionAlerts(alertListFilter.IPEquals, alertListFilter.RangeEquals,
|
||||||
alertListFilter.ScopeEquals, alertListFilter.ValueEquals); err != nil {
|
alertListFilter.ScopeEquals, alertListFilter.ValueEquals); err != nil {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
log.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
if limit != nil {
|
if limit != nil {
|
||||||
alertListFilter.Limit = limit
|
alertListFilter.Limit = limit
|
||||||
|
@ -273,7 +273,7 @@ cscli alerts list --type ban`,
|
||||||
days, err := strconv.Atoi(realDuration)
|
days, err := strconv.Atoi(realDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
log.Fatalf("Can't parse duration %s, valid durations format: 1d, 4h, 4h15m", *alertListFilter.Until)
|
return fmt.Errorf("can't parse duration %s, valid durations format: 1d, 4h, 4h15m", *alertListFilter.Until)
|
||||||
}
|
}
|
||||||
*alertListFilter.Until = fmt.Sprintf("%d%s", days*24, "h")
|
*alertListFilter.Until = fmt.Sprintf("%d%s", days*24, "h")
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ cscli alerts list --type ban`,
|
||||||
days, err := strconv.Atoi(realDuration)
|
days, err := strconv.Atoi(realDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
log.Fatalf("Can't parse duration %s, valid durations format: 1d, 4h, 4h15m", *alertListFilter.Since)
|
return fmt.Errorf("can't parse duration %s, valid durations format: 1d, 4h, 4h15m", *alertListFilter.Since)
|
||||||
}
|
}
|
||||||
*alertListFilter.Since = fmt.Sprintf("%d%s", days*24, "h")
|
*alertListFilter.Since = fmt.Sprintf("%d%s", days*24, "h")
|
||||||
}
|
}
|
||||||
|
@ -323,13 +323,15 @@ cscli alerts list --type ban`,
|
||||||
|
|
||||||
alerts, _, err := Client.Alerts.List(context.Background(), alertListFilter)
|
alerts, _, err := Client.Alerts.List(context.Background(), alertListFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to list alerts : %v", err)
|
return fmt.Errorf("unable to list alerts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AlertsToTable(alerts, printMachine)
|
err = AlertsToTable(alerts, printMachine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to list alerts : %v", err)
|
return fmt.Errorf("unable to list alerts: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdAlertsList.Flags().SortFlags = false
|
cmdAlertsList.Flags().SortFlags = false
|
||||||
|
@ -372,25 +374,27 @@ cscli alerts delete -s crowdsecurity/ssh-bf"`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Aliases: []string{"remove"},
|
Aliases: []string{"remove"},
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if AlertDeleteAll {
|
if AlertDeleteAll {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
if *alertDeleteFilter.ScopeEquals == "" && *alertDeleteFilter.ValueEquals == "" &&
|
if *alertDeleteFilter.ScopeEquals == "" && *alertDeleteFilter.ValueEquals == "" &&
|
||||||
*alertDeleteFilter.ScenarioEquals == "" && *alertDeleteFilter.IPEquals == "" &&
|
*alertDeleteFilter.ScenarioEquals == "" && *alertDeleteFilter.IPEquals == "" &&
|
||||||
*alertDeleteFilter.RangeEquals == "" && delAlertByID == "" {
|
*alertDeleteFilter.RangeEquals == "" && delAlertByID == "" {
|
||||||
_ = cmd.Usage()
|
_ = cmd.Usage()
|
||||||
log.Fatalln("At least one filter or --all must be specified")
|
return fmt.Errorf("at least one filter or --all must be specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if !AlertDeleteAll {
|
if !AlertDeleteAll {
|
||||||
if err := manageCliDecisionAlerts(alertDeleteFilter.IPEquals, alertDeleteFilter.RangeEquals,
|
if err := manageCliDecisionAlerts(alertDeleteFilter.IPEquals, alertDeleteFilter.RangeEquals,
|
||||||
alertDeleteFilter.ScopeEquals, alertDeleteFilter.ValueEquals); err != nil {
|
alertDeleteFilter.ScopeEquals, alertDeleteFilter.ValueEquals); err != nil {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
log.Fatalf("%s", err)
|
return err
|
||||||
}
|
}
|
||||||
if ActiveDecision != nil {
|
if ActiveDecision != nil {
|
||||||
alertDeleteFilter.ActiveDecisionEquals = ActiveDecision
|
alertDeleteFilter.ActiveDecisionEquals = ActiveDecision
|
||||||
|
@ -425,15 +429,17 @@ cscli alerts delete -s crowdsecurity/ssh-bf"`,
|
||||||
if delAlertByID == "" {
|
if delAlertByID == "" {
|
||||||
alerts, _, err = Client.Alerts.Delete(context.Background(), alertDeleteFilter)
|
alerts, _, err = Client.Alerts.Delete(context.Background(), alertDeleteFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to delete alerts : %v", err)
|
return fmt.Errorf("unable to delete alerts : %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alerts, _, err = Client.Alerts.DeleteOne(context.Background(), delAlertByID)
|
alerts, _, err = Client.Alerts.DeleteOne(context.Background(), delAlertByID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to delete alert : %v", err)
|
return fmt.Errorf("unable to delete alert: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Infof("%s alert(s) deleted", alerts.NbDeleted)
|
log.Infof("%s alert(s) deleted", alerts.NbDeleted)
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdAlertsDelete.Flags().SortFlags = false
|
cmdAlertsDelete.Flags().SortFlags = false
|
||||||
|
@ -455,20 +461,19 @@ func NewAlertsInspectCmd() *cobra.Command {
|
||||||
Short: `Show info about an alert`,
|
Short: `Show info about an alert`,
|
||||||
Example: `cscli alerts inspect 123`,
|
Example: `cscli alerts inspect 123`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
return
|
return fmt.Errorf("missing alert_id")
|
||||||
}
|
}
|
||||||
for _, alertID := range args {
|
for _, alertID := range args {
|
||||||
id, err := strconv.Atoi(alertID)
|
id, err := strconv.Atoi(alertID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("bad alert id %s", alertID)
|
return fmt.Errorf("bad alert id %s", alertID)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
alert, _, err := Client.Alerts.GetByID(context.Background(), id)
|
alert, _, err := Client.Alerts.GetByID(context.Background(), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't find alert with id %s: %s", alertID, err)
|
return fmt.Errorf("can't find alert with id %s: %s", alertID, err)
|
||||||
}
|
}
|
||||||
switch csConfig.Cscli.Output {
|
switch csConfig.Cscli.Output {
|
||||||
case "human":
|
case "human":
|
||||||
|
@ -478,17 +483,19 @@ func NewAlertsInspectCmd() *cobra.Command {
|
||||||
case "json":
|
case "json":
|
||||||
data, err := json.MarshalIndent(alert, "", " ")
|
data, err := json.MarshalIndent(alert, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to marshal alert with id %s: %s", alertID, err)
|
return fmt.Errorf("unable to marshal alert with id %s: %s", alertID, err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%s\n", string(data))
|
fmt.Printf("%s\n", string(data))
|
||||||
case "raw":
|
case "raw":
|
||||||
data, err := yaml.Marshal(alert)
|
data, err := yaml.Marshal(alert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to marshal alert with id %s: %s", alertID, err)
|
return fmt.Errorf("unable to marshal alert with id %s: %s", alertID, err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%s\n", string(data))
|
fmt.Printf("%s\n", string(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdAlertsInspect.Flags().SortFlags = false
|
cmdAlertsInspect.Flags().SortFlags = false
|
||||||
|
@ -506,21 +513,23 @@ func NewAlertsFlushCmd() *cobra.Command {
|
||||||
/!\ This command can be used only on the same machine than the local API`,
|
/!\ This command can be used only on the same machine than the local API`,
|
||||||
Example: `cscli alerts flush --max-items 1000 --max-age 7d`,
|
Example: `cscli alerts flush --max-items 1000 --max-age 7d`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
||||||
}
|
}
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
log.Info("Flushing alerts. !! This may take a long time !!")
|
log.Info("Flushing alerts. !! This may take a long time !!")
|
||||||
err = dbClient.FlushAlerts(maxAge, maxItems)
|
err = dbClient.FlushAlerts(maxAge, maxItems)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to flush alerts: %s", err)
|
return fmt.Errorf("unable to flush alerts: %s", err)
|
||||||
}
|
}
|
||||||
log.Info("Alerts flushed")
|
log.Info("Alerts flushed")
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
@ -29,14 +28,14 @@ func getBouncers(out io.Writer, dbClient *database.Client) error {
|
||||||
enc := json.NewEncoder(out)
|
enc := json.NewEncoder(out)
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
if err := enc.Encode(bouncers); err != nil {
|
if err := enc.Encode(bouncers); err != nil {
|
||||||
return errors.Wrap(err, "failed to unmarshal")
|
return fmt.Errorf("failed to unmarshal: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if csConfig.Cscli.Output == "raw" {
|
} else if csConfig.Cscli.Output == "raw" {
|
||||||
csvwriter := csv.NewWriter(out)
|
csvwriter := csv.NewWriter(out)
|
||||||
err := csvwriter.Write([]string{"name", "ip", "revoked", "last_pull", "type", "version", "auth_type"})
|
err := csvwriter.Write([]string{"name", "ip", "revoked", "last_pull", "type", "version", "auth_type"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to write raw header")
|
return fmt.Errorf("failed to write raw header: %w", err)
|
||||||
}
|
}
|
||||||
for _, b := range bouncers {
|
for _, b := range bouncers {
|
||||||
var revoked string
|
var revoked string
|
||||||
|
@ -47,7 +46,7 @@ func getBouncers(out io.Writer, dbClient *database.Client) error {
|
||||||
}
|
}
|
||||||
err := csvwriter.Write([]string{b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType})
|
err := csvwriter.Write([]string{b.Name, b.IPAddress, revoked, b.LastPull.Format(time.RFC3339), b.Type, b.Version, b.AuthType})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to write raw")
|
return fmt.Errorf("failed to write raw: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
csvwriter.Flush()
|
csvwriter.Flush()
|
||||||
|
@ -63,11 +62,12 @@ func NewBouncersListCmd() *cobra.Command {
|
||||||
Example: `cscli bouncers list`,
|
Example: `cscli bouncers list`,
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, arg []string) {
|
RunE: func(cmd *cobra.Command, arg []string) error {
|
||||||
err := getBouncers(color.Output, dbClient)
|
err := getBouncers(color.Output, dbClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to list bouncers: %s", err)
|
return fmt.Errorf("unable to list bouncers: %s", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,18 +91,18 @@ func runBouncersAdd(cmd *cobra.Command, args []string) error {
|
||||||
var apiKey string
|
var apiKey string
|
||||||
|
|
||||||
if keyName == "" {
|
if keyName == "" {
|
||||||
log.Fatalf("Please provide a name for the api key")
|
return fmt.Errorf("please provide a name for the api key")
|
||||||
}
|
}
|
||||||
apiKey = key
|
apiKey = key
|
||||||
if key == "" {
|
if key == "" {
|
||||||
apiKey, err = middlewares.GenerateAPIKey(keyLength)
|
apiKey, err = middlewares.GenerateAPIKey(keyLength)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to generate api key: %s", err)
|
return fmt.Errorf("unable to generate api key: %s", err)
|
||||||
}
|
}
|
||||||
_, err = dbClient.CreateBouncer(keyName, "", middlewares.HashSHA512(apiKey), types.ApiKeyAuthType)
|
_, err = dbClient.CreateBouncer(keyName, "", middlewares.HashSHA512(apiKey), types.ApiKeyAuthType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create bouncer: %s", err)
|
return fmt.Errorf("unable to create bouncer: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if csConfig.Cscli.Output == "human" {
|
if csConfig.Cscli.Output == "human" {
|
||||||
|
@ -114,7 +114,7 @@ func runBouncersAdd(cmd *cobra.Command, args []string) error {
|
||||||
} else if csConfig.Cscli.Output == "json" {
|
} else if csConfig.Cscli.Output == "json" {
|
||||||
j, err := json.Marshal(apiKey)
|
j, err := json.Marshal(apiKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to marshal api key")
|
return fmt.Errorf("unable to marshal api key")
|
||||||
}
|
}
|
||||||
fmt.Printf("%s", string(j))
|
fmt.Printf("%s", string(j))
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ func runBouncersDelete(cmd *cobra.Command, args []string) error {
|
||||||
for _, bouncerID := range args {
|
for _, bouncerID := range args {
|
||||||
err := dbClient.DeleteBouncer(bouncerID)
|
err := dbClient.DeleteBouncer(bouncerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to delete bouncer '%s': %s", bouncerID, err)
|
return fmt.Errorf("unable to delete bouncer '%s': %s", bouncerID, err)
|
||||||
}
|
}
|
||||||
log.Infof("bouncer '%s' deleted successfully", bouncerID)
|
log.Infof("bouncer '%s' deleted successfully", bouncerID)
|
||||||
}
|
}
|
||||||
|
@ -200,15 +200,16 @@ Note: This command requires database direct access, so is intended to be run on
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
Aliases: []string{"bouncer"},
|
Aliases: []string{"bouncer"},
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
||||||
}
|
}
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if logFile == "-" && ((fileInfo.Mode() & os.ModeCharDevice) == os.ModeCharDevice) {
|
if logFile == "-" && ((fileInfo.Mode() & os.ModeCharDevice) == os.ModeCharDevice) {
|
||||||
log.Fatal("-f - is intended to work with pipes.")
|
return fmt.Errorf("the option -f - is intended to work with pipes")
|
||||||
}
|
}
|
||||||
|
|
||||||
var f *os.File
|
var f *os.File
|
||||||
|
@ -77,13 +77,13 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
tmpFile = filepath.Join(dir, "cscli_test_tmp.log")
|
tmpFile = filepath.Join(dir, "cscli_test_tmp.log")
|
||||||
f, err = os.Create(tmpFile)
|
f, err = os.Create(tmpFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if logLine != "" {
|
if logLine != "" {
|
||||||
_, err = f.WriteString(logLine)
|
_, err = f.WriteString(logLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
} else if logFile == "-" {
|
} else if logFile == "-" {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
@ -110,7 +110,7 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
if logFile != "" {
|
if logFile != "" {
|
||||||
absolutePath, err := filepath.Abs(logFile)
|
absolutePath, err := filepath.Abs(logFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to get absolute path of '%s', exiting", logFile)
|
return fmt.Errorf("unable to get absolute path of '%s', exiting", logFile)
|
||||||
}
|
}
|
||||||
dsn = fmt.Sprintf("file://%s", absolutePath)
|
dsn = fmt.Sprintf("file://%s", absolutePath)
|
||||||
lineCount := types.GetLineCountForFile(absolutePath)
|
lineCount := types.GetLineCountForFile(absolutePath)
|
||||||
|
@ -120,7 +120,7 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if dsn == "" {
|
if dsn == "" {
|
||||||
log.Fatal("no acquisition (--file or --dsn) provided, can't run cscli test.")
|
return fmt.Errorf("no acquisition (--file or --dsn) provided, can't run cscli test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdArgs := []string{"-c", ConfigFilePath, "-type", logType, "-dsn", dsn, "-dump-data", "./", "-no-api"}
|
cmdArgs := []string{"-c", ConfigFilePath, "-type", logType, "-dsn", dsn, "-dump-data", "./", "-no-api"}
|
||||||
|
@ -129,13 +129,13 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
output, err := crowdsecCmd.CombinedOutput()
|
output, err := crowdsecCmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(string(output))
|
fmt.Println(string(output))
|
||||||
log.Fatalf("fail to run crowdsec for test: %v", err)
|
return fmt.Errorf("fail to run crowdsec for test: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// rm the temporary log file if only a log line/stdin was provided
|
// rm the temporary log file if only a log line/stdin was provided
|
||||||
if tmpFile != "" {
|
if tmpFile != "" {
|
||||||
if err := os.Remove(tmpFile); err != nil {
|
if err := os.Remove(tmpFile); err != nil {
|
||||||
log.Fatalf("unable to remove tmp log file '%s': %+v", tmpFile, err)
|
return fmt.Errorf("unable to remove tmp log file '%s': %+v", tmpFile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parserDumpFile := filepath.Join(dir, hubtest.ParserResultFileName)
|
parserDumpFile := filepath.Join(dir, hubtest.ParserResultFileName)
|
||||||
|
@ -143,12 +143,12 @@ func runExplain(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
parserDump, err := hubtest.LoadParserDump(parserDumpFile)
|
parserDump, err := hubtest.LoadParserDump(parserDumpFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load parser dump result: %s", err)
|
return fmt.Errorf("unable to load parser dump result: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketStateDump, err := hubtest.LoadBucketPourDump(bucketStateDumpFile)
|
bucketStateDump, err := hubtest.LoadBucketPourDump(bucketStateDumpFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load bucket dump result: %s", err)
|
return fmt.Errorf("unable to load bucket dump result: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hubtest.DumpTree(*parserDump, *bucketStateDump, opts)
|
hubtest.DumpTree(*parserDump, *bucketStateDump, opts)
|
||||||
|
|
|
@ -33,12 +33,14 @@ func NewHubTestCmd() *cobra.Command {
|
||||||
Long: "Run functional tests on hub configurations (parsers, scenarios, collections...)",
|
Long: "Run functional tests on hub configurations (parsers, scenarios, collections...)",
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
HubTest, err = hubtest.NewHubTest(hubPath, crowdsecPath, cscliPath)
|
HubTest, err = hubtest.NewHubTest(hubPath, crowdsecPath, cscliPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load hubtest: %+v", err)
|
return fmt.Errorf("unable to load hubtest: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubTest.PersistentFlags().StringVar(&hubPath, "hub", ".", "Path to hub folder")
|
cmdHubTest.PersistentFlags().StringVar(&hubPath, "hub", ".", "Path to hub folder")
|
||||||
|
@ -74,19 +76,19 @@ cscli hubtest create my-nginx-custom-test --type nginx
|
||||||
cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios crowdsecurity/http-probing`,
|
cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios crowdsecurity/http-probing`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
testName := args[0]
|
testName := args[0]
|
||||||
testPath := filepath.Join(HubTest.HubTestPath, testName)
|
testPath := filepath.Join(HubTest.HubTestPath, testName)
|
||||||
if _, err := os.Stat(testPath); os.IsExist(err) {
|
if _, err := os.Stat(testPath); os.IsExist(err) {
|
||||||
log.Fatalf("test '%s' already exists in '%s', exiting", testName, testPath)
|
return fmt.Errorf("test '%s' already exists in '%s', exiting", testName, testPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if logType == "" {
|
if logType == "" {
|
||||||
log.Fatalf("please provide a type (--type) for the test")
|
return fmt.Errorf("please provide a type (--type) for the test")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(testPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(testPath, os.ModePerm); err != nil {
|
||||||
log.Fatalf("unable to create folder '%s': %+v", testPath, err)
|
return fmt.Errorf("unable to create folder '%s': %+v", testPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create empty log file
|
// create empty log file
|
||||||
|
@ -94,7 +96,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
logFilePath := filepath.Join(testPath, logFileName)
|
logFilePath := filepath.Join(testPath, logFileName)
|
||||||
logFile, err := os.Create(logFilePath)
|
logFile, err := os.Create(logFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
logFile.Close()
|
logFile.Close()
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
parserAssertFilePath := filepath.Join(testPath, hubtest.ParserAssertFileName)
|
parserAssertFilePath := filepath.Join(testPath, hubtest.ParserAssertFileName)
|
||||||
parserAssertFile, err := os.Create(parserAssertFilePath)
|
parserAssertFile, err := os.Create(parserAssertFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
parserAssertFile.Close()
|
parserAssertFile.Close()
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
scenarioAssertFilePath := filepath.Join(testPath, hubtest.ScenarioAssertFileName)
|
scenarioAssertFilePath := filepath.Join(testPath, hubtest.ScenarioAssertFileName)
|
||||||
scenarioAssertFile, err := os.Create(scenarioAssertFilePath)
|
scenarioAssertFile, err := os.Create(scenarioAssertFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
scenarioAssertFile.Close()
|
scenarioAssertFile.Close()
|
||||||
|
|
||||||
|
@ -138,18 +140,18 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
configFilePath := filepath.Join(testPath, "config.yaml")
|
configFilePath := filepath.Join(testPath, "config.yaml")
|
||||||
fd, err := os.OpenFile(configFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
fd, err := os.OpenFile(configFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("open: %s", err)
|
return fmt.Errorf("open: %s", err)
|
||||||
}
|
}
|
||||||
data, err := yaml.Marshal(configFileData)
|
data, err := yaml.Marshal(configFileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("marshal: %s", err)
|
return fmt.Errorf("marshal: %s", err)
|
||||||
}
|
}
|
||||||
_, err = fd.Write(data)
|
_, err = fd.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("write: %s", err)
|
return fmt.Errorf("write: %s", err)
|
||||||
}
|
}
|
||||||
if err := fd.Close(); err != nil {
|
if err := fd.Close(); err != nil {
|
||||||
log.Fatalf(" close: %s", err)
|
return fmt.Errorf("close: %s", err)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" Test name : %s\n", testName)
|
fmt.Printf(" Test name : %s\n", testName)
|
||||||
|
@ -159,6 +161,7 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
|
||||||
fmt.Printf(" Scenario assertion file : %s (please fill it with assertion)\n", scenarioAssertFilePath)
|
fmt.Printf(" Scenario assertion file : %s (please fill it with assertion)\n", scenarioAssertFilePath)
|
||||||
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
fmt.Printf(" Configuration File : %s (please fill it with parsers, scenarios...)\n", configFilePath)
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubTestCreate.PersistentFlags().StringVarP(&logType, "type", "t", "", "Log type of the test")
|
cmdHubTestCreate.PersistentFlags().StringVarP(&logType, "type", "t", "", "Log type of the test")
|
||||||
|
@ -180,22 +183,21 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: "run [test_name]",
|
Short: "run [test_name]",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if !runAll && len(args) == 0 {
|
if !runAll && len(args) == 0 {
|
||||||
printHelp(cmd)
|
printHelp(cmd)
|
||||||
fmt.Println("Please provide test to run or --all flag")
|
return fmt.Errorf("Please provide test to run or --all flag")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if runAll {
|
if runAll {
|
||||||
if err := HubTest.LoadAllTests(); err != nil {
|
if err := HubTest.LoadAllTests(); err != nil {
|
||||||
log.Fatalf("unable to load all tests: %+v", err)
|
return fmt.Errorf("unable to load all tests: %+v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
_, err := HubTest.LoadTestItem(testName)
|
_, err := HubTest.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,8 +212,9 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
success := true
|
success := true
|
||||||
testResult := make(map[string]bool)
|
testResult := make(map[string]bool)
|
||||||
for _, test := range HubTest.Tests {
|
for _, test := range HubTest.Tests {
|
||||||
|
@ -228,7 +231,7 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
if !noClean {
|
if !noClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
log.Fatalf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("\nPlease fill your assert file(s) for test '%s', exiting\n", test.Name)
|
fmt.Printf("\nPlease fill your assert file(s) for test '%s', exiting\n", test.Name)
|
||||||
|
@ -241,7 +244,7 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
if !noClean {
|
if !noClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
log.Fatalf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,14 +281,14 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
Default: true,
|
Default: true,
|
||||||
}
|
}
|
||||||
if err := survey.AskOne(prompt, &cleanTestEnv); err != nil {
|
if err := survey.AskOne(prompt, &cleanTestEnv); err != nil {
|
||||||
log.Fatalf("unable to ask to remove runtime folder: %s", err)
|
return fmt.Errorf("unable to ask to remove runtime folder: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cleanTestEnv || forceClean {
|
if cleanTestEnv || forceClean {
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
log.Fatalf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +308,7 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
jsonStr, err := json.Marshal(jsonResult)
|
jsonStr, err := json.Marshal(jsonResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to json test result: %s", err)
|
return fmt.Errorf("unable to json test result: %s", err)
|
||||||
}
|
}
|
||||||
fmt.Println(string(jsonStr))
|
fmt.Println(string(jsonStr))
|
||||||
}
|
}
|
||||||
|
@ -313,6 +316,8 @@ func NewHubTestRunCmd() *cobra.Command {
|
||||||
if !success {
|
if !success {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubTestRun.Flags().BoolVar(&noClean, "no-clean", false, "Don't clean runtime environment if test succeed")
|
cmdHubTestRun.Flags().BoolVar(&noClean, "no-clean", false, "Don't clean runtime environment if test succeed")
|
||||||
|
@ -329,16 +334,18 @@ func NewHubTestCleanCmd() *cobra.Command {
|
||||||
Short: "clean [test_name]",
|
Short: "clean [test_name]",
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := HubTest.LoadTestItem(testName)
|
test, err := HubTest.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||||
}
|
}
|
||||||
if err := test.Clean(); err != nil {
|
if err := test.Clean(); err != nil {
|
||||||
log.Fatalf("unable to clean test '%s' env: %s", test.Name, err)
|
return fmt.Errorf("unable to clean test '%s' env: %s", test.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,11 +359,11 @@ func NewHubTestInfoCmd() *cobra.Command {
|
||||||
Short: "info [test_name]",
|
Short: "info [test_name]",
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := HubTest.LoadTestItem(testName)
|
test, err := HubTest.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load test '%s': %s", testName, err)
|
return fmt.Errorf("unable to load test '%s': %s", testName, err)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Printf(" Test name : %s\n", test.Name)
|
fmt.Printf(" Test name : %s\n", test.Name)
|
||||||
|
@ -366,6 +373,8 @@ func NewHubTestInfoCmd() *cobra.Command {
|
||||||
fmt.Printf(" Scenario assertion file : %s\n", filepath.Join(test.Path, hubtest.ScenarioAssertFileName))
|
fmt.Printf(" Scenario assertion file : %s\n", filepath.Join(test.Path, hubtest.ScenarioAssertFileName))
|
||||||
fmt.Printf(" Configuration File : %s\n", filepath.Join(test.Path, "config.yaml"))
|
fmt.Printf(" Configuration File : %s\n", filepath.Join(test.Path, "config.yaml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,9 +387,9 @@ func NewHubTestListCmd() *cobra.Command {
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "list",
|
Short: "list",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := HubTest.LoadAllTests(); err != nil {
|
if err := HubTest.LoadAllTests(); err != nil {
|
||||||
log.Fatalf("unable to load all tests: %+v", err)
|
return fmt.Errorf("unable to load all tests: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch csConfig.Cscli.Output {
|
switch csConfig.Cscli.Output {
|
||||||
|
@ -389,12 +398,14 @@ func NewHubTestListCmd() *cobra.Command {
|
||||||
case "json":
|
case "json":
|
||||||
j, err := json.MarshalIndent(HubTest.Tests, " ", " ")
|
j, err := json.MarshalIndent(HubTest.Tests, " ", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
fmt.Println(string(j))
|
fmt.Println(string(j))
|
||||||
default:
|
default:
|
||||||
log.Fatalf("only human/json output modes are supported")
|
return fmt.Errorf("only human/json output modes are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,9 +422,9 @@ func NewHubTestCoverageCmd() *cobra.Command {
|
||||||
Use: "coverage",
|
Use: "coverage",
|
||||||
Short: "coverage",
|
Short: "coverage",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := HubTest.LoadAllTests(); err != nil {
|
if err := HubTest.LoadAllTests(); err != nil {
|
||||||
log.Fatalf("unable to load all tests: %+v", err)
|
return fmt.Errorf("unable to load all tests: %+v", err)
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
scenarioCoverage := []hubtest.ScenarioCoverage{}
|
scenarioCoverage := []hubtest.ScenarioCoverage{}
|
||||||
|
@ -427,7 +438,7 @@ func NewHubTestCoverageCmd() *cobra.Command {
|
||||||
if showParserCov || showAll {
|
if showParserCov || showAll {
|
||||||
parserCoverage, err = HubTest.GetParsersCoverage()
|
parserCoverage, err = HubTest.GetParsersCoverage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("while getting parser coverage : %s", err)
|
return fmt.Errorf("while getting parser coverage: %s", err)
|
||||||
}
|
}
|
||||||
parserTested := 0
|
parserTested := 0
|
||||||
for _, test := range parserCoverage {
|
for _, test := range parserCoverage {
|
||||||
|
@ -441,7 +452,7 @@ func NewHubTestCoverageCmd() *cobra.Command {
|
||||||
if showScenarioCov || showAll {
|
if showScenarioCov || showAll {
|
||||||
scenarioCoverage, err = HubTest.GetScenariosCoverage()
|
scenarioCoverage, err = HubTest.GetScenariosCoverage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("while getting scenario coverage: %s", err)
|
return fmt.Errorf("while getting scenario coverage: %s", err)
|
||||||
}
|
}
|
||||||
scenarioTested := 0
|
scenarioTested := 0
|
||||||
for _, test := range scenarioCoverage {
|
for _, test := range scenarioCoverage {
|
||||||
|
@ -481,18 +492,19 @@ func NewHubTestCoverageCmd() *cobra.Command {
|
||||||
} else if csConfig.Cscli.Output == "json" {
|
} else if csConfig.Cscli.Output == "json" {
|
||||||
dump, err := json.MarshalIndent(parserCoverage, "", " ")
|
dump, err := json.MarshalIndent(parserCoverage, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("%s", dump)
|
fmt.Printf("%s", dump)
|
||||||
dump, err = json.MarshalIndent(scenarioCoverage, "", " ")
|
dump, err = json.MarshalIndent(scenarioCoverage, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("%s", dump)
|
fmt.Printf("%s", dump)
|
||||||
} else {
|
} else {
|
||||||
log.Fatalf("only human/json output modes are supported")
|
return fmt.Errorf("only human/json output modes are supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubTestCoverage.PersistentFlags().BoolVar(&showOnlyPercent, "percent", false, "Show only percentages of coverage")
|
cmdHubTestCoverage.PersistentFlags().BoolVar(&showOnlyPercent, "percent", false, "Show only percentages of coverage")
|
||||||
|
@ -510,22 +522,24 @@ func NewHubTestEvalCmd() *cobra.Command {
|
||||||
Short: "eval [test_name]",
|
Short: "eval [test_name]",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := HubTest.LoadTestItem(testName)
|
test, err := HubTest.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't load test: %+v", err)
|
return fmt.Errorf("can't load test: %+v", err)
|
||||||
}
|
}
|
||||||
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't load test results from '%s': %+v", test.ParserResultFile, err)
|
return fmt.Errorf("can't load test results from '%s': %+v", test.ParserResultFile, err)
|
||||||
}
|
}
|
||||||
output, err := test.ParserAssert.EvalExpression(evalExpression)
|
output, err := test.ParserAssert.EvalExpression(evalExpression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
fmt.Print(output)
|
fmt.Print(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdHubTestEval.PersistentFlags().StringVarP(&evalExpression, "expr", "e", "", "Expression to eval")
|
cmdHubTestEval.PersistentFlags().StringVarP(&evalExpression, "expr", "e", "", "Expression to eval")
|
||||||
|
@ -540,21 +554,21 @@ func NewHubTestExplainCmd() *cobra.Command {
|
||||||
Short: "explain [test_name]",
|
Short: "explain [test_name]",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
for _, testName := range args {
|
for _, testName := range args {
|
||||||
test, err := HubTest.LoadTestItem(testName)
|
test, err := HubTest.LoadTestItem(testName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("can't load test: %+v", err)
|
return fmt.Errorf("can't load test: %+v", err)
|
||||||
}
|
}
|
||||||
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := test.Run()
|
err := test.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("running test '%s' failed: %+v", test.Name, err)
|
return fmt.Errorf("running test '%s' failed: %+v", test.Name, err)
|
||||||
}
|
}
|
||||||
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
err = test.ParserAssert.LoadTest(test.ParserResultFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load parser result after run: %s", err)
|
return fmt.Errorf("unable to load parser result after run: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,16 +576,18 @@ func NewHubTestExplainCmd() *cobra.Command {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := test.Run()
|
err := test.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("running test '%s' failed: %+v", test.Name, err)
|
return fmt.Errorf("running test '%s' failed: %+v", test.Name, err)
|
||||||
}
|
}
|
||||||
err = test.ScenarioAssert.LoadTest(test.ScenarioResultFile, test.BucketPourResultFile)
|
err = test.ScenarioAssert.LoadTest(test.ScenarioResultFile, test.BucketPourResultFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to load scenario result after run: %s", err)
|
return fmt.Errorf("unable to load scenario result after run: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts := hubtest.DumpOpts{}
|
opts := hubtest.DumpOpts{}
|
||||||
hubtest.DumpTree(*test.ParserAssert.TestData, *test.ScenarioAssert.PourData, opts)
|
hubtest.DumpTree(*test.ParserAssert.TestData, *test.ScenarioAssert.PourData, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -67,7 +66,7 @@ func generateIDPrefix() (string, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return bId.String(), nil
|
return bId.String(), nil
|
||||||
}
|
}
|
||||||
return "", errors.Wrap(err, "generating machine id")
|
return "", fmt.Errorf("generating machine id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a unique identifier, composed by a prefix and a random suffix.
|
// Generate a unique identifier, composed by a prefix and a random suffix.
|
||||||
|
@ -114,14 +113,14 @@ func getAgents(out io.Writer, dbClient *database.Client) error {
|
||||||
enc := json.NewEncoder(out)
|
enc := json.NewEncoder(out)
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
if err := enc.Encode(machines); err != nil {
|
if err := enc.Encode(machines); err != nil {
|
||||||
log.Fatalf("failed to unmarshal")
|
return fmt.Errorf("failed to marshal")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else if csConfig.Cscli.Output == "raw" {
|
} else if csConfig.Cscli.Output == "raw" {
|
||||||
csvwriter := csv.NewWriter(out)
|
csvwriter := csv.NewWriter(out)
|
||||||
err := csvwriter.Write([]string{"machine_id", "ip_address", "updated_at", "validated", "version", "auth_type", "last_heartbeat"})
|
err := csvwriter.Write([]string{"machine_id", "ip_address", "updated_at", "validated", "version", "auth_type", "last_heartbeat"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to write header: %s", err)
|
return fmt.Errorf("failed to write header: %s", err)
|
||||||
}
|
}
|
||||||
for _, m := range machines {
|
for _, m := range machines {
|
||||||
var validated string
|
var validated string
|
||||||
|
@ -132,7 +131,7 @@ func getAgents(out io.Writer, dbClient *database.Client) error {
|
||||||
}
|
}
|
||||||
err := csvwriter.Write([]string{m.MachineId, m.IpAddress, m.UpdatedAt.Format(time.RFC3339), validated, m.Version, m.AuthType, displayLastHeartBeat(m, false)})
|
err := csvwriter.Write([]string{m.MachineId, m.IpAddress, m.UpdatedAt.Format(time.RFC3339), validated, m.Version, m.AuthType, displayLastHeartBeat(m, false)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to write raw output : %s", err)
|
return fmt.Errorf("failed to write raw output : %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
csvwriter.Flush()
|
csvwriter.Flush()
|
||||||
|
@ -150,18 +149,22 @@ func NewMachinesListCmd() *cobra.Command {
|
||||||
Example: `cscli machines list`,
|
Example: `cscli machines list`,
|
||||||
Args: cobra.MaximumNArgs(1),
|
Args: cobra.MaximumNArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
err := getAgents(color.Output, dbClient)
|
err := getAgents(color.Output, dbClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to list machines: %s", err)
|
return fmt.Errorf("unable to list machines: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,12 +182,14 @@ cscli machines add --auto
|
||||||
cscli machines add MyTestMachine --auto
|
cscli machines add MyTestMachine --auto
|
||||||
cscli machines add MyTestMachine --password MyPassword
|
cscli machines add MyTestMachine --password MyPassword
|
||||||
`,
|
`,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
RunE: runMachinesAdd,
|
RunE: runMachinesAdd,
|
||||||
}
|
}
|
||||||
|
@ -246,7 +251,7 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
machineID, err = generateID("")
|
machineID, err = generateID("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to generate machine id : %s", err)
|
return fmt.Errorf("unable to generate machine id: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
machineID = args[0]
|
machineID = args[0]
|
||||||
|
@ -275,7 +280,7 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
|
||||||
password := strfmt.Password(machinePassword)
|
password := strfmt.Password(machinePassword)
|
||||||
_, err = dbClient.CreateMachine(&machineID, &password, "", true, forceAdd, types.PasswordAuthType)
|
_, err = dbClient.CreateMachine(&machineID, &password, "", true, forceAdd, types.PasswordAuthType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create machine: %s", err)
|
return fmt.Errorf("unable to create machine: %s", err)
|
||||||
}
|
}
|
||||||
log.Infof("Machine '%s' successfully added to the local API", machineID)
|
log.Infof("Machine '%s' successfully added to the local API", machineID)
|
||||||
|
|
||||||
|
@ -285,7 +290,7 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
|
||||||
} else if csConfig.API.Server != nil && csConfig.API.Server.ListenURI != "" {
|
} else if csConfig.API.Server != nil && csConfig.API.Server.ListenURI != "" {
|
||||||
apiURL = "http://" + csConfig.API.Server.ListenURI
|
apiURL = "http://" + csConfig.API.Server.ListenURI
|
||||||
} else {
|
} else {
|
||||||
log.Fatalf("unable to dump an api URL. Please provide it in your configuration or with the -u parameter")
|
return fmt.Errorf("unable to dump an api URL. Please provide it in your configuration or with the -u parameter")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apiCfg := csconfig.ApiCredentialsCfg{
|
apiCfg := csconfig.ApiCredentialsCfg{
|
||||||
|
@ -295,12 +300,12 @@ func runMachinesAdd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
apiConfigDump, err := yaml.Marshal(apiCfg)
|
apiConfigDump, err := yaml.Marshal(apiCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to marshal api credentials: %s", err)
|
return fmt.Errorf("unable to marshal api credentials: %s", err)
|
||||||
}
|
}
|
||||||
if dumpFile != "" && dumpFile != "-" {
|
if dumpFile != "" && dumpFile != "-" {
|
||||||
err = os.WriteFile(dumpFile, apiConfigDump, 0644)
|
err = os.WriteFile(dumpFile, apiConfigDump, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("write api credentials in '%s' failed: %s", dumpFile, err)
|
return fmt.Errorf("write api credentials in '%s' failed: %s", dumpFile, err)
|
||||||
}
|
}
|
||||||
log.Printf("API credentials dumped to '%s'", dumpFile)
|
log.Printf("API credentials dumped to '%s'", dumpFile)
|
||||||
} else {
|
} else {
|
||||||
|
@ -318,12 +323,13 @@ func NewMachinesDeleteCmd() *cobra.Command {
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
Aliases: []string{"remove"},
|
Aliases: []string{"remove"},
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
var err error
|
var err error
|
||||||
|
@ -371,19 +377,23 @@ func NewMachinesValidateCmd() *cobra.Command {
|
||||||
Example: `cscli machines validate "machine_name"`,
|
Example: `cscli machines validate "machine_name"`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
dbClient, err = database.NewClient(csConfig.DbConfig)
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to create new database client: %s", err)
|
return fmt.Errorf("unable to create new database client: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
machineID := args[0]
|
machineID := args[0]
|
||||||
if err := dbClient.ValidateMachine(machineID); err != nil {
|
if err := dbClient.ValidateMachine(machineID); err != nil {
|
||||||
log.Fatalf("unable to validate machine '%s': %s", machineID, err)
|
return fmt.Errorf("unable to validate machine '%s': %s", machineID, err)
|
||||||
}
|
}
|
||||||
log.Infof("machine '%s' validated successfully", machineID)
|
log.Infof("machine '%s' validated successfully", machineID)
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,13 +410,15 @@ Note: This command requires database direct access, so is intended to be run on
|
||||||
Example: `cscli machines [action]`,
|
Example: `cscli machines [action]`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Aliases: []string{"machine"},
|
Aliases: []string{"machine"},
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
if err := csConfig.LoadAPIServer(); err != nil || csConfig.DisableAPI {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("local api : %s", err)
|
log.Errorf("local api : %s", err)
|
||||||
}
|
}
|
||||||
log.Fatal("Local API is disabled, please run this command on the local API machine")
|
return fmt.Errorf("local API is disabled, please run this command on the local API machine")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,10 +178,11 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.ExactArgs(0),
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := doc.GenMarkdownTreeCustom(rootCmd, "./doc/", prepender, linkHandler); err != nil {
|
if err := doc.GenMarkdownTreeCustom(rootCmd, "./doc/", prepender, linkHandler); err != nil {
|
||||||
log.Fatalf("Failed to generate cobra doc: %s", err)
|
return fmt.Errorf("Failed to generate cobra doc: %s", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
rootCmd.AddCommand(cmdDocGen)
|
rootCmd.AddCommand(cmdDocGen)
|
||||||
|
|
|
@ -19,6 +19,7 @@ setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
|
cd "$TEST_DIR" || exit 1
|
||||||
./instance-crowdsec stop
|
./instance-crowdsec stop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,3 +298,25 @@ declare stderr
|
||||||
rune -0 cscli config show --key Config.DbConfig.Password
|
rune -0 cscli config show --key Config.DbConfig.Password
|
||||||
assert_output 'P@ssw0rd$'
|
assert_output 'P@ssw0rd$'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "cscli doc" {
|
||||||
|
# generating documentation requires a directory named "doc"
|
||||||
|
|
||||||
|
cd "$BATS_TEST_TMPDIR"
|
||||||
|
rune -1 cscli doc
|
||||||
|
refute_output
|
||||||
|
assert_stderr --regexp 'Failed to generate cobra doc: open doc/.*: no such file or directory'
|
||||||
|
|
||||||
|
mkdir -p doc
|
||||||
|
rune -0 cscli doc
|
||||||
|
refute_output
|
||||||
|
refute_stderr
|
||||||
|
assert_file_exist "doc/cscli.md"
|
||||||
|
assert_file_not_exist "doc/cscli_setup.md"
|
||||||
|
|
||||||
|
# commands guarded by feature flags are not documented unless the feature flag is set
|
||||||
|
|
||||||
|
export CROWDSEC_FEATURE_CSCLI_SETUP="true"
|
||||||
|
rune -0 cscli doc
|
||||||
|
assert_file_exist "doc/cscli_setup.md"
|
||||||
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ teardown() {
|
||||||
config_disable_lapi
|
config_disable_lapi
|
||||||
./instance-crowdsec start || true
|
./instance-crowdsec start || true
|
||||||
run -1 --separate-stderr cscli machines list
|
run -1 --separate-stderr cscli machines list
|
||||||
assert_stderr --partial "Local API is disabled, please run this command on the local API machine"
|
assert_stderr --partial "local API is disabled, please run this command on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "cscli metrics" {
|
@test "cscli metrics" {
|
||||||
|
@ -87,5 +87,5 @@ teardown() {
|
||||||
assert_output --partial "/v1/watchers/login"
|
assert_output --partial "/v1/watchers/login"
|
||||||
|
|
||||||
assert_stderr --partial "crowdsec local API is disabled"
|
assert_stderr --partial "crowdsec local API is disabled"
|
||||||
assert_stderr --partial "Local API is disabled, please run this command on the local API machine"
|
assert_stderr --partial "local API is disabled, please run this command on the local API machine"
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,9 @@ teardown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "cscli alerts inspect" {
|
@test "cscli alerts inspect" {
|
||||||
|
rune -1 cscli alerts inspect
|
||||||
|
assert_stderr --partial 'missing alert_id'
|
||||||
|
|
||||||
run -0 cscli decisions add -i 10.20.30.40 -t ban
|
run -0 cscli decisions add -i 10.20.30.40 -t ban
|
||||||
run -0 cscli alerts list -o raw <(output)
|
run -0 cscli alerts list -o raw <(output)
|
||||||
run -0 grep 10.20.30.40 <(output)
|
run -0 grep 10.20.30.40 <(output)
|
||||||
|
@ -143,7 +146,7 @@ teardown() {
|
||||||
# can't delete twice
|
# can't delete twice
|
||||||
run -1 --separate-stderr cscli alerts delete --id "$ALERT_ID"
|
run -1 --separate-stderr cscli alerts delete --id "$ALERT_ID"
|
||||||
refute_output
|
refute_output
|
||||||
assert_stderr --partial "Unable to delete alert"
|
assert_stderr --partial "unable to delete alert"
|
||||||
assert_stderr --partial "API error: ent: alert not found"
|
assert_stderr --partial "API error: ent: alert not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue