fix: handle the break change for parse external sentinel redis url (#17501)

Handle the ParseSentinelURL to resolve an incompatible modification that does not recognize the default redis database.

Closes: #17483

Signed-off-by: chlins <chenyuzh@vmware.com>
This commit is contained in:
Chlins Zhang 2022-09-07 11:29:43 +08:00 committed by GitHub
parent a56d927143
commit 9573cd7753
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 8 deletions

View File

@ -27,6 +27,11 @@ import (
"github.com/goharbor/harbor/src/lib/errors"
)
var (
// defaultDBIndex defines the default redis db index
defaultDBIndex = 0
)
// ParseSentinelURL parses sentinel url to redis FailoverOptions.
// It's a modified version of go-redis ParseURL(https://github.com/go-redis/redis/blob/997118894af9d4244d4a471f2b317eead9c9ca62/options.go#L222) because official version does
// not support parse sentinel mode.
@ -45,15 +50,20 @@ func ParseSentinelURL(redisURL string) (*redis.FailoverOptions, error) {
return r == '/'
})
// expect path length is 2, example: [mymaster 1]
if len(f) != 2 {
// but if the db is default(0) which can be ignored, so when the path length is 1, then set db to 0
switch len(f) {
case 1:
o.MasterName = f[0]
o.DB = defaultDBIndex
case 2:
o.MasterName = f[0]
if o.DB, err = strconv.Atoi(f[1]); err != nil {
return nil, errors.Errorf("redis: invalid database number: %q", f[1])
}
default:
return nil, errors.Errorf("redis: invalid redis URL path: %s", u.Path)
}
o.MasterName = f[0]
if o.DB, err = strconv.Atoi(f[1]); err != nil {
return nil, errors.Errorf("redis: invalid database number: %q", f[1])
}
return setupConnParams(u, o)
}

View File

@ -22,9 +22,16 @@ import (
)
func TestParseSentinelURL(t *testing.T) {
url := "redis+sentinel://anonymous:password@host1:26379,host2:26379/mymaster/1?idle_timeout_seconds=30&max_retries=10&min_retry_backoff=1&max_retry_backoff=10&dial_timeout=30&read_timeout=5&write_timeout=5&pool_fifo=true&pool_size=1000&min_idle_conns=100&max_conn_age=10&pool_timeout=10"
// db index should be set to 0 if not specified
url := "redis+sentinel://anonymous:password@host1:26379,host2:26379/mymaster/?idle_timeout_seconds=30"
o, err := ParseSentinelURL(url)
assert.NoError(t, err)
assert.Equal(t, 0, o.DB)
// test options from query
url = "redis+sentinel://anonymous:password@host1:26379,host2:26379/mymaster/1?idle_timeout_seconds=30&max_retries=10&min_retry_backoff=1&max_retry_backoff=10&dial_timeout=30&read_timeout=5&write_timeout=5&pool_fifo=true&pool_size=1000&min_idle_conns=100&max_conn_age=10&pool_timeout=10"
o, err = ParseSentinelURL(url)
assert.NoError(t, err)
assert.Equal(t, "anonymous", o.Username)
assert.Equal(t, "password", o.Password)
assert.Equal(t, []string{"host1:26379", "host2:26379"}, o.SentinelAddrs)
@ -44,7 +51,7 @@ func TestParseSentinelURL(t *testing.T) {
assert.Equal(t, 10*time.Second, o.PoolTimeout)
// invalid url should return err
url = "invalid"
url = "###"
_, err = ParseSentinelURL(url)
assert.Error(t, err, "invalid url should return err")