-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support using redis urls to construct the redis client (#1994)
Currently Athens only supports connecting to Redis using a hostname:port combination in addition to a password. While this works in most cases it also means that if you have other options you wish to supply Athens has to be updated to support them. As a basic example Redis clusters that require TLS currently are not supported by Athens but with this change you can simply supply a [redis url](https://github.com/redis/redis-specifications/blob/master/uri/redis.txt) to connect over TLS. It also makes it easy to override the password, set a username and more all from a single configuration option: `rediss://username:[email protected]:6379/1?protocol=3`
- Loading branch information
Showing
5 changed files
with
130 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -334,7 +334,9 @@ ShutdownTimeout = 60 | |
# Env override: ATHENS_ETCD_ENDPOINTS | ||
Endpoints = "localhost:2379,localhost:22379,localhost:32379" | ||
[SingleFlight.Redis] | ||
# Endpoint is the redis endpoint for a SingleFlight lock. | ||
# Endpoint is the redis endpoint for a SingleFlight lock. Should be either a host:port | ||
# pair or redis url such as: | ||
# redis[s]://user:[email protected]:6379/0?protocol=3 | ||
# TODO(marwan): enable multiple endpoints for redis clusters. | ||
# Env override: ATHENS_REDIS_ENDPOINT | ||
Endpoint = "127.0.0.1:6379" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -445,6 +445,22 @@ You can also optionally specify a password to connect to the redis server with | |
# Env override: ATHENS_REDIS_PASSWORD | ||
Password = "" | ||
|
||
Connecting to Redis via a [redis url](https://github.com/redis/redis-specifications/blob/master/uri/redis.txt) is also | ||
supported: | ||
|
||
SingleFlightType = "redis" | ||
|
||
[SingleFlight] | ||
[SingleFlight.Redis] | ||
# Endpoint is the redis endpoint for the single flight mechanism | ||
# Env override: ATHENS_REDIS_ENDPOINT | ||
# Note, if TLS is required use rediss:// instead. | ||
Endpoint = "redis://user:[email protected]:6379:6379/0?protocol=3" | ||
|
||
If the redis url is invalid or cannot be parsed, Athens will fall back to treating `Endpoint` as if it were | ||
a normal `host:port` pair. If a password is supplied in the redis url, in addition to being provided in the `Password` | ||
configuration option, the two values must match otherwise Athens will fail to start. | ||
|
||
##### Customizing lock configurations: | ||
If you would like to customize the distributed lock options then you can optionally override the default lock config to better suit your use-case: | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,9 @@ import ( | |
"testing" | ||
"time" | ||
|
||
"github.com/go-redis/redis/v8" | ||
"github.com/gomods/athens/pkg/config" | ||
"github.com/gomods/athens/pkg/errors" | ||
"github.com/gomods/athens/pkg/storage" | ||
"github.com/gomods/athens/pkg/storage/mem" | ||
"golang.org/x/sync/errgroup" | ||
|
@@ -120,6 +122,73 @@ func TestWithRedisLockWithWrongPassword(t *testing.T) { | |
} | ||
} | ||
|
||
type getRedisClientOptionsFacet struct { | ||
endpoint string | ||
password string | ||
options *redis.Options | ||
err error | ||
} | ||
|
||
func Test_getRedisClientOptions(t *testing.T) { | ||
facets := []*getRedisClientOptionsFacet{ | ||
{ | ||
endpoint: "127.0.0.1:6379", | ||
options: &redis.Options{ | ||
Addr: "127.0.0.1:6379", | ||
}, | ||
}, | ||
{ | ||
endpoint: "127.0.0.1:6379", | ||
password: "1234", | ||
options: &redis.Options{ | ||
Addr: "127.0.0.1:6379", | ||
Password: "1234", | ||
}, | ||
}, | ||
{ | ||
endpoint: "rediss://username:[email protected]:6379", | ||
password: "1234", // Ignored because password was parsed | ||
err: errors.E("stash.WithRedisLock", errPasswordsDoNotMatch), | ||
}, | ||
{ | ||
endpoint: "rediss://username:[email protected]:6379", | ||
password: "1234", // Ignored because password was parsed | ||
err: errors.E("stash.WithRedisLock", errPasswordsDoNotMatch), | ||
}, | ||
} | ||
|
||
for i, facet := range facets { | ||
options, err := getRedisClientOptions(facet.endpoint, facet.password) | ||
if err != nil && facet.err == nil { | ||
t.Errorf("Facet %d: no error produced", i) | ||
continue | ||
} | ||
if facet.err != nil { | ||
if err == nil { | ||
t.Errorf("Facet %d: no error produced", i) | ||
} else { | ||
if err.Error() != facet.err.Error() { | ||
t.Errorf("Facet %d: expected %q, got %q", i, facet.err, err) | ||
} | ||
} | ||
} | ||
|
||
if err != nil { | ||
continue | ||
} | ||
if facet.options.Addr != options.Addr { | ||
t.Errorf("Facet %d: Expected Addr %q, got %q", i, facet.options.Addr, options.Addr) | ||
} | ||
if facet.options.Username != options.Username { | ||
t.Errorf("Facet %d: Expected Username %q, got %q", i, facet.options.Username, options.Username) | ||
} | ||
if facet.options.Password != options.Password { | ||
t.Errorf("Facet %d: Expected Password %q, got %q", i, facet.options.Password, options.Password) | ||
} | ||
|
||
} | ||
} | ||
|
||
// mockRedisStasher is like mockStasher | ||
// but leverages in memory storage | ||
// so that redis can determine | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters