break in smaller functions cscli hub, hubtest, notifications, parsers, scenarios, simulation (#2004)

This commit is contained in:
mmetc 2023-01-19 13:29:36 +01:00 committed by GitHub
parent 1e4441b6ae
commit 4bffc0df21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 243 additions and 100 deletions

View file

@ -11,7 +11,6 @@ import (
)
func NewHubCmd() *cobra.Command {
/* ---- HUB COMMAND */
var cmdHub = &cobra.Command{
Use: "hub [action]",
Short: "Manage Hub",
@ -37,6 +36,14 @@ cscli hub update # Download list of available configurations from the hub
}
cmdHub.PersistentFlags().StringVarP(&cwhub.HubBranch, "branch", "b", "", "Use given branch from hub")
cmdHub.AddCommand(NewHubListCmd())
cmdHub.AddCommand(NewHubUpdateCmd())
cmdHub.AddCommand(NewHubUpgradeCmd())
return cmdHub
}
func NewHubListCmd() *cobra.Command {
var cmdHubList = &cobra.Command{
Use: "list [-a]",
Short: "List installed configs",
@ -63,8 +70,11 @@ cscli hub update # Download list of available configurations from the hub
},
}
cmdHubList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
cmdHub.AddCommand(cmdHubList)
return cmdHubList
}
func NewHubUpdateCmd() *cobra.Command {
var cmdHubUpdate = &cobra.Command{
Use: "update",
Short: "Fetch available configs from hub",
@ -97,8 +107,11 @@ Fetches the [.index.json](https://github.com/crowdsecurity/hub/blob/master/.inde
}
},
}
cmdHub.AddCommand(cmdHubUpdate)
return cmdHubUpdate
}
func NewHubUpgradeCmd() *cobra.Command {
var cmdHubUpgrade = &cobra.Command{
Use: "upgrade",
Short: "Upgrade all configs installed from hub",
@ -137,6 +150,6 @@ Upgrade all configs installed from Crowdsec Hub. Run 'sudo cscli hub update' if
},
}
cmdHubUpgrade.PersistentFlags().BoolVar(&forceAction, "force", false, "Force upgrade : Overwrite tainted and outdated files")
cmdHub.AddCommand(cmdHubUpgrade)
return cmdHub
return cmdHubUpgrade
}

View file

