Added filter implementation for sentrypeer

This commit is contained in:
gezimbll
2023-07-12 10:25:42 -04:00
committed by Dan Christian Bogos
parent 13506235ae
commit ba20dbe831
8 changed files with 146 additions and 3 deletions

View File

@@ -61,3 +61,36 @@ func (ban APIBanCfg) Clone() (cln *APIBanCfg) {
}
return
}
type SentryPeerCfg struct {
Token string
Addr string
}
func (sp *SentryPeerCfg) loadFromJSONCfg(jsnCfg *SentryPeerJsonCfg) (err error) {
if jsnCfg == nil {
return
}
if jsnCfg.Addr != nil {
sp.Addr = *jsnCfg.Addr
}
if jsnCfg.Token != nil {
sp.Token = *jsnCfg.Token
}
return
}
func (sp *SentryPeerCfg) AsMapInterface() map[string]any {
return map[string]any{
"Addres": sp.Addr,
"Token": sp.Token,
}
}
func (sp *SentryPeerCfg) Clone() (cln *SentryPeerCfg) {
cln = &SentryPeerCfg{
Addr: sp.Addr,
Token: sp.Token,
}
return
}

View File

@@ -175,6 +175,7 @@ func newCGRConfig(config []byte) (cfg *CGRConfig, err error) {
cfg.sipAgentCfg = new(SIPAgentCfg)
cfg.configSCfg = new(ConfigSCfg)
cfg.apiBanCfg = new(APIBanCfg)
cfg.sentryPeerCfg = new(SentryPeerCfg)
cfg.coreSCfg = new(CoreSCfg)
cfg.dfltEvExp = &EventExporterCfg{Opts: &EventExporterOpts{
Els: new(ElsOpts),
@@ -325,6 +326,7 @@ type CGRConfig struct {
sipAgentCfg *SIPAgentCfg // SIPAgent config
configSCfg *ConfigSCfg // ConfigS config
apiBanCfg *APIBanCfg // APIBan config
sentryPeerCfg *SentryPeerCfg //SentryPeer config
coreSCfg *CoreSCfg // CoreS config
cacheDP map[string]utils.MapStorage
@@ -398,7 +400,7 @@ func (cfg *CGRConfig) loadFromJSONCfg(jsnCfg *CgrJsonCfg) (err error) {
cfg.loadLoaderCgrCfg, cfg.loadMigratorCgrCfg, cfg.loadTLSCgrCfg,
cfg.loadAnalyzerCgrCfg, cfg.loadApierCfg, cfg.loadErsCfg, cfg.loadEesCfg,
cfg.loadSIPAgentCfg, cfg.loadRegistrarCCfg,
cfg.loadConfigSCfg, cfg.loadAPIBanCgrCfg, cfg.loadCoreSCfg} {
cfg.loadConfigSCfg, cfg.loadAPIBanCgrCfg, cfg.loadSentryPeerCgrCfg, cfg.loadCoreSCfg} {
if err = loadFunc(jsnCfg); err != nil {
return
}
@@ -777,6 +779,13 @@ func (cfg *CGRConfig) loadAPIBanCgrCfg(jsnCfg *CgrJsonCfg) (err error) {
}
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) {
@@ -1136,6 +1145,11 @@ func (cfg *CGRConfig) APIBanCfg() *APIBanCfg {
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 {
@@ -1254,6 +1268,7 @@ func (cfg *CGRConfig) getLoadFunctions() map[string]func(*CgrJsonCfg) error {
TemplatesJson: cfg.loadTemplateSCfg,
ConfigSJson: cfg.loadConfigSCfg,
APIBanCfgJson: cfg.loadAPIBanCgrCfg,
SentryPeerCfgJson: cfg.loadSentryPeerCgrCfg,
CoreSCfgJson: cfg.loadCoreSCfg,
}
}
@@ -1450,6 +1465,7 @@ func (cfg *CGRConfig) reloadSections(sections ...string) {
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{}{}
@@ -1547,6 +1563,7 @@ func (cfg *CGRConfig) AsMapInterface(separator string) (mp map[string]any) {
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),
@@ -1704,6 +1721,8 @@ func (cfg *CGRConfig) V1GetConfig(args *SectionWithAPIOpts, reply *map[string]an
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:

View File

@@ -1266,6 +1266,9 @@ const CGRATES_CFG_JSON = `
"enabled": false,
"keys": [],
},
"sentrypeer":{
"addr":"",
"token":"",
}
}`

View File

@@ -64,6 +64,7 @@ const (
TemplatesJson = "templates"
ConfigSJson = "configs"
APIBanCfgJson = "apiban"
SentryPeerCfgJson = "sentrypeer"
CoreSCfgJson = "cores"
)
@@ -72,7 +73,7 @@ var (
CACHE_JSN, FilterSjsn, RALS_JSN, CDRS_JSN, ERsJson, SessionSJson, AsteriskAgentJSN, FreeSWITCHAgentJSN,
KamailioAgentJSN, DA_JSN, RA_JSN, HttpAgentJson, DNSAgentJson, ATTRIBUTE_JSN, ChargerSCfgJson, RESOURCES_JSON, STATS_JSON,
THRESHOLDS_JSON, RouteSJson, LoaderJson, MAILER_JSN, SURETAX_JSON, CgrLoaderCfgJson, CgrMigratorCfgJson, DispatcherSJson,
AnalyzerCfgJson, ApierS, EEsJson, SIPAgentJson, RegistrarCJson, TemplatesJson, ConfigSJson, APIBanCfgJson, CoreSCfgJson}
AnalyzerCfgJson, ApierS, EEsJson, SIPAgentJson, RegistrarCJson, TemplatesJson, ConfigSJson, APIBanCfgJson, SentryPeerCfgJson, CoreSCfgJson}
)
// Loads the json config out of io.Reader, eg other sources than file, maybe over http
@@ -559,6 +560,18 @@ func (jsnCfg CgrJsonCfg) ApiBanCfgJson() (*APIBanJsonCfg, error) {
return cfg, nil
}
func (jsnCfg CgrJsonCfg) SentryPeerJson() (*SentryPeerJsonCfg, error) {
rawCfg, hasKey := jsnCfg[SentryPeerCfgJson]
if !hasKey {
return nil, nil
}
cfg := new(SentryPeerJsonCfg)
if err := json.Unmarshal(*rawCfg, cfg); err != nil {
return nil, err
}
return cfg, nil
}
func (jsnCfg CgrJsonCfg) CoreSCfgJson() (*CoreSJsonCfg, error) {
rawCfg, hasKey := jsnCfg[CoreSCfgJson]
if !hasKey {

View File

@@ -876,6 +876,11 @@ type APIBanJsonCfg struct {
Keys *[]string
}
type SentryPeerJsonCfg struct {
Token *string
Addr *string
}
type CoreSJsonCfg struct {
Caps *int
Caps_strategy *string

View File

@@ -19,6 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package engine
import (
"fmt"
"net/http"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/guardian"
"github.com/cgrates/cgrates/utils"
@@ -117,3 +120,52 @@ func WeightFromDynamics(dWs []*utils.DynamicWeight,
}
return 0.0, nil
}
func GetSentryPeer(val, addr, token, path string, cacheRead, cacheWrite bool) (found bool, err error) {
valpath := utils.ConcatenatedKey(path, val)
if cacheRead {
if x, ok := Cache.Get(utils.MetaSentryPeer, valpath); ok && x != nil { // Attempt to find in cache first
return x.(bool), nil
}
}
var req *http.Request
if req, err = http.NewRequest("GET", addr+path+"/"+val, nil); err != nil {
return
}
req.Header = http.Header{
"Authorization": {fmt.Sprintf("Bearer %s", token)},
}
var resp *http.Response
resp, err = http.DefaultClient.Do(req)
if err != nil {
return false, err
}
defer resp.Body.Close()
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
if cacheWrite {
if err = Cache.Set(utils.MetaSentryPeer, valpath, true, nil, true, utils.NonTransactional); err != nil {
return false, err
}
}
return true, nil
} else {
switch {
case resp.StatusCode == http.StatusNotFound:
if cacheWrite {
if err = Cache.Set(utils.MetaSentryPeer, valpath, false, nil, true, utils.NonTransactional); err != nil {
return false, err
}
}
return
case resp.StatusCode >= 400 && resp.StatusCode < 500:
err = fmt.Errorf("client error<%s>", resp.Status)
return
case resp.StatusCode >= 500:
err = fmt.Errorf("server error<%s>", resp.Status)
return
default:
err = fmt.Errorf("unexpected status code<%s>", resp.Status)
}
}
return
}

View File

@@ -351,6 +351,8 @@ func (fltr *FilterRule) Pass(dDP utils.DataProvider) (result bool, err error) {
result, err = fltr.passIPNet(dDP)
case utils.MetaAPIBan, utils.MetaNotAPIBan:
result, err = fltr.passAPIBan(dDP)
case utils.MetaSentryPeer, utils.MetaNotSentryPeer:
result, err = fltr.passSentryPeer(dDP)
case utils.MetaActivationInterval, utils.MetaNotActivationInterval:
result, err = fltr.passActivationInterval(dDP)
case utils.MetaRegex, utils.MetaNotRegex:
@@ -646,6 +648,20 @@ func (fltr *FilterRule) passAPIBan(dDP utils.DataProvider) (bool, error) {
return dm.GetAPIBan(strVal, config.CgrConfig().APIBanCfg().Keys, fltr.Values[0] != utils.MetaAll, true, true)
}
func (fltr *FilterRule) passSentryPeer(dDP utils.DataProvider) (bool, error) {
strVal, err := fltr.rsrElement.ParseDataProvider(dDP)
if err != nil {
if err == utils.ErrNotFound {
return false, nil
}
return false, err
}
if fltr.Values[0] != "phone-numbers" && fltr.Values[0] != "ip-addresses" {
return false, fmt.Errorf("invalid value for sentrypeer filter: <%s>", fltr.Values[0])
}
return GetSentryPeer(strVal, config.CgrConfig().SentryPeerCfg().Addr, config.CgrConfig().SentryPeerCfg().Token, fltr.Values[0], true, true)
}
func parseTime(rsr *config.RSRParser, dDp utils.DataProvider) (_ time.Time, err error) {
var str string
if str, err = rsr.ParseDataProvider(dDp); err != nil {

View File

@@ -1157,6 +1157,7 @@ const (
MetaEqual = "*eq"
MetaIPNet = "*ipnet"
MetaAPIBan = "*apiban"
MetaSentryPeer = "*sentrypeer"
MetaActivationInterval = "*ai"
MetaRegex = "*regex"
@@ -1173,6 +1174,7 @@ const (
MetaNotEqual = "*noteq"
MetaNotIPNet = "*notipnet"
MetaNotAPIBan = "*notapiban"
MetaNotSentryPeer = "*notsentrypeer"
MetaNotActivationInterval = "*notai"
MetaNotRegex = "*notregex"