|
@@ -4,19 +4,17 @@ import (
|
|
|
"fmt"
|
|
|
"io/ioutil"
|
|
|
"os"
|
|
|
- "path/filepath"
|
|
|
- "strings"
|
|
|
|
|
|
- "github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
|
|
"github.com/pkg/errors"
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
"gopkg.in/yaml.v2"
|
|
|
)
|
|
|
|
|
|
/*top-level config : defaults,overriden by cfg file,overriden by cli*/
|
|
|
-type GlobalConfig struct {
|
|
|
+type Config struct {
|
|
|
//just a path to ourself :p
|
|
|
- Self *string `yaml:"-"`
|
|
|
+ FilePath *string `yaml:"-"`
|
|
|
+ Self []byte `yaml:"-"`
|
|
|
Common *CommonCfg `yaml:"common,omitempty"`
|
|
|
Prometheus *PrometheusCfg `yaml:"prometheus,omitempty"`
|
|
|
Crowdsec *CrowdsecServiceCfg `yaml:"crowdsec_service,omitempty"`
|
|
@@ -26,9 +24,10 @@ type GlobalConfig struct {
|
|
|
ConfigPaths *ConfigurationPaths `yaml:"config_paths,omitempty"`
|
|
|
DisableAPI bool `yaml:"-"`
|
|
|
DisableAgent bool `yaml:"-"`
|
|
|
+ Hub *Hub `yaml:"-"`
|
|
|
}
|
|
|
|
|
|
-func (c *GlobalConfig) Dump() error {
|
|
|
+func (c *Config) Dump() error {
|
|
|
out, err := yaml.Marshal(c)
|
|
|
if err != nil {
|
|
|
return errors.Wrap(err, "failed marshaling config")
|
|
@@ -37,192 +36,26 @@ func (c *GlobalConfig) Dump() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (c *GlobalConfig) LoadConfigurationFile(path string, disableAPI bool, disableAgent bool) error {
|
|
|
- c.DisableAPI = disableAPI
|
|
|
- c.DisableAgent = disableAgent
|
|
|
- fcontent, err := ioutil.ReadFile(path)
|
|
|
+func NewConfig(configFile string, disableAgent bool, disableAPI bool) (*Config, error) {
|
|
|
+ fcontent, err := ioutil.ReadFile(configFile)
|
|
|
if err != nil {
|
|
|
- return errors.Wrap(err, "failed to read config file")
|
|
|
+ return nil, errors.Wrap(err, "failed to read config file")
|
|
|
}
|
|
|
configData := os.ExpandEnv(string(fcontent))
|
|
|
- err = yaml.UnmarshalStrict([]byte(configData), c)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "failed unmarshaling config")
|
|
|
- }
|
|
|
- path, err = filepath.Abs(path)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "failed to load absolute path")
|
|
|
- }
|
|
|
- c.Self = &path
|
|
|
- if err := c.LoadConfiguration(); err != nil {
|
|
|
- return errors.Wrap(err, "failed to load sub configurations")
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (c *GlobalConfig) LoadConfiguration() error {
|
|
|
- if c.ConfigPaths.ConfigDir == "" {
|
|
|
- return fmt.Errorf("please provide a configuration directory with the 'config_dir' directive in the 'config_paths' section")
|
|
|
- }
|
|
|
-
|
|
|
- if c.ConfigPaths.DataDir == "" {
|
|
|
- return fmt.Errorf("please provide a data directory with the 'data_dir' directive in the 'config_paths' section")
|
|
|
- }
|
|
|
-
|
|
|
- if c.ConfigPaths.HubDir == "" {
|
|
|
- c.ConfigPaths.HubDir = filepath.Clean(c.ConfigPaths.ConfigDir + "/hub")
|
|
|
- }
|
|
|
-
|
|
|
- if c.ConfigPaths.HubIndexFile == "" {
|
|
|
- c.ConfigPaths.HubIndexFile = filepath.Clean(c.ConfigPaths.HubDir + "/.index.json")
|
|
|
- }
|
|
|
-
|
|
|
- if err := c.LoadSimulation(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if c.Crowdsec != nil {
|
|
|
- if c.Crowdsec.AcquisitionFilePath != "" {
|
|
|
- log.Debugf("non-empty acquisition file path %s", c.Crowdsec.AcquisitionFilePath)
|
|
|
- if _, err := os.Stat(c.Crowdsec.AcquisitionFilePath); err != nil {
|
|
|
- return errors.Wrapf(err, "while checking acquisition path %s", c.Crowdsec.AcquisitionFilePath)
|
|
|
- }
|
|
|
- c.Crowdsec.AcquisitionFiles = append(c.Crowdsec.AcquisitionFiles, c.Crowdsec.AcquisitionFilePath)
|
|
|
- }
|
|
|
- if c.Crowdsec.AcquisitionDirPath != "" {
|
|
|
- files, err := filepath.Glob(c.Crowdsec.AcquisitionDirPath + "/*.yaml")
|
|
|
- c.Crowdsec.AcquisitionFiles = append(c.Crowdsec.AcquisitionFiles, files...)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "while globing acquis_dir")
|
|
|
- }
|
|
|
- }
|
|
|
- if c.Crowdsec.AcquisitionDirPath == "" && c.Crowdsec.AcquisitionFilePath == "" {
|
|
|
- return fmt.Errorf("no acquisition_path nor acquisition_dir")
|
|
|
- }
|
|
|
-
|
|
|
- c.Crowdsec.ConfigDir = c.ConfigPaths.ConfigDir
|
|
|
- c.Crowdsec.DataDir = c.ConfigPaths.DataDir
|
|
|
- c.Crowdsec.HubDir = c.ConfigPaths.HubDir
|
|
|
- c.Crowdsec.HubIndexFile = c.ConfigPaths.HubIndexFile
|
|
|
- if c.Crowdsec.ParserRoutinesCount <= 0 {
|
|
|
- c.Crowdsec.ParserRoutinesCount = 1
|
|
|
- }
|
|
|
-
|
|
|
- if c.Crowdsec.BucketsRoutinesCount <= 0 {
|
|
|
- c.Crowdsec.BucketsRoutinesCount = 1
|
|
|
- }
|
|
|
-
|
|
|
- if c.Crowdsec.OutputRoutinesCount <= 0 {
|
|
|
- c.Crowdsec.OutputRoutinesCount = 1
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if err := c.CleanupPaths(); err != nil {
|
|
|
- return errors.Wrap(err, "invalid config")
|
|
|
- }
|
|
|
-
|
|
|
- if c.Cscli != nil {
|
|
|
- c.Cscli.DbConfig = c.DbConfig
|
|
|
- c.Cscli.ConfigDir = c.ConfigPaths.ConfigDir
|
|
|
- c.Cscli.DataDir = c.ConfigPaths.DataDir
|
|
|
- c.Cscli.HubDir = c.ConfigPaths.HubDir
|
|
|
- c.Cscli.HubIndexFile = c.ConfigPaths.HubIndexFile
|
|
|
- if c.Cscli.PrometheusUrl == "" {
|
|
|
- port := 6060
|
|
|
- if c.Prometheus.ListenPort != 0 {
|
|
|
- port = c.Prometheus.ListenPort
|
|
|
- }
|
|
|
- c.Cscli.PrometheusUrl = fmt.Sprintf("http://127.0.0.1:%d/", port)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if c.API.Client != nil && c.API.Client.CredentialsFilePath != "" && !c.DisableAgent {
|
|
|
- fcontent, err := ioutil.ReadFile(c.API.Client.CredentialsFilePath)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, fmt.Sprintf("failed to read api client credential configuration file '%s'", c.API.Client.CredentialsFilePath))
|
|
|
- }
|
|
|
- err = yaml.UnmarshalStrict(fcontent, &c.API.Client.Credentials)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, fmt.Sprintf("failed unmarshaling api client credential configuration file '%s'", c.API.Client.CredentialsFilePath))
|
|
|
- }
|
|
|
- if c.API.Client.Credentials != nil && c.API.Client.Credentials.URL != "" {
|
|
|
- if !strings.HasSuffix(c.API.Client.Credentials.URL, "/") {
|
|
|
- c.API.Client.Credentials.URL = c.API.Client.Credentials.URL + "/"
|
|
|
- }
|
|
|
- }
|
|
|
- if c.API.Client.InsecureSkipVerify == nil {
|
|
|
- apiclient.InsecureSkipVerify = false
|
|
|
- } else {
|
|
|
- apiclient.InsecureSkipVerify = *c.API.Client.InsecureSkipVerify
|
|
|
- }
|
|
|
- }
|
|
|
- if c.API.Server != nil && !c.DisableAPI {
|
|
|
- c.API.Server.DbConfig = c.DbConfig
|
|
|
- c.API.Server.LogDir = c.Common.LogDir
|
|
|
- c.API.Server.LogMedia = c.Common.LogMedia
|
|
|
- if err := c.API.Server.LoadProfiles(); err != nil {
|
|
|
- return errors.Wrap(err, "while loading profiles for LAPI")
|
|
|
- }
|
|
|
- if c.API.Server.OnlineClient != nil && c.API.Server.OnlineClient.CredentialsFilePath != "" {
|
|
|
- c.API.Server.OnlineClient.Credentials = new(ApiCredentialsCfg)
|
|
|
- fcontent, err := ioutil.ReadFile(c.API.Server.OnlineClient.CredentialsFilePath)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, fmt.Sprintf("failed to read api server credentials configuration file '%s'", c.API.Server.OnlineClient.CredentialsFilePath))
|
|
|
- }
|
|
|
- err = yaml.UnmarshalStrict(fcontent, c.API.Server.OnlineClient.Credentials)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, fmt.Sprintf("failed unmarshaling api server credentials configuration file '%s'", c.API.Server.OnlineClient.CredentialsFilePath))
|
|
|
- }
|
|
|
- if c.API.Server.OnlineClient.Credentials.Login == "" || c.API.Server.OnlineClient.Credentials.Password == "" || c.API.Server.OnlineClient.Credentials.URL == "" {
|
|
|
- log.Debugf("can't load CAPI credentials from '%s' (missing field)", c.API.Server.OnlineClient.CredentialsFilePath)
|
|
|
- c.API.Server.OnlineClient.Credentials = nil
|
|
|
- }
|
|
|
- }
|
|
|
- if c.API.Server.OnlineClient == nil || c.API.Server.OnlineClient.Credentials == nil {
|
|
|
- log.Printf("push and pull to crowdsec API disabled")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (c *GlobalConfig) LoadSimulation() error {
|
|
|
- if c.ConfigPaths == nil {
|
|
|
- return fmt.Errorf("ConfigPaths is empty")
|
|
|
+ cfg := Config{
|
|
|
+ FilePath: &configFile,
|
|
|
+ DisableAgent: disableAgent,
|
|
|
+ DisableAPI: disableAPI,
|
|
|
}
|
|
|
|
|
|
- simCfg := SimulationConfig{}
|
|
|
-
|
|
|
- if c.ConfigPaths.SimulationFilePath == "" {
|
|
|
- c.ConfigPaths.SimulationFilePath = filepath.Clean(c.ConfigPaths.ConfigDir + "/simulation.yaml")
|
|
|
- }
|
|
|
-
|
|
|
- rcfg, err := ioutil.ReadFile(c.ConfigPaths.SimulationFilePath)
|
|
|
+ err = yaml.UnmarshalStrict([]byte(configData), &cfg)
|
|
|
if err != nil {
|
|
|
- return errors.Wrapf(err, "while reading '%s'", c.ConfigPaths.SimulationFilePath)
|
|
|
- } else {
|
|
|
- if err := yaml.UnmarshalStrict(rcfg, &simCfg); err != nil {
|
|
|
- return fmt.Errorf("while unmarshaling simulation file '%s' : %s", c.ConfigPaths.SimulationFilePath, err)
|
|
|
- }
|
|
|
- }
|
|
|
- if simCfg.Simulation == nil {
|
|
|
- simCfg.Simulation = new(bool)
|
|
|
- }
|
|
|
- if c.Crowdsec != nil {
|
|
|
- c.Crowdsec.SimulationConfig = &simCfg
|
|
|
- }
|
|
|
- if c.Cscli != nil {
|
|
|
- c.Cscli.SimulationConfig = &simCfg
|
|
|
+ return nil, err
|
|
|
}
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func NewConfig() *GlobalConfig {
|
|
|
- cfg := GlobalConfig{}
|
|
|
- return &cfg
|
|
|
+ return &cfg, nil
|
|
|
}
|
|
|
|
|
|
-func NewDefaultConfig() *GlobalConfig {
|
|
|
+func NewDefaultConfig() *Config {
|
|
|
logLevel := log.InfoLevel
|
|
|
CommonCfg := CommonCfg{
|
|
|
Daemonize: false,
|
|
@@ -270,7 +103,7 @@ func NewDefaultConfig() *GlobalConfig {
|
|
|
DbPath: "/var/lib/crowdsec/data/crowdsec.db",
|
|
|
}
|
|
|
|
|
|
- globalCfg := GlobalConfig{
|
|
|
+ globalCfg := Config{
|
|
|
Common: &CommonCfg,
|
|
|
Prometheus: &prometheus,
|
|
|
Crowdsec: &crowdsecCfg,
|
|
@@ -282,60 +115,3 @@ func NewDefaultConfig() *GlobalConfig {
|
|
|
|
|
|
return &globalCfg
|
|
|
}
|
|
|
-
|
|
|
-func (c *GlobalConfig) CleanupPaths() error {
|
|
|
- var err error
|
|
|
-
|
|
|
- if c.Common != nil {
|
|
|
- var CommonCleanup = []*string{
|
|
|
- &c.Common.PidDir,
|
|
|
- &c.Common.LogDir,
|
|
|
- &c.Common.WorkingDir,
|
|
|
- }
|
|
|
- for _, k := range CommonCleanup {
|
|
|
- if *k == "" {
|
|
|
- continue
|
|
|
- }
|
|
|
- *k, err = filepath.Abs(*k)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "failed to clean path")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if c.Crowdsec != nil {
|
|
|
- var crowdsecCleanup = []*string{
|
|
|
- &c.Crowdsec.AcquisitionFilePath,
|
|
|
- }
|
|
|
- for _, k := range crowdsecCleanup {
|
|
|
- if *k == "" {
|
|
|
- continue
|
|
|
- }
|
|
|
- *k, err = filepath.Abs(*k)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "failed to clean path")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if c.ConfigPaths != nil {
|
|
|
- var configPathsCleanup = []*string{
|
|
|
- &c.ConfigPaths.HubDir,
|
|
|
- &c.ConfigPaths.HubIndexFile,
|
|
|
- &c.ConfigPaths.ConfigDir,
|
|
|
- &c.ConfigPaths.DataDir,
|
|
|
- &c.ConfigPaths.SimulationFilePath,
|
|
|
- }
|
|
|
- for _, k := range configPathsCleanup {
|
|
|
- if *k == "" {
|
|
|
- continue
|
|
|
- }
|
|
|
- *k, err = filepath.Abs(*k)
|
|
|
- if err != nil {
|
|
|
- return errors.Wrap(err, "failed to clean path")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|