@ -23,9 +23,7 @@ var (
)
func NewHubTestCmd() *cobra.Command {
/* ---- HUB COMMAND */
var hubPath string
var logType string
var crowdsecPath string
var cscliPath string
@ -47,11 +45,26 @@ func NewHubTestCmd() *cobra.Command {
cmdHubTest.PersistentFlags().StringVar(&crowdsecPath, "crowdsec", "crowdsec", "Path to crowdsec")
cmdHubTest.PersistentFlags().StringVar(&cscliPath, "cscli", "cscli", "Path to cscli")
cmdHubTest.AddCommand(NewHubTestCreateCmd())
cmdHubTest.AddCommand(NewHubTestRunCmd())
cmdHubTest.AddCommand(NewHubTestCleanCmd())
cmdHubTest.AddCommand(NewHubTestInfoCmd())
cmdHubTest.AddCommand(NewHubTestListCmd())
cmdHubTest.AddCommand(NewHubTestCoverageCmd())
cmdHubTest.AddCommand(NewHubTestEvalCmd())
cmdHubTest.AddCommand(NewHubTestExplainCmd())
return cmdHubTest
}
func NewHubTestCreateCmd() *cobra.Command {
parsers := []string{}
postoverflows := []string{}
scenarios := []string{}
var ignoreParsers bool
var labels map[string]string
var logType string
var cmdHubTestCreate = &cobra.Command{
Use: "create",
@ -153,11 +166,16 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
cmdHubTestCreate.Flags().StringSliceVar(&postoverflows, "postoverflows", postoverflows, "Postoverflows to add to test")
cmdHubTestCreate.Flags().StringSliceVarP(&scenarios, "scenarios", "s", scenarios, "Scenarios to add to test")
cmdHubTestCreate.PersistentFlags().BoolVar(&ignoreParsers, "ignore-parsers", false, "Don't run test on parsers")
cmdHubTest.AddCommand(cmdHubTestCreate)
return cmdHubTestCreate
}
func NewHubTestRunCmd() *cobra.Command {
var noClean bool
var runAll bool
var forceClean bool
var cmdHubTestRun = &cobra.Command{
Use: "run",
Short: "run [test_name]",
@ -300,8 +318,12 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
cmdHubTestRun.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")
cmdHubTestRun.Flags().BoolVar(&runAll, "all", false, "Run all tests")
cmdHubTest.AddCommand(cmdHubTestRun)
return cmdHubTestRun
}
func NewHubTestCleanCmd() *cobra.Command {
var cmdHubTestClean = &cobra.Command{
Use: "clean",
Short: "clean [test_name]",
@ -319,8 +341,12 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
}
},
}
cmdHubTest.AddCommand(cmdHubTestClean)
return cmdHubTestClean
}
func NewHubTestInfoCmd() *cobra.Command {
var cmdHubTestInfo = &cobra.Command{
Use: "info",
Short: "info [test_name]",
@ -342,8 +368,12 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
}
},
}
cmdHubTest.AddCommand(cmdHubTestInfo)
return cmdHubTestInfo
}
func NewHubTestListCmd() *cobra.Command {
var cmdHubTestList = &cobra.Command{
Use: "list",
Short: "list",
@ -367,11 +397,16 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
}
},
}
cmdHubTest.AddCommand(cmdHubTestList)
return cmdHubTestList
}
func NewHubTestCoverageCmd() *cobra.Command {
var showParserCov bool
var showScenarioCov bool
var showOnlyPercent bool
var cmdHubTestCoverage = &cobra.Command{
Use: "coverage",
Short: "coverage",
@ -463,8 +498,12 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
cmdHubTestCoverage.PersistentFlags().BoolVar(&showOnlyPercent, "percent", false, "Show only percentages of coverage")
cmdHubTestCoverage.PersistentFlags().BoolVar(&showParserCov, "parsers", false, "Show only parsers coverage")
cmdHubTestCoverage.PersistentFlags().BoolVar(&showScenarioCov, "scenarios", false, "Show only scenarios coverage")
cmdHubTest.AddCommand(cmdHubTestCoverage)
return cmdHubTestCoverage
}
func NewHubTestEvalCmd() *cobra.Command {
var evalExpression string
var cmdHubTestEval = &cobra.Command{
Use: "eval",
@ -490,8 +529,12 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
},
}
cmdHubTestEval.PersistentFlags().StringVarP(&evalExpression, "expr", "e", "", "Expression to eval")
cmdHubTest.AddCommand(cmdHubTestEval)
return cmdHubTestEval
}
func NewHubTestExplainCmd() *cobra.Command {
var cmdHubTestExplain = &cobra.Command{
Use: "explain",
Short: "explain [test_name]",
@ -531,7 +574,6 @@ cscli hubtest create my-scenario-test --parsers crowdsecurity/nginx --scenarios
}
},
}
cmdHubTest.AddCommand(cmdHubTestExplain)
return cmdHubTest
return cmdHubTestExplain
}

View file

@ -27,12 +27,14 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
)
type NotificationsCfg struct {
Config csplugin.PluginConfig `json:"plugin_config"`
Profiles []*csconfig.ProfileCfg `json:"associated_profiles"`
ids []uint
}
func NewNotificationsCmd() *cobra.Command {
var cmdNotifications = &cobra.Command{
Use: "notifications [action]",
@ -54,6 +56,80 @@ func NewNotificationsCmd() *cobra.Command {
},
}
cmdNotifications.AddCommand(NewNotificationsListCmd())
cmdNotifications.AddCommand(NewNotificationsInspectCmd())
cmdNotifications.AddCommand(NewNotificationsReinjectCmd())
return cmdNotifications
}
func getNotificationsConfiguration() (map[string]NotificationsCfg, error) {
pcfgs := map[string]csplugin.PluginConfig{}
wf := func(path string, info fs.FileInfo, err error) error {
if info == nil {
return errors.Wrapf(err, "error while traversing directory %s", path)
}
name := filepath.Join(csConfig.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 {
return errors.Wrapf(err, "Loading notifification plugin configuration with %s", name)
}
for _, t := range ts {
pcfgs[t.Name] = t
}
}
return nil
}
if err := filepath.Walk(csConfig.ConfigPaths.NotificationDir, wf); err != nil {
return nil, errors.Wrap(err, "Loading notifification plugin configuration")
}
// A bit of a tricky stuf now: reconcile profiles and notification plugins
ncfgs := map[string]NotificationsCfg{}
profiles, err := csprofiles.NewProfile(csConfig.API.Server.Profiles)
if err != nil {
return nil, errors.Wrap(err, "Cannot extract profiles from configuration")
}
for profileID, profile := range profiles {
loop:
for _, notif := range profile.Cfg.Notifications {
for name, pc := range pcfgs {
if notif == name {
if _, ok := ncfgs[pc.Name]; !ok {
ncfgs[pc.Name] = NotificationsCfg{
Config: pc,
Profiles: []*csconfig.ProfileCfg{profile.Cfg},
ids: []uint{uint(profileID)},
}
continue loop
}
tmp := ncfgs[pc.Name]
for _, pr := range tmp.Profiles {
var profiles []*csconfig.ProfileCfg
if pr.Name == profile.Cfg.Name {
continue
}
profiles = append(tmp.Profiles, profile.Cfg)
ids := append(tmp.ids, uint(profileID))
ncfgs[pc.Name] = NotificationsCfg{
Config: tmp.Config,
Profiles: profiles,
ids: ids,
}
}
}
}
}
}
return ncfgs, nil
}
func NewNotificationsListCmd() *cobra.Command {
var cmdNotificationsList = &cobra.Command{
Use: "list",
Short: "List active notifications plugins",
@ -96,8 +172,12 @@ func NewNotificationsCmd() *cobra.Command {
return nil
},
}
cmdNotifications.AddCommand(cmdNotificationsList)
return cmdNotificationsList
}
func NewNotificationsInspectCmd() *cobra.Command {
var cmdNotificationsInspect = &cobra.Command{
Use: "inspect",
Short: "Inspect active notifications plugin configuration",
@ -142,9 +222,15 @@ func NewNotificationsCmd() *cobra.Command {
return nil
},
}
cmdNotifications.AddCommand(cmdNotificationsInspect)
return cmdNotificationsInspect
}
func NewNotificationsReinjectCmd() *cobra.Command {
var remediation bool
var alertOverride string
var cmdNotificationsReinject = &cobra.Command{
Use: "reinject",
Short: "reinject alert into notifications system",
@ -264,69 +350,6 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
}
cmdNotificationsReinject.Flags().BoolVarP(&remediation, "remediation", "r", false, "Set Alert.Remediation to false in the reinjected alert (see your profile filter configuration)")
cmdNotificationsReinject.Flags().StringVarP(&alertOverride, "alert", "a", "", "JSON string used to override alert fields in the reinjected alert (see crowdsec/pkg/models/alert.go in the source tree for the full definition of the object)")
cmdNotifications.AddCommand(cmdNotificationsReinject)
return cmdNotifications
}
func getNotificationsConfiguration() (map[string]NotificationsCfg, error) {
pcfgs := map[string]csplugin.PluginConfig{}
wf := func(path string, info fs.FileInfo, err error) error {
if info == nil {
return errors.Wrapf(err, "error while traversing directory %s", path)
}
name := filepath.Join(csConfig.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 {
return errors.Wrapf(err, "Loading notifification plugin configuration with %s", name)
}
for _, t := range ts {
pcfgs[t.Name] = t
}
}
return nil
}
if err := filepath.Walk(csConfig.ConfigPaths.NotificationDir, wf); err != nil {
return nil, errors.Wrap(err, "Loading notifification plugin configuration")
}
// A bit of a tricky stuf now: reconcile profiles and notification plugins
ncfgs := map[string]NotificationsCfg{}
profiles, err := csprofiles.NewProfile(csConfig.API.Server.Profiles)
if err != nil {
return nil, errors.Wrap(err, "Cannot extract profiles from configuration")
}
for profileID, profile := range profiles {
loop:
for _, notif := range profile.Cfg.Notifications {
for name, pc := range pcfgs {
if notif == name {
if _, ok := ncfgs[pc.Name]; !ok {
ncfgs[pc.Name] = NotificationsCfg{
Config: pc,
Profiles: []*csconfig.ProfileCfg{profile.Cfg},
ids: []uint{uint(profileID)},
}
continue loop
}
tmp := ncfgs[pc.Name]
for _, pr := range tmp.Profiles {
var profiles []*csconfig.ProfileCfg
if pr.Name == profile.Cfg.Name {
continue
}
profiles = append(tmp.Profiles, profile.Cfg)
ids := append(tmp.ids, uint(profileID))
ncfgs[pc.Name] = NotificationsCfg{
Config: tmp.Config,
Profiles: profiles,
ids: ids,
}
}
}
}
}
}
return ncfgs, nil
return cmdNotificationsReinject
}

View file

