Add support for *remote_host in AgentRequest

This commit is contained in:
TeoV
2018-12-07 07:22:51 -08:00
committed by Dan Christian Bogos
parent 1f2f9be877
commit 7997e42be5
18 changed files with 116 additions and 43 deletions

View File

@@ -78,6 +78,11 @@ func (ar *AgentRequest) String() string {
return utils.ToJSON(ar)
}
// RemoteHost implements engine.DataProvider
func (aReq *AgentRequest) RemoteHost() net.Addr {
return aReq.Request.RemoteHost()
}
// FieldAsInterface implements engine.DataProvider
func (ar *AgentRequest) FieldAsInterface(fldPath []string) (val interface{}, err error) {
switch fldPath[0] {
@@ -171,6 +176,9 @@ func (aReq *AgentRequest) ParseField(
case utils.META_CONSTANT:
out, err = cfgFld.Value.ParseValue(utils.EmptyString)
isString = true
case utils.MetaRemoteHost:
out = aReq.RemoteHost().String()
isString = true
case utils.MetaVariable, utils.META_COMPOSED:
out, err = cfgFld.Value.ParseDataProvider(aReq, utils.NestingSep)
isString = true
@@ -243,19 +251,8 @@ func (aReq *AgentRequest) ParseField(
iFaceVals[i] = utils.StringToInterface(strVal)
}
out, err = utils.Sum(iFaceVals...)
case utils.MetaRemoteHost:
netInterfaceAddresses, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, netInterfaceAddress := range netInterfaceAddresses {
networkIp, ok := netInterfaceAddress.(*net.IPNet)
if ok && !networkIp.IP.IsLoopback() && networkIp.IP.To4() != nil {
out = networkIp.IP.String()
break
}
}
}
if err != nil &&
!strings.HasPrefix(err.Error(), "Could not find") {
return

View File

@@ -176,7 +176,7 @@ func TestAgReqParseFieldDiameter(t *testing.T) {
diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)),
}})
//create diameterDataProvider
dP := newDADataProvider(m)
dP := newDADataProvider(nil, m)
data, _ := engine.NewMapStorage()
dm := engine.NewDataManager(data)
cfg, _ := config.NewDefaultCGRConfig()
@@ -356,26 +356,3 @@ func TestAgReqParseFieldHttpXml(t *testing.T) {
}
}
func TestAgReqParseFieldRemoteHost(t *testing.T) {
data, _ := engine.NewMapStorage()
dm := engine.NewDataManager(data)
cfg, _ := config.NewDefaultCGRConfig()
filterS := engine.NewFilterS(cfg, nil, dm)
agReq := newAgentRequest(nil, nil, nil, nil, "cgrates.org", "", filterS)
tplFlds := []*config.FCTemplate{
&config.FCTemplate{Tag: "OriginHost",
FieldId: utils.OriginHost, Type: utils.MetaRemoteHost},
}
eMp := config.NewNavigableMap(nil)
eMp.Set([]string{utils.OriginHost}, []*config.NMItem{
&config.NMItem{Data: "192.168.56.203", Path: []string{utils.OriginHost},
Config: tplFlds[0]}}, false, true)
if mpOut, err := agReq.AsNavigableMap(tplFlds); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eMp, mpOut) {
t.Errorf("expecting: %+v, received: %+v", eMp, mpOut)
}
}

View File

