1
0
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:
Amnay
2020-05-27 19:40:50 +02:00
committed by GitHub
parent 11c8a983c8
commit 6a88da7f7a
5 changed files with 98 additions and 2 deletions

View File

@ -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 {

View 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)
})
}