@ -10,6 +10,7 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
)
func NewParsersCmd() *cobra.Command {
var cmdParsers = &cobra.Command{
Use: "parsers [action] [config]",
@ -49,7 +50,19 @@ cscli parsers remove crowdsecurity/sshd-logs
},
}
cmdParsers.AddCommand(NewParsersInstallCmd())
cmdParsers.AddCommand(NewParsersRemoveCmd())
cmdParsers.AddCommand(NewParsersUpgradeCmd())
cmdParsers.AddCommand(NewParsersInspectCmd())
cmdParsers.AddCommand(NewParsersListCmd())
return cmdParsers
}
func NewParsersInstallCmd() *cobra.Command {
var ignoreError bool
var cmdParsersInstall = &cobra.Command{
Use: "install [config]",
Short: "Install given parser(s)",
@ -81,8 +94,12 @@ cscli parsers remove crowdsecurity/sshd-logs
cmdParsersInstall.PersistentFlags().BoolVarP(&downloadOnly, "download-only", "d", false, "Only download packages, don't enable")
cmdParsersInstall.PersistentFlags().BoolVar(&forceAction, "force", false, "Force install : Overwrite tainted and outdated files")
cmdParsersInstall.PersistentFlags().BoolVar(&ignoreError, "ignore", false, "Ignore errors when installing multiple parsers")
cmdParsers.AddCommand(cmdParsersInstall)
return cmdParsersInstall
}
func NewParsersRemoveCmd() *cobra.Command {
var cmdParsersRemove = &cobra.Command{
Use: "remove [config]",
Short: "Remove given parser(s)",
@ -111,8 +128,12 @@ cscli parsers remove crowdsecurity/sshd-logs
cmdParsersRemove.PersistentFlags().BoolVar(&purge, "purge", false, "Delete source file too")
cmdParsersRemove.PersistentFlags().BoolVar(&forceAction, "force", false, "Force remove : Remove tainted and outdated files")
cmdParsersRemove.PersistentFlags().BoolVar(&all, "all", false, "Delete all the parsers")
cmdParsers.AddCommand(cmdParsersRemove)
return cmdParsersRemove
}
func NewParsersUpgradeCmd() *cobra.Command {
var cmdParsersUpgrade = &cobra.Command{
Use: "upgrade [config]",
Short: "Upgrade given parser(s)",
@ -137,8 +158,12 @@ cscli parsers remove crowdsecurity/sshd-logs
}
cmdParsersUpgrade.PersistentFlags().BoolVar(&all, "all", false, "Upgrade all the parsers")
cmdParsersUpgrade.PersistentFlags().BoolVar(&forceAction, "force", false, "Force upgrade : Overwrite tainted and outdated files")
cmdParsers.AddCommand(cmdParsersUpgrade)
return cmdParsersUpgrade
}
func NewParsersInspectCmd() *cobra.Command {
var cmdParsersInspect = &cobra.Command{
Use: "inspect [name]",
Short: "Inspect given parser",
@ -154,8 +179,12 @@ cscli parsers remove crowdsecurity/sshd-logs
},
}
cmdParsersInspect.PersistentFlags().StringVarP(&prometheusURL, "url", "u", "", "Prometheus url")
cmdParsers.AddCommand(cmdParsersInspect)
return cmdParsersInspect
}
func NewParsersListCmd() *cobra.Command {
var cmdParsersList = &cobra.Command{
Use: "list [name]",
Short: "List all parsers or given one",
@ -168,7 +197,6 @@ cscli parser list crowdsecurity/xxx`,
},
}
cmdParsersList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
cmdParsers.AddCommand(cmdParsersList)
return cmdParsers
return cmdParsersList
}

View file

@ -12,7 +12,6 @@ import (
)
func NewScenariosCmd() *cobra.Command {
var cmdScenarios = &cobra.Command{
Use: "scenarios [action] [config]",
Short: "Install/Remove/Upgrade/Inspect scenario(s) from hub",
@ -52,7 +51,18 @@ cscli scenarios remove crowdsecurity/ssh-bf
},
}
cmdScenarios.AddCommand(NewCmdScenariosInstall())
cmdScenarios.AddCommand(NewCmdScenariosRemove())
cmdScenarios.AddCommand(NewCmdScenariosUpgrade())
cmdScenarios.AddCommand(NewCmdScenariosInspect())
cmdScenarios.AddCommand(NewCmdScenariosList())
return cmdScenarios
}
func NewCmdScenariosInstall() *cobra.Command {
var ignoreError bool
var cmdScenariosInstall = &cobra.Command{
Use: "install [config]",
Short: "Install given scenario(s)",
@ -84,8 +94,11 @@ cscli scenarios remove crowdsecurity/ssh-bf
cmdScenariosInstall.PersistentFlags().BoolVarP(&downloadOnly, "download-only", "d", false, "Only download packages, don't enable")
cmdScenariosInstall.PersistentFlags().BoolVar(&forceAction, "force", false, "Force install : Overwrite tainted and outdated files")
cmdScenariosInstall.PersistentFlags().BoolVar(&ignoreError, "ignore", false, "Ignore errors when installing multiple scenarios")
cmdScenarios.AddCommand(cmdScenariosInstall)
return cmdScenariosInstall
}
func NewCmdScenariosRemove() *cobra.Command {
var cmdScenariosRemove = &cobra.Command{
Use: "remove [config]",
Short: "Remove given scenario(s)",
@ -114,8 +127,11 @@ cscli scenarios remove crowdsecurity/ssh-bf
cmdScenariosRemove.PersistentFlags().BoolVar(&purge, "purge", false, "Delete source file too")
cmdScenariosRemove.PersistentFlags().BoolVar(&forceAction, "force", false, "Force remove : Remove tainted and outdated files")
cmdScenariosRemove.PersistentFlags().BoolVar(&all, "all", false, "Delete all the scenarios")
cmdScenarios.AddCommand(cmdScenariosRemove)
return cmdScenariosRemove
}
func NewCmdScenariosUpgrade() *cobra.Command {
var cmdScenariosUpgrade = &cobra.Command{
Use: "upgrade [config]",
Short: "Upgrade given scenario(s)",
@ -140,8 +156,11 @@ cscli scenarios remove crowdsecurity/ssh-bf
}
cmdScenariosUpgrade.PersistentFlags().BoolVarP(&all, "all", "a", false, "Upgrade all the scenarios")
cmdScenariosUpgrade.PersistentFlags().BoolVar(&forceAction, "force", false, "Force upgrade : Overwrite tainted and outdated files")
cmdScenarios.AddCommand(cmdScenariosUpgrade)
return cmdScenariosUpgrade
}
func NewCmdScenariosInspect() *cobra.Command {
var cmdScenariosInspect = &cobra.Command{
Use: "inspect [config]",
Short: "Inspect given scenario",
@ -157,8 +176,11 @@ cscli scenarios remove crowdsecurity/ssh-bf
},
}
cmdScenariosInspect.PersistentFlags().StringVarP(&prometheusURL, "url", "u", "", "Prometheus url")
cmdScenarios.AddCommand(cmdScenariosInspect)
return cmdScenariosInspect
}
func NewCmdScenariosList() *cobra.Command {
var cmdScenariosList = &cobra.Command{
Use: "list [config]",
Short: "List all scenario(s) or given one",
@ -171,7 +193,6 @@ cscli scenarios list crowdsecurity/xxx`,
},
}
cmdScenariosList.PersistentFlags().BoolVarP(&all, "all", "a", false, "List disabled items as well")
cmdScenarios.AddCommand(cmdScenariosList)
return cmdScenarios
return cmdScenariosList
}

