Skip to content

Commit

Permalink
feat: Add ability to set Redis database and prefix in config (#614)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?

In a blue/green deployment model, two refinery clusters might want to
share the same instance of redis. It's also possible that multiple apps
want to share one redis. This permits that by:
- allowing the redis "database" (an integer from 0-15) to be specified
in the configuration
- allowing the redis "prefix" (a string used in the name of the keys
stored in redis) to be set as well. It already existed but was hardcoded
to "refinery".

## Short description of the changes

- Add RedisDatabase and RedisPrefix to the PeerManagement section of
config.
- Add tests
- Add documentation

Fixes #544
  • Loading branch information
kentquirk authored Feb 24, 2023
1 parent 60fc9c2 commit 4f9ced7
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 2 deletions.
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ type Config interface {
// management.
GetRedisPassword() (string, error)

// GetRedisPrefix returns the prefix string used in the keys for peer
// management.
GetRedisPrefix() string

// GetRedisDatabase returns the ID of the Redis database to use for peer management.
GetRedisDatabase() int

// GetUseTLS returns true when TLS must be enabled to dial the Redis instance to
// use for peer management.
GetUseTLS() (bool, error)
Expand Down
10 changes: 10 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ func TestPeerManagementType(t *testing.T) {
[PeerManagement]
Type = "redis"
Peers = ["http://refinery-1231:8080"]
RedisPrefix = "testPrefix"
RedisDatabase = 9
`, "")
defer os.Remove(rules)
defer os.Remove(config)
Expand All @@ -389,6 +391,14 @@ func TestPeerManagementType(t *testing.T) {
if d, _ := c.GetPeerManagementType(); d != "redis" {
t.Error("received", d, "expected", "redis")
}

if s := c.GetRedisPrefix(); s != "testPrefix" {
t.Error("received", s, "expected", "testPrefix")
}

if db := c.GetRedisDatabase(); db != 9 {
t.Error("received", db, "expected", 9)
}
}

func TestAbsentTraceKeyField(t *testing.T) {
Expand Down
17 changes: 17 additions & 0 deletions config/file_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type PeerManagementConfig struct {
RedisHost string
RedisUsername string
RedisPassword string
RedisPrefix string `validate:"required"`
RedisDatabase int `validate:"gte=0,lte=15"`
UseTLS bool
UseTLSInsecure bool
IdentifierInterfaceName string
Expand Down Expand Up @@ -152,6 +154,7 @@ func NewConfig(config, rules string, errorCallback func(error)) (Config, error)
c.SetDefault("CompressPeerCommunication", true)
c.SetDefault("APIKeys", []string{"*"})
c.SetDefault("PeerManagement.Peers", []string{"http://127.0.0.1:8081"})
c.SetDefault("PeerManagement.RedisPrefix", "refinery")
c.SetDefault("PeerManagement.Type", "file")
c.SetDefault("PeerManagement.UseTLS", false)
c.SetDefault("PeerManagement.UseTLSInsecure", false)
Expand Down Expand Up @@ -507,13 +510,27 @@ func (f *fileConfig) GetRedisUsername() (string, error) {
return f.config.GetString("PeerManagement.RedisUsername"), nil
}

func (f *fileConfig) GetRedisPrefix() string {
f.mux.RLock()
defer f.mux.RUnlock()

return f.config.GetString("PeerManagement.RedisPrefix")
}

func (f *fileConfig) GetRedisPassword() (string, error) {
f.mux.RLock()
defer f.mux.RUnlock()

return f.config.GetString("PeerManagement.RedisPassword"), nil
}

func (f *fileConfig) GetRedisDatabase() int {
f.mux.RLock()
defer f.mux.RUnlock()

return f.config.GetInt("PeerManagement.RedisDatabase")
}

func (f *fileConfig) GetUseTLS() (bool, error) {
f.mux.RLock()
defer f.mux.RUnlock()
Expand Down
16 changes: 16 additions & 0 deletions config/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type MockConfig struct {
GetRedisUsernameVal string
GetRedisPasswordErr error
GetRedisPasswordVal string
GetRedisDatabaseVal int
GetRedisPrefixVal string
GetUseTLSErr error
GetUseTLSVal bool
GetUseTLSInsecureErr error
Expand Down Expand Up @@ -224,6 +226,20 @@ func (m *MockConfig) GetRedisPassword() (string, error) {
return m.GetRedisPasswordVal, m.GetRedisPasswordErr
}

func (m *MockConfig) GetRedisPrefix() string {
m.Mux.RLock()
defer m.Mux.RUnlock()

return m.GetRedisPrefixVal
}

func (m *MockConfig) GetRedisDatabase() int {
m.Mux.RLock()
defer m.Mux.RUnlock()

return m.GetRedisDatabaseVal
}

func (m *MockConfig) GetUseTLS() (bool, error) {
m.Mux.RLock()
defer m.Mux.RUnlock()
Expand Down
14 changes: 14 additions & 0 deletions config_complete.toml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ Metrics = "honeycomb"
# Not eligible for live reload.
# RedisPassword = ""

# RedisPrefix is a string used as a prefix for the keys in redis while storing
# the peer membership. It might be useful to set this in any situation where
# multiple refinery clusters or multiple applications want to share a single
# Redis instance. It may not be blank.
# Default = "refinery"
# RedisPrefix = "customPrefix"

# RedisDatabase is an integer from 0-15 indicating the database number to use
# for the Redis instance storing the peer membership. It might be useful to set
# this in any situation where multiple refinery clusters or multiple
# applications want to share a single Redis instance.
# Default = 0
# RedisDatabase = 1

# UseTLS enables TLS when connecting to redis for peer cluster membership management, and sets the MinVersion to 1.2.
# Not eligible for live reload.
# UseTLS = false
Expand Down
4 changes: 2 additions & 2 deletions internal/peer/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func newRedisPeers(ctx context.Context, c config.Config, done chan struct{}) (Pe

peers := &redisPeers{
store: &redimem.RedisMembership{
Prefix: "refinery",
Prefix: c.GetRedisPrefix(),
Pool: pool,
},
peers: make([]string, 1),
Expand Down Expand Up @@ -225,7 +225,7 @@ func buildOptions(c config.Config) []redis.DialOption {
options := []redis.DialOption{
redis.DialReadTimeout(1 * time.Second),
redis.DialConnectTimeout(1 * time.Second),
redis.DialDatabase(0), // TODO enable multiple databases for multiple samproxies
redis.DialDatabase(c.GetRedisDatabase()),
}

username, _ := c.GetRedisUsername()
Expand Down

0 comments on commit 4f9ced7

Please sign in to comment.