Add Redis sentinel compatibility

(cherry picked from commit ff36b61f8c)
This commit is contained in:
Joel Speed 2019-05-24 17:32:55 +01:00 committed by Brian Van Klaveren
parent fc06e2dbef
commit 518c1d3e8e
3 changed files with 29 additions and 6 deletions

View File

@ -24,6 +24,7 @@ func main() {
upstreams := StringArray{}
skipAuthRegex := StringArray{}
googleGroups := StringArray{}
redisSentinelConnectionURLs := StringArray{}
config := flagSet.String("config", "", "path to config file")
showVersion := flagSet.Bool("version", false, "print version string")
@ -76,7 +77,10 @@ func main() {
flagSet.Bool("cookie-httponly", true, "set HttpOnly cookie flag")
flagSet.String("session-store-type", "cookie", "the session storage provider to use")
flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage type (eg: redis://HOST[:PORT])")
flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage (eg: redis://HOST[:PORT])")
flagSet.Bool("redis-use-sentinel", false, "Connect to redis via sentinels. Must set --redis-sentinel-master-name and --redis-sentinel-conneciton-urls to use this feature")
flagSet.String("redis-sentinel-master-name", "", "Redis sentinel master name. Used in conjuction with --redis-use-sentinel")
flagSet.Var(&redisSentinelConnectionURLs, "redis-sentinel-connection-urls", "List of Redis sentinel conneciton URLs (eg redis://HOST[:PORT]). Used in conjuction with --redis-use-sentinel")
flagSet.String("logging-filename", "", "File to log requests to, empty for stdout")
flagSet.Int("logging-max-size", 100, "Maximum size in megabytes of the log file before rotation")

View File

@ -25,5 +25,8 @@ var RedisSessionStoreType = "redis"
// RedisStoreOptions contains configuration options for the RedisSessionStore.
type RedisStoreOptions struct {
RedisConnectionURL string `flag:"redis-connection-url" cfg:"redis_connection_url" env:"OAUTH2_PROXY_REDIS_CONNECTION_URL"`
RedisConnectionURL string `flag:"redis-connection-url" cfg:"redis_connection_url" env:"OAUTH2_PROXY_REDIS_CONNECTION_URL"`
UseSentinel bool `flag:"redis-use-sentinel" cfg:"redis_use_sentinel" env:"OAUTH2_PROXY_REDIS_USE_SENTINEL"`
SentinelMasterName string `flag:"redis-sentinel-master-name" cfg:"redis_sentinel_master_name" env:"OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME"`
SentinelConnectionURLs []string `flag:"redis-sentinel-connection-urls" cfg:"redis_sentinel_connection_urls" env:"OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS"`
}

View File

@ -36,13 +36,11 @@ type SessionStore struct {
// NewRedisSessionStore initialises a new instance of the SessionStore from
// the configuration given
func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessions.SessionStore, error) {
opt, err := redis.ParseURL(opts.RedisStoreOptions.RedisConnectionURL)
client, err := newRedisClient(opts.RedisStoreOptions)
if err != nil {
return nil, fmt.Errorf("unable to parse redis url: %s", err)
return nil, fmt.Errorf("error constructing redis client: %v", err)
}
client := redis.NewClient(opt)
rs := &SessionStore{
Client: client,
CookieCipher: opts.Cipher,
@ -52,6 +50,24 @@ func NewRedisSessionStore(opts *options.SessionOptions, cookieOpts *options.Cook
}
func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) {
if opts.UseSentinel {
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: opts.SentinelMasterName,
SentinelAddrs: opts.SentinelConnectionURLs,
})
return client, nil
}
opt, err := redis.ParseURL(opts.RedisConnectionURL)
if err != nil {
return nil, fmt.Errorf("unable to parse redis url: %s", err)
}
client := redis.NewClient(opt)
return client, nil
}
// Save takes a sessions.SessionState and stores the information from it
// to redies, and adds a new ticket cookie on the HTTP response writer
func (store *SessionStore) Save(rw http.ResponseWriter, req *http.Request, s *sessions.SessionState) error {