diff --git a/server/etcdserver/api/etcdhttp/peer.go b/server/etcdserver/api/etcdhttp/peer.go index badc98634b1f..78ab354dbba0 100644 --- a/server/etcdserver/api/etcdhttp/peer.go +++ b/server/etcdserver/api/etcdhttp/peer.go @@ -21,14 +21,16 @@ import ( "strconv" "strings" + "go.uber.org/zap" + "google.golang.org/grpc/metadata" + + "go.etcd.io/etcd/api/v3/v3rpc/rpctypes" "go.etcd.io/etcd/client/pkg/v3/types" "go.etcd.io/etcd/server/v3/etcdserver" "go.etcd.io/etcd/server/v3/etcdserver/api" "go.etcd.io/etcd/server/v3/etcdserver/api/membership" "go.etcd.io/etcd/server/v3/etcdserver/api/rafthttp" "go.etcd.io/etcd/server/v3/lease/leasehttp" - - "go.uber.org/zap" ) const ( @@ -135,7 +137,14 @@ func (h *peerMemberPromoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ return } - resp, err := h.server.PromoteMember(r.Context(), id) + // reconstruct gRPC metadata from HTTP header (if present) so admin check can pass + ctx := r.Context() + if tok := r.Header.Get("Authorization"); tok != "" { + md := metadata.New(map[string]string{rpctypes.TokenFieldNameGRPC: tok}) + ctx = metadata.NewIncomingContext(ctx, md) + } + + resp, err := h.server.PromoteMember(ctx, id) if err != nil { switch err { case membership.ErrIDNotFound: