cfg: allow multiple dict dirs per radius client

ported from commit 47e75fab1
This commit is contained in:
ionutboangiu
2025-07-07 13:24:42 +03:00
committed by Dan Christian Bogos
parent baf767c966
commit c42198f3c2
8 changed files with 51 additions and 42 deletions

View File

@@ -50,7 +50,7 @@ func NewRadiusAgent(cgrCfg *config.CGRConfig, filterS *engine.FilterS,
utils.Logger.Info(
fmt.Sprintf("<%s> loading dictionary for clientID: <%s> out of path <%s>",
utils.RadiusAgent, clntID, dictPath))
if dts[clntID], err = radigo.NewDictionaryFromFoldersWithRFC2865([]string{dictPath}); err != nil {
if dts[clntID], err = radigo.NewDictionaryFromFoldersWithRFC2865(dictPath); err != nil {
return
}
}

View File

@@ -187,7 +187,7 @@ func newCGRConfig(config []byte) (cfg *CGRConfig, err error) {
asteriskAgentCfg: new(AsteriskAgentCfg),
diameterAgentCfg: new(DiameterAgentCfg),
radiusAgentCfg: &RadiusAgentCfg{
ClientDictionaries: make(map[string]string),
ClientDictionaries: make(map[string][]string),
ClientSecrets: make(map[string]string),
},
dnsAgentCfg: new(DNSAgentCfg),

View File

@@ -1047,7 +1047,9 @@ const CGRATES_CFG_JSON = `
"*default": "CGRateS.org"
},
"client_dictionaries": { // per client path towards directory holding additional dictionaries to load (extra to RFC)
"*default": "/usr/share/cgrates/radius/dict/", // key represents the client IP or catch-all <*default|$client_ip>
"*default": [ // key represents the client IP or catch-all <*default|$client_ip>
"/usr/share/cgrates/radius/dict/"
]
},
"sessions_conns": ["*internal"],
"stats_conns": [], // connections to StatS, empty to disable: <""|*internal|$rpc_conns_id>

View File

@@ -768,8 +768,8 @@ func TestRadiusAgentJsonCfg(t *testing.T) {
ClientSecrets: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
ClientDictionaries: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/radius/dict/",
ClientDictionaries: map[string][]string{
utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"},
},
SessionSConns: &[]string{utils.MetaInternal},
StatSConns: &[]string{},

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,7 @@ type RadiusAgentCfg struct {
ListenAuth string
ListenAcct string
ClientSecrets map[string]string
ClientDictionaries map[string]string
ClientDictionaries map[string][]string
SessionSConns []string
StatSConns []string
ThresholdSConns []string
@@ -108,19 +108,21 @@ func (ra RadiusAgentCfg) CloneSection() Section { return ra.Clone() }
// Clone returns a deep copy of RadiusAgentCfg
func (ra RadiusAgentCfg) Clone() *RadiusAgentCfg {
clone := &RadiusAgentCfg{
Enabled: ra.Enabled,
ListenNet: ra.ListenNet,
ListenAuth: ra.ListenAuth,
ListenAcct: ra.ListenAcct,
ClientSecrets: maps.Clone(ra.ClientSecrets),
// NOTE: shallow clone and value is a slice
ClientDictionaries: maps.Clone(ra.ClientDictionaries),
Enabled: ra.Enabled,
ListenNet: ra.ListenNet,
ListenAuth: ra.ListenAuth,
ListenAcct: ra.ListenAcct,
ClientSecrets: maps.Clone(ra.ClientSecrets),
SessionSConns: slices.Clone(ra.SessionSConns),
StatSConns: slices.Clone(ra.StatSConns),
ThresholdSConns: slices.Clone(ra.ThresholdSConns),
}
if ra.ClientDictionaries != nil {
clone.ClientDictionaries = make(map[string][]string, len(ra.ClientDictionaries))
for key, val := range ra.ClientDictionaries {
clone.ClientDictionaries[key] = slices.Clone(val)
}
}
if ra.RequestProcessors != nil {
clone.RequestProcessors = make([]*RequestProcessor, len(ra.RequestProcessors))
for i, req := range ra.RequestProcessors {
@@ -137,7 +139,7 @@ type RadiusAgentJsonCfg struct {
ListenAuth *string `json:"listen_auth"`
ListenAcct *string `json:"listen_acct"`
ClientSecrets map[string]string `json:"client_secrets"`
ClientDictionaries map[string]string `json:"client_dictionaries"`
ClientDictionaries map[string][]string `json:"client_dictionaries"`
SessionSConns *[]string `json:"sessions_conns"`
StatSConns *[]string `json:"stats_conns"`
ThresholdSConns *[]string `json:"thresholds_conns"`
@@ -161,7 +163,7 @@ func diffRadiusAgentJsonCfg(d *RadiusAgentJsonCfg, v1, v2 *RadiusAgentCfg) *Radi
d.ListenAcct = utils.StringPointer(v2.ListenAcct)
}
d.ClientSecrets = diffMapString(d.ClientSecrets, v1.ClientSecrets, v2.ClientSecrets)
d.ClientDictionaries = diffMapString(d.ClientDictionaries, v1.ClientDictionaries, v2.ClientDictionaries)
d.ClientDictionaries = diffMapStringSlice(d.ClientDictionaries, v1.ClientDictionaries, v2.ClientDictionaries)
if !slices.Equal(v1.SessionSConns, v2.SessionSConns) {
d.SessionSConns = utils.SliceStringPointer(stripInternalConns(v2.SessionSConns))
}

View File

@@ -33,7 +33,7 @@ func TestRadiusAgentCfgloadFromJsonCfgCase1(t *testing.T) {
ListenAuth: utils.StringPointer("127.0.0.1:1812"),
ListenAcct: utils.StringPointer("127.0.0.1:1813"),
ClientSecrets: map[string]string{utils.MetaDefault: "CGRateS.org"},
ClientDictionaries: map[string]string{utils.MetaDefault: "/usr/share/cgrates/radius/dict/"},
ClientDictionaries: map[string][]string{utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"}},
SessionSConns: &[]string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
StatSConns: &[]string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)},
ThresholdSConns: &[]string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)},
@@ -64,7 +64,7 @@ func TestRadiusAgentCfgloadFromJsonCfgCase1(t *testing.T) {
ListenAuth: "127.0.0.1:1812",
ListenAcct: "127.0.0.1:1813",
ClientSecrets: map[string]string{utils.MetaDefault: "CGRateS.org"},
ClientDictionaries: map[string]string{utils.MetaDefault: "/usr/share/cgrates/radius/dict/"},
ClientDictionaries: map[string][]string{utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"}},
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)},
ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)},
@@ -161,7 +161,9 @@ func TestRadiusAgentCfgAsMapInterface(t *testing.T) {
"listen_acct": "127.0.0.1:1892",
"client_dictionaries": {
"*default": "/usr/share/cgrates/",
"*default": [
"/usr/share/cgrates/"
]
},
"sessions_conns": ["*birpc_internal", "*conn1","*conn2"],
"stats_conns": ["*internal", "*conn1","*conn2"],
@@ -188,8 +190,8 @@ func TestRadiusAgentCfgAsMapInterface(t *testing.T) {
utils.ClientSecretsCfg: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
utils.ClientDictionariesCfg: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/",
utils.ClientDictionariesCfg: map[string][]string{
utils.MetaDefault: {"/usr/share/cgrates/"},
},
utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*conn1", "*conn2"},
utils.StatSConnsCfg: []string{utils.MetaInternal, "*conn1", "*conn2"},
@@ -227,8 +229,8 @@ func TestRadiusAgentCfgAsMapInterface1(t *testing.T) {
utils.ClientSecretsCfg: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
utils.ClientDictionariesCfg: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/radius/dict/",
utils.ClientDictionariesCfg: map[string][]string{
utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"},
},
utils.SessionSConnsCfg: []string{"*internal"},
utils.StatSConnsCfg: []string{},
@@ -249,7 +251,7 @@ func TestRadiusAgentCfgClone(t *testing.T) {
ListenAuth: "127.0.0.1:1812",
ListenAcct: "127.0.0.1:1813",
ClientSecrets: map[string]string{utils.MetaDefault: "CGRateS.org"},
ClientDictionaries: map[string]string{utils.MetaDefault: "/usr/share/cgrates/radius/dict/"},
ClientDictionaries: map[string][]string{utils.MetaDefault: {"/usr/share/cgrates/radius/dict/"}},
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
RequestProcessors: []*RequestProcessor{
{
@@ -285,7 +287,7 @@ func TestRadiusAgentCfgClone(t *testing.T) {
if rcv.ClientSecrets[utils.MetaDefault] = ""; ban.ClientSecrets[utils.MetaDefault] != "CGRateS.org" {
t.Errorf("Expected clone to not modify the cloned")
}
if rcv.ClientDictionaries[utils.MetaDefault] = ""; ban.ClientDictionaries[utils.MetaDefault] != "/usr/share/cgrates/radius/dict/" {
if rcv.ClientDictionaries[utils.MetaDefault][0] = ""; ban.ClientDictionaries[utils.MetaDefault][0] != "/usr/share/cgrates/radius/dict/" {
t.Errorf("Expected clone to not modify the cloned")
}
}
@@ -299,7 +301,7 @@ func TestDiffRadiusAgentJsonCfg(t *testing.T) {
ListenAuth: "radius_auth",
ListenAcct: "radius_account",
ClientSecrets: map[string]string{},
ClientDictionaries: map[string]string{},
ClientDictionaries: map[string][]string{},
SessionSConns: []string{"*localhost"},
StatSConns: []string{"*localhost"},
ThresholdSConns: []string{"*localhost"},
@@ -314,8 +316,8 @@ func TestDiffRadiusAgentJsonCfg(t *testing.T) {
ClientSecrets: map[string]string{
"radius_user": "radius_pass",
},
ClientDictionaries: map[string]string{
"radius_dict1": "radius_val1",
ClientDictionaries: map[string][]string{
"radius_dict1": {"radius_val1"},
},
SessionSConns: []string{"*internal"},
StatSConns: []string{"*internal"},
@@ -336,8 +338,8 @@ func TestDiffRadiusAgentJsonCfg(t *testing.T) {
ClientSecrets: map[string]string{
"radius_user": "radius_pass",
},
ClientDictionaries: map[string]string{
"radius_dict1": "radius_val1",
ClientDictionaries: map[string][]string{
"radius_dict1": {"radius_val1"},
},
SessionSConns: &[]string{"*internal"},
StatSConns: &[]string{"*internal"},
@@ -358,7 +360,7 @@ func TestDiffRadiusAgentJsonCfg(t *testing.T) {
v1 = v2
expected = &RadiusAgentJsonCfg{
ClientSecrets: map[string]string{},
ClientDictionaries: map[string]string{},
ClientDictionaries: map[string][]string{},
RequestProcessors: &[]*ReqProcessorJsnCfg{
{},
},
@@ -378,8 +380,8 @@ func TestRadiusAgentCloneSection(t *testing.T) {
ClientSecrets: map[string]string{
"radius_user": "radius_pass",
},
ClientDictionaries: map[string]string{
"radius_dict1": "radius_val1",
ClientDictionaries: map[string][]string{
"radius_dict1": {"radius_val1"},
},
SessionSConns: []string{"*internal"},
StatSConns: []string{"*internal"},
@@ -400,8 +402,8 @@ func TestRadiusAgentCloneSection(t *testing.T) {
ClientSecrets: map[string]string{
"radius_user": "radius_pass",
},
ClientDictionaries: map[string]string{
"radius_dict1": "radius_val1",
ClientDictionaries: map[string][]string{
"radius_dict1": {"radius_val1"},
},
SessionSConns: []string{"*internal"},
StatSConns: []string{"*internal"},

View File

@@ -478,6 +478,9 @@ func BoolPointer(b bool) *bool {
func MapStringStringPointer(mp map[string]string) *map[string]string {
return &mp
}
func MapStringSlicePointer(mp map[string][]string) *map[string][]string {
return &mp
}
func TimePointer(t time.Time) *time.Time {
return &t