diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go
index 2cfeae2f1..6eb115fb8 100755
--- a/cmd/cgr-loader/cgr-loader.go
+++ b/cmd/cgr-loader/cgr-loader.go
@@ -65,6 +65,10 @@ var (
"The delay before executing the commands if the redis cluster is in the CLUSTERDOWN state")
dbQueryTimeout = cgrLoaderFlags.String("query_timeout", utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.QueryTimeoutCfg]),
"The timeout for queries")
+ dbRedisTls = cgrLoaderFlags.Bool(utils.RedisTLS, false, "Use a tls connection when connecting to redis")
+ dbRedisClientCertificate = cgrLoaderFlags.String(utils.RedisClientCertificate, utils.EmptyString, "Path to the client certificate")
+ dbRedisClientKey = cgrLoaderFlags.String(utils.RedisClientKey, utils.EmptyString, "Path to the client key")
+ dbRedisCACertificate = cgrLoaderFlags.String(utils.RedisCACertificate, utils.EmptyString, "Path to the CA certificate")
storDBType = cgrLoaderFlags.String("stordb_type", dfltCfg.StorDbCfg().Type,
"The type of the storDb database <*mysql|*postgres|*mongo>")
@@ -162,6 +166,20 @@ func loadConfig() (ldrCfg *config.CGRConfig) {
ldrCfg.DataDbCfg().Opts[utils.QueryTimeoutCfg] = *dbQueryTimeout
}
+ rdsTLS, _ := utils.IfaceAsBool(dfltCfg.DataDbCfg().Opts[utils.RedisTLS])
+ if *dbRedisTls != rdsTLS {
+ ldrCfg.DataDbCfg().Opts[utils.RedisTLS] = *dbRedisTls
+ }
+ if *dbRedisClientCertificate != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisClientCertificate]) {
+ ldrCfg.DataDbCfg().Opts[utils.RedisClientCertificate] = *dbRedisClientCertificate
+ }
+ if *dbRedisClientKey != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisClientKey]) {
+ ldrCfg.DataDbCfg().Opts[utils.RedisClientKey] = *dbRedisClientKey
+ }
+ if *dbRedisCACertificate != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisCACertificate]) {
+ ldrCfg.DataDbCfg().Opts[utils.RedisCACertificate] = *dbRedisCACertificate
+ }
+
if *dbDataEncoding != dfltCfg.GeneralCfg().DBDataEncoding {
ldrCfg.GeneralCfg().DBDataEncoding = *dbDataEncoding
}
diff --git a/cmd/cgr-loader/cgr-loader_it_test.go b/cmd/cgr-loader/cgr-loader_it_test.go
index 30f695d36..fee614607 100644
--- a/cmd/cgr-loader/cgr-loader_it_test.go
+++ b/cmd/cgr-loader/cgr-loader_it_test.go
@@ -62,6 +62,10 @@ func TestLoadConfig(t *testing.T) {
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterOnDownDelayCfg: "0",
utils.RedisClusterCfg: false,
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
RmtConns: []string{},
RplConns: []string{},
diff --git a/cmd/cgr-migrator/cgr-migrator.go b/cmd/cgr-migrator/cgr-migrator.go
index 44dfb7187..000bdd704 100755
--- a/cmd/cgr-migrator/cgr-migrator.go
+++ b/cmd/cgr-migrator/cgr-migrator.go
@@ -73,6 +73,10 @@ var (
"The delay before executing the commands if the redis cluster is in the CLUSTERDOWN state")
dbQueryTimeout = cgrMigratorFlags.String("query_timeout", utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.QueryTimeoutCfg]),
"The timeout for queries")
+ dbRedisTls = cgrMigratorFlags.Bool(utils.RedisTLS, false, "Use a tls connection when connecting to redis")
+ dbRedisClientCertificate = cgrMigratorFlags.String(utils.RedisClientCertificate, utils.EmptyString, "Path to the client certificate")
+ dbRedisClientKey = cgrMigratorFlags.String(utils.RedisClientKey, utils.EmptyString, "Path to the client key")
+ dbRedisCACertificate = cgrMigratorFlags.String(utils.RedisCACertificate, utils.EmptyString, "Path to the CA certificate")
outDataDBType = cgrMigratorFlags.String("out_datadb_type", utils.MetaDataDB,
"output DataDB type <*redis|*mongo>")
@@ -182,6 +186,20 @@ func main() {
mgrCfg.DataDbCfg().Opts[utils.QueryTimeoutCfg] = *dbQueryTimeout
}
+ rdsTLS, _ := utils.IfaceAsBool(dfltCfg.DataDbCfg().Opts[utils.RedisTLS])
+ if *dbRedisTls != rdsTLS {
+ mgrCfg.DataDbCfg().Opts[utils.RedisTLS] = *dbRedisTls
+ }
+ if *dbRedisClientCertificate != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisClientCertificate]) {
+ mgrCfg.DataDbCfg().Opts[utils.RedisClientCertificate] = *dbRedisClientCertificate
+ }
+ if *dbRedisClientKey != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisClientKey]) {
+ mgrCfg.DataDbCfg().Opts[utils.RedisClientKey] = *dbRedisClientKey
+ }
+ if *dbRedisCACertificate != utils.IfaceAsString(dfltCfg.DataDbCfg().Opts[utils.RedisCACertificate]) {
+ mgrCfg.DataDbCfg().Opts[utils.RedisCACertificate] = *dbRedisCACertificate
+ }
+
// outDataDB
if *outDataDBType == utils.MetaDataDB {
if dfltCfg.MigratorCgrCfg().OutDataDBType == mgrCfg.MigratorCgrCfg().OutDataDBType {
diff --git a/config/config_defaults.go b/config/config_defaults.go
index 220a44651..433e699bf 100755
--- a/config/config_defaults.go
+++ b/config/config_defaults.go
@@ -107,7 +107,10 @@ const CGRATES_CFG_JSON = `
"redis_cluster_sync": "5s", // the sync interval for the redis cluster
"redis_cluster_ondown_delay": "0", // the delay before executing the commands if the redis cluster is in the CLUSTERDOWN state
"query_timeout":"10s",
- "redis_tls": false, // if true it will use a tls connection and use the client certificate, key and ca_certificate for tls connection
+ "redis_tls": false, // if true it will use a tls connection and use the redis_client_certificate certificate, redis_client_key and redis_ca_certificate for tls connection
+ "redis_client_certificate":"", // path to client certificate
+ "redis_client_key":"", // path to client key
+ "redis_ca_certificate":"", // path to CA certificate (populate for self-signed certificate otherwise let it empty)
}
},
@@ -873,7 +876,11 @@ const CGRATES_CFG_JSON = `
"redis_sentinel": "",
"redis_cluster": false,
"redis_cluster_sync": "5s",
- "redis_cluster_ondown_delay": "0",
+ "redis_cluster_ondown_delay": "0",
+ "redis_tls": false, // if true it will use a tls connection and use the redis_client_certificate, redis_client_key and redis_ca_certificate for tls connection
+ "redis_client_certificate":"", // path to client certificate
+ "redis_client_key":"", // path to client key
+ "redis_ca_certificate":"", // path to CA certificate (populate for self-signed certificate otherwise let it empty)
},
"out_stordb_opts":{},
},
diff --git a/config/config_json_test.go b/config/config_json_test.go
index b7d505ebc..9f0cf2952 100755
--- a/config/config_json_test.go
+++ b/config/config_json_test.go
@@ -337,6 +337,9 @@ func TestDfDataDbJsonCfg(t *testing.T) {
utils.RedisClusterOnDownDelayCfg: "0",
utils.RedisClusterSyncCfg: "5s",
utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
Items: &map[string]*ItemOptJson{
utils.MetaAccounts: {
@@ -1633,6 +1636,10 @@ func TestDfMigratorCfg(t *testing.T) {
utils.RedisClusterCfg: false,
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterOnDownDelayCfg: "0",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
}
if cfg, err := dfCgrJSONCfg.MigratorCfgJson(); err != nil {
diff --git a/config/config_test.go b/config/config_test.go
index 82ce3c0b1..1b6c6b757 100755
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -1736,6 +1736,10 @@ func TestCgrMigratorCfgDefault(t *testing.T) {
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterCfg: false,
utils.RedisSentinelNameCfg: "",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
OutStorDBOpts: make(map[string]interface{}),
}
diff --git a/config/migratorcfg_test.go b/config/migratorcfg_test.go
index 23c33209d..f36f342da 100644
--- a/config/migratorcfg_test.go
+++ b/config/migratorcfg_test.go
@@ -43,9 +43,6 @@ func TestMigratorCgrCfgloadFromJsonCfg(t *testing.T) {
utils.RedisClusterCfg: true,
utils.RedisClusterSyncCfg: "10s",
},
- Out_storDB_opts: map[string]interface{}{
- utils.RedisClusterCfg: true,
- },
}
expected := &MigratorCgrCfg{
OutDataDBType: utils.REDIS,
@@ -66,10 +63,12 @@ func TestMigratorCgrCfgloadFromJsonCfg(t *testing.T) {
utils.RedisClusterCfg: true,
utils.RedisClusterSyncCfg: "10s",
utils.RedisClusterOnDownDelayCfg: "0",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
- OutStorDBOpts: map[string]interface{}{
- utils.RedisClusterCfg: true,
- },
+ OutStorDBOpts: map[string]interface{}{},
}
if cfgJson, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
@@ -117,6 +116,10 @@ func TestMigratorCgrCfgAsMapInterface(t *testing.T) {
utils.RedisClusterCfg: true,
utils.RedisClusterSyncCfg: "2s",
utils.RedisClusterOnDownDelayCfg: "1",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -156,6 +159,10 @@ func TestMigratorCgrCfgAsMapInterface1(t *testing.T) {
utils.RedisClusterCfg: false,
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterOnDownDelayCfg: "0",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
@@ -190,6 +197,10 @@ func TestMigratorCgrCfgAsMapInterface2(t *testing.T) {
utils.RedisClusterCfg: false,
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterOnDownDelayCfg: "0",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
}
if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
diff --git a/data/conf/samples/tutredis_tls/cgrates.json b/data/conf/samples/tutredis_tls/cgrates.json
new file mode 100755
index 000000000..a9f4b3c87
--- /dev/null
+++ b/data/conf/samples/tutredis_tls/cgrates.json
@@ -0,0 +1,47 @@
+{
+// CGRateS Configuration file
+//
+
+
+"general": {
+ "log_level": 7,
+ "node_id": "RedisTLS"
+},
+
+
+"listen": {
+ "rpc_json": ":2012",
+ "rpc_gob": ":2013",
+ "http": ":2080",
+},
+
+
+"data_db": {
+ "db_type": "redis",
+ "db_host":"127.0.0.1:6400",
+ "db_name": "10",
+ "opts": {
+ "redis_tls": true,
+ "redis_client_certificate":"/usr/share/cgrates/tls/client.crt",
+ "redis_client_key":"/usr/share/cgrates/tls/client.key",
+ "redis_ca_certificate":"/usr/share/cgrates/tls/ca.crt",
+ },
+},
+
+
+"stor_db": {
+ "db_password": "CGRateS.org",
+},
+
+
+"rals": {
+ "enabled": true,
+},
+
+
+"apiers": {
+ "enabled": true,
+},
+
+
+}
diff --git a/engine/storage_redis.go b/engine/storage_redis.go
index 82079986a..b3475a94a 100644
--- a/engine/storage_redis.go
+++ b/engine/storage_redis.go
@@ -21,6 +21,8 @@ package engine
import (
"bytes"
"compress/zlib"
+ "crypto/tls"
+ "crypto/x509"
"errors"
"io"
"io/ioutil"
@@ -68,7 +70,8 @@ const (
func NewRedisStorage(address string, db int, user, pass, mrshlerStr string,
maxConns int, sentinelName string, isCluster bool, clusterSync,
- clusterOnDownDelay time.Duration) (rs *RedisStorage, err error) {
+ clusterOnDownDelay time.Duration, tlsConn bool,
+ tlsClientCert, tlsClientKey, tlsCACert string) (rs *RedisStorage, err error) {
rs = new(RedisStorage)
if rs.ms, err = NewMarshaler(mrshlerStr); err != nil {
rs = nil
@@ -86,6 +89,37 @@ func NewRedisStorage(address string, db int, user, pass, mrshlerStr string,
}
}
+ if tlsConn {
+ var cert tls.Certificate
+ if tlsClientCert != "" && tlsClientKey != "" {
+ cert, err = tls.LoadX509KeyPair(tlsClientCert, tlsClientKey)
+ if err != nil {
+ return
+ }
+ }
+ var rootCAs *x509.CertPool
+ if rootCAs, err = x509.SystemCertPool(); err != nil {
+ return
+ }
+ if rootCAs == nil {
+ rootCAs = x509.NewCertPool()
+ }
+ if tlsCACert != "" {
+ var ca []byte
+ if ca, err = ioutil.ReadFile(tlsCACert); err != nil {
+ return
+ }
+
+ if ok := rootCAs.AppendCertsFromPEM(ca); !ok {
+ return
+ }
+ }
+ dialOpts = append(dialOpts, radix.DialUseTLS(&tls.Config{
+ Certificates: []tls.Certificate{cert},
+ RootCAs: rootCAs,
+ }))
+ }
+
dialFunc := func(network, addr string) (radix.Conn, error) {
return radix.Dial(network, addr, dialOpts...)
}
diff --git a/engine/storage_utils.go b/engine/storage_utils.go
index e92e74593..781d1965f 100644
--- a/engine/storage_utils.go
+++ b/engine/storage_utils.go
@@ -54,9 +54,16 @@ func NewDataDBConn(dbType, host, port, name, user,
if clusterOnDownDelay, err = utils.IfaceAsDuration(opts[utils.RedisClusterOnDownDelayCfg]); err != nil {
return
}
+ var hasTlsConn bool
+ if hasTlsConn, err = utils.IfaceAsBool(opts[utils.RedisTLS]); err != nil {
+ return
+ }
d, err = NewRedisStorage(host, dbNo, user, pass, marshaler,
utils.REDIS_MAX_CONNS, utils.IfaceAsString(opts[utils.RedisSentinelNameCfg]),
- isCluster, clusterSync, clusterOnDownDelay)
+ isCluster, clusterSync, clusterOnDownDelay, hasTlsConn,
+ utils.IfaceAsString(opts[utils.RedisClientCertificate]),
+ utils.IfaceAsString(opts[utils.RedisClientKey]),
+ utils.IfaceAsString(opts[utils.RedisCACertificate]))
case utils.MONGO:
var ttl time.Duration
if ttl, err = utils.IfaceAsDuration(opts[utils.QueryTimeoutCfg]); err != nil {
diff --git a/engine/z_datamanager_it_test.go b/engine/z_datamanager_it_test.go
index 148f40b19..348e0ae20 100644
--- a/engine/z_datamanager_it_test.go
+++ b/engine/z_datamanager_it_test.go
@@ -53,7 +53,7 @@ func TestDMitinitDB(t *testing.T) {
dataDB, err = NewRedisStorage(
fmt.Sprintf("%s:%s", cfg.DataDbCfg().DataDbHost, cfg.DataDbCfg().DataDbPort),
4, cfg.DataDbCfg().DataDbUser, cfg.DataDbCfg().DataDbPass, cfg.GeneralCfg().DBDataEncoding,
- utils.REDIS_MAX_CONNS, "", false, 0, 0)
+ utils.REDIS_MAX_CONNS, "", false, 0, 0, false, utils.EmptyString, utils.EmptyString, utils.EmptyString)
if err != nil {
t.Fatal("Could not connect to Redis", err.Error())
}
diff --git a/engine/z_filterindexer_it_test.go b/engine/z_filterindexer_it_test.go
index 3f01922fa..2b1535b79 100644
--- a/engine/z_filterindexer_it_test.go
+++ b/engine/z_filterindexer_it_test.go
@@ -80,7 +80,7 @@ func TestFilterIndexerIT(t *testing.T) {
redisDB, err := NewRedisStorage(
fmt.Sprintf("%s:%s", cfg.DataDbCfg().DataDbHost, cfg.DataDbCfg().DataDbPort),
4, cfg.DataDbCfg().DataDbUser, cfg.DataDbCfg().DataDbPass, cfg.GeneralCfg().DBDataEncoding,
- utils.REDIS_MAX_CONNS, "", false, 0, 0)
+ utils.REDIS_MAX_CONNS, "", false, 0, 0, false, utils.EmptyString, utils.EmptyString, utils.EmptyString)
if err != nil {
t.Fatal("Could not connect to Redis", err.Error())
}
diff --git a/engine/z_onstor_it_test.go b/engine/z_onstor_it_test.go
index 815696ade..d52ca8afe 100644
--- a/engine/z_onstor_it_test.go
+++ b/engine/z_onstor_it_test.go
@@ -94,7 +94,7 @@ func TestOnStorIT(t *testing.T) {
rdsITdb, err = NewRedisStorage(
fmt.Sprintf("%s:%s", cfg.DataDbCfg().DataDbHost, cfg.DataDbCfg().DataDbPort),
4, cfg.DataDbCfg().DataDbUser, cfg.DataDbCfg().DataDbPass, cfg.GeneralCfg().DBDataEncoding,
- utils.REDIS_MAX_CONNS, "", false, 0, 0)
+ utils.REDIS_MAX_CONNS, "", false, 0, 0, false, utils.EmptyString, utils.EmptyString, utils.EmptyString)
if err != nil {
t.Fatal("Could not connect to Redis", err.Error())
}
diff --git a/general_tests/redis_tls_it_test.go b/general_tests/redis_tls_it_test.go
new file mode 100644
index 000000000..9691a4702
--- /dev/null
+++ b/general_tests/redis_tls_it_test.go
@@ -0,0 +1,155 @@
+// +build integration
+
+/*
+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 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+*/
+
+package general_tests
+
+import (
+ "flag"
+ "net/rpc"
+ "os/exec"
+ "path"
+ "reflect"
+ "testing"
+
+ "github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/utils"
+)
+
+var (
+ redisTLS = flag.Bool("redis_tls", false, "Run tests with redis tls")
+ redisTLSServer *exec.Cmd
+ redisTLSEngineCfg = path.Join(*dataDir, "conf", "samples", "tutredis_tls")
+ redisTLSCfg *config.CGRConfig
+ redisTLSRPC *rpc.Client
+
+ sTestsRedisTLS = []func(t *testing.T){
+ testRedisTLSStartServer,
+ testRedisTLSInitConfig,
+ testRedisTLSFlushDb,
+ testRedisTLSStartEngine,
+ testRedisTLSRPCCon,
+ testRedisTLSSetGetAttribute,
+ testRedisTLSKillEngine,
+ }
+)
+
+// Before running these tests first you need to make sure you build the redis server with TLS support
+// https://redis.io/topics/encryption
+func TestRedisTLS(t *testing.T) {
+ if !*redisTLS {
+ return
+ }
+ switch *dbType {
+ case utils.MetaMySQL:
+ case utils.MetaInternal,
+ utils.MetaMongo,
+ utils.MetaPostgres:
+ t.SkipNow()
+ default:
+ t.Fatal("Unknown Database type")
+ }
+ for _, stest := range sTestsRedisTLS {
+ t.Run("TestRedisTLS", stest)
+ }
+}
+
+func testRedisTLSStartServer(t *testing.T) {
+ // start the server with the server.crt server.key and ca.crt from /data/tls ( self sign certificate )
+ args := []string{
+ "--tls-port", "6400", "--port", "0", "--tls-cert-file", "/usr/share/cgrates/tls/server.crt",
+ "--tls-key-file", "/usr/share/cgrates/tls/server.key", "--tls-ca-cert-file", "/usr/share/cgrates/tls/ca.crt",
+ }
+ redisTLSServer = exec.Command("redis-server", args...)
+ if err := redisTLSServer.Start(); err != nil {
+ t.Error(err)
+ }
+}
+
+func testRedisTLSInitConfig(t *testing.T) {
+ var err error
+ redisTLSCfg, err = config.NewCGRConfigFromPath(redisTLSEngineCfg)
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func testRedisTLSFlushDb(t *testing.T) {
+ if err := engine.InitDataDb(redisTLSCfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testRedisTLSStartEngine(t *testing.T) {
+ // for the engine we will use the client.crt client.key and ca.crt
+ if _, err := engine.StopStartEngine(redisTLSEngineCfg, 2000); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testRedisTLSRPCCon(t *testing.T) {
+ var err error
+ redisTLSRPC, err = newRPCClient(redisTLSCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testRedisTLSSetGetAttribute(t *testing.T) {
+ alsPrf := &engine.AttributeProfile{
+ Tenant: "cgrates.org",
+ ID: "ApierTest",
+ Contexts: []string{utils.MetaSessionS, utils.MetaCDRs},
+ FilterIDs: []string{"*string:~*req.Account:1001"},
+ Attributes: []*engine.Attribute{
+ {
+ Path: utils.MetaReq + utils.NestingSep + utils.Subject,
+ Value: config.NewRSRParsersMustCompile("1001", utils.INFIELD_SEP),
+ },
+ },
+ Weight: 20,
+ }
+ alsPrf.Compile()
+ var result string
+ if err := redisTLSRPC.Call(utils.APIerSv1SetAttributeProfile, alsPrf, &result); err != nil {
+ t.Error(err)
+ } else if result != utils.OK {
+ t.Error("Unexpected reply returned", result)
+ }
+ var reply *engine.AttributeProfile
+ if err := redisTLSRPC.Call(utils.APIerSv1GetAttributeProfile,
+ &utils.TenantID{Tenant: "cgrates.org", ID: "ApierTest"}, &reply); err != nil {
+ t.Fatal(err)
+ }
+ reply.Compile()
+ if !reflect.DeepEqual(alsPrf, reply) {
+ t.Errorf("Expecting : %+v, received: %+v", alsPrf, reply)
+ }
+}
+
+func testRedisTLSKillEngine(t *testing.T) {
+ if err := exec.Command("pkill", "redis-server").Run(); err != nil {
+ t.Error(err)
+ }
+
+ if err := engine.KillEngine(2000); err != nil {
+ t.Error(err)
+ }
+}
diff --git a/packages/debian/changelog b/packages/debian/changelog
index 54caff481..f84df5b31 100644
--- a/packages/debian/changelog
+++ b/packages/debian/changelog
@@ -111,6 +111,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
* [ActionsS] Add prefix *acnt and *act to cdrLog action
* [AttributeS] Add support for *prefix and *suffix type
* [ConfigS] Add "redis_" prefix to "dataDB" option for redis
+ * [DataDB] Add support for redis with TLS connection ( + integration test )
-- DanB Wed, 19 Feb 2020 13:25:52 +0200
diff --git a/services/datadb_it_test.go b/services/datadb_it_test.go
index ce898fdb0..db43f775f 100644
--- a/services/datadb_it_test.go
+++ b/services/datadb_it_test.go
@@ -86,6 +86,10 @@ func TestDataDBReload(t *testing.T) {
utils.RedisClusterSyncCfg: "5s",
utils.RedisClusterCfg: false,
utils.RedisSentinelNameCfg: "",
+ utils.RedisTLS: false,
+ utils.RedisClientCertificate: "",
+ utils.RedisClientKey: "",
+ utils.RedisCACertificate: "",
},
RmtConns: []string{},
RplConns: []string{},
diff --git a/utils/consts.go b/utils/consts.go
index 0efd9147c..f3bae707a 100755
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -1927,6 +1927,9 @@ const (
RedisClusterSyncCfg = "redis_cluster_sync"
RedisClusterOnDownDelayCfg = "redis_cluster_ondown_delay"
RedisTLS = "redis_tls"
+ RedisClientCertificate = "redis_client_certificate"
+ RedisClientKey = "redis_client_key"
+ RedisCACertificate = "redis_ca_certificate"
)
// ItemOpt