go.etcd.io/etcd@v3.3.27+incompatible/etcdserver/api/v3rpc/member.go (about) 1 // Copyright 2016 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package v3rpc 16 17 import ( 18 "context" 19 "time" 20 21 "github.com/coreos/etcd/etcdserver" 22 "github.com/coreos/etcd/etcdserver/api" 23 "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" 24 pb "github.com/coreos/etcd/etcdserver/etcdserverpb" 25 "github.com/coreos/etcd/etcdserver/membership" 26 "github.com/coreos/etcd/pkg/types" 27 ) 28 29 type ClusterServer struct { 30 cluster api.Cluster 31 server etcdserver.ServerV3 32 } 33 34 func NewClusterServer(s etcdserver.ServerV3) *ClusterServer { 35 return &ClusterServer{ 36 cluster: s.Cluster(), 37 server: s, 38 } 39 } 40 41 func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) { 42 urls, err := types.NewURLs(r.PeerURLs) 43 if err != nil { 44 return nil, rpctypes.ErrGRPCMemberBadURLs 45 } 46 47 now := time.Now() 48 m := membership.NewMember("", urls, "", &now) 49 membs, merr := cs.server.AddMember(ctx, *m) 50 if merr != nil { 51 return nil, togRPCError(merr) 52 } 53 54 return &pb.MemberAddResponse{ 55 Header: cs.header(), 56 Member: &pb.Member{ID: uint64(m.ID), PeerURLs: m.PeerURLs}, 57 Members: membersToProtoMembers(membs), 58 }, nil 59 } 60 61 func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) { 62 membs, err := cs.server.RemoveMember(ctx, r.ID) 63 if err != nil { 64 return nil, togRPCError(err) 65 } 66 return &pb.MemberRemoveResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil 67 } 68 69 func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) { 70 m := membership.Member{ 71 ID: types.ID(r.ID), 72 RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs}, 73 } 74 membs, err := cs.server.UpdateMember(ctx, m) 75 if err != nil { 76 return nil, togRPCError(err) 77 } 78 return &pb.MemberUpdateResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil 79 } 80 81 func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) { 82 membs := membersToProtoMembers(cs.cluster.Members()) 83 return &pb.MemberListResponse{Header: cs.header(), Members: membs}, nil 84 } 85 86 func (cs *ClusterServer) header() *pb.ResponseHeader { 87 return &pb.ResponseHeader{ClusterId: uint64(cs.cluster.ID()), MemberId: uint64(cs.server.ID()), RaftTerm: cs.server.Term()} 88 } 89 90 func membersToProtoMembers(membs []*membership.Member) []*pb.Member { 91 protoMembs := make([]*pb.Member, len(membs)) 92 for i := range membs { 93 protoMembs[i] = &pb.Member{ 94 Name: membs[i].Name, 95 ID: uint64(membs[i].ID), 96 PeerURLs: membs[i].PeerURLs, 97 ClientURLs: membs[i].ClientURLs, 98 } 99 } 100 return protoMembs 101 }