@@ -157,7 +157,7 @@ func (da *DiameterAgent) handleMessage(c diam.Conn, m *diam.Message) {
var lclProcessed bool
lclProcessed, err = da.processRequest(reqProcessor,
newAgentRequest(
newDADataProvider(m), reqVars, rply,
newDADataProvider(c, m), reqVars, rply,
reqProcessor.Tenant, da.cgrCfg.GeneralCfg().DefaultTenant,
utils.FirstNonEmpty(reqProcessor.Timezone,
da.cgrCfg.GeneralCfg().DefaultTimezone),

View File

@@ -266,14 +266,15 @@ func writeOnConn(c diam.Conn, m *diam.Message) {
}
// newDADataProvider constructs a DataProvider for a diameter message
func newDADataProvider(m *diam.Message) config.DataProvider {
return &diameterDP{m: m, cache: config.NewNavigableMap(nil)}
func newDADataProvider(c diam.Conn, m *diam.Message) config.DataProvider {
return &diameterDP{c: c, m: m, cache: config.NewNavigableMap(nil)}
}
// diameterDP implements engine.DataProvider, serving as diam.Message data decoder
// decoded data is only searched once and cached
type diameterDP struct {
c diam.Conn
m *diam.Message
cache *config.NavigableMap
}
@@ -300,6 +301,11 @@ func (dP *diameterDP) FieldAsString(fldPath []string) (data string, err error) {
return utils.IfaceAsString(valIface)
}
// RemoteHost is part of engine.DataProvider interface
func (dP *diameterDP) RemoteHost() net.Addr {
return dP.c.RemoteAddr()
}
// FieldAsInterface is part of engine.DataProvider interface
func (dP *diameterDP) FieldAsInterface(fldPath []string) (data interface{}, err error) {
if data, err = dP.cache.FieldAsInterface(fldPath); err != nil {
@@ -446,7 +452,7 @@ func diamErr(m *diam.Message, resCode uint32,
tpl []*config.FCTemplate, tnt, tmz string,
filterS *engine.FilterS) (a *diam.Message, err error) {
aReq := newAgentRequest(
newDADataProvider(m), reqVars,
newDADataProvider(nil, m), reqVars,
config.NewNavigableMap(nil),
nil, tnt, tmz, filterS)
var rplyData *config.NavigableMap

View File

@@ -64,7 +64,7 @@ func TestDPFieldAsInterface(t *testing.T) {
diam.NewAVP(avp.ValueDigits, avp.Mbit, 0, datatype.Integer64(20000)),
}})
dP := newDADataProvider(m)
dP := newDADataProvider(nil, m)
eOut := interface{}("simuhuawei;1449573472;00002")
if out, err := dP.FieldAsInterface([]string{"Session-Id"}); err != nil {
t.Error(err)

View File

@@ -22,6 +22,7 @@ import (
"encoding/xml"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/http/httputil"
"strconv"
@@ -100,6 +101,11 @@ func (hU *httpUrlDP) AsNavigableMap([]*config.FCTemplate) (
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (hU *httpUrlDP) RemoteHost() net.Addr {
return newHttpRemoteAddr(hU.req.RemoteAddr)
}
func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) {
byteData, err := ioutil.ReadAll(req.Body)
if err != nil {
@@ -110,7 +116,7 @@ func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) {
if err != nil {
return nil, err
}
dP = &httpXmlDP{xmlDoc: doc, cache: config.NewNavigableMap(nil)}
dP = &httpXmlDP{xmlDoc: doc, cache: config.NewNavigableMap(nil), addr: req.RemoteAddr}
return
}
@@ -119,6 +125,7 @@ func newHTTPXmlDP(req *http.Request) (dP config.DataProvider, err error) {
type httpXmlDP struct {
cache *config.NavigableMap
xmlDoc *xmlquery.Node
addr string
}
// String is part of engine.DataProvider interface
@@ -189,6 +196,11 @@ func (hU *httpXmlDP) AsNavigableMap([]*config.FCTemplate) (
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (hU *httpXmlDP) RemoteHost() net.Addr {
return newHttpRemoteAddr(hU.addr)
}
// httpAgentReplyEncoder will encode []*engine.NMElement
// and write content to http writer
type httpAgentReplyEncoder interface {
@@ -233,3 +245,20 @@ func (xE *haXMLEncoder) Encode(nM *config.NavigableMap) (err error) {
_, err = xE.w.Write(xmlOut)
return
}
func newHttpRemoteAddr(ip string) *httpRemoteAddr {
return &httpRemoteAddr{ip: ip}
}
type httpRemoteAddr struct {
ip string
}
func (http *httpRemoteAddr) Network() string {
return utils.TCP
}
func (http *httpRemoteAddr) String() string {
return http.ip
}

View File

@@ -20,6 +20,7 @@ package agents
import (
"fmt"
"net"
"strings"
"github.com/cgrates/cgrates/config"
@@ -189,3 +190,8 @@ func (pk *radiusDP) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (pk *radiusDP) RemoteHost() net.Addr {
return pk.req.RemoteAddr()
}

View File

@@ -22,6 +22,7 @@ import (
"encoding/csv"
"encoding/json"
"fmt"
"net"
"strconv"
"strings"
"time"
@@ -272,3 +273,8 @@ func (cP *csvProvider) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (cP *csvProvider) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

View File

@@ -23,6 +23,7 @@ import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"strconv"
@@ -321,3 +322,8 @@ func (fP *fwvProvider) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (fP *fwvProvider) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

View File

@@ -23,6 +23,7 @@ import (
"errors"
"fmt"
"io"
"net"
"strconv"
"strings"
"time"
@@ -275,3 +276,8 @@ func (xP *xmlProvider) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (xP *xmlProvider) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

View File

@@ -18,10 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package config
import "net"
// DataProvider is a data source from multiple formats
type DataProvider interface {
String() string // printable version of data
FieldAsInterface(fldPath []string) (interface{}, error)
FieldAsString(fldPath []string) (string, error)
AsNavigableMap([]*FCTemplate) (*NavigableMap, error)
RemoteHost() net.Addr
}

View File

@@ -22,6 +22,7 @@ import (
"encoding/xml"
"errors"
"fmt"
"net"
"strconv"
"strings"
"time"
@@ -162,10 +163,16 @@ func (nM *NavigableMap) FieldAsString(fldPath []string) (fldVal string, err erro
return
}
// String is part of engine.DataProvider interface
func (nM *NavigableMap) String() string {
return utils.ToJSON(nM.data)
}
// RemoteHost is part of engine.DataProvider interface
func (nM *NavigableMap) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}
// indexMapElements will recursively go through map and index the element paths into elmns
func indexMapElements(mp map[string]interface{}, path []string, vals *[]interface{}) {
for k, v := range mp {

View File

@@ -24,6 +24,7 @@ import (
"errors"
"fmt"
"html/template"
"net"
"net/smtp"
"path"
"reflect"
@@ -902,3 +903,8 @@ func (cdrP *cdrLogProvider) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (cdrP *cdrLogProvider) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

View File

@@ -21,6 +21,7 @@ package engine
import (
"errors"
"fmt"
"net"
"reflect"
"time"
@@ -1091,3 +1092,8 @@ func (cd *CallDescriptor) String() string {
func (cd *CallDescriptor) AsNavigableMap(tpl []*config.FCTemplate) (nM *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of utils.DataProvider
func (cd *CallDescriptor) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

2
glide.lock generated
View File

@@ -18,7 +18,7 @@ imports:
- name: github.com/cgrates/osipsdagram
version: 3d6beed663452471dec3ca194137a30d379d9e8f
- name: github.com/cgrates/radigo
version: 69d4269e21990c0f120b8e60d5b75d533db7f3dd
version: e5c8f3272cccf795f47b82e25a8f3408312c14e0
- name: github.com/cgrates/rpcclient
version: 7316bff37a2b8692fbadd57f9c9cda070cc33081
- name: github.com/fiorix/go-diameter

View File

@@ -20,6 +20,7 @@ package loaders
import (
"fmt"
"net"
"strconv"
"github.com/cgrates/cgrates/config"
@@ -135,3 +136,8 @@ func (cP *csvProvider) AsNavigableMap([]*config.FCTemplate) (
nm *config.NavigableMap, err error) {
return nil, utils.ErrNotImplemented
}
// RemoteHost is part of engine.DataProvider interface
func (cP *csvProvider) RemoteHost() net.Addr {
return new(utils.LocalAddr)
}

View File

@@ -536,6 +536,8 @@ const (
IdxEnd = "]"
MetaLog = "*log"
MetaRemoteHost = "*remote_host"
Local = "local"
TCP = "tcp"
)
// Migrator Action

View File

@@ -339,3 +339,13 @@ func DaysInYear(year int) float64 {
last := first.AddDate(1, 0, 0)
return float64(last.Sub(first).Hours() / 24)
}
type LocalAddr struct{}
func (lc *LocalAddr) Network() string {
return Local
}
func (lc *LocalAddr) String() string {
return Local
}