diff --git a/cmd/crowdsec/api.go b/cmd/crowdsec/api.go index 2af3bbf05..daae1ca7a 100644 --- a/cmd/crowdsec/api.go +++ b/cmd/crowdsec/api.go @@ -4,14 +4,19 @@ import ( "runtime" "time" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "github.com/crowdsecurity/crowdsec/pkg/apiserver" "github.com/crowdsecurity/crowdsec/pkg/csconfig" "github.com/crowdsecurity/crowdsec/pkg/types" - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" ) func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) { + if cConfig.API.Server.OnlineClient == nil || cConfig.API.Server.OnlineClient.Credentials == nil { + log.Info("push and pull to Central API disabled") + } + apiServer, err := apiserver.NewServer(cConfig.API.Server) if err != nil { return nil, errors.Wrap(err, "unable to run local API") @@ -19,7 +24,7 @@ func initAPIServer(cConfig *csconfig.Config) (*apiserver.APIServer, error) { if hasPlugins(cConfig.API.Server.Profiles) { log.Info("initiating plugin broker") - //On windows, the plugins are always run as medium-integrity processes, so we don't care about plugin_config + // On windows, the plugins are always run as medium-integrity processes, so we don't care about plugin_config if cConfig.PluginConfig == nil && runtime.GOOS != "windows" { return nil, errors.New("plugins are enabled, but the plugin_config section is missing in the configuration") } diff --git a/cmd/crowdsec/main.go b/cmd/crowdsec/main.go index 43eb63ec4..63506a6c3 100644 --- a/cmd/crowdsec/main.go +++ b/cmd/crowdsec/main.go @@ -42,7 +42,7 @@ var ( /*the state of the buckets*/ holders []leakybucket.BucketFactory buckets *leakybucket.Buckets - outputEventChan chan types.Event //the buckets init returns its own chan that is used for multiplexing + outputEventChan chan types.Event // the buckets init returns its own chan that is used for multiplexing /*settings*/ lastProcessedItem time.Time /*keep track of last item timestamp in time-machine. it is used to GC buckets when we dump them.*/ pluginBroker csplugin.PluginBroker @@ -56,6 +56,7 @@ type Flags struct { DebugLevel bool InfoLevel bool WarnLevel bool + ErrorLevel bool PrintVersion bool SingleFileType string Labels map[string]string @@ -109,7 +110,6 @@ func newParsers() *parser.Parsers { } func LoadBuckets(cConfig *csconfig.Config) error { - var ( err error files []string @@ -160,9 +160,11 @@ func LoadAcquisition(cConfig *csconfig.Config) error { return nil } -var dumpFolder string -var dumpStates bool -var labels = make(labelsMap) +var ( + dumpFolder string + dumpStates bool + labels = make(labelsMap) +) func (l *labelsMap) String() string { return "labels" @@ -178,12 +180,12 @@ func (l labelsMap) Set(label string) error { } func (f *Flags) Parse() { - flag.StringVar(&f.ConfigFile, "c", csconfig.DefaultConfigPath("config.yaml"), "configuration file") flag.BoolVar(&f.TraceLevel, "trace", false, "VERY verbose") flag.BoolVar(&f.DebugLevel, "debug", false, "print debug-level on stderr") flag.BoolVar(&f.InfoLevel, "info", false, "print info-level on stderr") flag.BoolVar(&f.WarnLevel, "warning", false, "print warning-level on stderr") + flag.BoolVar(&f.ErrorLevel, "error", false, "print error-level on stderr") flag.BoolVar(&f.PrintVersion, "version", false, "display version") flag.StringVar(&f.OneShotDSN, "dsn", "", "Process a single data source in time-machine") flag.StringVar(&f.SingleFileType, "type", "", "Labels.type for file in time-machine") @@ -197,8 +199,41 @@ func (f *Flags) Parse() { flag.Parse() } +func newLogLevel(curLevelPtr *log.Level, f *Flags) *log.Level { + // mother of all defaults + ret := log.InfoLevel + + // keep if already set + if curLevelPtr != nil { + ret = *curLevelPtr + } + + // override from flags + switch { + case f.TraceLevel: + ret = log.TraceLevel + case f.DebugLevel: + ret = log.DebugLevel + case f.InfoLevel: + ret = log.InfoLevel + case f.WarnLevel: + ret = log.WarnLevel + case f.ErrorLevel: + ret = log.ErrorLevel + default: + } + + if ret == *curLevelPtr { + // avoid returning a new ptr to the same value + return curLevelPtr + } + return &ret +} + // LoadConfig returns a configuration parsed from configuration file func LoadConfig(cConfig *csconfig.Config) error { + cConfig.Common.LogLevel = newLogLevel(cConfig.Common.LogLevel, flags) + if dumpFolder != "" { parser.ParseDump = true parser.DumpFolder = dumpFolder @@ -226,23 +261,6 @@ func LoadConfig(cConfig *csconfig.Config) error { return errors.New("You must run at least the API Server or crowdsec") } - if flags.WarnLevel { - logLevel := log.WarnLevel - cConfig.Common.LogLevel = &logLevel - } - if flags.InfoLevel || cConfig.Common.LogLevel == nil { - logLevel := log.InfoLevel - cConfig.Common.LogLevel = &logLevel - } - if flags.DebugLevel { - logLevel := log.DebugLevel - cConfig.Common.LogLevel = &logLevel - } - if flags.TraceLevel { - logLevel := log.TraceLevel - cConfig.Common.LogLevel = &logLevel - } - if flags.TestMode && !cConfig.DisableAgent { cConfig.Crowdsec.LintOnly = true } @@ -268,6 +286,15 @@ func LoadConfig(cConfig *csconfig.Config) error { cConfig.Common.Daemonize = false } + // Configure logging + if err := types.SetDefaultLoggerConfig(cConfig.Common.LogMedia, + cConfig.Common.LogDir, *cConfig.Common.LogLevel, + cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles, + cConfig.Common.LogMaxAge, cConfig.Common.CompressLogs, + cConfig.Common.ForceColorLogs); err != nil { + return err + } + return nil } diff --git a/cmd/crowdsec/run_in_svc.go b/cmd/crowdsec/run_in_svc.go index 2e6e81c6e..b6035e5df 100644 --- a/cmd/crowdsec/run_in_svc.go +++ b/cmd/crowdsec/run_in_svc.go @@ -6,12 +6,12 @@ package main import ( "os" + log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/writer" + "github.com/crowdsecurity/crowdsec/pkg/csconfig" "github.com/crowdsecurity/crowdsec/pkg/cwversion" "github.com/crowdsecurity/crowdsec/pkg/database" - "github.com/crowdsecurity/crowdsec/pkg/types" - log "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/writer" ) func StartRunSvc() error { @@ -37,11 +37,6 @@ func StartRunSvc() error { if err := LoadConfig(cConfig); err != nil { return err } - // Configure logging - if err = types.SetDefaultLoggerConfig(cConfig.Common.LogMedia, cConfig.Common.LogDir, *cConfig.Common.LogLevel, - cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles, cConfig.Common.LogMaxAge, cConfig.Common.CompressLogs, cConfig.Common.ForceColorLogs); err != nil { - log.Fatal(err) - } log.Infof("Crowdsec %s", cwversion.VersionStr()) diff --git a/cmd/crowdsec/run_in_svc_windows.go b/cmd/crowdsec/run_in_svc_windows.go index caa1b960b..40e19dfe5 100644 --- a/cmd/crowdsec/run_in_svc_windows.go +++ b/cmd/crowdsec/run_in_svc_windows.go @@ -3,13 +3,13 @@ package main import ( "fmt" - "github.com/crowdsecurity/crowdsec/pkg/csconfig" - "github.com/crowdsecurity/crowdsec/pkg/cwversion" - "github.com/crowdsecurity/crowdsec/pkg/database" - "github.com/crowdsecurity/crowdsec/pkg/types" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/sys/windows/svc" + + "github.com/crowdsecurity/crowdsec/pkg/csconfig" + "github.com/crowdsecurity/crowdsec/pkg/cwversion" + "github.com/crowdsecurity/crowdsec/pkg/database" ) func StartRunSvc() error { @@ -66,11 +66,6 @@ func WindowsRun() error { return err } // Configure logging - if err = types.SetDefaultLoggerConfig(cConfig.Common.LogMedia, cConfig.Common.LogDir, *cConfig.Common.LogLevel, - cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles, cConfig.Common.LogMaxAge, cConfig.Common.CompressLogs, cConfig.Common.ForceColorLogs); err != nil { - return err - } - log.Infof("Crowdsec %s", cwversion.VersionStr()) if bincoverTesting != "" { diff --git a/cmd/crowdsec/serve.go b/cmd/crowdsec/serve.go index d309440c3..8b9486d28 100644 --- a/cmd/crowdsec/serve.go +++ b/cmd/crowdsec/serve.go @@ -62,14 +62,6 @@ func reloadHandler(sig os.Signal) (*csconfig.Config, error) { if err = LoadConfig(cConfig); err != nil { return nil, err } - // Configure logging - if err = types.SetDefaultLoggerConfig(cConfig.Common.LogMedia, - cConfig.Common.LogDir, *cConfig.Common.LogLevel, - cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles, - cConfig.Common.LogMaxAge, cConfig.Common.CompressLogs, - cConfig.Common.ForceColorLogs); err != nil { - return nil, err - } if !cConfig.DisableAPI { if flags.DisableCAPI { diff --git a/cmd/crowdsec/win_service.go b/cmd/crowdsec/win_service.go index 85b1f167f..b5c59ca45 100644 --- a/cmd/crowdsec/win_service.go +++ b/cmd/crowdsec/win_service.go @@ -11,13 +11,13 @@ import ( "syscall" "time" - "github.com/crowdsecurity/crowdsec/pkg/csconfig" - "github.com/crowdsecurity/crowdsec/pkg/types" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/eventlog" + + "github.com/crowdsecurity/crowdsec/pkg/csconfig" ) type crowdsec_winservice struct { @@ -45,7 +45,7 @@ func (m *crowdsec_winservice) Execute(args []string, r <-chan svc.ChangeRequest, err := shutdown(nil, m.config) if err != nil { log.Errorf("Error while shutting down: %s", err) - //don't return, we still want to notify windows that we are stopped ? + // don't return, we still want to notify windows that we are stopped ? } break loop default: @@ -64,8 +64,7 @@ func (m *crowdsec_winservice) Execute(args []string, r <-chan svc.ChangeRequest, } func runService(name string) error { - - //All the calls to logging before the logger is configured are pretty much useless, but we keep them for clarity + // All the calls to logging before the logger is configured are pretty much useless, but we keep them for clarity err := eventlog.InstallAsEventCreate("CrowdSec", eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { if errno, ok := err.(syscall.Errno); ok { @@ -79,14 +78,14 @@ func runService(name string) error { } } - //Let's use our source even if we could not install it: + // Let's use our source even if we could not install it: // - It could have been created earlier // - No permission to create it (e.g. running as non-admin when working on crowdsec) - //It will still work, windows will just display some additional errors in the event log + // It will still work, windows will just display some additional errors in the event log evtlog, err := eventlog.Open("CrowdSec") if err == nil { - //Send panic and fatal to event log, as they can happen before the logger is configured. + // Send panic and fatal to event log, as they can happen before the logger is configured. log.AddHook(&EventLogHook{ LogLevels: []log.Level{ log.PanicLevel, @@ -107,12 +106,6 @@ func runService(name string) error { return err } - // Configure logging - if err := types.SetDefaultLoggerConfig(cConfig.Common.LogMedia, cConfig.Common.LogDir, *cConfig.Common.LogLevel, - cConfig.Common.LogMaxSize, cConfig.Common.LogMaxFiles, cConfig.Common.LogMaxAge, cConfig.Common.CompressLogs, cConfig.Common.ForceColorLogs); err != nil { - return err - } - log.Infof("starting %s service", name) winsvc := crowdsec_winservice{config: cConfig} diff --git a/pkg/csconfig/api.go b/pkg/csconfig/api.go index 0f94b725d..1b4efa68c 100644 --- a/pkg/csconfig/api.go +++ b/pkg/csconfig/api.go @@ -9,12 +9,13 @@ import ( "strings" "time" - "github.com/crowdsecurity/crowdsec/pkg/apiclient" - "github.com/crowdsecurity/crowdsec/pkg/types" - "github.com/crowdsecurity/crowdsec/pkg/yamlpatch" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" + + "github.com/crowdsecurity/crowdsec/pkg/apiclient" + "github.com/crowdsecurity/crowdsec/pkg/types" + "github.com/crowdsecurity/crowdsec/pkg/yamlpatch" ) type APICfg struct { @@ -33,13 +34,13 @@ type ApiCredentialsCfg struct { /*global api config (for lapi->oapi)*/ type OnlineApiClientCfg struct { - CredentialsFilePath string `yaml:"credentials_path,omitempty"` //credz will be edited by software, store in diff file + CredentialsFilePath string `yaml:"credentials_path,omitempty"` // credz will be edited by software, store in diff file Credentials *ApiCredentialsCfg `yaml:"-"` } /*local api config (for crowdsec/cscli->lapi)*/ type LocalApiClientCfg struct { - CredentialsFilePath string `yaml:"credentials_path,omitempty"` //credz will be edited by software, store in diff file + CredentialsFilePath string `yaml:"credentials_path,omitempty"` // credz will be edited by software, store in diff file Credentials *ApiCredentialsCfg `yaml:"-"` InsecureSkipVerify *bool `yaml:"insecure_skip_verify"` // check if api certificate is bad or not } @@ -138,7 +139,7 @@ func toValidCIDR(ip string) string { /*local api service configuration*/ type LocalApiServerCfg struct { Enable *bool `yaml:"enable"` - ListenURI string `yaml:"listen_uri,omitempty"` //127.0.0.1:8080 + ListenURI string `yaml:"listen_uri,omitempty"` // 127.0.0.1:8080 TLS *TLSCfg `yaml:"tls"` DbConfig *DatabaseCfg `yaml:"-"` LogDir string `yaml:"-"` @@ -171,7 +172,6 @@ type TLSCfg struct { } func (c *Config) LoadAPIServer() error { - if c.DisableAPI { log.Warning("crowdsec local API is disabled from flag") } @@ -227,9 +227,7 @@ func (c *Config) LoadAPIServer() error { return errors.Wrap(err, "loading online client credentials") } } - if c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil { - log.Printf("push and pull to Central API disabled") - } + if err := c.LoadDBConfig(); err != nil { return err } diff --git a/tests/bats/04_nocapi.bats b/tests/bats/04_nocapi.bats index d77c64b49..b7fa20924 100644 --- a/tests/bats/04_nocapi.bats +++ b/tests/bats/04_nocapi.bats @@ -31,6 +31,7 @@ teardown() { @test "without capi: crowdsec LAPI should still work" { config_disable_capi + config_set '.common.log_media="stdout"' run -124 --separate-stderr timeout 1s "${CROWDSEC}" # from `man timeout`: If the command times out, and --preserve-status is not set, then exit with status 124. assert_stderr --partial "push and pull to Central API disabled" diff --git a/tests/lib/config/config-global b/tests/lib/config/config-global index c2f0767c9..592a927c2 100755 --- a/tests/lib/config/config-global +++ b/tests/lib/config/config-global @@ -81,7 +81,7 @@ load_init_data() { ./bin/assert-crowdsec-not-running || die "Cannot load fixture data." if [[ ! -f "${LOCAL_INIT_DIR}/init-config-data.tar" ]]; then - die "Initial data not found; did you run '${script_name} make' ?" + die "Initial data not found; did you run 'make bats-fixture' ?" fi dump_backend="$(cat "${LOCAL_INIT_DIR}/.backend")" diff --git a/tests/lib/config/config-local b/tests/lib/config/config-local index 7d84ac7df..0298fc4d4 100755 --- a/tests/lib/config/config-local +++ b/tests/lib/config/config-local @@ -137,7 +137,7 @@ load_init_data() { ./bin/assert-crowdsec-not-running || die "Cannot load fixture data." if [[ ! -f "${LOCAL_INIT_DIR}/init-config-data.tar" ]]; then - die "Initial data not found; did you run '${script_name} make' ?" + die "Initial data not found; did you run 'make bats-fixture' ?" fi dump_backend="$(cat "${LOCAL_INIT_DIR}/.backend")"