1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package v2v3
16
17 import (
18 "context"
19 "net/http"
20 "time"
21
22 pb "go.etcd.io/etcd/api/v3/etcdserverpb"
23 "go.etcd.io/etcd/client/pkg/v3/types"
24 "go.etcd.io/etcd/client/v3"
25 "go.etcd.io/etcd/server/v3/etcdserver"
26 "go.etcd.io/etcd/server/v3/etcdserver/api"
27 "go.etcd.io/etcd/server/v3/etcdserver/api/membership"
28
29 "github.com/coreos/go-semver/semver"
30 "go.uber.org/zap"
31 )
32
33 type fakeStats struct{}
34
35 func (s *fakeStats) SelfStats() []byte { return nil }
36 func (s *fakeStats) LeaderStats() []byte { return nil }
37 func (s *fakeStats) StoreStats() []byte { return nil }
38
39 type v2v3Server struct {
40 lg *zap.Logger
41 c *clientv3.Client
42 store *v2v3Store
43 fakeStats
44 }
45
46 func NewServer(lg *zap.Logger, c *clientv3.Client, pfx string) etcdserver.ServerPeer {
47 return &v2v3Server{lg: lg, c: c, store: newStore(c, pfx)}
48 }
49
50 func (s *v2v3Server) ClientCertAuthEnabled() bool { return false }
51
52 func (s *v2v3Server) LeaseHandler() http.Handler { panic("STUB: lease handler") }
53 func (s *v2v3Server) RaftHandler() http.Handler { panic("STUB: raft handler") }
54
55 func (s *v2v3Server) Leader() types.ID {
56 ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
57 defer cancel()
58 resp, err := s.c.Status(ctx, s.c.Endpoints()[0])
59 if err != nil {
60 return 0
61 }
62 return types.ID(resp.Leader)
63 }
64
65 func (s *v2v3Server) AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
66
67 resp, err := s.c.MemberAdd(ctx, memb.PeerURLs)
68 if err != nil {
69 return nil, err
70 }
71 return v3MembersToMembership(resp.Members), nil
72 }
73
74 func (s *v2v3Server) RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
75 resp, err := s.c.MemberRemove(ctx, id)
76 if err != nil {
77 return nil, err
78 }
79 return v3MembersToMembership(resp.Members), nil
80 }
81
82 func (s *v2v3Server) PromoteMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
83 resp, err := s.c.MemberPromote(ctx, id)
84 if err != nil {
85 return nil, err
86 }
87 return v3MembersToMembership(resp.Members), nil
88 }
89
90 func (s *v2v3Server) UpdateMember(ctx context.Context, m membership.Member) ([]*membership.Member, error) {
91 resp, err := s.c.MemberUpdate(ctx, uint64(m.ID), m.PeerURLs)
92 if err != nil {
93 return nil, err
94 }
95 return v3MembersToMembership(resp.Members), nil
96 }
97
98 func v3MembersToMembership(v3membs []*pb.Member) []*membership.Member {
99 membs := make([]*membership.Member, len(v3membs))
100 for i, m := range v3membs {
101 membs[i] = &membership.Member{
102 ID: types.ID(m.ID),
103 RaftAttributes: membership.RaftAttributes{
104 PeerURLs: m.PeerURLs,
105 IsLearner: m.IsLearner,
106 },
107 Attributes: membership.Attributes{
108 Name: m.Name,
109 ClientURLs: m.ClientURLs,
110 },
111 }
112 }
113 return membs
114 }
115
116 func (s *v2v3Server) ClusterVersion() *semver.Version { return s.Version() }
117 func (s *v2v3Server) Cluster() api.Cluster { return s }
118 func (s *v2v3Server) Alarms() []*pb.AlarmMember { return nil }
119 func (s *v2v3Server) LeaderChangedNotify() <-chan struct{} { return nil }
120
121 func (s *v2v3Server) Do(ctx context.Context, r pb.Request) (etcdserver.Response, error) {
122 applier := etcdserver.NewApplierV2(s.lg, s.store, nil)
123 reqHandler := etcdserver.NewStoreRequestV2Handler(s.store, applier)
124 req := (*etcdserver.RequestV2)(&r)
125 resp, err := req.Handle(ctx, reqHandler)
126 if resp.Err != nil {
127 return resp, resp.Err
128 }
129 return resp, err
130 }
131
View as plain text