Skip to content

Commit

Permalink
handle deprecated redis address config
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Torubarov <[email protected]>
  • Loading branch information
arttor committed Nov 18, 2024
1 parent adb6e9e commit 030f2c1
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 20 deletions.
16 changes: 12 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Common struct {

type Redis struct {
// Deprecated: Address is deprecated: use Addresses
// If Addresses set, Address will be ignored
Address string `yaml:"address"`
Addresses []string `yaml:"addresses"`
Sentinel RedisSentinel `yaml:"sentinel"`
Expand All @@ -68,15 +69,22 @@ type TLS struct {
}

func (r *Redis) validate() error {
if r.Address != "" && len(r.Addresses) != 0 {
return fmt.Errorf("invalid redis config: either address or addresses must be used, but not both")
}
if r.Address == "" && len(r.Addresses) == 0 {
if len(r.GetAddresses()) == 0 {
return fmt.Errorf("invalid redis config: address is not set")
}
return nil
}

func (r *Redis) GetAddresses() []string {
if len(r.Addresses) != 0 {
return r.Addresses
}
if r.Address != "" {
return []string{r.Address}
}
return nil
}

func Get(conf any, sources ...Src) error {
data, err := configFile.Open("config.yaml")
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ trace:
endpoint: # url to Jaeger or other open trace provider
redis:
# redis master address for standalone installation
# will be ignored if addresses is set
address: "127.0.0.1:6379"
# list of redis addresses for HA (cluster or sentinel) setup
addresses: []
Expand Down
73 changes: 69 additions & 4 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"reflect"
"testing"

"github.com/clyso/chorus/pkg/s3"
Expand All @@ -27,9 +28,16 @@ func TestOverride(t *testing.T) {
r.EqualValues(69, conf.Metrics.Port)
r.EqualValues("info", conf.Log.Level)
r.EqualValues(true, conf.Log.Json)
r.Empty(conf.Redis.Password)
r.NotEmpty(conf.Redis.Address)

r.EqualValues("user", conf.Redis.User)
r.EqualValues("pass", conf.Redis.Password)
r.EqualValues("sentinel", conf.Redis.Sentinel.User)
r.EqualValues("sentinel-pass", conf.Redis.Sentinel.Password)
r.EqualValues("master", conf.Redis.Sentinel.MasterName)
r.True(conf.Redis.TLS.Enabled)
r.True(conf.Redis.TLS.Insecure)

}

func TestOverride2(t *testing.T) {
Expand All @@ -42,13 +50,15 @@ func TestOverride2(t *testing.T) {
r.EqualValues(420, conf.Metrics.Port)
r.EqualValues("info", conf.Log.Level)
r.EqualValues(true, conf.Log.Json)
r.Empty(conf.Redis.Password)
r.NotEmpty(conf.Redis.Address)
r.Empty(conf.Redis.Addresses)
r.EqualValues([]string{conf.Redis.Address}, conf.Redis.GetAddresses())
}

func TestOverrideEnv(t *testing.T) {
t.Setenv("CFG_METRICS_PORT", "55")
t.Setenv("CFG_REDIS_PASSWORD", "secret")
t.Setenv("CFG_REDIS_ADDRESSES", "a,b,c")

r := require.New(t)
var conf Common
Expand All @@ -60,6 +70,8 @@ func TestOverrideEnv(t *testing.T) {
r.EqualValues(true, conf.Log.Json)
r.EqualValues("secret", conf.Redis.Password)
r.NotEmpty(conf.Redis.Address)
r.EqualValues([]string{"a", "b", "c"}, conf.Redis.Addresses, "redis addresses set from env")
r.EqualValues([]string{"a", "b", "c"}, conf.Redis.GetAddresses(), "address is ignored")
}

func TestStorageConfig_RateLimitConf(t *testing.T) {
Expand Down Expand Up @@ -127,12 +139,12 @@ func TestRedis_validate(t *testing.T) {
wantErr: true,
},
{
name: "invalid: both addresses set",
name: "valid: both addresses set",
fields: fields{
Address: "addr",
Addresses: []string{"addr"},
},
wantErr: true,
wantErr: false,
},
{
name: "valid: only address set",
Expand Down Expand Up @@ -177,3 +189,56 @@ func TestRedis_validate(t *testing.T) {
})
}
}

func TestRedis_GetAddresses(t *testing.T) {
type fields struct {
Address string
Addresses []string
}
tests := []struct {
name string
fields fields
want []string
}{
{
name: "only address is set",
fields: fields{
Address: "a",
Addresses: []string{},
},
want: []string{"a"},
},
{
name: "only addresses are set",
fields: fields{
Address: "",
Addresses: []string{"a", "b"},
},
want: []string{"a", "b"},
},
{
name: "address is ignored when addresses set",
fields: fields{
Address: "a",
Addresses: []string{"b", "c"},
},
want: []string{"b", "c"},
},
{
name: "nothing is set",
fields: fields{},
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Redis{
Address: tt.fields.Address,
Addresses: tt.fields.Addresses,
}
if got := r.GetAddresses(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Redis.GetAddresses() = %v, want %v", got, tt.want)
}
})
}
}
13 changes: 12 additions & 1 deletion pkg/config/override_test.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
log:
json: true
metrics:
port: 69
port: 69
redis:
user: user
password: pass
tls:
enabled: true
insecure: true
sentinel:
masterName: master
user: sentinel
password: sentinel-pass

16 changes: 5 additions & 11 deletions pkg/util/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import (
)

func NewRedis(conf *config.Redis, db int) redis.UniversalClient {
if conf.Address != "" {
conf.Addresses = append(conf.Addresses, conf.Address)
}
opt := &redis.UniversalOptions{
Addrs: conf.Addresses,
Addrs: conf.GetAddresses(),
DB: db,
Username: conf.User,
Password: conf.Password,
Expand All @@ -28,12 +25,9 @@ func NewRedis(conf *config.Redis, db int) redis.UniversalClient {
}

func NewRedisAsynq(conf *config.Redis, db int) asynq.RedisConnOpt {
if conf.Address != "" {
conf.Addresses = append(conf.Addresses, conf.Address)
}
if len(conf.Addresses) == 1 {
if len(conf.GetAddresses()) == 1 {
// Standalone
opt := asynq.RedisClientOpt{Addr: conf.Addresses[0], Username: conf.User, Password: conf.Password, DB: db}
opt := asynq.RedisClientOpt{Addr: conf.GetAddresses()[0], Username: conf.User, Password: conf.Password, DB: db}
if conf.TLS.Enabled {
opt.TLSConfig = &tls.Config{InsecureSkipVerify: conf.TLS.Insecure}
}
Expand All @@ -44,7 +38,7 @@ func NewRedisAsynq(conf *config.Redis, db int) asynq.RedisConnOpt {
// Sentinel
opt := asynq.RedisFailoverClientOpt{
MasterName: conf.Sentinel.MasterName,
SentinelAddrs: conf.Addresses,
SentinelAddrs: conf.GetAddresses(),
SentinelPassword: conf.Sentinel.Password,
Username: conf.User,
Password: conf.Password,
Expand All @@ -57,7 +51,7 @@ func NewRedisAsynq(conf *config.Redis, db int) asynq.RedisConnOpt {
}
// Cluster
opt := asynq.RedisClusterClientOpt{
Addrs: conf.Addresses,
Addrs: conf.GetAddresses(),
Username: conf.User,
Password: conf.Password,
}
Expand Down

0 comments on commit 030f2c1

Please sign in to comment.