You've already forked oauth2-proxy
mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-08-08 22:46:33 +02:00
Parse Redis cluster and sentinel urls (#573)
* Parse Redis cluster and sentinel urls * Add changelog entry for #573 * Add unit tests for redis session store * Use %v for error fmt Co-authored-by: Amnay Mokhtari <amnay.mokhtari@adevinta.com> Co-authored-by: Joel Speed <Joel.speed@hotmail.co.uk>
This commit is contained in:
@ -60,16 +60,24 @@ func newRedisCmdable(opts options.RedisStoreOptions) (Client, error) {
|
||||
}
|
||||
|
||||
if opts.UseSentinel {
|
||||
addrs, err := parseRedisURLs(opts.SentinelConnectionURLs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse redis urls: %v", err)
|
||||
}
|
||||
client := redis.NewFailoverClient(&redis.FailoverOptions{
|
||||
MasterName: opts.SentinelMasterName,
|
||||
SentinelAddrs: opts.SentinelConnectionURLs,
|
||||
SentinelAddrs: addrs,
|
||||
})
|
||||
return newClient(client), nil
|
||||
}
|
||||
|
||||
if opts.UseCluster {
|
||||
addrs, err := parseRedisURLs(opts.ClusterConnectionURLs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse redis urls: %v", err)
|
||||
}
|
||||
client := redis.NewClusterClient(&redis.ClusterOptions{
|
||||
Addrs: opts.ClusterConnectionURLs,
|
||||
Addrs: addrs,
|
||||
})
|
||||
return newClusterClient(client), nil
|
||||
}
|
||||
@ -108,6 +116,20 @@ func newRedisCmdable(opts options.RedisStoreOptions) (Client, error) {
|
||||
return newClient(client), nil
|
||||
}
|
||||
|
||||
// parseRedisURLs parses a list of redis urls and returns a list
|
||||
// of addresses in the form of host:port that can be used to connnect to Redis
|
||||
func parseRedisURLs(urls []string) ([]string, error) {
|
||||
addrs := []string{}
|
||||
for _, u := range urls {
|
||||
parsedURL, err := redis.ParseURL(u)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse redis url: %v", err)
|
||||
}
|
||||
addrs = append(addrs, parsedURL.Addr)
|
||||
}
|
||||
return addrs, 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 {
|
||||
|
60
pkg/sessions/redis/redis_store_test.go
Normal file
60
pkg/sessions/redis/redis_store_test.go
Normal file
@ -0,0 +1,60 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/Bose/minisentinel"
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRedisStore(t *testing.T) {
|
||||
t.Run("save session on redis standalone", func(t *testing.T) {
|
||||
redisServer, err := miniredis.Run()
|
||||
require.NoError(t, err)
|
||||
defer redisServer.Close()
|
||||
opts := options.NewOptions()
|
||||
redisURL := url.URL{
|
||||
Scheme: "redis",
|
||||
Host: redisServer.Addr(),
|
||||
}
|
||||
opts.Session.Redis.ConnectionURL = redisURL.String()
|
||||
redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie)
|
||||
require.NoError(t, err)
|
||||
err = redisStore.Save(
|
||||
httptest.NewRecorder(),
|
||||
httptest.NewRequest(http.MethodGet, "/", nil),
|
||||
&sessions.SessionState{})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("save session on redis sentinel", func(t *testing.T) {
|
||||
redisServer, err := miniredis.Run()
|
||||
require.NoError(t, err)
|
||||
defer redisServer.Close()
|
||||
sentinel := minisentinel.NewSentinel(redisServer)
|
||||
err = sentinel.Start()
|
||||
require.NoError(t, err)
|
||||
defer sentinel.Close()
|
||||
opts := options.NewOptions()
|
||||
sentinelURL := url.URL{
|
||||
Scheme: "redis",
|
||||
Host: sentinel.Addr(),
|
||||
}
|
||||
opts.Session.Redis.SentinelConnectionURLs = []string{sentinelURL.String()}
|
||||
opts.Session.Redis.UseSentinel = true
|
||||
opts.Session.Redis.SentinelMasterName = sentinel.MasterInfo().Name
|
||||
redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie)
|
||||
require.NoError(t, err)
|
||||
err = redisStore.Save(
|
||||
httptest.NewRecorder(),
|
||||
httptest.NewRequest(http.MethodGet, "/", nil),
|
||||
&sessions.SessionState{})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user