...

Source file src/go.etcd.io/etcd/server/v3/etcdserver/api/v3rpc/member.go

Documentation: go.etcd.io/etcd/server/v3/etcdserver/api/v3rpc

     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  	pb "go.etcd.io/etcd/api/v3/etcdserverpb"
    22  	"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
    23  	"go.etcd.io/etcd/client/pkg/v3/types"
    24  	"go.etcd.io/etcd/server/v3/etcdserver"
    25  	"go.etcd.io/etcd/server/v3/etcdserver/api"
    26  	"go.etcd.io/etcd/server/v3/etcdserver/api/membership"
    27  )
    28  
    29  type ClusterServer struct {
    30  	cluster api.Cluster
    31  	server  *etcdserver.EtcdServer
    32  }
    33  
    34  func NewClusterServer(s *etcdserver.EtcdServer) *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  	var m *membership.Member
    49  	if r.IsLearner {
    50  		m = membership.NewMemberAsLearner("", urls, "", &now)
    51  	} else {
    52  		m = membership.NewMember("", urls, "", &now)
    53  	}
    54  	membs, merr := cs.server.AddMember(ctx, *m)
    55  	if merr != nil {
    56  		return nil, togRPCError(merr)
    57  	}
    58  
    59  	return &pb.MemberAddResponse{
    60  		Header: cs.header(),
    61  		Member: &pb.Member{
    62  			ID:        uint64(m.ID),
    63  			PeerURLs:  m.PeerURLs,
    64  			IsLearner: m.IsLearner,
    65  		},
    66  		Members: membersToProtoMembers(membs),
    67  	}, nil
    68  }
    69  
    70  func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) {
    71  	membs, err := cs.server.RemoveMember(ctx, r.ID)
    72  	if err != nil {
    73  		return nil, togRPCError(err)
    74  	}
    75  	return &pb.MemberRemoveResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
    76  }
    77  
    78  func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) {
    79  	m := membership.Member{
    80  		ID:             types.ID(r.ID),
    81  		RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs},
    82  	}
    83  	membs, err := cs.server.UpdateMember(ctx, m)
    84  	if err != nil {
    85  		return nil, togRPCError(err)
    86  	}
    87  	return &pb.MemberUpdateResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
    88  }
    89  
    90  func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) {
    91  	if r.Linearizable {
    92  		if err := cs.server.LinearizableReadNotify(ctx); err != nil {
    93  			return nil, togRPCError(err)
    94  		}
    95  	}
    96  	membs := membersToProtoMembers(cs.cluster.Members())
    97  	return &pb.MemberListResponse{Header: cs.header(), Members: membs}, nil
    98  }
    99  
   100  func (cs *ClusterServer) MemberPromote(ctx context.Context, r *pb.MemberPromoteRequest) (*pb.MemberPromoteResponse, error) {
   101  	membs, err := cs.server.PromoteMember(ctx, r.ID)
   102  	if err != nil {
   103  		return nil, togRPCError(err)
   104  	}
   105  	return &pb.MemberPromoteResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
   106  }
   107  
   108  func (cs *ClusterServer) header() *pb.ResponseHeader {
   109  	return &pb.ResponseHeader{ClusterId: uint64(cs.cluster.ID()), MemberId: uint64(cs.server.ID()), RaftTerm: cs.server.Term()}
   110  }
   111  
   112  func membersToProtoMembers(membs []*membership.Member) []*pb.Member {
   113  	protoMembs := make([]*pb.Member, len(membs))
   114  	for i := range membs {
   115  		protoMembs[i] = &pb.Member{
   116  			Name:       membs[i].Name,
   117  			ID:         uint64(membs[i].ID),
   118  			PeerURLs:   membs[i].PeerURLs,
   119  			ClientURLs: membs[i].ClientURLs,
   120  			IsLearner:  membs[i].IsLearner,
   121  		}
   122  	}
   123  	return protoMembs
   124  }
   125  

View as plain text