cscli refact / encapsulate methods for capi, hubtest, dashboard, alerts, decisions, simulation (#2650)

This commit is contained in:
mmetc 2023-12-11 10:32:54 +01:00 committed by GitHub
parent 1b4ec66148
commit c10aad79d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 462 additions and 415 deletions

View file

@ -21,12 +21,11 @@ import (
"github.com/crowdsecurity/go-cs-lib/version" "github.com/crowdsecurity/go-cs-lib/version"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
"github.com/crowdsecurity/crowdsec/pkg/apiclient" "github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/database" "github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
) )
func DecisionsFromAlert(alert *models.Alert) string { func DecisionsFromAlert(alert *models.Alert) string {
@ -208,8 +207,14 @@ func DisplayOneAlert(alert *models.Alert, withDetail bool) error {
return nil return nil
} }
func NewAlertsCmd() *cobra.Command { type cliAlerts struct{}
var cmdAlerts = &cobra.Command{
func NewCLIAlerts() *cliAlerts {
return &cliAlerts{}
}
func (cli cliAlerts) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "alerts [action]", Use: "alerts [action]",
Short: "Manage alerts", Short: "Manage alerts",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
@ -239,15 +244,15 @@ func NewAlertsCmd() *cobra.Command {
}, },
} }
cmdAlerts.AddCommand(NewAlertsListCmd()) cmd.AddCommand(cli.NewListCmd())
cmdAlerts.AddCommand(NewAlertsInspectCmd()) cmd.AddCommand(cli.NewInspectCmd())
cmdAlerts.AddCommand(NewAlertsFlushCmd()) cmd.AddCommand(cli.NewFlushCmd())
cmdAlerts.AddCommand(NewAlertsDeleteCmd()) cmd.AddCommand(cli.NewDeleteCmd())
return cmdAlerts return cmd
} }
func NewAlertsListCmd() *cobra.Command { func (cli cliAlerts) NewListCmd() *cobra.Command {
var alertListFilter = apiclient.AlertsListOpts{ var alertListFilter = apiclient.AlertsListOpts{
ScopeEquals: new(string), ScopeEquals: new(string),
ValueEquals: new(string), ValueEquals: new(string),
@ -260,10 +265,11 @@ func NewAlertsListCmd() *cobra.Command {
IncludeCAPI: new(bool), IncludeCAPI: new(bool),
OriginEquals: new(string), OriginEquals: new(string),
} }
var limit = new(int) limit := new(int)
contained := new(bool) contained := new(bool)
var printMachine bool var printMachine bool
var cmdAlertsList = &cobra.Command{
cmd := &cobra.Command{
Use: "list [filters]", Use: "list [filters]",
Short: "List alerts", Short: "List alerts",
Example: `cscli alerts list Example: `cscli alerts list
@ -353,25 +359,25 @@ cscli alerts list --type ban`,
return nil return nil
}, },
} }
cmdAlertsList.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdAlertsList.Flags().BoolVarP(alertListFilter.IncludeCAPI, "all", "a", false, "Include decisions from Central API") cmd.Flags().BoolVarP(alertListFilter.IncludeCAPI, "all", "a", false, "Include decisions from Central API")
cmdAlertsList.Flags().StringVar(alertListFilter.Until, "until", "", "restrict to alerts older than until (ie. 4h, 30d)") cmd.Flags().StringVar(alertListFilter.Until, "until", "", "restrict to alerts older than until (ie. 4h, 30d)")
cmdAlertsList.Flags().StringVar(alertListFilter.Since, "since", "", "restrict to alerts newer than since (ie. 4h, 30d)") cmd.Flags().StringVar(alertListFilter.Since, "since", "", "restrict to alerts newer than since (ie. 4h, 30d)")
cmdAlertsList.Flags().StringVarP(alertListFilter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)") cmd.Flags().StringVarP(alertListFilter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)")
cmdAlertsList.Flags().StringVarP(alertListFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)") cmd.Flags().StringVarP(alertListFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)")
cmdAlertsList.Flags().StringVarP(alertListFilter.RangeEquals, "range", "r", "", "restrict to alerts from this range (shorthand for --scope range --value <RANGE/X>)") cmd.Flags().StringVarP(alertListFilter.RangeEquals, "range", "r", "", "restrict to alerts from this range (shorthand for --scope range --value <RANGE/X>)")
cmdAlertsList.Flags().StringVar(alertListFilter.TypeEquals, "type", "", "restrict to alerts with given decision type (ie. ban, captcha)") cmd.Flags().StringVar(alertListFilter.TypeEquals, "type", "", "restrict to alerts with given decision type (ie. ban, captcha)")
cmdAlertsList.Flags().StringVar(alertListFilter.ScopeEquals, "scope", "", "restrict to alerts of this scope (ie. ip,range)") cmd.Flags().StringVar(alertListFilter.ScopeEquals, "scope", "", "restrict to alerts of this scope (ie. ip,range)")
cmdAlertsList.Flags().StringVarP(alertListFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") cmd.Flags().StringVarP(alertListFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
cmdAlertsList.Flags().StringVar(alertListFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) cmd.Flags().StringVar(alertListFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
cmdAlertsList.Flags().BoolVar(contained, "contained", false, "query decisions contained by range") cmd.Flags().BoolVar(contained, "contained", false, "query decisions contained by range")
cmdAlertsList.Flags().BoolVarP(&printMachine, "machine", "m", false, "print machines that sent alerts") cmd.Flags().BoolVarP(&printMachine, "machine", "m", false, "print machines that sent alerts")
cmdAlertsList.Flags().IntVarP(limit, "limit", "l", 50, "limit size of alerts list table (0 to view all alerts)") cmd.Flags().IntVarP(limit, "limit", "l", 50, "limit size of alerts list table (0 to view all alerts)")
return cmdAlertsList return cmd
} }
func NewAlertsDeleteCmd() *cobra.Command { func (cli cliAlerts) NewDeleteCmd() *cobra.Command {
var ActiveDecision *bool var ActiveDecision *bool
var AlertDeleteAll bool var AlertDeleteAll bool
var delAlertByID string var delAlertByID string
@ -383,7 +389,7 @@ func NewAlertsDeleteCmd() *cobra.Command {
IPEquals: new(string), IPEquals: new(string),
RangeEquals: new(string), RangeEquals: new(string),
} }
var cmdAlertsDelete = &cobra.Command{ cmd := &cobra.Command{
Use: "delete [filters] [--all]", Use: "delete [filters] [--all]",
Short: `Delete alerts Short: `Delete alerts
/!\ This command can be use only on the same machine than the local API.`, /!\ This command can be use only on the same machine than the local API.`,
@ -461,21 +467,21 @@ cscli alerts delete -s crowdsecurity/ssh-bf"`,
return nil return nil
}, },
} }
cmdAlertsDelete.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdAlertsDelete.Flags().StringVar(alertDeleteFilter.ScopeEquals, "scope", "", "the scope (ie. ip,range)") cmd.Flags().StringVar(alertDeleteFilter.ScopeEquals, "scope", "", "the scope (ie. ip,range)")
cmdAlertsDelete.Flags().StringVarP(alertDeleteFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") cmd.Flags().StringVarP(alertDeleteFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
cmdAlertsDelete.Flags().StringVarP(alertDeleteFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)") cmd.Flags().StringVarP(alertDeleteFilter.ScenarioEquals, "scenario", "s", "", "the scenario (ie. crowdsecurity/ssh-bf)")
cmdAlertsDelete.Flags().StringVarP(alertDeleteFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)") cmd.Flags().StringVarP(alertDeleteFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)")
cmdAlertsDelete.Flags().StringVarP(alertDeleteFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)") cmd.Flags().StringVarP(alertDeleteFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)")
cmdAlertsDelete.Flags().StringVar(&delAlertByID, "id", "", "alert ID") cmd.Flags().StringVar(&delAlertByID, "id", "", "alert ID")
cmdAlertsDelete.Flags().BoolVarP(&AlertDeleteAll, "all", "a", false, "delete all alerts") cmd.Flags().BoolVarP(&AlertDeleteAll, "all", "a", false, "delete all alerts")
cmdAlertsDelete.Flags().BoolVar(contained, "contained", false, "query decisions contained by range") cmd.Flags().BoolVar(contained, "contained", false, "query decisions contained by range")
return cmdAlertsDelete return cmd
} }
func NewAlertsInspectCmd() *cobra.Command { func (cli cliAlerts) NewInspectCmd() *cobra.Command {
var details bool var details bool
var cmdAlertsInspect = &cobra.Command{ cmd := &cobra.Command{
Use: `inspect "alert_id"`, Use: `inspect "alert_id"`,
Short: `Show info about an alert`, Short: `Show info about an alert`,
Example: `cscli alerts inspect 123`, Example: `cscli alerts inspect 123`,
@ -517,16 +523,16 @@ func NewAlertsInspectCmd() *cobra.Command {
return nil return nil
}, },
} }
cmdAlertsInspect.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdAlertsInspect.Flags().BoolVarP(&details, "details", "d", false, "show alerts with events") cmd.Flags().BoolVarP(&details, "details", "d", false, "show alerts with events")
return cmdAlertsInspect return cmd
} }
func NewAlertsFlushCmd() *cobra.Command { func (cli cliAlerts) NewFlushCmd() *cobra.Command {
var maxItems int var maxItems int
var maxAge string var maxAge string
var cmdAlertsFlush = &cobra.Command{ cmd := &cobra.Command{
Use: `flush`, Use: `flush`,
Short: `Flush alerts Short: `Flush alerts
/!\ 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`,
@ -552,9 +558,9 @@ func NewAlertsFlushCmd() *cobra.Command {
}, },
} }
cmdAlertsFlush.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdAlertsFlush.Flags().IntVar(&maxItems, "max-items", 5000, "Maximum number of alert items to keep in the database") cmd.Flags().IntVar(&maxItems, "max-items", 5000, "Maximum number of alert items to keep in the database")
cmdAlertsFlush.Flags().StringVar(&maxAge, "max-age", "7d", "Maximum age of alert items to keep in the database") cmd.Flags().StringVar(&maxAge, "max-age", "7d", "Maximum age of alert items to keep in the database")
return cmdAlertsFlush return cmd
} }

View file

@ -13,20 +13,27 @@ import (
"github.com/crowdsecurity/go-cs-lib/version" "github.com/crowdsecurity/go-cs-lib/version"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
"github.com/crowdsecurity/crowdsec/pkg/apiclient" "github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/csconfig" "github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/types"
"github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
) )
const CAPIBaseURL string = "https://api.crowdsec.net/" const (
const CAPIURLPrefix = "v3" CAPIBaseURL = "https://api.crowdsec.net/"
CAPIURLPrefix = "v3"
)
func NewCapiCmd() *cobra.Command { type cliCapi struct{}
var cmdCapi = &cobra.Command{
func NewCLICapi() *cliCapi {
return &cliCapi{}
}
func (cli cliCapi) NewCommand() *cobra.Command {
var cmd = &cobra.Command{
Use: "capi [action]", Use: "capi [action]",
Short: "Manage interaction with Central API (CAPI)", Short: "Manage interaction with Central API (CAPI)",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
@ -44,17 +51,17 @@ func NewCapiCmd() *cobra.Command {
}, },
} }
cmdCapi.AddCommand(NewCapiRegisterCmd()) cmd.AddCommand(cli.NewRegisterCmd())
cmdCapi.AddCommand(NewCapiStatusCmd()) cmd.AddCommand(cli.NewStatusCmd())
return cmdCapi return cmd
} }
func NewCapiRegisterCmd() *cobra.Command { func (cli cliCapi) NewRegisterCmd() *cobra.Command {
var capiUserPrefix string var capiUserPrefix string
var outputFile string var outputFile string
var cmdCapiRegister = &cobra.Command{ var cmd = &cobra.Command{
Use: "register", Use: "register",
Short: "Register to Central API (CAPI)", Short: "Register to Central API (CAPI)",
Args: cobra.MinimumNArgs(0), Args: cobra.MinimumNArgs(0),
@ -116,17 +123,18 @@ func NewCapiRegisterCmd() *cobra.Command {
return nil return nil
}, },
} }
cmdCapiRegister.Flags().StringVarP(&outputFile, "file", "f", "", "output file destination")
cmdCapiRegister.Flags().StringVar(&capiUserPrefix, "schmilblick", "", "set a schmilblick (use in tests only)") cmd.Flags().StringVarP(&outputFile, "file", "f", "", "output file destination")
if err := cmdCapiRegister.Flags().MarkHidden("schmilblick"); err != nil { cmd.Flags().StringVar(&capiUserPrefix, "schmilblick", "", "set a schmilblick (use in tests only)")
if err := cmd.Flags().MarkHidden("schmilblick"); err != nil {
log.Fatalf("failed to hide flag: %s", err) log.Fatalf("failed to hide flag: %s", err)
} }
return cmdCapiRegister return cmd
} }
func NewCapiStatusCmd() *cobra.Command { func (cli cliCapi) NewStatusCmd() *cobra.Command {
var cmdCapiStatus = &cobra.Command{ var cmd = &cobra.Command{
Use: "status", Use: "status",
Short: "Check status with the Central API (CAPI)", Short: "Check status with the Central API (CAPI)",
Args: cobra.MinimumNArgs(0), Args: cobra.MinimumNArgs(0),
@ -185,5 +193,5 @@ func NewCapiStatusCmd() *cobra.Command {
}, },
} }
return cmdCapiStatus return cmd
} }

View file

@ -43,9 +43,15 @@ var (
// information needed to set up a random password on user's behalf // information needed to set up a random password on user's behalf
) )
func NewDashboardCmd() *cobra.Command { type cliDashboard struct{}
func NewCLIDashboard() *cliDashboard {
return &cliDashboard{}
}
func (cli cliDashboard) NewCommand() *cobra.Command {
/* ---- UPDATE COMMAND */ /* ---- UPDATE COMMAND */
var cmdDashboard = &cobra.Command{ cmd := &cobra.Command{
Use: "dashboard [command]", Use: "dashboard [command]",
Short: "Manage your metabase dashboard container [requires local API]", Short: "Manage your metabase dashboard container [requires local API]",
Long: `Install/Start/Stop/Remove a metabase container exposing dashboard and metrics. Long: `Install/Start/Stop/Remove a metabase container exposing dashboard and metrics.
@ -93,19 +99,19 @@ cscli dashboard remove
}, },
} }
cmdDashboard.AddCommand(NewDashboardSetupCmd()) cmd.AddCommand(cli.NewSetupCmd())
cmdDashboard.AddCommand(NewDashboardStartCmd()) cmd.AddCommand(cli.NewStartCmd())
cmdDashboard.AddCommand(NewDashboardStopCmd()) cmd.AddCommand(cli.NewStopCmd())
cmdDashboard.AddCommand(NewDashboardShowPasswordCmd()) cmd.AddCommand(cli.NewShowPasswordCmd())
cmdDashboard.AddCommand(NewDashboardRemoveCmd()) cmd.AddCommand(cli.NewRemoveCmd())
return cmdDashboard return cmd
} }
func NewDashboardSetupCmd() *cobra.Command { func (cli cliDashboard) NewSetupCmd() *cobra.Command {
var force bool var force bool
var cmdDashSetup = &cobra.Command{ cmd := &cobra.Command{
Use: "setup", Use: "setup",
Short: "Setup a metabase container.", Short: "Setup a metabase container.",
Long: `Perform a metabase docker setup, download standard dashboards, create a fresh user and start the container`, Long: `Perform a metabase docker setup, download standard dashboards, create a fresh user and start the container`,
@ -158,20 +164,20 @@ cscli dashboard setup -l 0.0.0.0 -p 443 --password <password>
return nil return nil
}, },
} }
cmdDashSetup.Flags().BoolVarP(&force, "force", "f", false, "Force setup : override existing files") cmd.Flags().BoolVarP(&force, "force", "f", false, "Force setup : override existing files")
cmdDashSetup.Flags().StringVarP(&metabaseDbPath, "dir", "d", "", "Shared directory with metabase container") cmd.Flags().StringVarP(&metabaseDbPath, "dir", "d", "", "Shared directory with metabase container")
cmdDashSetup.Flags().StringVarP(&metabaseListenAddress, "listen", "l", metabaseListenAddress, "Listen address of container") cmd.Flags().StringVarP(&metabaseListenAddress, "listen", "l", metabaseListenAddress, "Listen address of container")
cmdDashSetup.Flags().StringVar(&metabaseImage, "metabase-image", metabaseImage, "Metabase image to use") cmd.Flags().StringVar(&metabaseImage, "metabase-image", metabaseImage, "Metabase image to use")
cmdDashSetup.Flags().StringVarP(&metabaseListenPort, "port", "p", metabaseListenPort, "Listen port of container") cmd.Flags().StringVarP(&metabaseListenPort, "port", "p", metabaseListenPort, "Listen port of container")
cmdDashSetup.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes") cmd.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes")
//cmdDashSetup.Flags().StringVarP(&metabaseUser, "user", "u", "crowdsec@crowdsec.net", "metabase user") //cmd.Flags().StringVarP(&metabaseUser, "user", "u", "crowdsec@crowdsec.net", "metabase user")
cmdDashSetup.Flags().StringVar(&metabasePassword, "password", "", "metabase password") cmd.Flags().StringVar(&metabasePassword, "password", "", "metabase password")
return cmdDashSetup return cmd
} }
func NewDashboardStartCmd() *cobra.Command { func (cli cliDashboard) NewStartCmd() *cobra.Command {
var cmdDashStart = &cobra.Command{ cmd := &cobra.Command{
Use: "start", Use: "start",
Short: "Start the metabase container.", Short: "Start the metabase container.",
Long: `Stats the metabase container using docker.`, Long: `Stats the metabase container using docker.`,
@ -194,12 +200,12 @@ func NewDashboardStartCmd() *cobra.Command {
return nil return nil
}, },
} }
cmdDashStart.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes") cmd.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes")
return cmdDashStart return cmd
} }
func NewDashboardStopCmd() *cobra.Command { func (cli cliDashboard) NewStopCmd() *cobra.Command {
var cmdDashStop = &cobra.Command{ cmd := &cobra.Command{
Use: "stop", Use: "stop",
Short: "Stops the metabase container.", Short: "Stops the metabase container.",
Long: `Stops the metabase container using docker.`, Long: `Stops the metabase container using docker.`,
@ -212,11 +218,11 @@ func NewDashboardStopCmd() *cobra.Command {
return nil return nil
}, },
} }
return cmdDashStop return cmd
} }
func NewDashboardShowPasswordCmd() *cobra.Command { func (cli cliDashboard) NewShowPasswordCmd() *cobra.Command {
var cmdDashShowPassword = &cobra.Command{Use: "show-password", cmd := &cobra.Command{Use: "show-password",
Short: "displays password of metabase.", Short: "displays password of metabase.",
Args: cobra.ExactArgs(0), Args: cobra.ExactArgs(0),
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -229,13 +235,13 @@ func NewDashboardShowPasswordCmd() *cobra.Command {
return nil return nil
}, },
} }
return cmdDashShowPassword return cmd
} }
func NewDashboardRemoveCmd() *cobra.Command { func (cli cliDashboard) NewRemoveCmd() *cobra.Command {
var force bool var force bool
var cmdDashRemove = &cobra.Command{ cmd := &cobra.Command{
Use: "remove", Use: "remove",
Short: "removes the metabase container.", Short: "removes the metabase container.",
Long: `removes the metabase container using docker.`, Long: `removes the metabase container using docker.`,
@ -300,17 +306,19 @@ cscli dashboard remove --force
return nil return nil
}, },
} }
cmdDashRemove.Flags().BoolVarP(&force, "force", "f", false, "Remove also the metabase image") cmd.Flags().BoolVarP(&force, "force", "f", false, "Remove also the metabase image")
cmdDashRemove.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes") cmd.Flags().BoolVarP(&forceYes, "yes", "y", false, "force yes")
return cmdDashRemove return cmd
} }
func passwordIsValid(password string) bool { func passwordIsValid(password string) bool {
hasDigit := false hasDigit := false
for _, j := range password { for _, j := range password {
if unicode.IsDigit(j) { if unicode.IsDigit(j) {
hasDigit = true hasDigit = true
break break
} }
} }
@ -319,7 +327,6 @@ func passwordIsValid(password string) bool {
return false return false
} }
return true return true
} }
func checkSystemMemory(forceYes *bool) error { func checkSystemMemory(forceYes *bool) error {

View file

@ -9,8 +9,14 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func NewDashboardCmd() *cobra.Command { type cliDashboard struct{}
var cmdDashboard = &cobra.Command{
func NewCLIDashboard() *cliDashboard {
return &cliDashboard{}
}
func (cli cliDashboard) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "dashboard", Use: "dashboard",
DisableAutoGenTag: true, DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
@ -18,5 +24,5 @@ func NewDashboardCmd() *cobra.Command {
}, },
} }
return cmdDashboard return cmd
} }

View file

@ -102,8 +102,15 @@ func DecisionsToTable(alerts *models.GetAlertsResponse, printMachine bool) error
return nil return nil
} }
func NewDecisionsCmd() *cobra.Command {
var cmdDecisions = &cobra.Command{ type cliDecisions struct {}
func NewCLIDecisions() *cliDecisions {
return &cliDecisions{}
}
func (cli cliDecisions) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "decisions [action]", Use: "decisions [action]",
Short: "Manage decisions", Short: "Manage decisions",
Long: `Add/List/Delete/Import decisions from LAPI`, Long: `Add/List/Delete/Import decisions from LAPI`,
@ -135,15 +142,15 @@ func NewDecisionsCmd() *cobra.Command {
}, },
} }
cmdDecisions.AddCommand(NewDecisionsListCmd()) cmd.AddCommand(cli.NewListCmd())
cmdDecisions.AddCommand(NewDecisionsAddCmd()) cmd.AddCommand(cli.NewAddCmd())
cmdDecisions.AddCommand(NewDecisionsDeleteCmd()) cmd.AddCommand(cli.NewDeleteCmd())
cmdDecisions.AddCommand(NewDecisionsImportCmd()) cmd.AddCommand(cli.NewImportCmd())
return cmdDecisions return cmd
} }
func NewDecisionsListCmd() *cobra.Command { func (cli cliDecisions) NewListCmd() *cobra.Command {
var filter = apiclient.AlertsListOpts{ var filter = apiclient.AlertsListOpts{
ValueEquals: new(string), ValueEquals: new(string),
ScopeEquals: new(string), ScopeEquals: new(string),
@ -161,7 +168,7 @@ func NewDecisionsListCmd() *cobra.Command {
contained := new(bool) contained := new(bool)
var printMachine bool var printMachine bool
var cmdDecisionsList = &cobra.Command{ cmd := &cobra.Command{
Use: "list [options]", Use: "list [options]",
Short: "List decisions from LAPI", Short: "List decisions from LAPI",
Example: `cscli decisions list -i 1.2.3.4 Example: `cscli decisions list -i 1.2.3.4
@ -251,26 +258,26 @@ cscli decisions list -t ban
return nil return nil
}, },
} }
cmdDecisionsList.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdDecisionsList.Flags().BoolVarP(filter.IncludeCAPI, "all", "a", false, "Include decisions from Central API") cmd.Flags().BoolVarP(filter.IncludeCAPI, "all", "a", false, "Include decisions from Central API")
cmdDecisionsList.Flags().StringVar(filter.Since, "since", "", "restrict to alerts newer than since (ie. 4h, 30d)") cmd.Flags().StringVar(filter.Since, "since", "", "restrict to alerts newer than since (ie. 4h, 30d)")
cmdDecisionsList.Flags().StringVar(filter.Until, "until", "", "restrict to alerts older than until (ie. 4h, 30d)") cmd.Flags().StringVar(filter.Until, "until", "", "restrict to alerts older than until (ie. 4h, 30d)")
cmdDecisionsList.Flags().StringVarP(filter.TypeEquals, "type", "t", "", "restrict to this decision type (ie. ban,captcha)") cmd.Flags().StringVarP(filter.TypeEquals, "type", "t", "", "restrict to this decision type (ie. ban,captcha)")
cmdDecisionsList.Flags().StringVar(filter.ScopeEquals, "scope", "", "restrict to this scope (ie. ip,range,session)") cmd.Flags().StringVar(filter.ScopeEquals, "scope", "", "restrict to this scope (ie. ip,range,session)")
cmdDecisionsList.Flags().StringVar(filter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) cmd.Flags().StringVar(filter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
cmdDecisionsList.Flags().StringVarP(filter.ValueEquals, "value", "v", "", "restrict to this value (ie. 1.2.3.4,userName)") cmd.Flags().StringVarP(filter.ValueEquals, "value", "v", "", "restrict to this value (ie. 1.2.3.4,userName)")
cmdDecisionsList.Flags().StringVarP(filter.ScenarioEquals, "scenario", "s", "", "restrict to this scenario (ie. crowdsecurity/ssh-bf)") cmd.Flags().StringVarP(filter.ScenarioEquals, "scenario", "s", "", "restrict to this scenario (ie. crowdsecurity/ssh-bf)")
cmdDecisionsList.Flags().StringVarP(filter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)") cmd.Flags().StringVarP(filter.IPEquals, "ip", "i", "", "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)")
cmdDecisionsList.Flags().StringVarP(filter.RangeEquals, "range", "r", "", "restrict to alerts from this source range (shorthand for --scope range --value <RANGE>)") cmd.Flags().StringVarP(filter.RangeEquals, "range", "r", "", "restrict to alerts from this source range (shorthand for --scope range --value <RANGE>)")
cmdDecisionsList.Flags().IntVarP(filter.Limit, "limit", "l", 100, "number of alerts to get (use 0 to remove the limit)") cmd.Flags().IntVarP(filter.Limit, "limit", "l", 100, "number of alerts to get (use 0 to remove the limit)")
cmdDecisionsList.Flags().BoolVar(NoSimu, "no-simu", false, "exclude decisions in simulation mode") cmd.Flags().BoolVar(NoSimu, "no-simu", false, "exclude decisions in simulation mode")
cmdDecisionsList.Flags().BoolVarP(&printMachine, "machine", "m", false, "print machines that triggered decisions") cmd.Flags().BoolVarP(&printMachine, "machine", "m", false, "print machines that triggered decisions")
cmdDecisionsList.Flags().BoolVar(contained, "contained", false, "query decisions contained by range") cmd.Flags().BoolVar(contained, "contained", false, "query decisions contained by range")
return cmdDecisionsList return cmd
} }
func NewDecisionsAddCmd() *cobra.Command { func (cli cliDecisions) NewAddCmd() *cobra.Command {
var ( var (
addIP string addIP string
addRange string addRange string
@ -281,7 +288,7 @@ func NewDecisionsAddCmd() *cobra.Command {
addType string addType string
) )
var cmdDecisionsAdd = &cobra.Command{ cmd := &cobra.Command{
Use: "add [options]", Use: "add [options]",
Short: "Add decision to LAPI", Short: "Add decision to LAPI",
Example: `cscli decisions add --ip 1.2.3.4 Example: `cscli decisions add --ip 1.2.3.4
@ -369,19 +376,19 @@ cscli decisions add --scope username --value foobar
}, },
} }
cmdDecisionsAdd.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdDecisionsAdd.Flags().StringVarP(&addIP, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)") cmd.Flags().StringVarP(&addIP, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)")
cmdDecisionsAdd.Flags().StringVarP(&addRange, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)") cmd.Flags().StringVarP(&addRange, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)")
cmdDecisionsAdd.Flags().StringVarP(&addDuration, "duration", "d", "4h", "Decision duration (ie. 1h,4h,30m)") cmd.Flags().StringVarP(&addDuration, "duration", "d", "4h", "Decision duration (ie. 1h,4h,30m)")
cmdDecisionsAdd.Flags().StringVarP(&addValue, "value", "v", "", "The value (ie. --scope username --value foobar)") cmd.Flags().StringVarP(&addValue, "value", "v", "", "The value (ie. --scope username --value foobar)")
cmdDecisionsAdd.Flags().StringVar(&addScope, "scope", types.Ip, "Decision scope (ie. ip,range,username)") cmd.Flags().StringVar(&addScope, "scope", types.Ip, "Decision scope (ie. ip,range,username)")
cmdDecisionsAdd.Flags().StringVarP(&addReason, "reason", "R", "", "Decision reason (ie. scenario-name)") cmd.Flags().StringVarP(&addReason, "reason", "R", "", "Decision reason (ie. scenario-name)")
cmdDecisionsAdd.Flags().StringVarP(&addType, "type", "t", "ban", "Decision type (ie. ban,captcha,throttle)") cmd.Flags().StringVarP(&addType, "type", "t", "ban", "Decision type (ie. ban,captcha,throttle)")
return cmdDecisionsAdd return cmd
} }
func NewDecisionsDeleteCmd() *cobra.Command { func (cli cliDecisions) NewDeleteCmd() *cobra.Command {
var delFilter = apiclient.DecisionsDeleteOpts{ var delFilter = apiclient.DecisionsDeleteOpts{
ScopeEquals: new(string), ScopeEquals: new(string),
ValueEquals: new(string), ValueEquals: new(string),
@ -395,7 +402,7 @@ func NewDecisionsDeleteCmd() *cobra.Command {
var delDecisionAll bool var delDecisionAll bool
contained := new(bool) contained := new(bool)
var cmdDecisionsDelete = &cobra.Command{ cmd := &cobra.Command{
Use: "delete [options]", Use: "delete [options]",
Short: "Delete decisions", Short: "Delete decisions",
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -472,17 +479,17 @@ cscli decisions delete --type captcha
}, },
} }
cmdDecisionsDelete.Flags().SortFlags = false cmd.Flags().SortFlags = false
cmdDecisionsDelete.Flags().StringVarP(delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)") cmd.Flags().StringVarP(delFilter.IPEquals, "ip", "i", "", "Source ip (shorthand for --scope ip --value <IP>)")
cmdDecisionsDelete.Flags().StringVarP(delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)") cmd.Flags().StringVarP(delFilter.RangeEquals, "range", "r", "", "Range source ip (shorthand for --scope range --value <RANGE>)")
cmdDecisionsDelete.Flags().StringVarP(delFilter.TypeEquals, "type", "t", "", "the decision type (ie. ban,captcha)") cmd.Flags().StringVarP(delFilter.TypeEquals, "type", "t", "", "the decision type (ie. ban,captcha)")
cmdDecisionsDelete.Flags().StringVarP(delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope") cmd.Flags().StringVarP(delFilter.ValueEquals, "value", "v", "", "the value to match for in the specified scope")
cmdDecisionsDelete.Flags().StringVarP(delFilter.ScenarioEquals, "scenario", "s", "", "the scenario name (ie. crowdsecurity/ssh-bf)") cmd.Flags().StringVarP(delFilter.ScenarioEquals, "scenario", "s", "", "the scenario name (ie. crowdsecurity/ssh-bf)")
cmdDecisionsDelete.Flags().StringVar(delFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ","))) cmd.Flags().StringVar(delFilter.OriginEquals, "origin", "", fmt.Sprintf("the value to match for the specified origin (%s ...)", strings.Join(types.GetOrigins(), ",")))
cmdDecisionsDelete.Flags().StringVar(&delDecisionId, "id", "", "decision id") cmd.Flags().StringVar(&delDecisionId, "id", "", "decision id")
cmdDecisionsDelete.Flags().BoolVar(&delDecisionAll, "all", false, "delete all decisions") cmd.Flags().BoolVar(&delDecisionAll, "all", false, "delete all decisions")
cmdDecisionsDelete.Flags().BoolVar(contained, "contained", false, "query decisions contained by range") cmd.Flags().BoolVar(contained, "contained", false, "query decisions contained by range")
return cmdDecisionsDelete return cmd
} }

View file

@ -63,7 +63,7 @@ func parseDecisionList(content []byte, format string) ([]decisionRaw, error) {
} }
func runDecisionsImport(cmd *cobra.Command, args []string) error { func (cli cliDecisions) runImport(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
input, err := flags.GetString("input") input, err := flags.GetString("input")
@ -226,8 +226,8 @@ func runDecisionsImport(cmd *cobra.Command, args []string) error {
} }
func NewDecisionsImportCmd() *cobra.Command { func (cli cliDecisions) NewImportCmd() *cobra.Command {
var cmdDecisionsImport = &cobra.Command{ cmd := &cobra.Command{
Use: "import [options]", Use: "import [options]",
Short: "Import decisions from a file or pipe", Short: "Import decisions from a file or pipe",
Long: "expected format:\n" + Long: "expected format:\n" +
@ -250,10 +250,10 @@ Raw values, standard input:
$ echo "1.2.3.4" | cscli decisions import -i - --format values $ echo "1.2.3.4" | cscli decisions import -i - --format values
`, `,
RunE: runDecisionsImport, RunE: cli.runImport,
} }
flags := cmdDecisionsImport.Flags() flags := cmd.Flags()
flags.SortFlags = false flags.SortFlags = false
flags.StringP("input", "i", "", "Input file") flags.StringP("input", "i", "", "Input file")
flags.StringP("duration", "d", "4h", "Decision duration: 1h,4h,30m") flags.StringP("duration", "d", "4h", "Decision duration: 1h,4h,30m")
@ -263,7 +263,7 @@ $ echo "1.2.3.4" | cscli decisions import -i - --format values
flags.Int("batch", 0, "Split import in batches of N decisions") flags.Int("batch", 0, "Split import in batches of N decisions")
flags.String("format", "", "Input format: 'json', 'csv' or 'values' (each line is a value, no headers)") flags.String("format", "", "Input format: 'json', 'csv' or 'values' (each line is a value, no headers)")
cmdDecisionsImport.MarkFlagRequired("input") cmd.MarkFlagRequired("input")
return cmdDecisionsImport return cmd
} }

View file

@ -13,8 +13,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewAppsecConfigCLI() *itemCLI { func NewCLIAppsecConfig() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.APPSEC_CONFIGS, name: cwhub.APPSEC_CONFIGS,
singular: "appsec-config", singular: "appsec-config",
oneOrMore: "appsec-config(s)", oneOrMore: "appsec-config(s)",
@ -46,7 +46,7 @@ cscli appsec-configs list crowdsecurity/vpatch`,
} }
} }
func NewAppsecRuleCLI() *itemCLI { func NewCLIAppsecRule() *cliItem {
inspectDetail := func(item *cwhub.Item) error { inspectDetail := func(item *cwhub.Item) error {
appsecRule := appsec.AppsecCollectionConfig{} appsecRule := appsec.AppsecCollectionConfig{}
yamlContent, err := os.ReadFile(item.State.LocalPath) yamlContent, err := os.ReadFile(item.State.LocalPath)
@ -71,7 +71,7 @@ func NewAppsecRuleCLI() *itemCLI {
return nil return nil
} }
return &itemCLI{ return &cliItem{
name: "appsec-rules", name: "appsec-rules",
singular: "appsec-rule", singular: "appsec-rule",
oneOrMore: "appsec-rule(s)", oneOrMore: "appsec-rule(s)",

View file

@ -4,8 +4,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewCollectionCLI() *itemCLI { func NewCLICollection() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.COLLECTIONS, name: cwhub.COLLECTIONS,
singular: "collection", singular: "collection",
oneOrMore: "collection(s)", oneOrMore: "collection(s)",

View file

@ -4,8 +4,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewContextCLI() *itemCLI { func NewCLIContext() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.CONTEXTS, name: cwhub.CONTEXTS,
singular: "context", singular: "context",
oneOrMore: "context(s)", oneOrMore: "context(s)",

View file

@ -4,8 +4,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewParserCLI() *itemCLI { func NewCLIParser() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.PARSERS, name: cwhub.PARSERS,
singular: "parser", singular: "parser",
oneOrMore: "parser(s)", oneOrMore: "parser(s)",

View file

@ -4,8 +4,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewPostOverflowCLI() *itemCLI { func NewCLIPostOverflow() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.POSTOVERFLOWS, name: cwhub.POSTOVERFLOWS,
singular: "postoverflow", singular: "postoverflow",
oneOrMore: "postoverflow(s)", oneOrMore: "postoverflow(s)",

View file

@ -4,8 +4,8 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
func NewScenarioCLI() *itemCLI { func NewCLIScenario() *cliItem {
return &itemCLI{ return &cliItem{
name: cwhub.SCENARIOS, name: cwhub.SCENARIOS,
singular: "scenario", singular: "scenario",
oneOrMore: "scenario(s)", oneOrMore: "scenario(s)",

View file

@ -23,12 +23,18 @@ var HubAppsecTests hubtest.HubTest
var hubPtr *hubtest.HubTest var hubPtr *hubtest.HubTest
var isAppsecTest bool var isAppsecTest bool
func NewHubTestCmd() *cobra.Command { type cliHubTest struct{}
func NewCLIHubTest() *cliHubTest {
return &cliHubTest{}
}
func (cli cliHubTest) NewCommand() *cobra.Command {
var hubPath string var hubPath string
var crowdsecPath string var crowdsecPath string
var cscliPath string var cscliPath string
var cmdHubTest = &cobra.Command{ cmd := &cobra.Command{
Use: "hubtest", Use: "hubtest",
Short: "Run functional tests on hub configurations", Short: "Run functional tests on hub configurations",
Long: "Run functional tests on hub configurations (parsers, scenarios, collections...)", Long: "Run functional tests on hub configurations (parsers, scenarios, collections...)",
@ -54,24 +60,24 @@ func NewHubTestCmd() *cobra.Command {
}, },
} }
cmdHubTest.PersistentFlags().StringVar(&hubPath, "hub", ".", "Path to hub folder") cmd.PersistentFlags().StringVar(&hubPath, "hub", ".", "Path to hub folder")
cmdHubTest.PersistentFlags().StringVar(&crowdsecPath, "crowdsec", "crowdsec", "Path to crowdsec") cmd.PersistentFlags().StringVar(&crowdsecPath, "crowdsec", "crowdsec", "Path to crowdsec")
cmdHubTest.PersistentFlags().StringVar(&cscliPath, "cscli", "cscli", "Path to cscli") cmd.PersistentFlags().StringVar(&cscliPath, "cscli", "cscli", "Path to cscli")
cmdHubTest.PersistentFlags().BoolVar(&isAppsecTest, "appsec", false, "Command relates to appsec tests") cmd.PersistentFlags().BoolVar(&isAppsecTest, "appsec", false, "Command relates to appsec tests")
cmdHubTest.AddCommand(NewHubTestCreateCmd()) cmd.AddCommand(cli.NewCreateCmd())
cmdHubTest.AddCommand(NewHubTestRunCmd()) cmd.AddCommand(cli.NewRunCmd())
cmdHubTest.AddCommand(NewHubTestCleanCmd()) cmd.AddCommand(cli.NewCleanCmd())
cmdHubTest.AddCommand(NewHubTestInfoCmd()) cmd.AddCommand(cli.NewInfoCmd())
cmdHubTest.AddCommand(NewHubTestListCmd()) cmd.AddCommand(cli.NewListCmd())
cmdHubTest.AddCommand(NewHubTestCoverageCmd()) cmd.AddCommand(cli.NewCoverageCmd())
cmdHubTest.AddCommand(NewHubTestEvalCmd()) cmd.AddCommand(cli.NewEvalCmd())
cmdHubTest.AddCommand(NewHubTestExplainCmd()) cmd.AddCommand(cli.NewExplainCmd())
return cmdHubTest return cmd
} }
func NewHubTestCreateCmd() *cobra.Command { func (cli cliHubTest) NewCreateCmd() *cobra.Command {
parsers := []string{} parsers := []string{}
postoverflows := []string{} postoverflows := []string{}
scenarios := []string{} scenarios := []string{}
@ -79,7 +85,7 @@ func NewHubTestCreateCmd() *cobra.Command {
var labels map[string]string var labels map[string]string
var logType string var logType string
var cmdHubTestCreate = &cobra.Command{ cmd := &cobra.Command{
Use: "create", Use: "create",
Short: "create [test_name]", Short: "create [test_name]",
Example: `cscli hubtest create my-awesome-test --type syslog Example: `cscli hubtest create my-awesome-test --type syslog
@ -191,21 +197,21 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
}, },
} }
cmdHubTestCreate.PersistentFlags().StringVarP(&logType, "type", "t", "", "Log type of the test") cmd.PersistentFlags().StringVarP(&logType, "type", "t", "", "Log type of the test")
cmdHubTestCreate.Flags().StringSliceVarP(&parsers, "parsers", "p", parsers, "Parsers to add to test") cmd.Flags().StringSliceVarP(&parsers, "parsers", "p", parsers, "Parsers to add to test")
cmdHubTestCreate.Flags().StringSliceVar(&postoverflows, "postoverflows", postoverflows, "Postoverflows to add to test") cmd.Flags().StringSliceVar(&postoverflows, "postoverflows", postoverflows, "Postoverflows to add to test")
cmdHubTestCreate.Flags().StringSliceVarP(&scenarios, "scenarios", "s", scenarios, "Scenarios to add to test") cmd.Flags().StringSliceVarP(&scenarios, "scenarios", "s", scenarios, "Scenarios to add to test")
cmdHubTestCreate.PersistentFlags().BoolVar(&ignoreParsers, "ignore-parsers", false, "Don't run test on parsers") cmd.PersistentFlags().BoolVar(&ignoreParsers, "ignore-parsers", false, "Don't run test on parsers")
return cmdHubTestCreate return cmd
} }
func NewHubTestRunCmd() *cobra.Command { func (cli cliHubTest) NewRunCmd() *cobra.Command {
var noClean bool var noClean bool
var runAll bool var runAll bool
var forceClean bool var forceClean bool
var cmdHubTestRun = &cobra.Command{ var cmd = &cobra.Command{
Use: "run", Use: "run",
Short: "run [test_name]", Short: "run [test_name]",
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -353,15 +359,15 @@ func NewHubTestRunCmd() *cobra.Command {
}, },
} }
cmdHubTestRun.Flags().BoolVar(&noClean, "no-clean", false, "Don't clean runtime environment if test succeed") cmd.Flags().BoolVar(&noClean, "no-clean", false, "Don't clean runtime environment if test succeed")
cmdHubTestRun.Flags().BoolVar(&forceClean, "clean", false, "Clean runtime environment if test fail") cmd.Flags().BoolVar(&forceClean, "clean", false, "Clean runtime environment if test fail")
cmdHubTestRun.Flags().BoolVar(&runAll, "all", false, "Run all tests") cmd.Flags().BoolVar(&runAll, "all", false, "Run all tests")
return cmdHubTestRun return cmd
} }
func NewHubTestCleanCmd() *cobra.Command { func (cli cliHubTest) NewCleanCmd() *cobra.Command {
var cmdHubTestClean = &cobra.Command{ var cmd = &cobra.Command{
Use: "clean", Use: "clean",
Short: "clean [test_name]", Short: "clean [test_name]",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
@ -381,17 +387,16 @@ func NewHubTestCleanCmd() *cobra.Command {
}, },
} }
return cmdHubTestClean return cmd
} }
func NewHubTestInfoCmd() *cobra.Command { func (cli cliHubTest) NewInfoCmd() *cobra.Command {
var cmdHubTestInfo = &cobra.Command{ cmd := &cobra.Command{
Use: "info", Use: "info",
Short: "info [test_name]", Short: "info [test_name]",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
for _, testName := range args { for _, testName := range args {
test, err := hubPtr.LoadTestItem(testName) test, err := hubPtr.LoadTestItem(testName)
if err != nil { if err != nil {
@ -415,11 +420,11 @@ func NewHubTestInfoCmd() *cobra.Command {
}, },
} }
return cmdHubTestInfo return cmd
} }
func NewHubTestListCmd() *cobra.Command { func (cli cliHubTest) NewListCmd() *cobra.Command {
var cmdHubTestList = &cobra.Command{ cmd := &cobra.Command{
Use: "list", Use: "list",
Short: "list", Short: "list",
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -445,16 +450,16 @@ func NewHubTestListCmd() *cobra.Command {
}, },
} }
return cmdHubTestList return cmd
} }
func NewHubTestCoverageCmd() *cobra.Command { func (cli cliHubTest) NewCoverageCmd() *cobra.Command {
var showParserCov bool var showParserCov bool
var showScenarioCov bool var showScenarioCov bool
var showOnlyPercent bool var showOnlyPercent bool
var showAppsecCov bool var showAppsecCov bool
var cmdHubTestCoverage = &cobra.Command{ cmd := &cobra.Command{
Use: "coverage", Use: "coverage",
Short: "coverage", Short: "coverage",
DisableAutoGenTag: true, DisableAutoGenTag: true,
@ -580,17 +585,18 @@ func NewHubTestCoverageCmd() *cobra.Command {
}, },
} }
cmdHubTestCoverage.PersistentFlags().BoolVar(&showOnlyPercent, "percent", false, "Show only percentages of coverage") cmd.PersistentFlags().BoolVar(&showOnlyPercent, "percent", false, "Show only percentages of coverage")
cmdHubTestCoverage.PersistentFlags().BoolVar(&showParserCov, "parsers", false, "Show only parsers coverage") cmd.PersistentFlags().BoolVar(&showParserCov, "parsers", false, "Show only parsers coverage")
cmdHubTestCoverage.PersistentFlags().BoolVar(&showScenarioCov, "scenarios", false, "Show only scenarios coverage") cmd.PersistentFlags().BoolVar(&showScenarioCov, "scenarios", false, "Show only scenarios coverage")
cmdHubTestCoverage.PersistentFlags().BoolVar(&showAppsecCov, "appsec", false, "Show only appsec coverage") cmd.PersistentFlags().BoolVar(&showAppsecCov, "appsec", false, "Show only appsec coverage")
return cmdHubTestCoverage return cmd
} }
func NewHubTestEvalCmd() *cobra.Command { func (cli cliHubTest) NewEvalCmd() *cobra.Command {
var evalExpression string var evalExpression string
var cmdHubTestEval = &cobra.Command{
cmd := &cobra.Command{
Use: "eval", Use: "eval",
Short: "eval [test_name]", Short: "eval [test_name]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
@ -619,13 +625,13 @@ func NewHubTestEvalCmd() *cobra.Command {
}, },
} }
cmdHubTestEval.PersistentFlags().StringVarP(&evalExpression, "expr", "e", "", "Expression to eval") cmd.PersistentFlags().StringVarP(&evalExpression, "expr", "e", "", "Expression to eval")
return cmdHubTestEval return cmd
} }
func NewHubTestExplainCmd() *cobra.Command { func (cli cliHubTest) NewExplainCmd() *cobra.Command {
var cmdHubTestExplain = &cobra.Command{ cmd := &cobra.Command{
Use: "explain", Use: "explain",
Short: "explain [test_name]", Short: "explain [test_name]",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
@ -665,5 +671,5 @@ func NewHubTestExplainCmd() *cobra.Command {
}, },
} }
return cmdHubTestExplain return cmd
} }

View file

@ -22,7 +22,7 @@ type cliHelp struct {
example string example string
} }
type itemCLI struct { type cliItem struct {
name string // plural, as used in the hub index name string // plural, as used in the hub index
singular string singular string
oneOrMore string // parenthetical pluralizaion: "parser(s)" oneOrMore string // parenthetical pluralizaion: "parser(s)"
@ -35,7 +35,7 @@ type itemCLI struct {
listHelp cliHelp listHelp cliHelp
} }
func (it itemCLI) NewCommand() *cobra.Command { func (it cliItem) NewCommand() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.help.use, fmt.Sprintf("%s <action> [item]...", it.name)), Use: coalesce.String(it.help.use, fmt.Sprintf("%s <action> [item]...", it.name)),
Short: coalesce.String(it.help.short, fmt.Sprintf("Manage hub %s", it.name)), Short: coalesce.String(it.help.short, fmt.Sprintf("Manage hub %s", it.name)),
@ -55,7 +55,7 @@ func (it itemCLI) NewCommand() *cobra.Command {
return cmd return cmd
} }
func (it itemCLI) Install(cmd *cobra.Command, args []string) error { func (it cliItem) Install(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
downloadOnly, err := flags.GetBool("download-only") downloadOnly, err := flags.GetBool("download-only")
@ -103,7 +103,7 @@ func (it itemCLI) Install(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (it itemCLI) NewInstallCmd() *cobra.Command { func (it cliItem) NewInstallCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.installHelp.use, "install [item]..."), Use: coalesce.String(it.installHelp.use, "install [item]..."),
Short: coalesce.String(it.installHelp.short, fmt.Sprintf("Install given %s", it.oneOrMore)), Short: coalesce.String(it.installHelp.short, fmt.Sprintf("Install given %s", it.oneOrMore)),
@ -138,7 +138,7 @@ func istalledParentNames(item *cwhub.Item) []string {
return ret return ret
} }
func (it itemCLI) Remove(cmd *cobra.Command, args []string) error { func (it cliItem) Remove(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
purge, err := flags.GetBool("purge") purge, err := flags.GetBool("purge")
@ -232,7 +232,7 @@ func (it itemCLI) Remove(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (it itemCLI) NewRemoveCmd() *cobra.Command { func (it cliItem) NewRemoveCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.removeHelp.use, "remove [item]..."), Use: coalesce.String(it.removeHelp.use, "remove [item]..."),
Short: coalesce.String(it.removeHelp.short, fmt.Sprintf("Remove given %s", it.oneOrMore)), Short: coalesce.String(it.removeHelp.short, fmt.Sprintf("Remove given %s", it.oneOrMore)),
@ -254,7 +254,7 @@ func (it itemCLI) NewRemoveCmd() *cobra.Command {
return cmd return cmd
} }
func (it itemCLI) Upgrade(cmd *cobra.Command, args []string) error { func (it cliItem) Upgrade(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
force, err := flags.GetBool("force") force, err := flags.GetBool("force")
@ -328,7 +328,7 @@ func (it itemCLI) Upgrade(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (it itemCLI) NewUpgradeCmd() *cobra.Command { func (it cliItem) NewUpgradeCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.upgradeHelp.use, "upgrade [item]..."), Use: coalesce.String(it.upgradeHelp.use, "upgrade [item]..."),
Short: coalesce.String(it.upgradeHelp.short, fmt.Sprintf("Upgrade given %s", it.oneOrMore)), Short: coalesce.String(it.upgradeHelp.short, fmt.Sprintf("Upgrade given %s", it.oneOrMore)),
@ -348,7 +348,7 @@ func (it itemCLI) NewUpgradeCmd() *cobra.Command {
return cmd return cmd
} }
func (it itemCLI) Inspect(cmd *cobra.Command, args []string) error { func (it cliItem) Inspect(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
url, err := flags.GetString("url") url, err := flags.GetString("url")
@ -389,7 +389,7 @@ func (it itemCLI) Inspect(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (it itemCLI) NewInspectCmd() *cobra.Command { func (it cliItem) NewInspectCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.inspectHelp.use, "inspect [item]..."), Use: coalesce.String(it.inspectHelp.use, "inspect [item]..."),
Short: coalesce.String(it.inspectHelp.short, fmt.Sprintf("Inspect given %s", it.oneOrMore)), Short: coalesce.String(it.inspectHelp.short, fmt.Sprintf("Inspect given %s", it.oneOrMore)),
@ -410,7 +410,7 @@ func (it itemCLI) NewInspectCmd() *cobra.Command {
return cmd return cmd
} }
func (it itemCLI) List(cmd *cobra.Command, args []string) error { func (it cliItem) List(cmd *cobra.Command, args []string) error {
flags := cmd.Flags() flags := cmd.Flags()
all, err := flags.GetBool("all") all, err := flags.GetBool("all")
@ -437,7 +437,7 @@ func (it itemCLI) List(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func (it itemCLI) NewListCmd() *cobra.Command { func (it cliItem) NewListCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: coalesce.String(it.listHelp.use, "list [item... | -a]"), Use: coalesce.String(it.listHelp.use, "list [item... | -a]"),
Short: coalesce.String(it.listHelp.short, fmt.Sprintf("List %s", it.oneOrMore)), Short: coalesce.String(it.listHelp.short, fmt.Sprintf("List %s", it.oneOrMore)),

View file

@ -228,28 +228,28 @@ It is meant to allow you to manage bans, parsers/scenarios/etc, api and generall
rootCmd.AddCommand(NewConfigCmd()) rootCmd.AddCommand(NewConfigCmd())
rootCmd.AddCommand(NewCLIHub().NewCommand()) rootCmd.AddCommand(NewCLIHub().NewCommand())
rootCmd.AddCommand(NewMetricsCmd()) rootCmd.AddCommand(NewMetricsCmd())
rootCmd.AddCommand(NewDashboardCmd()) rootCmd.AddCommand(NewCLIDashboard().NewCommand())
rootCmd.AddCommand(NewDecisionsCmd()) rootCmd.AddCommand(NewCLIDecisions().NewCommand())
rootCmd.AddCommand(NewAlertsCmd()) rootCmd.AddCommand(NewCLIAlerts().NewCommand())
rootCmd.AddCommand(NewSimulationCmds()) rootCmd.AddCommand(NewCLISimulation().NewCommand())
rootCmd.AddCommand(NewCLIBouncers().NewCommand()) rootCmd.AddCommand(NewCLIBouncers().NewCommand())
rootCmd.AddCommand(NewCLIMachines().NewCommand()) rootCmd.AddCommand(NewCLIMachines().NewCommand())
rootCmd.AddCommand(NewCapiCmd()) rootCmd.AddCommand(NewCLICapi().NewCommand())
rootCmd.AddCommand(NewLapiCmd()) rootCmd.AddCommand(NewLapiCmd())
rootCmd.AddCommand(NewCompletionCmd()) rootCmd.AddCommand(NewCompletionCmd())
rootCmd.AddCommand(NewConsoleCmd()) rootCmd.AddCommand(NewConsoleCmd())
rootCmd.AddCommand(NewCLIExplain().NewCommand()) rootCmd.AddCommand(NewCLIExplain().NewCommand())
rootCmd.AddCommand(NewHubTestCmd()) rootCmd.AddCommand(NewCLIHubTest().NewCommand())
rootCmd.AddCommand(NewCLINotifications().NewCommand()) rootCmd.AddCommand(NewCLINotifications().NewCommand())
rootCmd.AddCommand(NewCLISupport().NewCommand()) rootCmd.AddCommand(NewCLISupport().NewCommand())
rootCmd.AddCommand(NewCLIPapi().NewCommand()) rootCmd.AddCommand(NewCLIPapi().NewCommand())
rootCmd.AddCommand(NewCollectionCLI().NewCommand()) rootCmd.AddCommand(NewCLICollection().NewCommand())
rootCmd.AddCommand(NewParserCLI().NewCommand()) rootCmd.AddCommand(NewCLIParser().NewCommand())
rootCmd.AddCommand(NewScenarioCLI().NewCommand()) rootCmd.AddCommand(NewCLIScenario().NewCommand())
rootCmd.AddCommand(NewPostOverflowCLI().NewCommand()) rootCmd.AddCommand(NewCLIPostOverflow().NewCommand())
rootCmd.AddCommand(NewContextCLI().NewCommand()) rootCmd.AddCommand(NewCLIContext().NewCommand())
rootCmd.AddCommand(NewAppsecConfigCLI().NewCommand()) rootCmd.AddCommand(NewCLIAppsecConfig().NewCommand())
rootCmd.AddCommand(NewAppsecRuleCLI().NewCommand()) rootCmd.AddCommand(NewCLIAppsecRule().NewCommand())
if fflag.CscliSetup.IsEnabled() { if fflag.CscliSetup.IsEnabled() {
rootCmd.AddCommand(NewSetupCmd()) rootCmd.AddCommand(NewSetupCmd())

View file

@ -13,6 +13,174 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub" "github.com/crowdsecurity/crowdsec/pkg/cwhub"
) )
type cliSimulation struct {}
func NewCLISimulation() *cliSimulation {
return &cliSimulation{}
}
func (cli cliSimulation) NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "simulation [command]",
Short: "Manage simulation status of scenarios",
Example: `cscli simulation status
cscli simulation enable crowdsecurity/ssh-bf
cscli simulation disable crowdsecurity/ssh-bf`,
DisableAutoGenTag: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := csConfig.LoadSimulation(); err != nil {
log.Fatal(err)
}
if csConfig.Cscli.SimulationConfig == nil {
return fmt.Errorf("no simulation configured")
}
return nil
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
if cmd.Name() != "status" {
log.Infof(ReloadMessage())
}
},
}
cmd.Flags().SortFlags = false
cmd.PersistentFlags().SortFlags = false
cmd.AddCommand(cli.NewEnableCmd())
cmd.AddCommand(cli.NewDisableCmd())
cmd.AddCommand(cli.NewStatusCmd())
return cmd
}
func (cli cliSimulation) NewEnableCmd() *cobra.Command {
var forceGlobalSimulation bool
cmd := &cobra.Command{
Use: "enable [scenario] [-global]",
Short: "Enable the simulation, globally or on specified scenarios",
Example: `cscli simulation enable`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
hub, err := require.Hub(csConfig, nil)
if err != nil {
log.Fatal(err)
}
if len(args) > 0 {
for _, scenario := range args {
var item = hub.GetItem(cwhub.SCENARIOS, scenario)
if item == nil {
log.Errorf("'%s' doesn't exist or is not a scenario", scenario)
continue
}
if !item.State.Installed {
log.Warningf("'%s' isn't enabled", scenario)
}
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if *csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warning("global simulation is already enabled")
continue
}
if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
log.Warningf("simulation for '%s' already enabled", scenario)
continue
}
if *csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
if err := removeFromExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation enabled for '%s'", scenario)
continue
}
if err := addToExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' enabled", scenario)
}
if err := dumpSimulationFile(); err != nil {
log.Fatalf("simulation enable: %s", err)
}
} else if forceGlobalSimulation {
if err := enableGlobalSimulation(); err != nil {
log.Fatalf("unable to enable global simulation mode : %s", err)
}
} else {
printHelp(cmd)
}
},
}
cmd.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Enable global simulation (reverse mode)")
return cmd
}
func (cli cliSimulation) NewDisableCmd() *cobra.Command {
var forceGlobalSimulation bool
cmd := &cobra.Command{
Use: "disable [scenario]",
Short: "Disable the simulation mode. Disable only specified scenarios",
Example: `cscli simulation disable`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
for _, scenario := range args {
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if !*csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warningf("%s isn't in simulation mode", scenario)
continue
}
if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
if err := removeFromExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' disabled", scenario)
continue
}
if isExcluded {
log.Warningf("simulation mode is enabled but is already disable for '%s'", scenario)
continue
}
if err := addToExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' disabled", scenario)
}
if err := dumpSimulationFile(); err != nil {
log.Fatalf("simulation disable: %s", err)
}
} else if forceGlobalSimulation {
if err := disableGlobalSimulation(); err != nil {
log.Fatalf("unable to disable global simulation mode : %s", err)
}
} else {
printHelp(cmd)
}
},
}
cmd.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Disable global simulation (reverse mode)")
return cmd
}
func (cli cliSimulation) NewStatusCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Show simulation mode status",
Example: `cscli simulation status`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
if err := simulationStatus(); err != nil {
log.Fatal(err)
}
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
},
}
return cmd
}
func addToExclusion(name string) error { func addToExclusion(name string) error {
csConfig.Cscli.SimulationConfig.Exclusions = append(csConfig.Cscli.SimulationConfig.Exclusions, name) csConfig.Cscli.SimulationConfig.Exclusions = append(csConfig.Cscli.SimulationConfig.Exclusions, name)
return nil return nil
@ -100,164 +268,3 @@ func simulationStatus() error {
return nil return nil
} }
func NewSimulationCmds() *cobra.Command {
var cmdSimulation = &cobra.Command{
Use: "simulation [command]",
Short: "Manage simulation status of scenarios",
Example: `cscli simulation status
cscli simulation enable crowdsecurity/ssh-bf
cscli simulation disable crowdsecurity/ssh-bf`,
DisableAutoGenTag: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := csConfig.LoadSimulation(); err != nil {
log.Fatal(err)
}
if csConfig.Cscli.SimulationConfig == nil {
return fmt.Errorf("no simulation configured")
}
return nil
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
if cmd.Name() != "status" {
log.Infof(ReloadMessage())
}
},
}
cmdSimulation.Flags().SortFlags = false
cmdSimulation.PersistentFlags().SortFlags = false
cmdSimulation.AddCommand(NewSimulationEnableCmd())
cmdSimulation.AddCommand(NewSimulationDisableCmd())
cmdSimulation.AddCommand(NewSimulationStatusCmd())
return cmdSimulation
}
func NewSimulationEnableCmd() *cobra.Command {
var forceGlobalSimulation bool
var cmdSimulationEnable = &cobra.Command{
Use: "enable [scenario] [-global]",
Short: "Enable the simulation, globally or on specified scenarios",
Example: `cscli simulation enable`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
hub, err := require.Hub(csConfig, nil)
if err != nil {
log.Fatal(err)
}
if len(args) > 0 {
for _, scenario := range args {
var item = hub.GetItem(cwhub.SCENARIOS, scenario)
if item == nil {
log.Errorf("'%s' doesn't exist or is not a scenario", scenario)
continue
}
if !item.State.Installed {
log.Warningf("'%s' isn't enabled", scenario)
}
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if *csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warning("global simulation is already enabled")
continue
}
if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
log.Warningf("simulation for '%s' already enabled", scenario)
continue
}
if *csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
if err := removeFromExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation enabled for '%s'", scenario)
continue
}
if err := addToExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' enabled", scenario)
}
if err := dumpSimulationFile(); err != nil {
log.Fatalf("simulation enable: %s", err)
}
} else if forceGlobalSimulation {
if err := enableGlobalSimulation(); err != nil {
log.Fatalf("unable to enable global simulation mode : %s", err)
}
} else {
printHelp(cmd)
}
},
}
cmdSimulationEnable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Enable global simulation (reverse mode)")
return cmdSimulationEnable
}
func NewSimulationDisableCmd() *cobra.Command {
var forceGlobalSimulation bool
var cmdSimulationDisable = &cobra.Command{
Use: "disable [scenario]",
Short: "Disable the simulation mode. Disable only specified scenarios",
Example: `cscli simulation disable`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
for _, scenario := range args {
isExcluded := slices.Contains(csConfig.Cscli.SimulationConfig.Exclusions, scenario)
if !*csConfig.Cscli.SimulationConfig.Simulation && !isExcluded {
log.Warningf("%s isn't in simulation mode", scenario)
continue
}
if !*csConfig.Cscli.SimulationConfig.Simulation && isExcluded {
if err := removeFromExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' disabled", scenario)
continue
}
if isExcluded {
log.Warningf("simulation mode is enabled but is already disable for '%s'", scenario)
continue
}
if err := addToExclusion(scenario); err != nil {
log.Fatal(err)
}
log.Printf("simulation mode for '%s' disabled", scenario)
}
if err := dumpSimulationFile(); err != nil {
log.Fatalf("simulation disable: %s", err)
}
} else if forceGlobalSimulation {
if err := disableGlobalSimulation(); err != nil {
log.Fatalf("unable to disable global simulation mode : %s", err)
}
} else {
printHelp(cmd)
}
},
}
cmdSimulationDisable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Disable global simulation (reverse mode)")
return cmdSimulationDisable
}
func NewSimulationStatusCmd() *cobra.Command {
var cmdSimulationStatus = &cobra.Command{
Use: "status",
Short: "Show simulation mode status",
Example: `cscli simulation status`,
DisableAutoGenTag: true,
Run: func(cmd *cobra.Command, args []string) {
if err := simulationStatus(); err != nil {
log.Fatal(err)
}
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
},
}
return cmdSimulationStatus
}