Skip to content

Commit ab91cd0

Browse files
(FFM-6136) Add redis connection string support (#122)
1 parent 434bb12 commit ab91cd0

File tree

5 files changed

+41
-9
lines changed

5 files changed

+41
-9
lines changed

cache/redis_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (r *RedisCache) Remove(ctx context.Context, key string, field string) {
110110
func (r *RedisCache) HealthCheck(ctx context.Context) error {
111111
res := r.client.Ping(ctx)
112112
if res.Err() != nil {
113-
return fmt.Errorf("redis failed to respond")
113+
return fmt.Errorf("redis failed to respond err: %s", res.Err())
114114
}
115115
return nil
116116
}

cmd/ff-proxy/main.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,14 +339,32 @@ func main() {
339339
// if we're just generating the offline config we should only use in memory mode for now
340340
// when we move to a pattern of allowing periodic config dumps to disk we can remove this requirement
341341
if redisAddress != "" && !generateOfflineConfig {
342-
client := redis.NewClient(&redis.Options{
343-
Addr: redisAddress,
344-
Password: redisPassword,
345-
DB: redisDB,
346-
})
342+
// if address does not start with redis:// or rediss:// then default to redis://
343+
// if the connection string starts with rediss:// it means we'll connect with TLS enabled
344+
redisConnectionString := redisAddress
345+
if !strings.HasPrefix(redisAddress, "redis://") && !strings.HasPrefix(redisAddress, "rediss://") {
346+
redisConnectionString = fmt.Sprintf("redis://%s", redisAddress)
347+
}
348+
parsed, err := redis.ParseURL(redisConnectionString)
349+
if err != nil {
350+
logger.Error("failed to parse redis address url", "connection string", redisConnectionString, "err", err)
351+
os.Exit(1)
352+
}
353+
// TODO - going forward we can open up support for more of these query param connection string options e.g. max_retries etc
354+
// we would first need to test the impact that these would have if unset vs current defaults
355+
opts := redis.UniversalOptions{}
356+
opts.DB = parsed.DB
357+
opts.Addrs = []string{parsed.Addr}
358+
opts.Username = parsed.Username
359+
opts.Password = parsed.Password
360+
opts.TLSConfig = parsed.TLSConfig
361+
if redisPassword != "" {
362+
opts.Password = redisPassword
363+
}
364+
client := redis.NewUniversalClient(&opts)
347365
logger.Info("connecting to redis", "address", redisAddress)
348366
sdkCache = cache.NewRedisCache(client)
349-
err := sdkCache.HealthCheck(ctx)
367+
err = sdkCache.HealthCheck(ctx)
350368
if err != nil {
351369
logger.Error("failed to connect to redis", "err", err)
352370
os.Exit(1)

docs/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ Config required to connect to redis. Note only `REDIS_ADDRESS` is required to co
3535

3636
| Environment Variable | Flag | Description | Type | Default |
3737
|----------------------|----------------|--------------------------------------------------------------------|--------|---------|
38-
| REDIS_ADDRESS | redis-address | Redis host:port address. | string | |
38+
| REDIS_ADDRESS | redis-address | Redis host:port address. See below for info on connecting via TLS | string | |
3939
| REDIS_PASSWORD | redis-db | (Optional) Database to be selected after connecting to the server. | string | |
4040
| REDIS_DB | redis-password | (Optional) Redis password. | int | 0 |
4141

42+
**Connecting to Redis via TLS:** To connect to a redis instance which has TLS enabled you should prepend `rediss://` to the beginning of your REDIS_ADDRESS url e.g. `rediss://localhost:6379`
43+
4244
### Debug
4345
Enable debug logging.
4446

docs/debugging.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ The response will look something like this:
1515

1616
`{"cache":"healthy","env-0000-0000-0000-0000-0000":"healthy", "env-0000-0000-0000-0000-0002":"healthy"}`
1717

18+
If you've configured a custom port using the PORT environment variable your healthcheck should point at that port instead e.g. for port 10000 it would be set to:
19+
20+
`curl https://localhost:10000/health`
21+
1822
If using a Redis cache the cache healthcheck will verify that we could successfully ping the Redis client.
1923

20-
You will have a health entry for each environment you've configured the Relay Proxy with. This will display if your streaming connection for these environments is healthy. You can find which friendly environment identifier this UUID maps to by checking your proxy startup logs.
24+
You will have a health entry for each environment you've configured the Relay Proxy with. This will display if your streaming connection for these environments is healthy. You can find which friendly environment identifier this UUID maps to by checking your proxy startup logs.
2125

2226

2327
### Sample CURL Requests

docs/redis_cache.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ You can optionally configure the Relay Proxy to store flag data in redis. See [c
55
The Relay Proxy does not currently support clustered Redis or Redis Sentinel.
66

77

8+
9+
## FAQs
10+
### Can the Relay Proxy be connected to an Elasticache redis instance?
11+
Yes. Relay Proxy can connect to Elasticache redis instances as long as cluster mode is disabled.
12+
13+
### Can I connect to Redis instances which have TLS enabled?
14+
Yes. To connect to a redis instance which has TLS enabled you just need to prepend the REDIS_ADDRESS location with `rediss://` e.g. `rediss://localhost:6379`.
15+
816
### What happens if network connection is lost?
917
If connection is lost to Harness servers the Relay Proxy will continue to serve the cached values to connected sdks.
1018

0 commit comments

Comments
 (0)