github.com/crowdsecurity/crowdsec@v1.6.1/pkg/csconfig/config.go (about)

     1  // Package csconfig contains the configuration structures for crowdsec and cscli.
     2  package csconfig
     3  
     4  import (
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	log "github.com/sirupsen/logrus"
    13  	"gopkg.in/yaml.v3"
    14  
    15  	"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
    16  	"github.com/crowdsecurity/go-cs-lib/csstring"
    17  	"github.com/crowdsecurity/go-cs-lib/ptr"
    18  	"github.com/crowdsecurity/go-cs-lib/yamlpatch"
    19  )
    20  
    21  // defaultConfigDir is the base path to all configuration files, to be overridden in the Makefile */
    22  var defaultConfigDir = "/etc/crowdsec"
    23  
    24  // defaultDataDir is the base path to all data files, to be overridden in the Makefile */
    25  var defaultDataDir = "/var/lib/crowdsec/data/"
    26  
    27  var globalConfig = Config{}
    28  
    29  // Config contains top-level defaults -> overridden by configuration file -> overridden by CLI flags
    30  type Config struct {
    31  	// just a path to ourselves :p
    32  	FilePath     *string             `yaml:"-"`
    33  	Self         []byte              `yaml:"-"`
    34  	Common       *CommonCfg          `yaml:"common,omitempty"`
    35  	Prometheus   *PrometheusCfg      `yaml:"prometheus,omitempty"`
    36  	Crowdsec     *CrowdsecServiceCfg `yaml:"crowdsec_service,omitempty"`
    37  	Cscli        *CscliCfg           `yaml:"cscli,omitempty"`
    38  	DbConfig     *DatabaseCfg        `yaml:"db_config,omitempty"`
    39  	API          *APICfg             `yaml:"api,omitempty"`
    40  	ConfigPaths  *ConfigurationPaths `yaml:"config_paths,omitempty"`
    41  	PluginConfig *PluginCfg          `yaml:"plugin_config,omitempty"`
    42  	DisableAPI   bool                `yaml:"-"`
    43  	DisableAgent bool                `yaml:"-"`
    44  	Hub          *LocalHubCfg        `yaml:"-"`
    45  }
    46  
    47  func NewConfig(configFile string, disableAgent bool, disableAPI bool, inCli bool) (*Config, string, error) {
    48  	patcher := yamlpatch.NewPatcher(configFile, ".local")
    49  	patcher.SetQuiet(inCli)
    50  
    51  	fcontent, err := patcher.MergedPatchContent()
    52  	if err != nil {
    53  		return nil, "", err
    54  	}
    55  
    56  	configData := csstring.StrictExpand(string(fcontent), os.LookupEnv)
    57  	cfg := Config{
    58  		FilePath:     &configFile,
    59  		DisableAgent: disableAgent,
    60  		DisableAPI:   disableAPI,
    61  	}
    62  
    63  	dec := yaml.NewDecoder(strings.NewReader(configData))
    64  	dec.KnownFields(true)
    65  
    66  	err = dec.Decode(&cfg)
    67  	if err != nil {
    68  		if !errors.Is(err, io.EOF) {
    69  			// this is actually the "merged" yaml
    70  			return nil, "", fmt.Errorf("%s: %w", configFile, err)
    71  		}
    72  	}
    73  
    74  	if cfg.Prometheus == nil {
    75  		cfg.Prometheus = &PrometheusCfg{}
    76  	}
    77  
    78  	if cfg.Prometheus.ListenAddr == "" {
    79  		cfg.Prometheus.ListenAddr = "127.0.0.1"
    80  		log.Debugf("prometheus.listen_addr is empty, defaulting to %s", cfg.Prometheus.ListenAddr)
    81  	}
    82  
    83  	if cfg.Prometheus.ListenPort == 0 {
    84  		cfg.Prometheus.ListenPort = 6060
    85  		log.Debugf("prometheus.listen_port is empty or zero, defaulting to %d", cfg.Prometheus.ListenPort)
    86  	}
    87  
    88  	if err = cfg.loadCommon(); err != nil {
    89  		return nil, "", err
    90  	}
    91  
    92  	if err = cfg.loadConfigurationPaths(); err != nil {
    93  		return nil, "", err
    94  	}
    95  
    96  	if err = cfg.loadHub(); err != nil {
    97  		return nil, "", err
    98  	}
    99  
   100  	if err = cfg.loadCSCLI(); err != nil {
   101  		return nil, "", err
   102  	}
   103  
   104  	globalConfig = cfg
   105  
   106  	return &cfg, configData, nil
   107  }
   108  
   109  func GetConfig() Config {
   110  	return globalConfig
   111  }
   112  
   113  func NewDefaultConfig() *Config {
   114  	logLevel := log.InfoLevel
   115  	commonCfg := CommonCfg{
   116  		Daemonize: false,
   117  		LogMedia:  "stdout",
   118  		LogLevel:  &logLevel,
   119  	}
   120  	prometheus := PrometheusCfg{
   121  		Enabled: true,
   122  		Level:   configuration.CFG_METRICS_FULL,
   123  	}
   124  	configPaths := ConfigurationPaths{
   125  		ConfigDir:          DefaultConfigPath("."),
   126  		DataDir:            DefaultDataPath("."),
   127  		SimulationFilePath: DefaultConfigPath("simulation.yaml"),
   128  		HubDir:             DefaultConfigPath("hub"),
   129  		HubIndexFile:       DefaultConfigPath("hub", ".index.json"),
   130  	}
   131  	crowdsecCfg := CrowdsecServiceCfg{
   132  		AcquisitionFilePath: DefaultConfigPath("acquis.yaml"),
   133  		ParserRoutinesCount: 1,
   134  	}
   135  
   136  	cscliCfg := CscliCfg{
   137  		Output: "human",
   138  		Color:  "auto",
   139  	}
   140  
   141  	apiCfg := APICfg{
   142  		Client: &LocalApiClientCfg{
   143  			CredentialsFilePath: DefaultConfigPath("lapi-secrets.yaml"),
   144  		},
   145  		Server: &LocalApiServerCfg{
   146  			ListenURI:              "127.0.0.1:8080",
   147  			UseForwardedForHeaders: false,
   148  			OnlineClient: &OnlineApiClientCfg{
   149  				CredentialsFilePath: DefaultConfigPath("online_api_credentials.yaml"),
   150  			},
   151  		},
   152  		CTI: &CTICfg{
   153  			Enabled: ptr.Of(false),
   154  		},
   155  	}
   156  
   157  	dbConfig := DatabaseCfg{
   158  		Type:         "sqlite",
   159  		DbPath:       DefaultDataPath("crowdsec.db"),
   160  		MaxOpenConns: ptr.Of(DEFAULT_MAX_OPEN_CONNS),
   161  	}
   162  
   163  	globalCfg := Config{
   164  		Common:      &commonCfg,
   165  		Prometheus:  &prometheus,
   166  		Crowdsec:    &crowdsecCfg,
   167  		Cscli:       &cscliCfg,
   168  		API:         &apiCfg,
   169  		ConfigPaths: &configPaths,
   170  		DbConfig:    &dbConfig,
   171  	}
   172  
   173  	return &globalCfg
   174  }
   175  
   176  // DefaultConfigPath returns the default path for a configuration resource
   177  // "elem" parameters are path components relative to the default cfg directory.
   178  func DefaultConfigPath(elem ...string) string {
   179  	elem = append([]string{defaultConfigDir}, elem...)
   180  	return filepath.Join(elem...)
   181  }
   182  
   183  // DefaultDataPath returns the default path for a data resource.
   184  // "elem" parameters are path components relative to the default data directory.
   185  func DefaultDataPath(elem ...string) string {
   186  	elem = append([]string{defaultDataDir}, elem...)
   187  	return filepath.Join(elem...)
   188  }