From f1c823761bb4eb35c4aba2a9b5f39f0705793f66 Mon Sep 17 00:00:00 2001 From: TeoV Date: Thu, 15 Oct 2020 16:34:36 +0300 Subject: [PATCH] [DataDB] Add support for redis with TLS connection ( + integration test ) fixes #2435 --- cmd/cgr-loader/cgr-loader.go | 18 +++ cmd/cgr-loader/cgr-loader_it_test.go | 4 + cmd/cgr-migrator/cgr-migrator.go | 18 +++ config/config_defaults.go | 11 +- config/config_json_test.go | 7 + config/config_test.go | 4 + config/migratorcfg_test.go | 23 ++- data/conf/samples/tutredis_tls/cgrates.json | 47 ++++++ engine/storage_redis.go | 36 ++++- engine/storage_utils.go | 9 +- engine/z_datamanager_it_test.go | 2 +- engine/z_filterindexer_it_test.go | 2 +- engine/z_onstor_it_test.go | 2 +- general_tests/redis_tls_it_test.go | 155 ++++++++++++++++++++ packages/debian/changelog | 1 + services/datadb_it_test.go | 4 + utils/consts.go | 3 + 17 files changed, 333 insertions(+), 13 deletions(-) create mode 100755 data/conf/samples/tutredis_tls/cgrates.json create mode 100644 general_tests/redis_tls_it_test.go 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