View file

@ -127,7 +127,16 @@ cscli simulation disable crowdsecurity/ssh-bf`,
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",
@ -186,7 +195,12 @@ cscli simulation disable crowdsecurity/ssh-bf`,
},
}
cmdSimulationEnable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Enable global simulation (reverse mode)")
cmdSimulation.AddCommand(cmdSimulationEnable)
return cmdSimulationEnable
}
func NewSimulationDisableCmd() *cobra.Command {
var forceGlobalSimulation bool
var cmdSimulationDisable = &cobra.Command{
Use: "disable [scenario]",
@ -230,8 +244,11 @@ cscli simulation disable crowdsecurity/ssh-bf`,
},
}
cmdSimulationDisable.Flags().BoolVarP(&forceGlobalSimulation, "global", "g", false, "Disable global simulation (reverse mode)")
cmdSimulation.AddCommand(cmdSimulationDisable)
return cmdSimulationDisable
}
func NewSimulationStatusCmd() *cobra.Command {
var cmdSimulationStatus = &cobra.Command{
Use: "status",
Short: "Show simulation mode status",
@ -245,7 +262,6 @@ cscli simulation disable crowdsecurity/ssh-bf`,
PersistentPostRun: func(cmd *cobra.Command, args []string) {
},
}
cmdSimulation.AddCommand(cmdSimulationStatus)
return cmdSimulation
return cmdSimulationStatus
}