From faee8678439aa283cf19ab4185d0e348e702a739 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Sat, 28 Aug 2021 23:47:14 +0900 Subject: [PATCH] *: implement a retry logic for auth old revision in the client --- api/v3rpc/rpctypes/error.go | 2 ++ client/v3/retry_interceptor.go | 3 ++- server/etcdserver/api/v3rpc/util.go | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/api/v3rpc/rpctypes/error.go b/api/v3rpc/rpctypes/error.go index 72a58b9ee2dc..a32d7d8b8c95 100644 --- a/api/v3rpc/rpctypes/error.go +++ b/api/v3rpc/rpctypes/error.go @@ -65,6 +65,7 @@ var ( ErrGRPCAuthNotEnabled = status.New(codes.FailedPrecondition, "etcdserver: authentication is not enabled").Err() ErrGRPCInvalidAuthToken = status.New(codes.Unauthenticated, "etcdserver: invalid auth token").Err() ErrGRPCInvalidAuthMgmt = status.New(codes.InvalidArgument, "etcdserver: invalid auth management").Err() + ErrGRPCAuthOldRevision = status.New(codes.InvalidArgument, "etcdserver: revision of auth store is old").Err() ErrGRPCNoLeader = status.New(codes.Unavailable, "etcdserver: no leader").Err() ErrGRPCNotLeader = status.New(codes.FailedPrecondition, "etcdserver: not leader").Err() @@ -131,6 +132,7 @@ var ( ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled, ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken, ErrorDesc(ErrGRPCInvalidAuthMgmt): ErrGRPCInvalidAuthMgmt, + ErrorDesc(ErrGRPCAuthOldRevision): ErrGRPCAuthOldRevision, ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, ErrorDesc(ErrGRPCNotLeader): ErrGRPCNotLeader, diff --git a/client/v3/retry_interceptor.go b/client/v3/retry_interceptor.go index 218381d93809..776e33d010c1 100644 --- a/client/v3/retry_interceptor.go +++ b/client/v3/retry_interceptor.go @@ -157,7 +157,8 @@ func (c *Client) shouldRefreshToken(err error, callOpts *options) bool { // which is possible when the client token is cleared somehow return c.authTokenBundle != nil // equal to c.Username != "" && c.Password != "" } - return callOpts.retryAuth && rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken + + return callOpts.retryAuth && (errors.Is(err, rpctypes.ErrInvalidAuthToken) || errors.Is(err, rpctypes.ErrGRPCAuthOldRevision)) } // type serverStreamingRetryingStream is the implementation of grpc.ClientStream that acts as a diff --git a/server/etcdserver/api/v3rpc/util.go b/server/etcdserver/api/v3rpc/util.go index 373d430e24fe..f054f29c8112 100644 --- a/server/etcdserver/api/v3rpc/util.go +++ b/server/etcdserver/api/v3rpc/util.go @@ -84,6 +84,7 @@ var toGRPCErrorMap = map[error]error{ auth.ErrAuthNotEnabled: rpctypes.ErrGRPCAuthNotEnabled, auth.ErrInvalidAuthToken: rpctypes.ErrGRPCInvalidAuthToken, auth.ErrInvalidAuthMgmt: rpctypes.ErrGRPCInvalidAuthMgmt, + auth.ErrAuthOldRevision: rpctypes.ErrGRPCAuthOldRevision, // In sync with status.FromContextError context.Canceled: rpctypes.ErrGRPCCanceled,