diff --git a/clientv3/cluster.go b/clientv3/cluster.go index ab2825b102f..922d900e3c3 100644 --- a/clientv3/cluster.go +++ b/clientv3/cluster.go @@ -50,6 +50,10 @@ func NewCluster(c *Client) Cluster { return &cluster{remote: RetryClusterClient(c)} } +func NewClusterFromClusterClient(remote pb.ClusterClient) Cluster { + return &cluster{remote: remote} +} + func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) { r := &pb.MemberAddRequest{PeerURLs: peerAddrs} resp, err := c.remote.MemberAdd(ctx, r) diff --git a/etcdserver/api/v3client/v3client.go b/etcdserver/api/v3client/v3client.go index 2bcd64a1bfd..f2799e56eab 100644 --- a/etcdserver/api/v3client/v3client.go +++ b/etcdserver/api/v3client/v3client.go @@ -42,5 +42,10 @@ func New(s *etcdserver.EtcdServer) *clientv3.Client { mc := adapter.MaintenanceServerToMaintenanceClient(v3rpc.NewMaintenanceServer(s)) c.Maintenance = clientv3.NewMaintenanceFromMaintenanceClient(mc) + clc := adapter.ClusterServerToClusterClient(v3rpc.NewClusterServer(s)) + c.Cluster = clientv3.NewClusterFromClusterClient(clc) + + // TODO: implement clientv3.Auth interface? + return c } diff --git a/integration/cluster_proxy.go b/integration/cluster_proxy.go index 30984ddef58..0152a16c67c 100644 --- a/integration/cluster_proxy.go +++ b/integration/cluster_proxy.go @@ -57,9 +57,10 @@ func toGRPC(c *clientv3.Client) grpcAPI { wp, wpch := grpcproxy.NewWatchProxy(c) lp, lpch := grpcproxy.NewLeaseProxy(c) mp := grpcproxy.NewMaintenanceProxy(c) + clp, _ := grpcproxy.NewClusterProxy(c, "", "") // without registering proxy URLs grpc := grpcAPI{ - pb.NewClusterClient(c.ActiveConnection()), + adapter.ClusterServerToClusterClient(clp), adapter.KvServerToKvClient(kvp), adapter.LeaseServerToLeaseClient(lp), adapter.WatchServerToWatchClient(wp), diff --git a/proxy/grpcproxy/adapter/cluster_client_adapter.go b/proxy/grpcproxy/adapter/cluster_client_adapter.go new file mode 100644 index 00000000000..4ddf78e15ec --- /dev/null +++ b/proxy/grpcproxy/adapter/cluster_client_adapter.go @@ -0,0 +1,44 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package adapter + +import ( + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + + "golang.org/x/net/context" + "google.golang.org/grpc" +) + +type cls2clc struct{ cls pb.ClusterServer } + +func ClusterServerToClusterClient(cls pb.ClusterServer) pb.ClusterClient { + return &cls2clc{cls} +} + +func (s *cls2clc) MemberList(ctx context.Context, r *pb.MemberListRequest, opts ...grpc.CallOption) (*pb.MemberListResponse, error) { + return s.cls.MemberList(ctx, r) +} + +func (s *cls2clc) MemberAdd(ctx context.Context, r *pb.MemberAddRequest, opts ...grpc.CallOption) (*pb.MemberAddResponse, error) { + return s.cls.MemberAdd(ctx, r) +} + +func (s *cls2clc) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest, opts ...grpc.CallOption) (*pb.MemberUpdateResponse, error) { + return s.cls.MemberUpdate(ctx, r) +} + +func (s *cls2clc) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest, opts ...grpc.CallOption) (*pb.MemberRemoveResponse, error) { + return s.cls.MemberRemove(ctx, r) +}