diff --git a/cmd/crowdsec-cli/capi.go b/cmd/crowdsec-cli/capi.go index e56a8a747..ec11acbbe 100644 --- a/cmd/crowdsec-cli/capi.go +++ b/cmd/crowdsec-cli/capi.go @@ -175,7 +175,7 @@ func (cli *cliCapi) status() error { return err } - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return fmt.Errorf("failed to get scenarios: %w", err) } diff --git a/cmd/crowdsec-cli/console.go b/cmd/crowdsec-cli/console.go index 9e881a43f..4aba689aa 100644 --- a/cmd/crowdsec-cli/console.go +++ b/cmd/crowdsec-cli/console.go @@ -103,7 +103,7 @@ After running this command your will need to validate the enrollment in the weba return err } - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return fmt.Errorf("failed to get installed scenarios: %w", err) } diff --git a/cmd/crowdsec-cli/hub.go b/cmd/crowdsec-cli/hub.go index 600e56889..71347a5a5 100644 --- a/cmd/crowdsec-cli/hub.go +++ b/cmd/crowdsec-cli/hub.go @@ -13,7 +13,7 @@ import ( "github.com/crowdsecurity/crowdsec/pkg/cwhub" ) -type cliHub struct { +type cliHub struct{ cfg configGetter } @@ -137,7 +137,7 @@ func (cli *cliHub) upgrade(force bool) error { } for _, itemType := range cwhub.ItemTypes { - items, err := hub.GetInstalledItems(itemType) + items, err := hub.GetInstalledItemsByType(itemType) if err != nil { return err } diff --git a/cmd/crowdsec-cli/item_suggest.go b/cmd/crowdsec-cli/item_suggest.go index d3beee721..9272abedd 100644 --- a/cmd/crowdsec-cli/item_suggest.go +++ b/cmd/crowdsec-cli/item_suggest.go @@ -61,7 +61,7 @@ func compInstalledItems(itemType string, args []string, toComplete string) ([]st return nil, cobra.ShellCompDirectiveDefault } - items, err := hub.GetInstalledItemNames(itemType) + items, err := hub.GetInstalledNamesByType(itemType) if err != nil { cobra.CompDebugln(fmt.Sprintf("list installed %s err: %s", itemType, err), true) return nil, cobra.ShellCompDirectiveDefault diff --git a/cmd/crowdsec-cli/itemcli.go b/cmd/crowdsec-cli/itemcli.go index c2614068f..cdaf78770 100644 --- a/cmd/crowdsec-cli/itemcli.go +++ b/cmd/crowdsec-cli/itemcli.go @@ -147,9 +147,9 @@ func (cli cliItem) remove(args []string, purge bool, force bool, all bool) error } if all { - getter := hub.GetInstalledItems + getter := hub.GetInstalledItemsByType if purge { - getter = hub.GetAllItems + getter = hub.GetItemsByType } items, err := getter(cli.name) @@ -262,7 +262,7 @@ func (cli cliItem) upgrade(args []string, force bool, all bool) error { } if all { - items, err := hub.GetInstalledItems(cli.name) + items, err := hub.GetInstalledItemsByType(cli.name) if err != nil { return err } diff --git a/cmd/crowdsec-cli/items.go b/cmd/crowdsec-cli/items.go index b8c83809d..4ae643151 100644 --- a/cmd/crowdsec-cli/items.go +++ b/cmd/crowdsec-cli/items.go @@ -17,7 +17,7 @@ import ( // selectItems returns a slice of items of a given type, selected by name and sorted by case-insensitive name func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]*cwhub.Item, error) { - itemNames := hub.GetItemNames(itemType) + itemNames := hub.GetNamesByType(itemType) notExist := []string{} diff --git a/cmd/crowdsec-cli/lapi.go b/cmd/crowdsec-cli/lapi.go index 51f372cc2..99c3ee45a 100644 --- a/cmd/crowdsec-cli/lapi.go +++ b/cmd/crowdsec-cli/lapi.go @@ -56,7 +56,7 @@ func (cli *cliLapi) status() error { return err } - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return fmt.Errorf("failed to get scenarios: %w", err) } diff --git a/cmd/crowdsec-cli/notifications.go b/cmd/crowdsec-cli/notifications.go index f12333a39..0b5ee5378 100644 --- a/cmd/crowdsec-cli/notifications.go +++ b/cmd/crowdsec-cli/notifications.go @@ -4,6 +4,7 @@ import ( "context" "encoding/csv" "encoding/json" + "errors" "fmt" "io/fs" "net/url" @@ -88,7 +89,7 @@ func (cli *cliNotifications) getPluginConfigs() (map[string]csplugin.PluginConfi return fmt.Errorf("error while traversing directory %s: %w", path, err) } - name := filepath.Join(cfg.ConfigPaths.NotificationDir, info.Name()) //Avoid calling info.Name() twice + name := filepath.Join(cfg.ConfigPaths.NotificationDir, info.Name()) // Avoid calling info.Name() twice if (strings.HasSuffix(name, "yaml") || strings.HasSuffix(name, "yml")) && !(info.IsDir()) { ts, err := csplugin.ParsePluginConfigFile(name) if err != nil { @@ -266,7 +267,7 @@ func (cli *cliNotifications) NewTestCmd() *cobra.Command { if !ok { return fmt.Errorf("plugin name: '%s' does not exist", args[0]) } - //Create a single profile with plugin name as notification name + // Create a single profile with plugin name as notification name return pluginBroker.Init(cfg.PluginConfig, []*csconfig.ProfileCfg{ { Notifications: []string{ @@ -320,8 +321,8 @@ func (cli *cliNotifications) NewTestCmd() *cobra.Command { Alert: alert, } - //time.Sleep(2 * time.Second) // There's no mechanism to ensure notification has been sent - pluginTomb.Kill(fmt.Errorf("terminating")) + // time.Sleep(2 * time.Second) // There's no mechanism to ensure notification has been sent + pluginTomb.Kill(errors.New("terminating")) pluginTomb.Wait() return nil @@ -416,8 +417,8 @@ cscli notifications reinject -a '{"remediation": true,"scenario":"not break } } - //time.Sleep(2 * time.Second) // There's no mechanism to ensure notification has been sent - pluginTomb.Kill(fmt.Errorf("terminating")) + // time.Sleep(2 * time.Second) // There's no mechanism to ensure notification has been sent + pluginTomb.Kill(errors.New("terminating")) pluginTomb.Wait() return nil diff --git a/cmd/crowdsec-cli/papi.go b/cmd/crowdsec-cli/papi.go index e18af94d4..5808fcce5 100644 --- a/cmd/crowdsec-cli/papi.go +++ b/cmd/crowdsec-cli/papi.go @@ -64,25 +64,22 @@ func (cli *cliPapi) NewStatusCmd() *cobra.Command { cfg := cli.cfg() dbClient, err = database.NewClient(cfg.DbConfig) if err != nil { - return fmt.Errorf("unable to initialize database client: %s", err) + return fmt.Errorf("unable to initialize database client: %w", err) } apic, err := apiserver.NewAPIC(cfg.API.Server.OnlineClient, dbClient, cfg.API.Server.ConsoleConfig, cfg.API.Server.CapiWhitelists) - if err != nil { - return fmt.Errorf("unable to initialize API client: %s", err) + return fmt.Errorf("unable to initialize API client: %w", err) } papi, err := apiserver.NewPAPI(apic, dbClient, cfg.API.Server.ConsoleConfig, log.GetLevel()) - if err != nil { - return fmt.Errorf("unable to initialize PAPI client: %s", err) + return fmt.Errorf("unable to initialize PAPI client: %w", err) } perms, err := papi.GetPermissions() - if err != nil { - return fmt.Errorf("unable to get PAPI permissions: %s", err) + return fmt.Errorf("unable to get PAPI permissions: %w", err) } var lastTimestampStr *string lastTimestampStr, err = dbClient.GetConfigItem(apiserver.PapiPullKey) @@ -118,27 +115,26 @@ func (cli *cliPapi) NewSyncCmd() *cobra.Command { dbClient, err = database.NewClient(cfg.DbConfig) if err != nil { - return fmt.Errorf("unable to initialize database client: %s", err) + return fmt.Errorf("unable to initialize database client: %w", err) } apic, err := apiserver.NewAPIC(cfg.API.Server.OnlineClient, dbClient, cfg.API.Server.ConsoleConfig, cfg.API.Server.CapiWhitelists) if err != nil { - return fmt.Errorf("unable to initialize API client: %s", err) + return fmt.Errorf("unable to initialize API client: %w", err) } t.Go(apic.Push) papi, err := apiserver.NewPAPI(apic, dbClient, cfg.API.Server.ConsoleConfig, log.GetLevel()) if err != nil { - return fmt.Errorf("unable to initialize PAPI client: %s", err) + return fmt.Errorf("unable to initialize PAPI client: %w", err) } t.Go(papi.SyncDecisions) err = papi.PullOnce(time.Time{}, true) - if err != nil { - return fmt.Errorf("unable to sync decisions: %s", err) + return fmt.Errorf("unable to sync decisions: %w", err) } log.Infof("Sending acknowledgements to CAPI") diff --git a/cmd/crowdsec-cli/require/require.go b/cmd/crowdsec-cli/require/require.go index 0f5ce182d..708b2d1c7 100644 --- a/cmd/crowdsec-cli/require/require.go +++ b/cmd/crowdsec-cli/require/require.go @@ -1,6 +1,7 @@ package require import ( + "errors" "fmt" "io" @@ -16,7 +17,7 @@ func LAPI(c *csconfig.Config) error { } if c.DisableAPI { - return fmt.Errorf("local API is disabled -- this command must be run on the local API machine") + return errors.New("local API is disabled -- this command must be run on the local API machine") } return nil @@ -32,7 +33,7 @@ func CAPI(c *csconfig.Config) error { func PAPI(c *csconfig.Config) error { if c.API.Server.OnlineClient.Credentials.PapiURL == "" { - return fmt.Errorf("no PAPI URL in configuration") + return errors.New("no PAPI URL in configuration") } return nil @@ -40,7 +41,7 @@ func PAPI(c *csconfig.Config) error { func CAPIRegistered(c *csconfig.Config) error { if c.API.Server.OnlineClient.Credentials == nil { - return fmt.Errorf("the Central API (CAPI) must be configured with 'cscli capi register'") + return errors.New("the Central API (CAPI) must be configured with 'cscli capi register'") } return nil @@ -56,7 +57,7 @@ func DB(c *csconfig.Config) error { func Notifications(c *csconfig.Config) error { if c.ConfigPaths.NotificationDir == "" { - return fmt.Errorf("config_paths.notification_dir is not set in crowdsec config") + return errors.New("config_paths.notification_dir is not set in crowdsec config") } return nil @@ -82,7 +83,7 @@ func Hub(c *csconfig.Config, remote *cwhub.RemoteHubCfg, logger *logrus.Logger) local := c.Hub if local == nil { - return nil, fmt.Errorf("you must configure cli before interacting with hub") + return nil, errors.New("you must configure cli before interacting with hub") } if logger == nil { diff --git a/cmd/crowdsec-cli/setup.go b/cmd/crowdsec-cli/setup.go index 48dcee089..ba3670848 100644 --- a/cmd/crowdsec-cli/setup.go +++ b/cmd/crowdsec-cli/setup.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "errors" "fmt" "os" "os/exec" @@ -118,9 +119,11 @@ func runSetupDetect(cmd *cobra.Command, args []string) error { switch detectConfigFile { case "-": log.Tracef("Reading detection rules from stdin") + detectReader = os.Stdin default: log.Tracef("Reading detection rules: %s", detectConfigFile) + detectReader, err = os.Open(detectConfigFile) if err != nil { return err @@ -171,6 +174,7 @@ func runSetupDetect(cmd *cobra.Command, args []string) error { _, err := exec.LookPath("systemctl") if err != nil { log.Debug("systemctl not available: snubbing systemd") + snubSystemd = true } } @@ -182,6 +186,7 @@ func runSetupDetect(cmd *cobra.Command, args []string) error { if forcedOSFamily == "" && forcedOSID != "" { log.Debug("force-os-id is set: force-os-family defaults to 'linux'") + forcedOSFamily = "linux" } @@ -219,6 +224,7 @@ func runSetupDetect(cmd *cobra.Command, args []string) error { if err != nil { return err } + fmt.Println(setup) return nil @@ -318,6 +324,7 @@ func runSetupInstallHub(cmd *cobra.Command, args []string) error { func runSetupValidate(cmd *cobra.Command, args []string) error { fromFile := args[0] + input, err := os.ReadFile(fromFile) if err != nil { return fmt.Errorf("while reading stdin: %w", err) @@ -325,7 +332,7 @@ func runSetupValidate(cmd *cobra.Command, args []string) error { if err = setup.Validate(input); err != nil { fmt.Printf("%v\n", err) - return fmt.Errorf("invalid setup file") + return errors.New("invalid setup file") } return nil diff --git a/cmd/crowdsec-cli/simulation.go b/cmd/crowdsec-cli/simulation.go index 6ccac7617..f3c1a6273 100644 --- a/cmd/crowdsec-cli/simulation.go +++ b/cmd/crowdsec-cli/simulation.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "os" "slices" @@ -36,7 +37,7 @@ cscli simulation disable crowdsecurity/ssh-bf`, return err } if cli.cfg().Cscli.SimulationConfig == nil { - return fmt.Errorf("no simulation configured") + return errors.New("no simulation configured") } return nil @@ -99,11 +100,11 @@ func (cli *cliSimulation) NewEnableCmd() *cobra.Command { log.Printf("simulation mode for '%s' enabled", scenario) } if err := cli.dumpSimulationFile(); err != nil { - return fmt.Errorf("simulation enable: %s", err) + return fmt.Errorf("simulation enable: %w", err) } } else if forceGlobalSimulation { if err := cli.enableGlobalSimulation(); err != nil { - return fmt.Errorf("unable to enable global simulation mode: %s", err) + return fmt.Errorf("unable to enable global simulation mode: %w", err) } } else { printHelp(cmd) @@ -146,11 +147,11 @@ func (cli *cliSimulation) NewDisableCmd() *cobra.Command { log.Printf("simulation mode for '%s' disabled", scenario) } if err := cli.dumpSimulationFile(); err != nil { - return fmt.Errorf("simulation disable: %s", err) + return fmt.Errorf("simulation disable: %w", err) } } else if forceGlobalSimulation { if err := cli.disableGlobalSimulation(); err != nil { - return fmt.Errorf("unable to disable global simulation mode: %s", err) + return fmt.Errorf("unable to disable global simulation mode: %w", err) } } else { printHelp(cmd) @@ -202,7 +203,7 @@ func (cli *cliSimulation) enableGlobalSimulation() error { cfg.Cscli.SimulationConfig.Exclusions = []string{} if err := cli.dumpSimulationFile(); err != nil { - return fmt.Errorf("unable to dump simulation file: %s", err) + return fmt.Errorf("unable to dump simulation file: %w", err) } log.Printf("global simulation: enabled") @@ -215,12 +216,12 @@ func (cli *cliSimulation) dumpSimulationFile() error { newConfigSim, err := yaml.Marshal(cfg.Cscli.SimulationConfig) if err != nil { - return fmt.Errorf("unable to marshal simulation configuration: %s", err) + return fmt.Errorf("unable to marshal simulation configuration: %w", err) } err = os.WriteFile(cfg.ConfigPaths.SimulationFilePath, newConfigSim, 0o644) if err != nil { - return fmt.Errorf("write simulation config in '%s' failed: %s", cfg.ConfigPaths.SimulationFilePath, err) + return fmt.Errorf("write simulation config in '%s' failed: %w", cfg.ConfigPaths.SimulationFilePath, err) } log.Debugf("updated simulation file %s", cfg.ConfigPaths.SimulationFilePath) @@ -237,12 +238,12 @@ func (cli *cliSimulation) disableGlobalSimulation() error { newConfigSim, err := yaml.Marshal(cfg.Cscli.SimulationConfig) if err != nil { - return fmt.Errorf("unable to marshal new simulation configuration: %s", err) + return fmt.Errorf("unable to marshal new simulation configuration: %w", err) } err = os.WriteFile(cfg.ConfigPaths.SimulationFilePath, newConfigSim, 0o644) if err != nil { - return fmt.Errorf("unable to write new simulation config in '%s': %s", cfg.ConfigPaths.SimulationFilePath, err) + return fmt.Errorf("unable to write new simulation config in '%s': %w", cfg.ConfigPaths.SimulationFilePath, err) } log.Printf("global simulation: disabled") @@ -269,8 +270,10 @@ func (cli *cliSimulation) status() { } } else { log.Println("global simulation: disabled") + if len(cfg.Cscli.SimulationConfig.Exclusions) > 0 { log.Println("Scenarios in simulation mode :") + for _, scenario := range cfg.Cscli.SimulationConfig.Exclusions { log.Printf(" - %s", scenario) } diff --git a/cmd/crowdsec-cli/support.go b/cmd/crowdsec-cli/support.go index 8b2481b4c..a48edeeeb 100644 --- a/cmd/crowdsec-cli/support.go +++ b/cmd/crowdsec-cli/support.go @@ -199,7 +199,7 @@ func collectAPIStatus(login string, password string, endpoint string, prefix str return []byte(fmt.Sprintf("cannot parse API URL: %s", err)) } - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return []byte(fmt.Sprintf("could not collect scenarios: %s", err)) } diff --git a/cmd/crowdsec/lapiclient.go b/cmd/crowdsec/lapiclient.go index fd29aa9d9..f12aea5ac 100644 --- a/cmd/crowdsec/lapiclient.go +++ b/cmd/crowdsec/lapiclient.go @@ -17,12 +17,12 @@ import ( ) func AuthenticatedLAPIClient(credentials csconfig.ApiCredentialsCfg, hub *cwhub.Hub) (*apiclient.ApiClient, error) { - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return nil, fmt.Errorf("loading list of installed hub scenarios: %w", err) } - appsecRules, err := hub.GetInstalledItemNames(cwhub.APPSEC_RULES) + appsecRules, err := hub.GetInstalledNamesByType(cwhub.APPSEC_RULES) if err != nil { return nil, fmt.Errorf("loading list of installed hub appsec rules: %w", err) } @@ -52,11 +52,11 @@ func AuthenticatedLAPIClient(credentials csconfig.ApiCredentialsCfg, hub *cwhub. PapiURL: papiURL, VersionPrefix: "v1", UpdateScenario: func() ([]string, error) { - scenarios, err := hub.GetInstalledItemNames(cwhub.SCENARIOS) + scenarios, err := hub.GetInstalledNamesByType(cwhub.SCENARIOS) if err != nil { return nil, err } - appsecRules, err := hub.GetInstalledItemNames(cwhub.APPSEC_RULES) + appsecRules, err := hub.GetInstalledNamesByType(cwhub.APPSEC_RULES) if err != nil { return nil, err } diff --git a/pkg/alertcontext/config.go b/pkg/alertcontext/config.go index 74ca1523a..21d16db39 100644 --- a/pkg/alertcontext/config.go +++ b/pkg/alertcontext/config.go @@ -104,7 +104,7 @@ func LoadConsoleContext(c *csconfig.Config, hub *cwhub.Hub) error { c.Crowdsec.ContextToSend = make(map[string][]string, 0) if hub != nil { - items, err := hub.GetInstalledItems(cwhub.CONTEXTS) + items, err := hub.GetInstalledItemsByType(cwhub.CONTEXTS) if err != nil { return err } diff --git a/pkg/cwhub/hub.go b/pkg/cwhub/hub.go index 44e24020d..6b9f56b2e 100644 --- a/pkg/cwhub/hub.go +++ b/pkg/cwhub/hub.go @@ -214,9 +214,9 @@ func (h *Hub) GetItemFQ(itemFQName string) (*Item, error) { return i, nil } -// GetItemNames returns a slice of (full) item names for a given type +// GetNamesByType returns a slice of (full) item names for a given type // (eg. for collections: crowdsecurity/apache2 crowdsecurity/nginx). -func (h *Hub) GetItemNames(itemType string) []string { +func (h *Hub) GetNamesByType(itemType string) []string { m := h.GetItemMap(itemType) if m == nil { return nil @@ -230,8 +230,8 @@ func (h *Hub) GetItemNames(itemType string) []string { return names } -// GetAllItems returns a slice of all the items of a given type, installed or not. -func (h *Hub) GetAllItems(itemType string) ([]*Item, error) { +// GetItemsByType returns a slice of all the items of a given type, installed or not. +func (h *Hub) GetItemsByType(itemType string) ([]*Item, error) { if !slices.Contains(ItemTypes, itemType) { return nil, fmt.Errorf("invalid item type %s", itemType) } @@ -250,8 +250,8 @@ func (h *Hub) GetAllItems(itemType string) ([]*Item, error) { return ret, nil } -// GetInstalledItems returns a slice of the installed items of a given type. -func (h *Hub) GetInstalledItems(itemType string) ([]*Item, error) { +// GetInstalledItemsByType returns a slice of the installed items of a given type. +func (h *Hub) GetInstalledItemsByType(itemType string) ([]*Item, error) { if !slices.Contains(ItemTypes, itemType) { return nil, fmt.Errorf("invalid item type %s", itemType) } @@ -269,9 +269,9 @@ func (h *Hub) GetInstalledItems(itemType string) ([]*Item, error) { return retItems, nil } -// GetInstalledItemNames returns the names of the installed items of a given type. -func (h *Hub) GetInstalledItemNames(itemType string) ([]string, error) { - items, err := h.GetInstalledItems(itemType) +// GetInstalledNamesByType returns the names of the installed items of a given type. +func (h *Hub) GetInstalledNamesByType(itemType string) ([]string, error) { + items, err := h.GetInstalledItemsByType(itemType) if err != nil { return nil, err }