diff --git a/ring.go b/ring.go index 1f75913a3..60dbe6742 100644 --- a/ring.go +++ b/ring.go @@ -13,6 +13,7 @@ import ( "github.com/cespare/xxhash/v2" "github.com/dgryski/go-rendezvous" //nolint + "github.com/redis/go-redis/v9/auth" "github.com/redis/go-redis/v9/internal" "github.com/redis/go-redis/v9/internal/hashtag" @@ -73,7 +74,24 @@ type RingOptions struct { Protocol int Username string Password string - DB int + // CredentialsProvider allows the username and password to be updated + // before reconnecting. It should return the current username and password. + CredentialsProvider func() (username string, password string) + + // CredentialsProviderContext is an enhanced parameter of CredentialsProvider, + // done to maintain API compatibility. In the future, + // there might be a merge between CredentialsProviderContext and CredentialsProvider. + // There will be a conflict between them; if CredentialsProviderContext exists, we will ignore CredentialsProvider. + CredentialsProviderContext func(ctx context.Context) (username string, password string, err error) + + // StreamingCredentialsProvider is used to retrieve the credentials + // for the connection from an external source. Those credentials may change + // during the connection lifetime. This is useful for managed identity + // scenarios where the credentials are retrieved from an external source. + // + // Currently, this is a placeholder for the future implementation. + StreamingCredentialsProvider auth.StreamingCredentialsProvider + DB int MaxRetries int MinRetryBackoff time.Duration @@ -154,10 +172,11 @@ func (opt *RingOptions) clientOptions() *Options { Dialer: opt.Dialer, OnConnect: opt.OnConnect, - Protocol: opt.Protocol, - Username: opt.Username, - Password: opt.Password, - DB: opt.DB, + Protocol: opt.Protocol, + Username: opt.Username, + Password: opt.Password, + CredentialsProvider: opt.CredentialsProvider, + DB: opt.DB, MaxRetries: -1, diff --git a/sentinel.go b/sentinel.go index 43fbcd244..04c0f7269 100644 --- a/sentinel.go +++ b/sentinel.go @@ -12,6 +12,7 @@ import ( "sync" "time" + "github.com/redis/go-redis/v9/auth" "github.com/redis/go-redis/v9/internal" "github.com/redis/go-redis/v9/internal/pool" "github.com/redis/go-redis/v9/internal/rand" @@ -60,7 +61,24 @@ type FailoverOptions struct { Protocol int Username string Password string - DB int + // CredentialsProvider allows the username and password to be updated + // before reconnecting. It should return the current username and password. + CredentialsProvider func() (username string, password string) + + // CredentialsProviderContext is an enhanced parameter of CredentialsProvider, + // done to maintain API compatibility. In the future, + // there might be a merge between CredentialsProviderContext and CredentialsProvider. + // There will be a conflict between them; if CredentialsProviderContext exists, we will ignore CredentialsProvider. + CredentialsProviderContext func(ctx context.Context) (username string, password string, err error) + + // StreamingCredentialsProvider is used to retrieve the credentials + // for the connection from an external source. Those credentials may change + // during the connection lifetime. This is useful for managed identity + // scenarios where the credentials are retrieved from an external source. + // + // Currently, this is a placeholder for the future implementation. + StreamingCredentialsProvider auth.StreamingCredentialsProvider + DB int MaxRetries int MinRetryBackoff time.Duration @@ -107,10 +125,13 @@ func (opt *FailoverOptions) clientOptions() *Options { Dialer: opt.Dialer, OnConnect: opt.OnConnect, - DB: opt.DB, - Protocol: opt.Protocol, - Username: opt.Username, - Password: opt.Password, + DB: opt.DB, + Protocol: opt.Protocol, + Username: opt.Username, + Password: opt.Password, + CredentialsProvider: opt.CredentialsProvider, + CredentialsProviderContext: opt.CredentialsProviderContext, + StreamingCredentialsProvider: opt.StreamingCredentialsProvider, MaxRetries: opt.MaxRetries, MinRetryBackoff: opt.MinRetryBackoff, @@ -187,9 +208,12 @@ func (opt *FailoverOptions) clusterOptions() *ClusterOptions { Dialer: opt.Dialer, OnConnect: opt.OnConnect, - Protocol: opt.Protocol, - Username: opt.Username, - Password: opt.Password, + Protocol: opt.Protocol, + Username: opt.Username, + Password: opt.Password, + CredentialsProvider: opt.CredentialsProvider, + CredentialsProviderContext: opt.CredentialsProviderContext, + StreamingCredentialsProvider: opt.StreamingCredentialsProvider, MaxRedirects: opt.MaxRetries, diff --git a/universal.go b/universal.go index a1ce17bac..9d51b928e 100644 --- a/universal.go +++ b/universal.go @@ -5,6 +5,8 @@ import ( "crypto/tls" "net" "time" + + "github.com/redis/go-redis/v9/auth" ) // UniversalOptions information is required by UniversalClient to establish @@ -26,9 +28,27 @@ type UniversalOptions struct { Dialer func(ctx context.Context, network, addr string) (net.Conn, error) OnConnect func(ctx context.Context, cn *Conn) error - Protocol int - Username string - Password string + Protocol int + Username string + Password string + // CredentialsProvider allows the username and password to be updated + // before reconnecting. It should return the current username and password. + CredentialsProvider func() (username string, password string) + + // CredentialsProviderContext is an enhanced parameter of CredentialsProvider, + // done to maintain API compatibility. In the future, + // there might be a merge between CredentialsProviderContext and CredentialsProvider. + // There will be a conflict between them; if CredentialsProviderContext exists, we will ignore CredentialsProvider. + CredentialsProviderContext func(ctx context.Context) (username string, password string, err error) + + // StreamingCredentialsProvider is used to retrieve the credentials + // for the connection from an external source. Those credentials may change + // during the connection lifetime. This is useful for managed identity + // scenarios where the credentials are retrieved from an external source. + // + // Currently, this is a placeholder for the future implementation. + StreamingCredentialsProvider auth.StreamingCredentialsProvider + SentinelUsername string SentinelPassword string @@ -96,9 +116,12 @@ func (o *UniversalOptions) Cluster() *ClusterOptions { Dialer: o.Dialer, OnConnect: o.OnConnect, - Protocol: o.Protocol, - Username: o.Username, - Password: o.Password, + Protocol: o.Protocol, + Username: o.Username, + Password: o.Password, + CredentialsProvider: o.CredentialsProvider, + CredentialsProviderContext: o.CredentialsProviderContext, + StreamingCredentialsProvider: o.StreamingCredentialsProvider, MaxRedirects: o.MaxRedirects, ReadOnly: o.ReadOnly, @@ -147,10 +170,14 @@ func (o *UniversalOptions) Failover() *FailoverOptions { Dialer: o.Dialer, OnConnect: o.OnConnect, - DB: o.DB, - Protocol: o.Protocol, - Username: o.Username, - Password: o.Password, + DB: o.DB, + Protocol: o.Protocol, + Username: o.Username, + Password: o.Password, + CredentialsProvider: o.CredentialsProvider, + CredentialsProviderContext: o.CredentialsProviderContext, + StreamingCredentialsProvider: o.StreamingCredentialsProvider, + SentinelUsername: o.SentinelUsername, SentinelPassword: o.SentinelPassword, @@ -199,10 +226,13 @@ func (o *UniversalOptions) Simple() *Options { Dialer: o.Dialer, OnConnect: o.OnConnect, - DB: o.DB, - Protocol: o.Protocol, - Username: o.Username, - Password: o.Password, + DB: o.DB, + Protocol: o.Protocol, + Username: o.Username, + Password: o.Password, + CredentialsProvider: o.CredentialsProvider, + CredentialsProviderContext: o.CredentialsProviderContext, + StreamingCredentialsProvider: o.StreamingCredentialsProvider, MaxRetries: o.MaxRetries, MinRetryBackoff: o.MinRetryBackoff,