/* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see */ package config import ( "bytes" "encoding/json" "errors" "fmt" "io" "net" "net/http" "os" "path/filepath" "runtime" "strings" "sync" "time" "github.com/cgrates/birpc/context" "github.com/cgrates/rpcclient" "github.com/cgrates/cgrates/utils" ) var ( dbDefaultsCfg dbDefaults cgrCfg *CGRConfig // will be shared dfltFsConnConfig *FsConnCfg // Default FreeSWITCH Connection configuration, built out of json default configuration dfltKamConnConfig *KamConnCfg // Default Kamailio Connection configuration dfltRemoteHost *RemoteHost dfltAstConnCfg *AsteriskConnCfg ) func newDbDefaults() dbDefaults { deflt := dbDefaults{ utils.MetaMySQL: map[string]string{ "DbName": "cgrates", "DbPort": "3306", }, utils.MetaPostgres: map[string]string{ "DbName": "cgrates", "DbPort": "5432", }, utils.MetaMongo: map[string]string{ "DbName": "cgrates", "DbPort": "27017", }, utils.MetaRedis: map[string]string{ "DbName": "10", "DbPort": "6379", }, utils.MetaInternal: map[string]string{ "DbName": "internal", "DbPort": "internal", }, } return deflt } type dbDefaults map[string]map[string]string func (dbDflt dbDefaults) dbName(dbType string, flagInput string) string { if flagInput != utils.MetaDynamic { return flagInput } return dbDflt[dbType]["DbName"] } func (dbDflt dbDefaults) dbPort(dbType string, flagInput string) string { if flagInput != utils.MetaDynamic { return flagInput } return dbDflt[dbType]["DbPort"] } func init() { cgrCfg = NewDefaultCGRConfig() dbDefaultsCfg = newDbDefaults() } // CgrConfig is used to retrieve system configuration from other packages func CgrConfig() *CGRConfig { return cgrCfg } // SetCgrConfig is used to set system configuration from other places func SetCgrConfig(cfg *CGRConfig) { cgrCfg = cfg } // NewDefaultCGRConfig returns the default configuration func NewDefaultCGRConfig() (cfg *CGRConfig) { cfg, _ = newCGRConfig([]byte(CGRATES_CFG_JSON)) return } func newCGRConfig(config []byte) (cfg *CGRConfig, err error) { cfg = new(CGRConfig) cfg.initChanels() cfg.DataFolderPath = "/usr/share/cgrates/" cfg.rpcConns = make(map[string]*RPCConn) cfg.templates = make(map[string][]*FCTemplate) cfg.generalCfg = new(GeneralCfg) cfg.generalCfg.NodeID = utils.UUIDSha1Prefix() cfg.dataDbCfg = new(DataDbCfg) cfg.dataDbCfg.Items = make(map[string]*ItemOpt) cfg.dataDbCfg.Opts = &DataDBOpts{} cfg.storDbCfg = new(StorDbCfg) cfg.storDbCfg.Items = make(map[string]*ItemOpt) cfg.storDbCfg.Opts = &StorDBOpts{} cfg.tlsCfg = new(TLSCfg) cfg.cacheCfg = new(CacheCfg) cfg.cacheCfg.Partitions = make(map[string]*CacheParamCfg) cfg.listenCfg = new(ListenCfg) cfg.httpCfg = new(HTTPCfg) cfg.httpCfg.dialer = &net.Dialer{} cfg.httpCfg.ClientOpts = &http.Transport{} cfg.filterSCfg = new(FilterSCfg) cfg.ralsCfg = new(RalsCfg) cfg.ralsCfg.MaxComputedUsage = make(map[string]time.Duration) cfg.ralsCfg.BalanceRatingSubject = make(map[string]string) cfg.schedulerCfg = new(SchedulerCfg) cfg.cdrsCfg = new(CdrsCfg) cfg.analyzerSCfg = new(AnalyzerSCfg) cfg.sessionSCfg = new(SessionSCfg) cfg.sessionSCfg.STIRCfg = new(STIRcfg) cfg.sessionSCfg.DefaultUsage = make(map[string]time.Duration) cfg.fsAgentCfg = new(FsAgentCfg) cfg.kamAgentCfg = new(KamAgentCfg) cfg.asteriskAgentCfg = new(AsteriskAgentCfg) cfg.diameterAgentCfg = new(DiameterAgentCfg) cfg.radiusAgentCfg = new(RadiusAgentCfg) cfg.dnsAgentCfg = new(DNSAgentCfg) cfg.prometheusAgentCfg = new(PrometheusAgentCfg) cfg.attributeSCfg = &AttributeSCfg{Opts: &AttributesOpts{}} cfg.chargerSCfg = new(ChargerSCfg) cfg.resourceSCfg = &ResourceSConfig{Opts: &ResourcesOpts{}} cfg.statsCfg = &StatSCfg{Opts: &StatsOpts{}} cfg.trendsCfg = new(TrendSCfg) cfg.rankingsCfg = new(RankingSCfg) cfg.thresholdSCfg = &ThresholdSCfg{Opts: &ThresholdsOpts{}} cfg.routeSCfg = &RouteSCfg{Opts: &RoutesOpts{}} cfg.sureTaxCfg = new(SureTaxCfg) cfg.dispatcherSCfg = new(DispatcherSCfg) cfg.registrarCCfg = new(RegistrarCCfgs) cfg.registrarCCfg.RPC = new(RegistrarCCfg) cfg.registrarCCfg.Dispatchers = new(RegistrarCCfg) cfg.registrarCCfg.RPC.Hosts = make(map[string][]*RemoteHost) cfg.registrarCCfg.Dispatchers.Hosts = make(map[string][]*RemoteHost) cfg.loaderCgrCfg = new(LoaderCgrCfg) cfg.migratorCgrCfg = new(MigratorCgrCfg) cfg.migratorCgrCfg.OutDataDBOpts = &DataDBOpts{} cfg.migratorCgrCfg.OutStorDBOpts = &StorDBOpts{} cfg.mailerCfg = new(MailerCfg) cfg.apier = new(ApierCfg) cfg.ersCfg = new(ERsCfg) cfg.eesCfg = &EEsCfg{ Cache: make(map[string]*CacheParamCfg), FailedPosts: &FailedPostsCfg{}, } cfg.sipAgentCfg = new(SIPAgentCfg) cfg.janusAgentCfg = new(JanusAgentCfg) cfg.configSCfg = new(ConfigSCfg) cfg.apiBanCfg = new(APIBanCfg) cfg.sentryPeerCfg = new(SentryPeerCfg) cfg.coreSCfg = new(CoreSCfg) cfg.ipsCfg = &IPsCfg{Opts: &IPsOpts{}} cfg.dfltEvExp = &EventExporterCfg{Opts: &EventExporterOpts{ Els: new(ElsOpts), SQL: new(SQLOpts), AMQP: new(AMQPOpts), AWS: new(AWSOpts), NATS: new(NATSOpts), RPC: new(RPCOpts), Kafka: new(KafkaOpts), }} cfg.dfltEvRdr = &EventReaderCfg{Opts: &EventReaderOpts{ SQL: new(SQLROpts), CSV: new(CSVROpts), AWS: new(AWSROpts), AMQP: new(AMQPROpts), Kafka: new(KafkaROpts), NATS: new(NATSROpts), }} cfg.cacheDP = make(map[string]utils.MapStorage) var cgrJSONCfg *CgrJsonCfg if cgrJSONCfg, err = NewCgrJsonCfgFromBytes(config); err != nil { return } if err = cfg.loadFromJSONCfg(cgrJSONCfg); err != nil { return } // populate default ERs reader for _, ersRdr := range cfg.ersCfg.Readers { if ersRdr.ID == utils.MetaDefault { cfg.dfltEvRdr = ersRdr.Clone() break } } // populate default EEs exporter for _, ersExp := range cfg.eesCfg.Exporters { if ersExp.ID == utils.MetaDefault { cfg.dfltEvExp = ersExp.Clone() break } } dfltFsConnConfig = cfg.fsAgentCfg.EventSocketConns[0] // We leave it crashing here on purpose if no Connection defaults defined dfltKamConnConfig = cfg.kamAgentCfg.EvapiConns[0] dfltAstConnCfg = cfg.asteriskAgentCfg.AsteriskConns[0] dfltRemoteHost = new(RemoteHost) *dfltRemoteHost = *cfg.rpcConns[utils.MetaLocalHost].Conns[0] err = cfg.checkConfigSanity() return } // NewCGRConfigFromJSONStringWithDefaults returns the given config with the default option loaded func NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr string) (cfg *CGRConfig, err error) { cfg = NewDefaultCGRConfig() jsnCfg := new(CgrJsonCfg) if err = NewRjReaderFromBytes([]byte(cfgJSONStr)).Decode(jsnCfg); err != nil { return } else if err = cfg.loadFromJSONCfg(jsnCfg); err != nil { return } return } // NewCGRConfigFromPath reads all json files out of a folder/subfolders and loads them up in lexical order func NewCGRConfigFromPath(path string) (cfg *CGRConfig, err error) { cfg = NewDefaultCGRConfig() cfg.ConfigPath = path if err = cfg.loadConfigFromPath(path, []func(*CgrJsonCfg) error{cfg.loadFromJSONCfg}, false); err != nil { return } err = cfg.checkConfigSanity() return } // newCGRConfigFromPathWithoutEnv reads all json files out of a folder/subfolders and loads them up in lexical order // it will not read *env variables and will not checkConfigSanity as it is not needed for configs func newCGRConfigFromPathWithoutEnv(path string) (cfg *CGRConfig, err error) { cfg = NewDefaultCGRConfig() cfg.ConfigPath = path err = cfg.loadConfigFromPath(path, []func(*CgrJsonCfg) error{cfg.loadFromJSONCfg}, true) return } func isHidden(fileName string) bool { if fileName == "." || fileName == ".." { return false } return strings.HasPrefix(fileName, ".") } // CGRConfig holds system configuration, defaults are overwritten with values from config file if found type CGRConfig struct { lks map[string]*sync.RWMutex DataFolderPath string // Path towards data folder, for tests internal usage, not loading out of .json options ConfigPath string // Path towards config // Cache defaults loaded from json and needing clones dfltEvRdr *EventReaderCfg // default event reader dfltEvExp *EventExporterCfg // default event exporter httpAgentCfg HTTPAgentCfgs // HttpAgent configs rldChans map[string]chan struct{} // index here the channels used for reloads rpcConns RPCConns templates FcTemplates generalCfg *GeneralCfg // General config dataDbCfg *DataDbCfg // Database config storDbCfg *StorDbCfg // StroreDb config tlsCfg *TLSCfg // TLS config cacheCfg *CacheCfg // Cache config listenCfg *ListenCfg // Listen config httpCfg *HTTPCfg // HTTP config filterSCfg *FilterSCfg // FilterS config ralsCfg *RalsCfg // Rals config schedulerCfg *SchedulerCfg // Scheduler config cdrsCfg *CdrsCfg // Cdrs config sessionSCfg *SessionSCfg // SessionS config fsAgentCfg *FsAgentCfg // FreeSWITCHAgent config kamAgentCfg *KamAgentCfg // KamailioAgent config asteriskAgentCfg *AsteriskAgentCfg // AsteriskAgent config diameterAgentCfg *DiameterAgentCfg // DiameterAgent config radiusAgentCfg *RadiusAgentCfg // RadiusAgent config dnsAgentCfg *DNSAgentCfg // DNSAgent config prometheusAgentCfg *PrometheusAgentCfg // PrometheusAgent config attributeSCfg *AttributeSCfg // AttributeS config chargerSCfg *ChargerSCfg // ChargerS config resourceSCfg *ResourceSConfig // ResourceS config statsCfg *StatSCfg // StatS config trendsCfg *TrendSCfg // TrendS config rankingsCfg *RankingSCfg // Rankings config thresholdSCfg *ThresholdSCfg // ThresholdS config routeSCfg *RouteSCfg // RouteS config sureTaxCfg *SureTaxCfg // SureTax config dispatcherSCfg *DispatcherSCfg // DispatcherS config registrarCCfg *RegistrarCCfgs // RegistrarC config loaderCgrCfg *LoaderCgrCfg // LoaderCgr config migratorCgrCfg *MigratorCgrCfg // MigratorCgr config mailerCfg *MailerCfg // Mailer config analyzerSCfg *AnalyzerSCfg // AnalyzerS config apier *ApierCfg // APIer config ersCfg *ERsCfg // EventReader config eesCfg *EEsCfg // EventExporter config sipAgentCfg *SIPAgentCfg // SIPAgent config janusAgentCfg *JanusAgentCfg // JanusAgent config configSCfg *ConfigSCfg // ConfigS config apiBanCfg *APIBanCfg // APIBan config sentryPeerCfg *SentryPeerCfg //SentryPeer config coreSCfg *CoreSCfg // CoreS config ipsCfg *IPsCfg // IPs config cacheDP map[string]utils.MapStorage cacheDPMux sync.RWMutex } var possibleLoaderTypes = utils.NewStringSet([]string{utils.MetaAttributes, utils.MetaResources, utils.MetaIPs, utils.MetaFilters, utils.MetaStats, utils.MetaRoutes, utils.MetaThresholds, utils.MetaChargers, utils.MetaDispatchers, utils.MetaDispatcherHosts}) var possibleReaderTypes = utils.NewStringSet([]string{utils.MetaFileCSV, utils.MetaKafkajsonMap, utils.MetaFileXML, utils.MetaSQL, utils.MetaFileFWV, utils.MetaFileJSON, utils.MetaNone, utils.MetaAMQPjsonMap, utils.MetaS3jsonMap, utils.MetaSQSjsonMap, utils.MetaAMQPV1jsonMap, utils.MetaNatsjsonMap}) var possibleExporterTypes = utils.NewStringSet([]string{utils.MetaFileCSV, utils.MetaNone, utils.MetaFileFWV, utils.MetaHTTPPost, utils.MetaHTTPjsonMap, utils.MetaAMQPjsonMap, utils.MetaAMQPV1jsonMap, utils.MetaSQSjsonMap, utils.MetaKafkajsonMap, utils.MetaS3jsonMap, utils.MetaElastic, utils.MetaVirt, utils.MetaSQL, utils.MetaNatsjsonMap, utils.MetaLog, utils.MetaRPC}) // Loads from json configuration object, will be used for defaults, config from file and reload, might need lock func (cfg *CGRConfig) loadFromJSONCfg(jsnCfg *CgrJsonCfg) (err error) { // Load sections out of JSON config, stop on error for _, loadFunc := range []func(*CgrJsonCfg) error{ cfg.loadRPCConns, cfg.loadGeneralCfg, cfg.loadTemplateSCfg, cfg.loadCacheCfg, cfg.loadListenCfg, cfg.loadHTTPCfg, cfg.loadDataDBCfg, cfg.loadStorDBCfg, cfg.loadFilterSCfg, cfg.loadRalSCfg, cfg.loadSchedulerCfg, cfg.loadCdrsCfg, cfg.loadSessionSCfg, cfg.loadFreeswitchAgentCfg, cfg.loadKamAgentCfg, cfg.loadAsteriskAgentCfg, cfg.loadDiameterAgentCfg, cfg.loadRadiusAgentCfg, cfg.loadDNSAgentCfg, cfg.loadHTTPAgentCfg, cfg.loadPrometheusAgentCfg, cfg.loadAttributeSCfg, cfg.loadChargerSCfg, cfg.loadResourceSCfg, cfg.loadStatSCfg, cfg.loadTrendSCfg, cfg.loadRankingSCfg, cfg.loadThresholdSCfg, cfg.loadRouteSCfg, cfg.loadMailerCfg, cfg.loadSureTaxCfg, cfg.loadDispatcherSCfg, cfg.loadLoaderCgrCfg, cfg.loadMigratorCgrCfg, cfg.loadTLSCgrCfg, cfg.loadAnalyzerCgrCfg, cfg.loadApierCfg, cfg.loadErsCfg, cfg.loadEesCfg, cfg.loadSIPAgentCfg, cfg.loadRegistrarCCfg, cfg.loadJanusAgentCfg, cfg.loadConfigSCfg, cfg.loadAPIBanCgrCfg, cfg.loadSentryPeerCgrCfg, cfg.loadCoreSCfg, cfg.loadIPsCfg, } { if err = loadFunc(jsnCfg); err != nil { return } } return } // loadRPCConns loads the RPCConns section of the configuration func (cfg *CGRConfig) loadRPCConns(jsnCfg *CgrJsonCfg) (err error) { var jsnRPCConns map[string]*RPCConnsJson if jsnRPCConns, err = jsnCfg.RPCConnJsonCfg(); err != nil { return } // hardoded the *internal connection cfg.rpcConns[utils.MetaInternal] = &RPCConn{ Strategy: rpcclient.PoolFirst, PoolSize: 0, Conns: []*RemoteHost{{ Address: utils.MetaInternal, }}, } cfg.rpcConns[rpcclient.BiRPCInternal] = &RPCConn{ Strategy: rpcclient.PoolFirst, PoolSize: 0, Conns: []*RemoteHost{{ Address: rpcclient.BiRPCInternal, }}, } cfg.rpcConns[utils.MetaLocalHost] = &RPCConn{ Strategy: rpcclient.PoolFirst, PoolSize: 0, Conns: []*RemoteHost{{ Address: "127.0.0.1:2012", Transport: utils.MetaJSON, }}, } cfg.rpcConns[utils.MetaBiJSONLocalHost] = &RPCConn{ Strategy: rpcclient.PoolFirst, PoolSize: 0, Conns: []*RemoteHost{{ Address: "127.0.0.1:2014", Transport: rpcclient.BiRPCJSON, }}, } for key, val := range jsnRPCConns { cfg.rpcConns[key] = NewDfltRPCConn() cfg.rpcConns[key].loadFromJSONCfg(val) } return } // loadGeneralCfg loads the General section of the configuration func (cfg *CGRConfig) loadGeneralCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnGeneralCfg *GeneralJsonCfg if jsnGeneralCfg, err = jsnCfg.GeneralJsonCfg(); err != nil { return } return cfg.generalCfg.loadFromJSONCfg(jsnGeneralCfg) } // loadCacheCfg loads the Cache section of the configuration func (cfg *CGRConfig) loadCacheCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnCacheCfg *CacheJsonCfg if jsnCacheCfg, err = jsnCfg.CacheJsonCfg(); err != nil { return } return cfg.cacheCfg.loadFromJSONCfg(jsnCacheCfg) } // loadListenCfg loads the Listen section of the configuration func (cfg *CGRConfig) loadListenCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnListenCfg *ListenJsonCfg if jsnListenCfg, err = jsnCfg.ListenJsonCfg(); err != nil { return } return cfg.listenCfg.loadFromJSONCfg(jsnListenCfg) } // loadHTTPCfg loads the Http section of the configuration func (cfg *CGRConfig) loadHTTPCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnHTTPCfg *HTTPJsonCfg if jsnHTTPCfg, err = jsnCfg.HttpJsonCfg(); err != nil { return } return cfg.httpCfg.loadFromJSONCfg(jsnHTTPCfg) } // loadDataDBCfg loads the DataDB section of the configuration func (cfg *CGRConfig) loadDataDBCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnDataDbCfg *DbJsonCfg if jsnDataDbCfg, err = jsnCfg.DbJsonCfg(DATADB_JSN); err != nil { return } if err = cfg.dataDbCfg.loadFromJSONCfg(jsnDataDbCfg); err != nil { return } // in case of internalDB we need to disable the cache // so we enforce it here if cfg.dataDbCfg.Type == utils.MetaInternal { // overwrite only StatelessDataDBPartitions and leave other unmodified ( e.g. *diameter_messages, *closed_sessions, etc... ) for key := range utils.StatelessDataDBPartitions { if _, has := cfg.cacheCfg.Partitions[key]; has { cfg.cacheCfg.Partitions[key] = &CacheParamCfg{} } } } return } // loadStorDBCfg loads the StorDB section of the configuration func (cfg *CGRConfig) loadStorDBCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnDataDbCfg *DbJsonCfg if jsnDataDbCfg, err = jsnCfg.DbJsonCfg(STORDB_JSN); err != nil { return } return cfg.storDbCfg.loadFromJSONCfg(jsnDataDbCfg) } // loadFilterSCfg loads the FilterS section of the configuration func (cfg *CGRConfig) loadFilterSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnFilterSCfg *FilterSJsonCfg if jsnFilterSCfg, err = jsnCfg.FilterSJsonCfg(); err != nil { return } return cfg.filterSCfg.loadFromJSONCfg(jsnFilterSCfg) } // loadRalSCfg loads the RalS section of the configuration func (cfg *CGRConfig) loadRalSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRALsCfg *RalsJsonCfg if jsnRALsCfg, err = jsnCfg.RalsJsonCfg(); err != nil { return } return cfg.ralsCfg.loadFromJSONCfg(jsnRALsCfg) } // loadSchedulerCfg loads the Scheduler section of the configuration func (cfg *CGRConfig) loadSchedulerCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSchedCfg *SchedulerJsonCfg if jsnSchedCfg, err = jsnCfg.SchedulerJsonCfg(); err != nil { return } return cfg.schedulerCfg.loadFromJSONCfg(jsnSchedCfg) } // loadCdrsCfg loads the Cdrs section of the configuration func (cfg *CGRConfig) loadCdrsCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnCdrsCfg *CdrsJsonCfg if jsnCdrsCfg, err = jsnCfg.CdrsJsonCfg(); err != nil { return } return cfg.cdrsCfg.loadFromJSONCfg(jsnCdrsCfg) } // loadSessionSCfg loads the SessionS section of the configuration func (cfg *CGRConfig) loadSessionSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSessionSCfg *SessionSJsonCfg if jsnSessionSCfg, err = jsnCfg.SessionSJsonCfg(); err != nil { return } return cfg.sessionSCfg.loadFromJSONCfg(jsnSessionSCfg) } // loadFreeswitchAgentCfg loads the FreeswitchAgent section of the configuration func (cfg *CGRConfig) loadFreeswitchAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSmFsCfg *FreeswitchAgentJsonCfg if jsnSmFsCfg, err = jsnCfg.FreeswitchAgentJsonCfg(); err != nil { return } return cfg.fsAgentCfg.loadFromJSONCfg(jsnSmFsCfg) } // loadKamAgentCfg loads the KamAgent section of the configuration func (cfg *CGRConfig) loadKamAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnKamAgentCfg *KamAgentJsonCfg if jsnKamAgentCfg, err = jsnCfg.KamAgentJsonCfg(); err != nil { return } return cfg.kamAgentCfg.loadFromJSONCfg(jsnKamAgentCfg) } // loadAsteriskAgentCfg loads the AsteriskAgent section of the configuration func (cfg *CGRConfig) loadAsteriskAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSMAstCfg *AsteriskAgentJsonCfg if jsnSMAstCfg, err = jsnCfg.AsteriskAgentJsonCfg(); err != nil { return } return cfg.asteriskAgentCfg.loadFromJSONCfg(jsnSMAstCfg) } // loadDiameterAgentCfg loads the DiameterAgent section of the configuration func (cfg *CGRConfig) loadDiameterAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnDACfg *DiameterAgentJsonCfg if jsnDACfg, err = jsnCfg.DiameterAgentJsonCfg(); err != nil { return } return cfg.diameterAgentCfg.loadFromJSONCfg(jsnDACfg, cfg.generalCfg.RSRSep) } // loadRadiusAgentCfg loads the RadiusAgent section of the configuration func (cfg *CGRConfig) loadRadiusAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRACfg *RadiusAgentJsonCfg if jsnRACfg, err = jsnCfg.RadiusAgentJsonCfg(); err != nil { return } return cfg.radiusAgentCfg.loadFromJSONCfg(jsnRACfg, cfg.generalCfg.RSRSep) } // loadDNSAgentCfg loads the DNSAgent section of the configuration func (cfg *CGRConfig) loadDNSAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnDNSCfg *DNSAgentJsonCfg if jsnDNSCfg, err = jsnCfg.DNSAgentJsonCfg(); err != nil { return } return cfg.dnsAgentCfg.loadFromJSONCfg(jsnDNSCfg, cfg.generalCfg.RSRSep) } // loadHTTPAgentCfg loads the HttpAgent section of the configuration func (cfg *CGRConfig) loadHTTPAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnHTTPAgntCfg *[]*HttpAgentJsonCfg if jsnHTTPAgntCfg, err = jsnCfg.HttpAgentJsonCfg(); err != nil { return } return cfg.httpAgentCfg.loadFromJSONCfg(jsnHTTPAgntCfg, cfg.generalCfg.RSRSep) } // loadPrometheusAgentCfg loads the PrometheusAgent section of the configuration. func (cfg *CGRConfig) loadPrometheusAgentCfg(jsnCfg *CgrJsonCfg) error { jsnPACfg, err := jsnCfg.PrometheusAgentJsonCfg() if err != nil { return err } return cfg.prometheusAgentCfg.loadFromJSONCfg(jsnPACfg) } // loadAttributeSCfg loads the AttributeS section of the configuration func (cfg *CGRConfig) loadAttributeSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnAttributeSCfg *AttributeSJsonCfg if jsnAttributeSCfg, err = jsnCfg.AttributeServJsonCfg(); err != nil { return } return cfg.attributeSCfg.loadFromJSONCfg(jsnAttributeSCfg) } // loadChargerSCfg loads the ChargerS section of the configuration func (cfg *CGRConfig) loadChargerSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnChargerSCfg *ChargerSJsonCfg if jsnChargerSCfg, err = jsnCfg.ChargerServJsonCfg(); err != nil { return } return cfg.chargerSCfg.loadFromJSONCfg(jsnChargerSCfg) } // loadResourceSCfg loads the ResourceS section of the configuration func (cfg *CGRConfig) loadResourceSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRLSCfg *ResourceSJsonCfg if jsnRLSCfg, err = jsnCfg.ResourceSJsonCfg(); err != nil { return } return cfg.resourceSCfg.loadFromJSONCfg(jsnRLSCfg) } // loadStatSCfg loads the StatS section of the configuration func (cfg *CGRConfig) loadStatSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnStatSCfg *StatServJsonCfg if jsnStatSCfg, err = jsnCfg.StatSJsonCfg(); err != nil { return } return cfg.statsCfg.loadFromJSONCfg(jsnStatSCfg) } // loadTrendSCfg loads the TrendS section of the configuration func (cfg *CGRConfig) loadTrendSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnTrendSCfg *TrendsJsonCfg if jsnTrendSCfg, err = jsnCfg.TrendsJsonCfg(); err != nil { return } return cfg.trendsCfg.loadFromJSONCfg(jsnTrendSCfg) } // loadRankingSCfg loads the RankingS section of the configuration func (cfg *CGRConfig) loadRankingSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRankingSCfg *RankingsJsonCfg if jsnRankingSCfg, err = jsnCfg.RankingsJsonCfg(); err != nil { return } return cfg.rankingsCfg.loadFromJSONCfg(jsnRankingSCfg) } // loadThresholdSCfg loads the ThresholdS section of the configuration func (cfg *CGRConfig) loadThresholdSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnThresholdSCfg *ThresholdSJsonCfg if jsnThresholdSCfg, err = jsnCfg.ThresholdSJsonCfg(); err != nil { return } return cfg.thresholdSCfg.loadFromJSONCfg(jsnThresholdSCfg) } // loadRouteSCfg loads the RouteS section of the configuration func (cfg *CGRConfig) loadRouteSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRouteSCfg *RouteSJsonCfg if jsnRouteSCfg, err = jsnCfg.RouteSJsonCfg(); err != nil { return } return cfg.routeSCfg.loadFromJSONCfg(jsnRouteSCfg) } // loadMailerCfg loads the Mailer section of the configuration func (cfg *CGRConfig) loadMailerCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnMailerCfg *MailerJsonCfg if jsnMailerCfg, err = jsnCfg.MailerJsonCfg(); err != nil { return } return cfg.mailerCfg.loadFromJSONCfg(jsnMailerCfg) } // loadSureTaxCfg loads the SureTax section of the configuration func (cfg *CGRConfig) loadSureTaxCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSureTaxCfg *SureTaxJsonCfg if jsnSureTaxCfg, err = jsnCfg.SureTaxJsonCfg(); err != nil { return } return cfg.sureTaxCfg.loadFromJSONCfg(jsnSureTaxCfg) } // loadDispatcherSCfg loads the DispatcherS section of the configuration func (cfg *CGRConfig) loadDispatcherSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnDispatcherSCfg *DispatcherSJsonCfg if jsnDispatcherSCfg, err = jsnCfg.DispatcherSJsonCfg(); err != nil { return } return cfg.dispatcherSCfg.loadFromJSONCfg(jsnDispatcherSCfg) } // loadRegistrarCCfg loads the RegistrarC section of the configuration func (cfg *CGRConfig) loadRegistrarCCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnRegistrarCCfg *RegistrarCJsonCfgs if jsnRegistrarCCfg, err = jsnCfg.RegistrarCJsonCfgs(); err != nil { return } return cfg.registrarCCfg.loadFromJSONCfg(jsnRegistrarCCfg) } // loadLoaderCgrCfg loads the Loader section of the configuration func (cfg *CGRConfig) loadLoaderCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnLoaderCgrCfg *LoaderCfgJson if jsnLoaderCgrCfg, err = jsnCfg.LoaderCfgJson(); err != nil { return } return cfg.loaderCgrCfg.loadFromJSONCfg(jsnLoaderCgrCfg) } // loadMigratorCgrCfg loads the Migrator section of the configuration func (cfg *CGRConfig) loadMigratorCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnMigratorCgrCfg *MigratorCfgJson if jsnMigratorCgrCfg, err = jsnCfg.MigratorCfgJson(); err != nil { return } return cfg.migratorCgrCfg.loadFromJSONCfg(jsnMigratorCgrCfg) } // loadTLSCgrCfg loads the Tls section of the configuration func (cfg *CGRConfig) loadTLSCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnTLSCgrCfg *TlsJsonCfg if jsnTLSCgrCfg, err = jsnCfg.TlsCfgJson(); err != nil { return } return cfg.tlsCfg.loadFromJSONCfg(jsnTLSCgrCfg) } // loadAnalyzerCgrCfg loads the Analyzer section of the configuration func (cfg *CGRConfig) loadAnalyzerCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnAnalyzerCgrCfg *AnalyzerSJsonCfg if jsnAnalyzerCgrCfg, err = jsnCfg.AnalyzerCfgJson(); err != nil { return } return cfg.analyzerSCfg.loadFromJSONCfg(jsnAnalyzerCgrCfg) } // loadAPIBanCgrCfg loads the Analyzer section of the configuration func (cfg *CGRConfig) loadAPIBanCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnAPIBanCfg *APIBanJsonCfg if jsnAPIBanCfg, err = jsnCfg.ApiBanCfgJson(); err != nil { return } return cfg.apiBanCfg.loadFromJSONCfg(jsnAPIBanCfg) } func (cfg *CGRConfig) loadSentryPeerCgrCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSentryPeerCfg *SentryPeerJsonCfg if jsnSentryPeerCfg, err = jsnCfg.SentryPeerJson(); err != nil { return } return cfg.sentryPeerCfg.loadFromJSONCfg(jsnSentryPeerCfg) } // loadApierCfg loads the Apier section of the configuration func (cfg *CGRConfig) loadApierCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnApierCfg *ApierJsonCfg if jsnApierCfg, err = jsnCfg.ApierCfgJson(); err != nil { return } return cfg.apier.loadFromJSONCfg(jsnApierCfg) } // loadCoreSCfg loads the CoreS section of the configuration func (cfg *CGRConfig) loadCoreSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnCoreCfg *CoreSJsonCfg if jsnCoreCfg, err = jsnCfg.CoreSCfgJson(); err != nil { return } return cfg.coreSCfg.loadFromJSONCfg(jsnCoreCfg) } // loadErsCfg loads the Ers section of the configuration func (cfg *CGRConfig) loadErsCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnERsCfg *ERsJsonCfg if jsnERsCfg, err = jsnCfg.ERsJsonCfg(); err != nil { return } return cfg.ersCfg.loadFromJSONCfg(jsnERsCfg, cfg.templates, cfg.generalCfg.RSRSep, cfg.dfltEvRdr) } // loadEesCfg loads the Ees section of the configuration func (cfg *CGRConfig) loadEesCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnEEsCfg *EEsJsonCfg if jsnEEsCfg, err = jsnCfg.EEsJsonCfg(); err != nil { return } return cfg.eesCfg.loadFromJSONCfg(jsnEEsCfg, cfg.templates, cfg.generalCfg.RSRSep, cfg.dfltEvExp) } // loadSIPAgentCfg loads the sip_agent section of the configuration func (cfg *CGRConfig) loadSIPAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnSIPAgentCfg *SIPAgentJsonCfg if jsnSIPAgentCfg, err = jsnCfg.SIPAgentJsonCfg(); err != nil { return } return cfg.sipAgentCfg.loadFromJSONCfg(jsnSIPAgentCfg, cfg.generalCfg.RSRSep) } func (cfg *CGRConfig) loadJanusAgentCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnJanusAgentCfg *JanusAgentJsonCfg if jsnJanusAgentCfg, err = jsnCfg.JanusAgentCfgJson(); err != nil { return } return cfg.janusAgentCfg.loadFromJSONCfg(jsnJanusAgentCfg, cfg.generalCfg.RSRSep) } // loadTemplateSCfg loads the Template section of the configuration func (cfg *CGRConfig) loadTemplateSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnTemplateCfg map[string][]*FcTemplateJsonCfg if jsnTemplateCfg, err = jsnCfg.TemplateSJsonCfg(); err != nil { return } for k, val := range jsnTemplateCfg { if cfg.templates[k], err = FCTemplatesFromFCTemplatesJSONCfg(val, cfg.generalCfg.RSRSep); err != nil { return } } return } func (cfg *CGRConfig) loadConfigSCfg(jsnCfg *CgrJsonCfg) (err error) { var jsnConfigSCfg *ConfigSCfgJson if jsnConfigSCfg, err = jsnCfg.ConfigSJsonCfg(); err != nil { return } return cfg.configSCfg.loadFromJSONCfg(jsnConfigSCfg) } // loadIPsCfg loads the IPs section of the configuration. func (cfg *CGRConfig) loadIPsCfg(jsnCfg *CgrJsonCfg) error { jsnIPsCfg, err := jsnCfg.IPsJsonCfg() if err != nil { return err } return cfg.ipsCfg.loadFromJSONCfg(jsnIPsCfg) } // SureTaxCfg use locking to retrieve the configuration, possibility later for runtime reload func (cfg *CGRConfig) SureTaxCfg() *SureTaxCfg { cfg.lks[SURETAX_JSON].Lock() defer cfg.lks[SURETAX_JSON].Unlock() return cfg.sureTaxCfg } // DiameterAgentCfg returns the config for Diameter Agent func (cfg *CGRConfig) DiameterAgentCfg() *DiameterAgentCfg { cfg.lks[DA_JSN].Lock() defer cfg.lks[DA_JSN].Unlock() return cfg.diameterAgentCfg } // RadiusAgentCfg returns the config for Radius Agent func (cfg *CGRConfig) RadiusAgentCfg() *RadiusAgentCfg { cfg.lks[RA_JSN].Lock() defer cfg.lks[RA_JSN].Unlock() return cfg.radiusAgentCfg } // DNSAgentCfg returns the config for DNS Agent func (cfg *CGRConfig) DNSAgentCfg() *DNSAgentCfg { cfg.lks[DNSAgentJson].Lock() defer cfg.lks[DNSAgentJson].Unlock() return cfg.dnsAgentCfg } // PrometheusAgentCfg returns the config for Prometheus Agent func (cfg *CGRConfig) PrometheusAgentCfg() *PrometheusAgentCfg { cfg.lks[PrometheusAgentJSON].Lock() defer cfg.lks[PrometheusAgentJSON].Unlock() return cfg.prometheusAgentCfg } // AttributeSCfg returns the config for AttributeS func (cfg *CGRConfig) AttributeSCfg() *AttributeSCfg { cfg.lks[ATTRIBUTE_JSN].Lock() defer cfg.lks[ATTRIBUTE_JSN].Unlock() return cfg.attributeSCfg } // ChargerSCfg returns the config for ChargerS func (cfg *CGRConfig) ChargerSCfg() *ChargerSCfg { cfg.lks[ChargerSCfgJson].Lock() defer cfg.lks[ChargerSCfgJson].Unlock() return cfg.chargerSCfg } // ResourceSCfg returns the config for ResourceS func (cfg *CGRConfig) ResourceSCfg() *ResourceSConfig { // not done cfg.lks[RESOURCES_JSON].Lock() defer cfg.lks[RESOURCES_JSON].Unlock() return cfg.resourceSCfg } // StatSCfg returns the config for StatS func (cfg *CGRConfig) StatSCfg() *StatSCfg { // not done cfg.lks[STATS_JSON].Lock() defer cfg.lks[STATS_JSON].Unlock() return cfg.statsCfg } // TrendSCfg returns the config for TrendS func (cfg *CGRConfig) TrendSCfg() *TrendSCfg { cfg.lks[TRENDS_JSON].Lock() defer cfg.lks[TRENDS_JSON].Unlock() return cfg.trendsCfg } // RankingSCfg returns the config for RankingS func (cfg *CGRConfig) RankingSCfg() *RankingSCfg { cfg.lks[RANKINGS_JSON].Lock() defer cfg.lks[RANKINGS_JSON].Unlock() return cfg.rankingsCfg } // ThresholdSCfg returns the config for ThresholdS func (cfg *CGRConfig) ThresholdSCfg() *ThresholdSCfg { cfg.lks[THRESHOLDS_JSON].Lock() defer cfg.lks[THRESHOLDS_JSON].Unlock() return cfg.thresholdSCfg } // RouteSCfg returns the config for RouteS func (cfg *CGRConfig) RouteSCfg() *RouteSCfg { cfg.lks[RouteSJson].Lock() defer cfg.lks[RouteSJson].Unlock() return cfg.routeSCfg } // SessionSCfg returns the config for SessionS func (cfg *CGRConfig) SessionSCfg() *SessionSCfg { cfg.lks[SessionSJson].Lock() defer cfg.lks[SessionSJson].Unlock() return cfg.sessionSCfg } // FsAgentCfg returns the config for FsAgent func (cfg *CGRConfig) FsAgentCfg() *FsAgentCfg { cfg.lks[FreeSWITCHAgentJSN].Lock() defer cfg.lks[FreeSWITCHAgentJSN].Unlock() return cfg.fsAgentCfg } // KamAgentCfg returns the config for KamAgent func (cfg *CGRConfig) KamAgentCfg() *KamAgentCfg { cfg.lks[KamailioAgentJSN].Lock() defer cfg.lks[KamailioAgentJSN].Unlock() return cfg.kamAgentCfg } // AsteriskAgentCfg returns the config for AsteriskAgent func (cfg *CGRConfig) AsteriskAgentCfg() *AsteriskAgentCfg { cfg.lks[AsteriskAgentJSN].Lock() defer cfg.lks[AsteriskAgentJSN].Unlock() return cfg.asteriskAgentCfg } // HTTPAgentCfg returns the config for HttpAgent func (cfg *CGRConfig) HTTPAgentCfg() HTTPAgentCfgs { cfg.lks[HttpAgentJson].Lock() defer cfg.lks[HttpAgentJson].Unlock() return cfg.httpAgentCfg } // FilterSCfg returns the config for FilterS func (cfg *CGRConfig) FilterSCfg() *FilterSCfg { cfg.lks[FilterSjsn].Lock() defer cfg.lks[FilterSjsn].Unlock() return cfg.filterSCfg } // CacheCfg returns the config for Cache func (cfg *CGRConfig) CacheCfg() *CacheCfg { cfg.lks[CACHE_JSN].Lock() defer cfg.lks[CACHE_JSN].Unlock() return cfg.cacheCfg } // LoaderCgrCfg returns the config for cgr-loader func (cfg *CGRConfig) LoaderCgrCfg() *LoaderCgrCfg { cfg.lks[CgrLoaderCfgJson].Lock() defer cfg.lks[CgrLoaderCfgJson].Unlock() return cfg.loaderCgrCfg } // DispatcherSCfg returns the config for DispatcherS func (cfg *CGRConfig) DispatcherSCfg() *DispatcherSCfg { cfg.lks[DispatcherSJson].Lock() defer cfg.lks[DispatcherSJson].Unlock() return cfg.dispatcherSCfg } // RegistrarCCfg returns the config for RegistrarC func (cfg *CGRConfig) RegistrarCCfg() *RegistrarCCfgs { cfg.lks[DispatcherSJson].Lock() defer cfg.lks[DispatcherSJson].Unlock() return cfg.registrarCCfg } // MigratorCgrCfg returns the config for Migrator func (cfg *CGRConfig) MigratorCgrCfg() *MigratorCgrCfg { cfg.lks[CgrMigratorCfgJson].Lock() defer cfg.lks[CgrMigratorCfgJson].Unlock() return cfg.migratorCgrCfg } // SchedulerCfg returns the config for Scheduler func (cfg *CGRConfig) SchedulerCfg() *SchedulerCfg { cfg.lks[SCHEDULER_JSN].Lock() defer cfg.lks[SCHEDULER_JSN].Unlock() return cfg.schedulerCfg } // DataDbCfg returns the config for DataDb func (cfg *CGRConfig) DataDbCfg() *DataDbCfg { cfg.lks[DATADB_JSN].Lock() defer cfg.lks[DATADB_JSN].Unlock() return cfg.dataDbCfg } // StorDbCfg returns the config for StorDb func (cfg *CGRConfig) StorDbCfg() *StorDbCfg { cfg.lks[STORDB_JSN].Lock() defer cfg.lks[STORDB_JSN].Unlock() return cfg.storDbCfg } // GeneralCfg returns the General config section func (cfg *CGRConfig) GeneralCfg() *GeneralCfg { cfg.lks[GENERAL_JSN].Lock() defer cfg.lks[GENERAL_JSN].Unlock() return cfg.generalCfg } // TLSCfg returns the config for Tls func (cfg *CGRConfig) TLSCfg() *TLSCfg { cfg.lks[TlsCfgJson].Lock() defer cfg.lks[TlsCfgJson].Unlock() return cfg.tlsCfg } // ListenCfg returns the server Listen config func (cfg *CGRConfig) ListenCfg() *ListenCfg { cfg.lks[LISTEN_JSN].Lock() defer cfg.lks[LISTEN_JSN].Unlock() return cfg.listenCfg } // HTTPCfg returns the config for HTTP func (cfg *CGRConfig) HTTPCfg() *HTTPCfg { cfg.lks[HTTP_JSN].Lock() defer cfg.lks[HTTP_JSN].Unlock() return cfg.httpCfg } // RalsCfg returns the config for Ral Service func (cfg *CGRConfig) RalsCfg() *RalsCfg { cfg.lks[RALS_JSN].Lock() defer cfg.lks[RALS_JSN].Unlock() return cfg.ralsCfg } // CdrsCfg returns the config for CDR Server func (cfg *CGRConfig) CdrsCfg() *CdrsCfg { cfg.lks[CDRS_JSN].Lock() defer cfg.lks[CDRS_JSN].Unlock() return cfg.cdrsCfg } // MailerCfg returns the config for Mailer func (cfg *CGRConfig) MailerCfg() *MailerCfg { cfg.lks[MAILER_JSN].Lock() defer cfg.lks[MAILER_JSN].Unlock() return cfg.mailerCfg } // AnalyzerSCfg returns the config for AnalyzerS func (cfg *CGRConfig) AnalyzerSCfg() *AnalyzerSCfg { cfg.lks[AnalyzerCfgJson].Lock() defer cfg.lks[AnalyzerCfgJson].Unlock() return cfg.analyzerSCfg } // ApierCfg reads the Apier configuration func (cfg *CGRConfig) ApierCfg() *ApierCfg { cfg.lks[ApierS].Lock() defer cfg.lks[ApierS].Unlock() return cfg.apier } // ERsCfg reads the EventReader configuration func (cfg *CGRConfig) ERsCfg() *ERsCfg { cfg.lks[ERsJson].RLock() defer cfg.lks[ERsJson].RUnlock() return cfg.ersCfg } // EEsCfg reads the EventExporter configuration func (cfg *CGRConfig) EEsCfg() *EEsCfg { cfg.lks[EEsJson].RLock() defer cfg.lks[EEsJson].RUnlock() return cfg.eesCfg } // EEsNoLksCfg reads the EventExporter configuration without locks func (cfg *CGRConfig) EEsNoLksCfg() *EEsCfg { return cfg.eesCfg } // SIPAgentCfg reads the SIPAgent configuration func (cfg *CGRConfig) SIPAgentCfg() *SIPAgentCfg { cfg.lks[SIPAgentJson].Lock() defer cfg.lks[SIPAgentJson].Unlock() return cfg.sipAgentCfg } // JanusAgentCfg reads the JanusAgent configuration func (cfg *CGRConfig) JanusAgentCfg() *JanusAgentCfg { cfg.lks[JanusAgentJson].Lock() defer cfg.lks[JanusAgentJson].Unlock() return cfg.janusAgentCfg } // RPCConns reads the RPCConns configuration func (cfg *CGRConfig) RPCConns() RPCConns { cfg.lks[RPCConnsJsonName].RLock() defer cfg.lks[RPCConnsJsonName].RUnlock() return cfg.rpcConns } // TemplatesCfg returns the config for templates func (cfg *CGRConfig) TemplatesCfg() FcTemplates { cfg.lks[TemplatesJson].Lock() defer cfg.lks[TemplatesJson].Unlock() return cfg.templates } // ConfigSCfg returns the configs configuration func (cfg *CGRConfig) ConfigSCfg() *ConfigSCfg { cfg.lks[ConfigSJson].RLock() defer cfg.lks[ConfigSJson].RUnlock() return cfg.configSCfg } // APIBanCfg reads the ApiBan configuration func (cfg *CGRConfig) APIBanCfg() *APIBanCfg { cfg.lks[APIBanCfgJson].Lock() defer cfg.lks[APIBanCfgJson].Unlock() return cfg.apiBanCfg } func (cfg *CGRConfig) SentryPeerCfg() *SentryPeerCfg { cfg.lks[SentryPeerCfgJson].Lock() defer cfg.lks[SentryPeerCfgJson].Unlock() return cfg.sentryPeerCfg } // CoreSCfg reads the CoreS configuration func (cfg *CGRConfig) CoreSCfg() *CoreSCfg { cfg.lks[CoreSCfgJson].Lock() defer cfg.lks[CoreSCfgJson].Unlock() return cfg.coreSCfg } // IPsCfg returns the IPs configuration. func (cfg *CGRConfig) IPsCfg() *IPsCfg { cfg.lks[IPsJSON].Lock() defer cfg.lks[IPsJSON].Unlock() return cfg.ipsCfg } // GetReloadChan returns the reload chanel for the given section func (cfg *CGRConfig) GetReloadChan(sectID string) chan struct{} { return cfg.rldChans[sectID] } func (cfg *CGRConfig) rLockSections() { for _, lk := range cfg.lks { lk.RLock() } } func (cfg *CGRConfig) rUnlockSections() { for _, lk := range cfg.lks { lk.RUnlock() } } func (cfg *CGRConfig) lockSections() { for _, lk := range cfg.lks { lk.Lock() } } func (cfg *CGRConfig) unlockSections() { for _, lk := range cfg.lks { lk.Unlock() } } // RLocks will read-lock locks with IDs. // User needs to know what he is doing since this can panic func (cfg *CGRConfig) RLocks(lkIDs ...string) { for _, lkID := range lkIDs { cfg.lks[lkID].RLock() } } // RUnlocks will read-unlock locks with IDs. // User needs to know what he is doing since this can panic func (cfg *CGRConfig) RUnlocks(lkIDs ...string) { for _, lkID := range lkIDs { cfg.lks[lkID].RUnlock() } } // LockSections will lock the given sections // User needs to know what he is doing since this can panic func (cfg *CGRConfig) LockSections(lkIDs ...string) { for _, lkID := range lkIDs { cfg.lks[lkID].Lock() } } // UnlockSections will unlock the given sections // User needs to know what he is doing since this can panic func (cfg *CGRConfig) UnlockSections(lkIDs ...string) { for _, lkID := range lkIDs { cfg.lks[lkID].Unlock() } } func (cfg *CGRConfig) getLoadFunctions() map[string]func(*CgrJsonCfg) error { return map[string]func(*CgrJsonCfg) error{ GENERAL_JSN: cfg.loadGeneralCfg, DATADB_JSN: cfg.loadDataDBCfg, STORDB_JSN: cfg.loadStorDBCfg, LISTEN_JSN: cfg.loadListenCfg, TlsCfgJson: cfg.loadTLSCgrCfg, HTTP_JSN: cfg.loadHTTPCfg, SCHEDULER_JSN: cfg.loadSchedulerCfg, CACHE_JSN: cfg.loadCacheCfg, FilterSjsn: cfg.loadFilterSCfg, RALS_JSN: cfg.loadRalSCfg, CDRS_JSN: cfg.loadCdrsCfg, ERsJson: cfg.loadErsCfg, EEsJson: cfg.loadEesCfg, SessionSJson: cfg.loadSessionSCfg, AsteriskAgentJSN: cfg.loadAsteriskAgentCfg, FreeSWITCHAgentJSN: cfg.loadFreeswitchAgentCfg, KamailioAgentJSN: cfg.loadKamAgentCfg, DA_JSN: cfg.loadDiameterAgentCfg, RA_JSN: cfg.loadRadiusAgentCfg, HttpAgentJson: cfg.loadHTTPAgentCfg, DNSAgentJson: cfg.loadDNSAgentCfg, PrometheusAgentJSON: cfg.loadPrometheusAgentCfg, ATTRIBUTE_JSN: cfg.loadAttributeSCfg, ChargerSCfgJson: cfg.loadChargerSCfg, RESOURCES_JSON: cfg.loadResourceSCfg, STATS_JSON: cfg.loadStatSCfg, TRENDS_JSON: cfg.loadTrendSCfg, RANKINGS_JSON: cfg.loadRankingSCfg, THRESHOLDS_JSON: cfg.loadThresholdSCfg, RouteSJson: cfg.loadRouteSCfg, MAILER_JSN: cfg.loadMailerCfg, SURETAX_JSON: cfg.loadSureTaxCfg, CgrLoaderCfgJson: cfg.loadLoaderCgrCfg, CgrMigratorCfgJson: cfg.loadMigratorCgrCfg, DispatcherSJson: cfg.loadDispatcherSCfg, RegistrarCJson: cfg.loadRegistrarCCfg, AnalyzerCfgJson: cfg.loadAnalyzerCgrCfg, ApierS: cfg.loadApierCfg, RPCConnsJsonName: cfg.loadRPCConns, SIPAgentJson: cfg.loadSIPAgentCfg, JanusAgentJson: cfg.loadJanusAgentCfg, TemplatesJson: cfg.loadTemplateSCfg, ConfigSJson: cfg.loadConfigSCfg, APIBanCfgJson: cfg.loadAPIBanCgrCfg, SentryPeerCfgJson: cfg.loadSentryPeerCgrCfg, CoreSCfgJson: cfg.loadCoreSCfg, IPsJSON: cfg.loadIPsCfg, } } func (cfg *CGRConfig) loadCfgWithLocks(path, section string) (err error) { var loadFuncs []func(*CgrJsonCfg) error loadMap := cfg.getLoadFunctions() if section == utils.EmptyString || section == utils.MetaAll { for _, sec := range sortedCfgSections { cfg.lks[sec].Lock() defer cfg.lks[sec].Unlock() loadFuncs = append(loadFuncs, loadMap[sec]) } } else if fnct, has := loadMap[section]; !has { return fmt.Errorf("Invalid section: <%s>", section) } else { cfg.lks[section].Lock() defer cfg.lks[section].Unlock() loadFuncs = append(loadFuncs, fnct) } return cfg.loadConfigFromPath(path, loadFuncs, false) } func (*CGRConfig) loadConfigFromReader(rdr io.Reader, loadFuncs []func(jsnCfg *CgrJsonCfg) error, envOff bool) (err error) { jsnCfg := new(CgrJsonCfg) var rjr *RjReader if rjr, err = NewRjReader(rdr); err != nil { return } rjr.envOff = envOff defer rjr.Close() // make sure we make the buffer nil if err = rjr.Decode(jsnCfg); err != nil { return } for _, loadFunc := range loadFuncs { if err = loadFunc(jsnCfg); err != nil { return } } return } // Reads all .json files out of a folder/subfolders and loads them up in lexical order func (cfg *CGRConfig) loadConfigFromPath(path string, loadFuncs []func(jsnCfg *CgrJsonCfg) error, envOff bool) (err error) { if utils.IsURL(path) { return cfg.loadConfigFromHTTP(path, loadFuncs) // prefix protocol } var fi os.FileInfo if fi, err = os.Stat(path); err != nil { if os.IsNotExist(err) { return utils.ErrPathNotReachable(path) } return } else if !fi.IsDir() && path != utils.ConfigPath { // If config dir defined, needs to exist, not checking for default return fmt.Errorf("path: %s not a directory", path) } // safe to assume that path is a directory return cfg.loadConfigFromFolder(path, loadFuncs, envOff) } func (cfg *CGRConfig) loadConfigFromFolder(cfgDir string, loadFuncs []func(jsnCfg *CgrJsonCfg) error, envOff bool) (err error) { jsonFilesFound := false if err = filepath.Walk(cfgDir, func(path string, info os.FileInfo, err error) (werr error) { if !info.IsDir() || isHidden(info.Name()) { // also ignore hidden files and folders return } var cfgFiles []string if cfgFiles, werr = filepath.Glob(filepath.Join(path, "*.json")); werr != nil { return } if cfgFiles == nil { // No need of processing further since there are no config files in the folder return } if !jsonFilesFound { jsonFilesFound = true } for _, jsonFilePath := range cfgFiles { if werr = cfg.loadConfigFromFile(jsonFilePath, loadFuncs, envOff); werr != nil { return } } return }); err != nil { return } if !jsonFilesFound { return fmt.Errorf("No config file found on path %s", cfgDir) } return } // loadConfigFromFile loads the config from a file // extracted from a loadConfigFromFolder in order to test all cases func (cfg *CGRConfig) loadConfigFromFile(jsonFilePath string, loadFuncs []func(jsnCfg *CgrJsonCfg) error, envOff bool) (err error) { var cfgFile *os.File cfgFile, err = os.Open(jsonFilePath) if err != nil { return } err = cfg.loadConfigFromReader(cfgFile, loadFuncs, envOff) cfgFile.Close() if err != nil { err = fmt.Errorf("file <%s>:%s", jsonFilePath, err.Error()) } return } func (cfg *CGRConfig) loadConfigFromHTTP(urlPaths string, loadFuncs []func(jsnCfg *CgrJsonCfg) error) (err error) { for _, urlPath := range strings.Split(urlPaths, utils.InfieldSep) { var myClient = &http.Client{ Timeout: CgrConfig().GeneralCfg().ReplyTimeout, } var cfgReq *http.Response cfgReq, err = myClient.Get(urlPath) if err != nil { return utils.ErrPathNotReachable(urlPath) } err = cfg.loadConfigFromReader(cfgReq.Body, loadFuncs, false) cfgReq.Body.Close() if err != nil { err = fmt.Errorf("url <%s>:%s", urlPath, err.Error()) return } } return } // populates the config locks and the reload channels func (cfg *CGRConfig) initChanels() { cfg.lks = make(map[string]*sync.RWMutex) cfg.rldChans = make(map[string]chan struct{}) for _, section := range sortedCfgSections { cfg.lks[section] = new(sync.RWMutex) cfg.rldChans[section] = make(chan struct{}) } } func (cfg *CGRConfig) loadCfgFromJSONWithLocks(rdr io.Reader, sections []string) (err error) { var loadFuncs []func(*CgrJsonCfg) error loadMap := cfg.getLoadFunctions() for _, section := range sections { fnct, has := loadMap[section] if !has { return fmt.Errorf("Invalid section: <%s>", section) } cfg.lks[section].Lock() defer cfg.lks[section].Unlock() loadFuncs = append(loadFuncs, fnct) } return cfg.loadConfigFromReader(rdr, loadFuncs, false) } // reloadSections sends a signal to the reload channel for the needed sections // the list of sections should be always valid because we load the config first with this list func (cfg *CGRConfig) reloadSections(sections ...string) { subsystemsThatNeedDataDB := utils.NewStringSet([]string{DATADB_JSN, SCHEDULER_JSN, RALS_JSN, CDRS_JSN, SessionSJson, ATTRIBUTE_JSN, ChargerSCfgJson, RESOURCES_JSON, STATS_JSON, THRESHOLDS_JSON, RouteSJson, DispatcherSJson, ApierS, IPsJSON, }) subsystemsThatNeedStorDB := utils.NewStringSet([]string{STORDB_JSN, RALS_JSN, CDRS_JSN, ApierS}) needsDataDB := false needsStorDB := false for _, section := range sections { if !needsDataDB && subsystemsThatNeedDataDB.Has(section) { needsDataDB = true cfg.rldChans[DATADB_JSN] <- struct{}{} // reload datadb before } if !needsStorDB && subsystemsThatNeedStorDB.Has(section) { needsStorDB = true cfg.rldChans[STORDB_JSN] <- struct{}{} // reload stordb before } if needsDataDB && needsStorDB { break } } runtime.Gosched() for _, section := range sections { switch section { case ConfigSJson: case GENERAL_JSN: // nothing to reload case RPCConnsJsonName: // nothing to reload cfg.rldChans[RPCConnsJsonName] <- struct{}{} case DATADB_JSN: // reloaded before case STORDB_JSN: // reloaded before case LISTEN_JSN: case CACHE_JSN: case FilterSjsn: case MAILER_JSN: case SURETAX_JSON: case CgrLoaderCfgJson: case CgrMigratorCfgJson: case TemplatesJson: case TlsCfgJson: // nothing to reload case APIBanCfgJson: // nothing to reload case SentryPeerCfgJson: case CoreSCfgJson: // nothing to reload case HTTP_JSN: cfg.rldChans[HTTP_JSN] <- struct{}{} case SCHEDULER_JSN: cfg.rldChans[SCHEDULER_JSN] <- struct{}{} case RALS_JSN: cfg.rldChans[RALS_JSN] <- struct{}{} case CDRS_JSN: cfg.rldChans[CDRS_JSN] <- struct{}{} case ERsJson: cfg.rldChans[ERsJson] <- struct{}{} case SessionSJson: cfg.rldChans[SessionSJson] <- struct{}{} case AsteriskAgentJSN: cfg.rldChans[AsteriskAgentJSN] <- struct{}{} case FreeSWITCHAgentJSN: cfg.rldChans[FreeSWITCHAgentJSN] <- struct{}{} case KamailioAgentJSN: cfg.rldChans[KamailioAgentJSN] <- struct{}{} case DA_JSN: cfg.rldChans[DA_JSN] <- struct{}{} case RA_JSN: cfg.rldChans[RA_JSN] <- struct{}{} case HttpAgentJson: cfg.rldChans[HttpAgentJson] <- struct{}{} case DNSAgentJson: cfg.rldChans[DNSAgentJson] <- struct{}{} case PrometheusAgentJSON: cfg.rldChans[PrometheusAgentJSON] <- struct{}{} case ATTRIBUTE_JSN: cfg.rldChans[ATTRIBUTE_JSN] <- struct{}{} case ChargerSCfgJson: cfg.rldChans[ChargerSCfgJson] <- struct{}{} case RESOURCES_JSON: cfg.rldChans[RESOURCES_JSON] <- struct{}{} case STATS_JSON: cfg.rldChans[STATS_JSON] <- struct{}{} case TRENDS_JSON: cfg.rldChans[TRENDS_JSON] <- struct{}{} case RANKINGS_JSON: cfg.rldChans[RANKINGS_JSON] <- struct{}{} case THRESHOLDS_JSON: cfg.rldChans[THRESHOLDS_JSON] <- struct{}{} case RouteSJson: cfg.rldChans[RouteSJson] <- struct{}{} case JanusAgentJson: cfg.rldChans[JanusAgentJson] <- struct{}{} case DispatcherSJson: cfg.rldChans[DispatcherSJson] <- struct{}{} case AnalyzerCfgJson: cfg.rldChans[AnalyzerCfgJson] <- struct{}{} case ApierS: cfg.rldChans[ApierS] <- struct{}{} case EEsJson: cfg.rldChans[EEsJson] <- struct{}{} case SIPAgentJson: cfg.rldChans[SIPAgentJson] <- struct{}{} case RegistrarCJson: cfg.rldChans[RegistrarCJson] <- struct{}{} case IPsJSON: cfg.rldChans[IPsJSON] <- struct{}{} } } } // AsMapInterface returns the config as a map[string]any func (cfg *CGRConfig) AsMapInterface(separator string) (mp map[string]any) { return map[string]any{ HttpAgentJson: cfg.httpAgentCfg.AsMapInterface(separator), RPCConnsJsonName: cfg.rpcConns.AsMapInterface(), GENERAL_JSN: cfg.generalCfg.AsMapInterface(), DATADB_JSN: cfg.dataDbCfg.AsMapInterface(), STORDB_JSN: cfg.storDbCfg.AsMapInterface(), TlsCfgJson: cfg.tlsCfg.AsMapInterface(), CACHE_JSN: cfg.cacheCfg.AsMapInterface(), LISTEN_JSN: cfg.listenCfg.AsMapInterface(), HTTP_JSN: cfg.httpCfg.AsMapInterface(), FilterSjsn: cfg.filterSCfg.AsMapInterface(), RALS_JSN: cfg.ralsCfg.AsMapInterface(), SCHEDULER_JSN: cfg.schedulerCfg.AsMapInterface(), CDRS_JSN: cfg.cdrsCfg.AsMapInterface(), SessionSJson: cfg.sessionSCfg.AsMapInterface(), FreeSWITCHAgentJSN: cfg.fsAgentCfg.AsMapInterface(separator), KamailioAgentJSN: cfg.kamAgentCfg.AsMapInterface(), AsteriskAgentJSN: cfg.asteriskAgentCfg.AsMapInterface(), DA_JSN: cfg.diameterAgentCfg.AsMapInterface(separator), RA_JSN: cfg.radiusAgentCfg.AsMapInterface(separator), DNSAgentJson: cfg.dnsAgentCfg.AsMapInterface(separator), PrometheusAgentJSON: cfg.prometheusAgentCfg.AsMapInterface(), ATTRIBUTE_JSN: cfg.attributeSCfg.AsMapInterface(), ChargerSCfgJson: cfg.chargerSCfg.AsMapInterface(), RESOURCES_JSON: cfg.resourceSCfg.AsMapInterface(), STATS_JSON: cfg.statsCfg.AsMapInterface(), TRENDS_JSON: cfg.trendsCfg.AsMapInterface(), RANKINGS_JSON: cfg.rankingsCfg.AsMapInterface(), THRESHOLDS_JSON: cfg.thresholdSCfg.AsMapInterface(), RouteSJson: cfg.routeSCfg.AsMapInterface(), SURETAX_JSON: cfg.sureTaxCfg.AsMapInterface(separator), DispatcherSJson: cfg.dispatcherSCfg.AsMapInterface(), RegistrarCJson: cfg.registrarCCfg.AsMapInterface(), CgrLoaderCfgJson: cfg.loaderCgrCfg.AsMapInterface(), CgrMigratorCfgJson: cfg.migratorCgrCfg.AsMapInterface(), MAILER_JSN: cfg.mailerCfg.AsMapInterface(), AnalyzerCfgJson: cfg.analyzerSCfg.AsMapInterface(), ApierS: cfg.apier.AsMapInterface(), ERsJson: cfg.ersCfg.AsMapInterface(separator), APIBanCfgJson: cfg.apiBanCfg.AsMapInterface(), SentryPeerCfgJson: cfg.sentryPeerCfg.AsMapInterface(), EEsJson: cfg.eesCfg.AsMapInterface(separator), SIPAgentJson: cfg.sipAgentCfg.AsMapInterface(separator), TemplatesJson: cfg.templates.AsMapInterface(separator), ConfigSJson: cfg.configSCfg.AsMapInterface(), CoreSCfgJson: cfg.coreSCfg.AsMapInterface(), IPsJSON: cfg.ipsCfg.AsMapInterface(), } } // ReloadArgs the API params for V1ReloadConfig type ReloadArgs struct { APIOpts map[string]any Tenant string Path string Section string DryRun bool } // V1ReloadConfig reloads the configuration func (cfg *CGRConfig) V1ReloadConfig(ctx *context.Context, args *ReloadArgs, reply *string) (err error) { if missing := utils.MissingStructFields(args, []string{"Path"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } cfgV := cfg if args.DryRun { cfgV = cfg.Clone() } cfgV.reloadDPCache(args.Section) if err = cfgV.loadCfgWithLocks(args.Path, args.Section); err != nil { return } // lock all sections cfgV.rLockSections() err = cfgV.checkConfigSanity() cfgV.rUnlockSections() // unlock before checking the error if err != nil { return } if !args.DryRun { if args.Section == utils.EmptyString || args.Section == utils.MetaAll { cfgV.reloadSections(sortedCfgSections...) } else { cfgV.reloadSections(args.Section) } } *reply = utils.OK return } // SectionWithAPIOpts the API params for GetConfig type SectionWithAPIOpts struct { APIOpts map[string]any Tenant string Section string } // V1GetConfig will retrieve from CGRConfig a section func (cfg *CGRConfig) V1GetConfig(ctx *context.Context, args *SectionWithAPIOpts, reply *map[string]any) (err error) { args.Section = utils.FirstNonEmpty(args.Section, utils.MetaAll) cfg.cacheDPMux.RLock() if mp, has := cfg.cacheDP[args.Section]; has && mp != nil { *reply = mp cfg.cacheDPMux.RUnlock() return } cfg.cacheDPMux.RUnlock() defer func() { if err != nil { return } cfg.cacheDPMux.Lock() cfg.cacheDP[args.Section] = *reply cfg.cacheDPMux.Unlock() }() var mp any switch args.Section { case utils.MetaAll: *reply = cfg.AsMapInterface(cfg.GeneralCfg().RSRSep) return case GENERAL_JSN: mp = cfg.GeneralCfg().AsMapInterface() case DATADB_JSN: mp = cfg.DataDbCfg().AsMapInterface() case STORDB_JSN: mp = cfg.StorDbCfg().AsMapInterface() case TlsCfgJson: mp = cfg.TLSCfg().AsMapInterface() case CACHE_JSN: mp = cfg.CacheCfg().AsMapInterface() case LISTEN_JSN: mp = cfg.ListenCfg().AsMapInterface() case HTTP_JSN: mp = cfg.HTTPCfg().AsMapInterface() case FilterSjsn: mp = cfg.FilterSCfg().AsMapInterface() case RALS_JSN: mp = cfg.RalsCfg().AsMapInterface() case SCHEDULER_JSN: mp = cfg.SchedulerCfg().AsMapInterface() case CDRS_JSN: mp = cfg.CdrsCfg().AsMapInterface() case SessionSJson: mp = cfg.SessionSCfg().AsMapInterface() case FreeSWITCHAgentJSN: mp = cfg.FsAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case KamailioAgentJSN: mp = cfg.KamAgentCfg().AsMapInterface() case AsteriskAgentJSN: mp = cfg.AsteriskAgentCfg().AsMapInterface() case DA_JSN: mp = cfg.DiameterAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case RA_JSN: mp = cfg.RadiusAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case DNSAgentJson: mp = cfg.DNSAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case PrometheusAgentJSON: mp = cfg.PrometheusAgentCfg().AsMapInterface() case ATTRIBUTE_JSN: mp = cfg.AttributeSCfg().AsMapInterface() case ChargerSCfgJson: mp = cfg.ChargerSCfg().AsMapInterface() case RESOURCES_JSON: mp = cfg.ResourceSCfg().AsMapInterface() case STATS_JSON: mp = cfg.StatSCfg().AsMapInterface() case TRENDS_JSON: mp = cfg.TrendSCfg().AsMapInterface() case RANKINGS_JSON: mp = cfg.RankingSCfg().AsMapInterface() case THRESHOLDS_JSON: mp = cfg.ThresholdSCfg().AsMapInterface() case RouteSJson: mp = cfg.RouteSCfg().AsMapInterface() case SURETAX_JSON: mp = cfg.SureTaxCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case DispatcherSJson: mp = cfg.DispatcherSCfg().AsMapInterface() case RegistrarCJson: mp = cfg.RegistrarCCfg().AsMapInterface() case CgrLoaderCfgJson: mp = cfg.LoaderCgrCfg().AsMapInterface() case CgrMigratorCfgJson: mp = cfg.MigratorCgrCfg().AsMapInterface() case ApierS: mp = cfg.ApierCfg().AsMapInterface() case EEsJson: mp = cfg.EEsCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case ERsJson: mp = cfg.ERsCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case RPCConnsJsonName: mp = cfg.RPCConns().AsMapInterface() case SIPAgentJson: mp = cfg.SIPAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case TemplatesJson: mp = cfg.TemplatesCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case ConfigSJson: mp = cfg.ConfigSCfg().AsMapInterface() case APIBanCfgJson: mp = cfg.APIBanCfg().AsMapInterface() case SentryPeerCfgJson: mp = cfg.SentryPeerCfg().AsMapInterface() case HttpAgentJson: mp = cfg.HTTPAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case MAILER_JSN: mp = cfg.MailerCfg().AsMapInterface() case AnalyzerCfgJson: mp = cfg.AnalyzerSCfg().AsMapInterface() case CoreSCfgJson: mp = cfg.CoreSCfg().AsMapInterface() case IPsJSON: mp = cfg.IPsCfg().AsMapInterface() default: return errors.New("Invalid section") } *reply = map[string]any{args.Section: mp} return } // SetConfigArgs the API params for V1SetConfig type SetConfigArgs struct { APIOpts map[string]any Tenant string Config map[string]any DryRun bool } // V1SetConfig reloads the sections of config func (cfg *CGRConfig) V1SetConfig(ctx *context.Context, args *SetConfigArgs, reply *string) (err error) { if len(args.Config) == 0 { *reply = utils.OK return } sections := make([]string, 0, len(args.Config)) for section := range args.Config { sections = append(sections, section) } var b []byte if b, err = json.Marshal(args.Config); err != nil { return } cfgV := cfg if args.DryRun { cfgV = cfg.Clone() } cfgV.reloadDPCache(sections...) if err = cfgV.loadCfgFromJSONWithLocks(bytes.NewBuffer(b), sections); err != nil { return } // lock all sections cfgV.rLockSections() err = cfgV.checkConfigSanity() cfgV.rUnlockSections() // unlock before checking the error if err != nil { return } if !args.DryRun { cfgV.reloadSections(sections...) } *reply = utils.OK return } // V1GetConfigAsJSON will retrieve from CGRConfig a section as a string func (cfg *CGRConfig) V1GetConfigAsJSON(ctx *context.Context, args *SectionWithAPIOpts, reply *string) (err error) { args.Section = utils.FirstNonEmpty(args.Section, utils.MetaAll) cfg.cacheDPMux.RLock() if mp, has := cfg.cacheDP[args.Section]; has && mp != nil { *reply = utils.ToJSON(mp) cfg.cacheDPMux.RUnlock() return } cfg.cacheDPMux.RUnlock() var rplyMap utils.MapStorage defer func() { if err != nil { return } cfg.cacheDPMux.Lock() cfg.cacheDP[args.Section] = rplyMap cfg.cacheDPMux.Unlock() }() var mp any switch args.Section { case utils.MetaAll: rplyMap = cfg.AsMapInterface(cfg.GeneralCfg().RSRSep) *reply = utils.ToJSON(rplyMap) return case GENERAL_JSN: mp = cfg.GeneralCfg().AsMapInterface() case DATADB_JSN: mp = cfg.DataDbCfg().AsMapInterface() case STORDB_JSN: mp = cfg.StorDbCfg().AsMapInterface() case TlsCfgJson: mp = cfg.TLSCfg().AsMapInterface() case CACHE_JSN: mp = cfg.CacheCfg().AsMapInterface() case LISTEN_JSN: mp = cfg.ListenCfg().AsMapInterface() case HTTP_JSN: mp = cfg.HTTPCfg().AsMapInterface() case FilterSjsn: mp = cfg.FilterSCfg().AsMapInterface() case RALS_JSN: mp = cfg.RalsCfg().AsMapInterface() case SCHEDULER_JSN: mp = cfg.SchedulerCfg().AsMapInterface() case CDRS_JSN: mp = cfg.CdrsCfg().AsMapInterface() case SessionSJson: mp = cfg.SessionSCfg().AsMapInterface() case FreeSWITCHAgentJSN: mp = cfg.FsAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case KamailioAgentJSN: mp = cfg.KamAgentCfg().AsMapInterface() case AsteriskAgentJSN: mp = cfg.AsteriskAgentCfg().AsMapInterface() case DA_JSN: mp = cfg.DiameterAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case RA_JSN: mp = cfg.RadiusAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case DNSAgentJson: mp = cfg.DNSAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case JanusAgentJson: mp = cfg.JanusAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case PrometheusAgentJSON: mp = cfg.PrometheusAgentCfg().AsMapInterface() case ATTRIBUTE_JSN: mp = cfg.AttributeSCfg().AsMapInterface() case ChargerSCfgJson: mp = cfg.ChargerSCfg().AsMapInterface() case RESOURCES_JSON: mp = cfg.ResourceSCfg().AsMapInterface() case STATS_JSON: mp = cfg.StatSCfg().AsMapInterface() case TRENDS_JSON: mp = cfg.TrendSCfg().AsMapInterface() case RANKINGS_JSON: mp = cfg.RankingSCfg().AsMapInterface() case THRESHOLDS_JSON: mp = cfg.ThresholdSCfg().AsMapInterface() case RouteSJson: mp = cfg.RouteSCfg().AsMapInterface() case SURETAX_JSON: mp = cfg.SureTaxCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case DispatcherSJson: mp = cfg.DispatcherSCfg().AsMapInterface() case RegistrarCJson: mp = cfg.RegistrarCCfg().AsMapInterface() case CgrLoaderCfgJson: mp = cfg.LoaderCgrCfg().AsMapInterface() case CgrMigratorCfgJson: mp = cfg.MigratorCgrCfg().AsMapInterface() case ApierS: mp = cfg.ApierCfg().AsMapInterface() case EEsJson: mp = cfg.EEsCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case ERsJson: mp = cfg.ERsCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case SIPAgentJson: mp = cfg.SIPAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case ConfigSJson: mp = cfg.ConfigSCfg().AsMapInterface() case APIBanCfgJson: mp = cfg.APIBanCfg().AsMapInterface() case SentryPeerCfgJson: mp = cfg.SentryPeerCfg().AsMapInterface() case RPCConnsJsonName: mp = cfg.RPCConns().AsMapInterface() case TemplatesJson: mp = cfg.TemplatesCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case HttpAgentJson: mp = cfg.HTTPAgentCfg().AsMapInterface(cfg.GeneralCfg().RSRSep) case MAILER_JSN: mp = cfg.MailerCfg().AsMapInterface() case AnalyzerCfgJson: mp = cfg.AnalyzerSCfg().AsMapInterface() case CoreSCfgJson: mp = cfg.CoreSCfg().AsMapInterface() case IPsJSON: mp = cfg.IPsCfg().AsMapInterface() default: return errors.New("Invalid section") } rplyMap = map[string]any{args.Section: mp} *reply = utils.ToJSON(rplyMap) return } // SetConfigFromJSONArgs the API params for V1SetConfigFromJSON type SetConfigFromJSONArgs struct { APIOpts map[string]any Tenant string Config string DryRun bool } // V1SetConfigFromJSON reloads the sections of config func (cfg *CGRConfig) V1SetConfigFromJSON(ctx *context.Context, args *SetConfigFromJSONArgs, reply *string) (err error) { if len(args.Config) == 0 { *reply = utils.OK return } cfgV := cfg if args.DryRun { cfgV = cfg.Clone() } cfgV.reloadDPCache(sortedCfgSections...) if err = cfgV.loadCfgFromJSONWithLocks(bytes.NewBufferString(args.Config), sortedCfgSections); err != nil { return } // lock all sections cfgV.rLockSections() err = cfgV.checkConfigSanity() cfgV.rUnlockSections() // unlock before checking the error if err != nil { return } if !args.DryRun { cfgV.reloadSections(sortedCfgSections...) } *reply = utils.OK return } // Clone returns a deep copy of CGRConfig func (cfg *CGRConfig) Clone() (cln *CGRConfig) { cln = &CGRConfig{ DataFolderPath: cfg.DataFolderPath, ConfigPath: cfg.ConfigPath, dfltEvRdr: cfg.dfltEvRdr.Clone(), dfltEvExp: cfg.dfltEvExp.Clone(), httpAgentCfg: cfg.httpAgentCfg.Clone(), rpcConns: cfg.rpcConns.Clone(), templates: cfg.templates.Clone(), generalCfg: cfg.generalCfg.Clone(), dataDbCfg: cfg.dataDbCfg.Clone(), storDbCfg: cfg.storDbCfg.Clone(), tlsCfg: cfg.tlsCfg.Clone(), cacheCfg: cfg.cacheCfg.Clone(), listenCfg: cfg.listenCfg.Clone(), httpCfg: cfg.httpCfg.Clone(), filterSCfg: cfg.filterSCfg.Clone(), ralsCfg: cfg.ralsCfg.Clone(), schedulerCfg: cfg.schedulerCfg.Clone(), cdrsCfg: cfg.cdrsCfg.Clone(), sessionSCfg: cfg.sessionSCfg.Clone(), fsAgentCfg: cfg.fsAgentCfg.Clone(), janusAgentCfg: cfg.janusAgentCfg.Clone(), kamAgentCfg: cfg.kamAgentCfg.Clone(), asteriskAgentCfg: cfg.asteriskAgentCfg.Clone(), diameterAgentCfg: cfg.diameterAgentCfg.Clone(), radiusAgentCfg: cfg.radiusAgentCfg.Clone(), dnsAgentCfg: cfg.dnsAgentCfg.Clone(), prometheusAgentCfg: cfg.prometheusAgentCfg.Clone(), attributeSCfg: cfg.attributeSCfg.Clone(), chargerSCfg: cfg.chargerSCfg.Clone(), resourceSCfg: cfg.resourceSCfg.Clone(), statsCfg: cfg.statsCfg.Clone(), trendsCfg: cfg.trendsCfg.Clone(), rankingsCfg: cfg.rankingsCfg.Clone(), thresholdSCfg: cfg.thresholdSCfg.Clone(), routeSCfg: cfg.routeSCfg.Clone(), sureTaxCfg: cfg.sureTaxCfg.Clone(), dispatcherSCfg: cfg.dispatcherSCfg.Clone(), registrarCCfg: cfg.registrarCCfg.Clone(), loaderCgrCfg: cfg.loaderCgrCfg.Clone(), migratorCgrCfg: cfg.migratorCgrCfg.Clone(), mailerCfg: cfg.mailerCfg.Clone(), analyzerSCfg: cfg.analyzerSCfg.Clone(), apier: cfg.apier.Clone(), ersCfg: cfg.ersCfg.Clone(), eesCfg: cfg.eesCfg.Clone(), sipAgentCfg: cfg.sipAgentCfg.Clone(), configSCfg: cfg.configSCfg.Clone(), apiBanCfg: cfg.apiBanCfg.Clone(), sentryPeerCfg: cfg.sentryPeerCfg.Clone(), coreSCfg: cfg.coreSCfg.Clone(), ipsCfg: cfg.ipsCfg.Clone(), cacheDP: make(map[string]utils.MapStorage), } cln.initChanels() return } func (cfg *CGRConfig) reloadDPCache(sections ...string) { cfg.cacheDPMux.Lock() delete(cfg.cacheDP, utils.MetaAll) for _, sec := range sections { delete(cfg.cacheDP, sec) } cfg.cacheDPMux.Unlock() } // GetDataProvider returns the config as a data provider interface func (cfg *CGRConfig) GetDataProvider() utils.MapStorage { cfg.cacheDPMux.RLock() val, has := cfg.cacheDP[utils.MetaAll] cfg.cacheDPMux.RUnlock() if !has || val == nil { cfg.cacheDPMux.Lock() val = utils.MapStorage(cfg.AsMapInterface(cfg.GeneralCfg().RSRSep)) cfg.cacheDP[utils.MetaAll] = val cfg.cacheDPMux.Unlock() } return val }