diff --git a/cmd/crowdsec-cli/cliconfig/show.go b/cmd/crowdsec-cli/cliconfig/show.go index cff214e49..b5830ceec 100644 --- a/cmd/crowdsec-cli/cliconfig/show.go +++ b/cmd/crowdsec-cli/cliconfig/show.go @@ -25,7 +25,7 @@ func (cli *cliConfig) showKey(key string) error { } opts := []expr.Option{} - opts = append(opts, exprhelpers.GetExprOptions(map[string]interface{}{})...) + opts = append(opts, exprhelpers.GetExprOptions(map[string]any{})...) opts = append(opts, expr.Env(Env{})) program, err := expr.Compile(key, opts...) @@ -44,7 +44,7 @@ func (cli *cliConfig) showKey(key string) error { // that would break compatibility with previous versions switch output.(type) { case string: - fmt.Println(output) + fmt.Fprintln(os.Stdout, output) default: litter.Dump(output) } @@ -54,7 +54,7 @@ func (cli *cliConfig) showKey(key string) error { return fmt.Errorf("failed to serialize configuration: %w", err) } - fmt.Println(string(data)) + fmt.Fprintln(os.Stdout, string(data)) } return nil @@ -67,6 +67,7 @@ func (cli *cliConfig) template() string { - Configuration Folder : {{.ConfigPaths.ConfigDir}} - Data Folder : {{.ConfigPaths.DataDir}} - Hub Folder : {{.ConfigPaths.HubDir}} + - Notification Folder : {{.ConfigPaths.NotificationDir}} - Simulation File : {{.ConfigPaths.SimulationFilePath}} {{- end }} @@ -216,14 +217,14 @@ func (cli *cliConfig) show() error { return fmt.Errorf("failed to serialize configuration: %w", err) } - fmt.Println(string(data)) + fmt.Fprintln(os.Stdout, string(data)) case "raw": data, err := yaml.Marshal(cfg) if err != nil { return fmt.Errorf("failed to serialize configuration: %w", err) } - fmt.Println(string(data)) + fmt.Fprintln(os.Stdout, string(data)) } return nil diff --git a/cmd/crowdsec-cli/clinotifications/notifications.go b/cmd/crowdsec-cli/clinotifications/notifications.go index 7856c89ff..9031a2d93 100644 --- a/cmd/crowdsec-cli/clinotifications/notifications.go +++ b/cmd/crowdsec-cli/clinotifications/notifications.go @@ -70,7 +70,7 @@ func (cli *cliNotifications) NewCommand() *cobra.Command { return fmt.Errorf("loading api client: %w", err) } - return require.Notifications(cfg) + return nil }, } @@ -176,7 +176,7 @@ func (cli *cliNotifications) newListCmd() *cobra.Command { if err != nil { return fmt.Errorf("failed to serialize notification configuration: %w", err) } - fmt.Printf("%s", string(x)) + fmt.Fprint(os.Stdout, string(x)) } else if cfg.Cscli.Output == "raw" { csvwriter := csv.NewWriter(os.Stdout) err := csvwriter.Write([]string{"Name", "Type", "Profile name"}) @@ -223,19 +223,19 @@ func (cli *cliNotifications) newInspectCmd() *cobra.Command { return fmt.Errorf("plugin '%s' does not exist or is not active", args[0]) } if cfg.Cscli.Output == "human" || cfg.Cscli.Output == "raw" { - fmt.Printf(" - %15s: %15s\n", "Type", ncfg.Config.Type) - fmt.Printf(" - %15s: %15s\n", "Name", ncfg.Config.Name) - fmt.Printf(" - %15s: %15s\n", "Timeout", ncfg.Config.TimeOut) - fmt.Printf(" - %15s: %15s\n", "Format", ncfg.Config.Format) + fmt.Fprintf(os.Stdout, " - %15s: %15s\n", "Type", ncfg.Config.Type) + fmt.Fprintf(os.Stdout, " - %15s: %15s\n", "Name", ncfg.Config.Name) + fmt.Fprintf(os.Stdout, " - %15s: %15s\n", "Timeout", ncfg.Config.TimeOut) + fmt.Fprintf(os.Stdout, " - %15s: %15s\n", "Format", ncfg.Config.Format) for k, v := range ncfg.Config.Config { - fmt.Printf(" - %15s: %15v\n", k, v) + fmt.Fprintf(os.Stdout, " - %15s: %15v\n", k, v) } } else if cfg.Cscli.Output == "json" { x, err := json.MarshalIndent(cfg, "", " ") if err != nil { return fmt.Errorf("failed to serialize notification configuration: %w", err) } - fmt.Printf("%s", string(x)) + fmt.Fprint(os.Stdout, string(x)) } return nil diff --git a/cmd/crowdsec-cli/require/require.go b/cmd/crowdsec-cli/require/require.go index beffa29f3..098218263 100644 --- a/cmd/crowdsec-cli/require/require.go +++ b/cmd/crowdsec-cli/require/require.go @@ -74,14 +74,6 @@ func DB(c *csconfig.Config) error { return nil } -func Notifications(c *csconfig.Config) error { - if c.ConfigPaths.NotificationDir == "" { - return errors.New("config_paths.notification_dir is not set in crowdsec config") - } - - return nil -} - func HubDownloader(ctx context.Context, c *csconfig.Config) *cwhub.Downloader { // set branch in config, and log if necessary branch := HubBranch(ctx, c) diff --git a/cmd/crowdsec/api.go b/cmd/crowdsec/api.go index ccb0acf02..1b14d2f69 100644 --- a/cmd/crowdsec/api.go +++ b/cmd/crowdsec/api.go @@ -32,10 +32,6 @@ func initAPIServer(ctx context.Context, cConfig *csconfig.Config) (*apiserver.AP return nil, errors.New("plugins are enabled, but the plugin_config section is missing in the configuration") } - if cConfig.ConfigPaths.NotificationDir == "" { - return nil, errors.New("plugins are enabled, but config_paths.notification_dir is not defined") - } - if cConfig.ConfigPaths.PluginDir == "" { return nil, errors.New("plugins are enabled, but config_paths.plugin_dir is not defined") } diff --git a/pkg/csconfig/config_paths.go b/pkg/csconfig/config_paths.go index a8d39a664..5fdf1d94b 100644 --- a/pkg/csconfig/config_paths.go +++ b/pkg/csconfig/config_paths.go @@ -19,10 +19,15 @@ type ConfigurationPaths struct { func (c *Config) loadConfigurationPaths() error { var err error + if c.ConfigPaths == nil { return errors.New("no configuration paths provided") } + if c.ConfigPaths.ConfigDir == "" { + c.ConfigPaths.ConfigDir = filepath.Dir(c.FilePath) + } + if c.ConfigPaths.DataDir == "" { return errors.New("please provide a data directory with the 'data_dir' directive in the 'config_paths' section") } @@ -35,6 +40,10 @@ func (c *Config) loadConfigurationPaths() error { c.ConfigPaths.HubIndexFile = filepath.Join(c.ConfigPaths.HubDir, ".index.json") } + if c.ConfigPaths.NotificationDir == "" { + c.ConfigPaths.NotificationDir = filepath.Join(c.ConfigPaths.ConfigDir, "notifications") + } + if c.ConfigPaths.PatternDir == "" { c.ConfigPaths.PatternDir = filepath.Join(c.ConfigPaths.ConfigDir, "patterns") } @@ -53,6 +62,7 @@ func (c *Config) loadConfigurationPaths() error { if *k == "" { continue } + *k, err = filepath.Abs(*k) if err != nil { return fmt.Errorf("failed to get absolute path of '%s': %w", *k, err) diff --git a/test/bats/01_cscli.bats b/test/bats/01_cscli.bats index 77c128568..df4ece8d7 100644 --- a/test/bats/01_cscli.bats +++ b/test/bats/01_cscli.bats @@ -147,6 +147,11 @@ teardown() { # defaults + config_set 'del(.config_paths.config_dir)' + rune -0 cscli config show --key Config.ConfigPaths.ConfigDir + assert_output "$configdir" + echo "$config" > "$CONFIG_YAML" + config_set 'del(.config_paths.hub_dir)' rune -0 cscli hub list rune -0 cscli config show --key Config.ConfigPaths.HubDir diff --git a/test/bats/72_plugin_badconfig.bats b/test/bats/72_plugin_badconfig.bats index 216b29f4d..ab8ceecc5 100644 --- a/test/bats/72_plugin_badconfig.bats +++ b/test/bats/72_plugin_badconfig.bats @@ -12,6 +12,9 @@ setup_file() { PROFILES_PATH=$(config_get '.api.server.profiles_path') export PROFILES_PATH + + CONFIG_DIR=$(dirname "$CONFIG_YAML") + export CONFIG_DIR } teardown_file() { @@ -72,7 +75,6 @@ teardown() { } @test "duplicate notification config" { - CONFIG_DIR=$(dirname "$CONFIG_YAML") # email_default has two configurations rune -0 yq -i '.name="email_default"' "$CONFIG_DIR/notifications/http.yaml" # enable a notification, otherwise plugins are ignored @@ -110,10 +112,8 @@ teardown() { @test "config.yaml: missing config_paths.notification_dir" { config_set 'del(.config_paths.notification_dir)' - config_set "$PROFILES_PATH" '.notifications=["http_default"]' - rune -0 wait-for \ - --err "api server init: plugins are enabled, but config_paths.notification_dir is not defined" \ - "$CROWDSEC" + rune -0 cscli config show --key Config.ConfigPaths.NotificationDir + assert_output "$CONFIG_DIR/notifications" } @test "config.yaml: missing config_paths.plugin_dir" {