From cde7af72b5e319578f8e4974177aac000d1d97ed Mon Sep 17 00:00:00 2001 From: shawwang Date: Wed, 11 Mar 2020 23:55:05 +0800 Subject: [PATCH] etcdserver: fix #11689 LeaseRevoke may fail to apply when authentication is enabled and upgrading cluster from etcd-3.2 to etcd-3.3 --- auth/store.go | 37 +++++++++++++++++++++++++++++++++++++ etcdserver/v3_server.go | 3 +++ 2 files changed, 40 insertions(+) diff --git a/auth/store.go b/auth/store.go index 2e07897da75e..0bf99b540149 100644 --- a/auth/store.go +++ b/auth/store.go @@ -162,6 +162,9 @@ type AuthStore interface { // AuthInfoFromTLS gets AuthInfo from TLS info of gRPC's context AuthInfoFromTLS(ctx context.Context) *AuthInfo + + // WithRoot generates and installs a token that can be used as a root credential + WithRoot(ctx context.Context) context.Context } type TokenProvider interface { @@ -1070,3 +1073,37 @@ func NewTokenProvider(tokenOpts string, indexWaiter func(uint64) <-chan struct{} return nil, ErrInvalidAuthOpts } } + +func (as *authStore) WithRoot(ctx context.Context) context.Context { + if !as.isAuthEnabled() { + return ctx + } + + var ctxForAssign context.Context + if ts, ok := as.tokenProvider.(*tokenSimple); ok && ts != nil { + ctx1 := context.WithValue(ctx, "index", uint64(0)) + prefix, err := ts.genTokenPrefix() + if err != nil { + plog.Errorf("failed to generate prefix of internally used token") + return ctx + } + ctxForAssign = context.WithValue(ctx1, "simpleToken", prefix) + } else { + ctxForAssign = ctx + } + + token, err := as.tokenProvider.assign(ctxForAssign, "root", as.Revision()) + if err != nil { + // this must not happen + plog.Errorf("failed to assign token for lease revoking: %s", err) + return ctx + } + + mdMap := map[string]string{ + "token": token, + } + tokenMD := metadata.New(mdMap) + + // use "mdIncomingKey{}" since it's called from local etcdserver + return metadata.NewIncomingContext(ctx, tokenMD) +} diff --git a/etcdserver/v3_server.go b/etcdserver/v3_server.go index 028df0b8830b..1f4a5be1fb1f 100644 --- a/etcdserver/v3_server.go +++ b/etcdserver/v3_server.go @@ -222,6 +222,9 @@ func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (* } func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { + // fix: LeaseRevoke may fail to apply when authentication is enabled and upgrading cluster from etcd-3.2 to etcd-3.3 + // see https://github.com/etcd-io/etcd/issues/11689 + ctx = s.authStore.WithRoot(s.ctx) resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseRevoke: r}) if err != nil { return nil, err