diff --git a/src/lib/cache/redis/util.go b/src/lib/cache/redis/util.go index d55907347..f6b25ca71 100644 --- a/src/lib/cache/redis/util.go +++ b/src/lib/cache/redis/util.go @@ -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) } diff --git a/src/lib/cache/redis/util_test.go b/src/lib/cache/redis/util_test.go index 0e3d0fe0f..9d862e537 100644 --- a/src/lib/cache/redis/util_test.go +++ b/src/lib/cache/redis/util_test.go @@ -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")