[VOL-4291] Rw-core updates for gRPC migration

Change-Id: I8d5a554409115b29318089671ca4e1ab3fa98810
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/capability.go b/vendor/go.etcd.io/etcd/etcdserver/api/capability.go
deleted file mode 100644
index 09b754d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/capability.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 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 api
-
-import (
-	"sync"
-
-	"go.etcd.io/etcd/version"
-	"go.uber.org/zap"
-
-	"github.com/coreos/go-semver/semver"
-	"github.com/coreos/pkg/capnslog"
-)
-
-type Capability string
-
-const (
-	AuthCapability  Capability = "auth"
-	V3rpcCapability Capability = "v3rpc"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api")
-
-	// capabilityMaps is a static map of version to capability map.
-	capabilityMaps = map[string]map[Capability]bool{
-		"3.0.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.1.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.2.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.3.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.4.0": {AuthCapability: true, V3rpcCapability: true},
-		"3.5.0": {AuthCapability: true, V3rpcCapability: true},
-	}
-
-	enableMapMu sync.RWMutex
-	// enabledMap points to a map in capabilityMaps
-	enabledMap map[Capability]bool
-
-	curVersion *semver.Version
-)
-
-func init() {
-	enabledMap = map[Capability]bool{
-		AuthCapability:  true,
-		V3rpcCapability: true,
-	}
-}
-
-// UpdateCapability updates the enabledMap when the cluster version increases.
-func UpdateCapability(lg *zap.Logger, v *semver.Version) {
-	if v == nil {
-		// if recovered but version was never set by cluster
-		return
-	}
-	enableMapMu.Lock()
-	if curVersion != nil && !curVersion.LessThan(*v) {
-		enableMapMu.Unlock()
-		return
-	}
-	curVersion = v
-	enabledMap = capabilityMaps[curVersion.String()]
-	enableMapMu.Unlock()
-
-	if lg != nil {
-		lg.Info(
-			"enabled capabilities for version",
-			zap.String("cluster-version", version.Cluster(v.String())),
-		)
-	} else {
-		plog.Infof("enabled capabilities for version %s", version.Cluster(v.String()))
-	}
-}
-
-func IsCapabilityEnabled(c Capability) bool {
-	enableMapMu.RLock()
-	defer enableMapMu.RUnlock()
-	if enabledMap == nil {
-		return false
-	}
-	return enabledMap[c]
-}
-
-func EnableCapability(c Capability) {
-	enableMapMu.Lock()
-	defer enableMapMu.Unlock()
-	enabledMap[c] = true
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/cluster.go b/vendor/go.etcd.io/etcd/etcdserver/api/cluster.go
deleted file mode 100644
index 901be9d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/cluster.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 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 api
-
-import (
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-// Cluster is an interface representing a collection of members in one etcd cluster.
-type Cluster interface {
-	// ID returns the cluster ID
-	ID() types.ID
-	// ClientURLs returns an aggregate set of all URLs on which this
-	// cluster is listening for client requests
-	ClientURLs() []string
-	// Members returns a slice of members sorted by their ID
-	Members() []*membership.Member
-	// Member retrieves a particular member based on ID, or nil if the
-	// member does not exist in the cluster
-	Member(id types.ID) *membership.Member
-	// Version is the cluster-wide minimum major.minor version.
-	Version() *semver.Version
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/doc.go
deleted file mode 100644
index f44881b..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 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 api manages the capabilities and features that are exposed to clients by the etcd cluster.
-package api
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/base.go b/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/base.go
deleted file mode 100644
index c9df62e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/base.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2015 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 etcdhttp
-
-import (
-	"encoding/json"
-	"expvar"
-	"fmt"
-	"net/http"
-	"strings"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-	"go.etcd.io/etcd/pkg/logutil"
-	"go.etcd.io/etcd/version"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/etcdhttp")
-	mlog = logutil.NewMergeLogger(plog)
-)
-
-const (
-	configPath  = "/config"
-	varsPath    = "/debug/vars"
-	versionPath = "/version"
-)
-
-// HandleBasic adds handlers to a mux for serving JSON etcd client requests
-// that do not access the v2 store.
-func HandleBasic(mux *http.ServeMux, server etcdserver.ServerPeer) {
-	mux.HandleFunc(varsPath, serveVars)
-
-	// TODO: deprecate '/config/local/log' in v3.5
-	mux.HandleFunc(configPath+"/local/log", logHandleFunc)
-
-	HandleMetricsHealth(mux, server)
-	mux.HandleFunc(versionPath, versionHandler(server.Cluster(), serveVersion))
-}
-
-func versionHandler(c api.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		v := c.Version()
-		if v != nil {
-			fn(w, r, v.String())
-		} else {
-			fn(w, r, "not_decided")
-		}
-	}
-}
-
-func serveVersion(w http.ResponseWriter, r *http.Request, clusterV string) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-	vs := version.Versions{
-		Server:  version.Version,
-		Cluster: clusterV,
-	}
-
-	w.Header().Set("Content-Type", "application/json")
-	b, err := json.Marshal(&vs)
-	if err != nil {
-		plog.Panicf("cannot marshal versions to json (%v)", err)
-	}
-	w.Write(b)
-}
-
-// TODO: deprecate '/config/local/log' in v3.5
-func logHandleFunc(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "PUT") {
-		return
-	}
-
-	in := struct{ Level string }{}
-
-	d := json.NewDecoder(r.Body)
-	if err := d.Decode(&in); err != nil {
-		WriteError(nil, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid json body"))
-		return
-	}
-
-	logl, err := capnslog.ParseLevel(strings.ToUpper(in.Level))
-	if err != nil {
-		WriteError(nil, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid log level "+in.Level))
-		return
-	}
-
-	plog.Noticef("globalLogLevel set to %q", logl.String())
-	capnslog.SetGlobalLogLevel(logl)
-	w.WriteHeader(http.StatusNoContent)
-}
-
-func serveVars(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-
-	w.Header().Set("Content-Type", "application/json; charset=utf-8")
-	fmt.Fprintf(w, "{\n")
-	first := true
-	expvar.Do(func(kv expvar.KeyValue) {
-		if !first {
-			fmt.Fprintf(w, ",\n")
-		}
-		first = false
-		fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
-	})
-	fmt.Fprintf(w, "\n}\n")
-}
-
-func allowMethod(w http.ResponseWriter, r *http.Request, m string) bool {
-	if m == r.Method {
-		return true
-	}
-	w.Header().Set("Allow", m)
-	http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-	return false
-}
-
-// WriteError logs and writes the given Error to the ResponseWriter
-// If Error is an etcdErr, it is rendered to the ResponseWriter
-// Otherwise, it is assumed to be a StatusInternalServerError
-func WriteError(lg *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
-	if err == nil {
-		return
-	}
-	switch e := err.(type) {
-	case *v2error.Error:
-		e.WriteTo(w)
-
-	case *httptypes.HTTPError:
-		if et := e.WriteTo(w); et != nil {
-			if lg != nil {
-				lg.Debug(
-					"failed to write v2 HTTP error",
-					zap.String("remote-addr", r.RemoteAddr),
-					zap.String("internal-server-error", e.Error()),
-					zap.Error(et),
-				)
-			} else {
-				plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-			}
-		}
-
-	default:
-		switch err {
-		case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost, etcdserver.ErrNotEnoughStartedMembers,
-			etcdserver.ErrUnhealthy:
-			if lg != nil {
-				lg.Warn(
-					"v2 response error",
-					zap.String("remote-addr", r.RemoteAddr),
-					zap.String("internal-server-error", err.Error()),
-				)
-			} else {
-				mlog.MergeError(err)
-			}
-
-		default:
-			if lg != nil {
-				lg.Warn(
-					"unexpected v2 response error",
-					zap.String("remote-addr", r.RemoteAddr),
-					zap.String("internal-server-error", err.Error()),
-				)
-			} else {
-				mlog.MergeErrorf("got unexpected response error (%v)", err)
-			}
-		}
-
-		herr := httptypes.NewHTTPError(http.StatusInternalServerError, "Internal Server Error")
-		if et := herr.WriteTo(w); et != nil {
-			if lg != nil {
-				lg.Debug(
-					"failed to write v2 HTTP error",
-					zap.String("remote-addr", r.RemoteAddr),
-					zap.String("internal-server-error", err.Error()),
-					zap.Error(et),
-				)
-			} else {
-				plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-			}
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/doc.go
deleted file mode 100644
index a03b626..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 etcdhttp implements HTTP transportation layer for etcdserver.
-package etcdhttp
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/metrics.go
deleted file mode 100644
index f455e40..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/metrics.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// 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 etcdhttp
-
-import (
-	"context"
-	"encoding/json"
-	"net/http"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/raft"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/prometheus/client_golang/prometheus/promhttp"
-)
-
-const (
-	PathMetrics = "/metrics"
-	PathHealth  = "/health"
-)
-
-// HandleMetricsHealth registers metrics and health handlers.
-func HandleMetricsHealth(mux *http.ServeMux, srv etcdserver.ServerV2) {
-	mux.Handle(PathMetrics, promhttp.Handler())
-	mux.Handle(PathHealth, NewHealthHandler(func() Health { return checkHealth(srv) }))
-}
-
-// HandlePrometheus registers prometheus handler on '/metrics'.
-func HandlePrometheus(mux *http.ServeMux) {
-	mux.Handle(PathMetrics, promhttp.Handler())
-}
-
-// NewHealthHandler handles '/health' requests.
-func NewHealthHandler(hfunc func() Health) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		if r.Method != http.MethodGet {
-			w.Header().Set("Allow", http.MethodGet)
-			http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-			return
-		}
-		h := hfunc()
-		d, _ := json.Marshal(h)
-		if h.Health != "true" {
-			http.Error(w, string(d), http.StatusServiceUnavailable)
-			return
-		}
-		w.WriteHeader(http.StatusOK)
-		w.Write(d)
-	}
-}
-
-var (
-	healthSuccess = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "health_success",
-		Help:      "The total number of successful health checks",
-	})
-	healthFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "health_failures",
-		Help:      "The total number of failed health checks",
-	})
-)
-
-func init() {
-	prometheus.MustRegister(healthSuccess)
-	prometheus.MustRegister(healthFailed)
-}
-
-// Health defines etcd server health status.
-// TODO: remove manual parsing in etcdctl cluster-health
-type Health struct {
-	Health string `json:"health"`
-}
-
-// TODO: server NOSPACE, etcdserver.ErrNoLeader in health API
-
-func checkHealth(srv etcdserver.ServerV2) Health {
-	h := Health{Health: "true"}
-
-	as := srv.Alarms()
-	if len(as) > 0 {
-		h.Health = "false"
-	}
-
-	if h.Health == "true" {
-		if uint64(srv.Leader()) == raft.None {
-			h.Health = "false"
-		}
-	}
-
-	if h.Health == "true" {
-		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-		_, err := srv.Do(ctx, etcdserverpb.Request{Method: "QGET"})
-		cancel()
-		if err != nil {
-			h.Health = "false"
-		}
-	}
-
-	if h.Health == "true" {
-		healthSuccess.Inc()
-	} else {
-		healthFailed.Inc()
-	}
-	return h
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/peer.go b/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/peer.go
deleted file mode 100644
index 6c61bf5..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/etcdhttp/peer.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2015 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 etcdhttp
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"strconv"
-	"strings"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/rafthttp"
-	"go.etcd.io/etcd/lease/leasehttp"
-	"go.etcd.io/etcd/pkg/types"
-
-	"go.uber.org/zap"
-)
-
-const (
-	peerMembersPath         = "/members"
-	peerMemberPromotePrefix = "/members/promote/"
-)
-
-// NewPeerHandler generates an http.Handler to handle etcd peer requests.
-func NewPeerHandler(lg *zap.Logger, s etcdserver.ServerPeer) http.Handler {
-	return newPeerHandler(lg, s, s.RaftHandler(), s.LeaseHandler())
-}
-
-func newPeerHandler(lg *zap.Logger, s etcdserver.Server, raftHandler http.Handler, leaseHandler http.Handler) http.Handler {
-	peerMembersHandler := newPeerMembersHandler(lg, s.Cluster())
-	peerMemberPromoteHandler := newPeerMemberPromoteHandler(lg, s)
-
-	mux := http.NewServeMux()
-	mux.HandleFunc("/", http.NotFound)
-	mux.Handle(rafthttp.RaftPrefix, raftHandler)
-	mux.Handle(rafthttp.RaftPrefix+"/", raftHandler)
-	mux.Handle(peerMembersPath, peerMembersHandler)
-	mux.Handle(peerMemberPromotePrefix, peerMemberPromoteHandler)
-	if leaseHandler != nil {
-		mux.Handle(leasehttp.LeasePrefix, leaseHandler)
-		mux.Handle(leasehttp.LeaseInternalPrefix, leaseHandler)
-	}
-	mux.HandleFunc(versionPath, versionHandler(s.Cluster(), serveVersion))
-	return mux
-}
-
-func newPeerMembersHandler(lg *zap.Logger, cluster api.Cluster) http.Handler {
-	return &peerMembersHandler{
-		lg:      lg,
-		cluster: cluster,
-	}
-}
-
-type peerMembersHandler struct {
-	lg      *zap.Logger
-	cluster api.Cluster
-}
-
-func newPeerMemberPromoteHandler(lg *zap.Logger, s etcdserver.Server) http.Handler {
-	return &peerMemberPromoteHandler{
-		lg:      lg,
-		cluster: s.Cluster(),
-		server:  s,
-	}
-}
-
-type peerMemberPromoteHandler struct {
-	lg      *zap.Logger
-	cluster api.Cluster
-	server  etcdserver.Server
-}
-
-func (h *peerMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "GET") {
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	if r.URL.Path != peerMembersPath {
-		http.Error(w, "bad path", http.StatusBadRequest)
-		return
-	}
-	ms := h.cluster.Members()
-	w.Header().Set("Content-Type", "application/json")
-	if err := json.NewEncoder(w).Encode(ms); err != nil {
-		if h.lg != nil {
-			h.lg.Warn("failed to encode membership members", zap.Error(err))
-		} else {
-			plog.Warningf("failed to encode members response (%v)", err)
-		}
-	}
-}
-
-func (h *peerMemberPromoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r, "POST") {
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	if !strings.HasPrefix(r.URL.Path, peerMemberPromotePrefix) {
-		http.Error(w, "bad path", http.StatusBadRequest)
-		return
-	}
-	idStr := strings.TrimPrefix(r.URL.Path, peerMemberPromotePrefix)
-	id, err := strconv.ParseUint(idStr, 10, 64)
-	if err != nil {
-		http.Error(w, fmt.Sprintf("member %s not found in cluster", idStr), http.StatusNotFound)
-		return
-	}
-
-	resp, err := h.server.PromoteMember(r.Context(), id)
-	if err != nil {
-		switch err {
-		case membership.ErrIDNotFound:
-			http.Error(w, err.Error(), http.StatusNotFound)
-		case membership.ErrMemberNotLearner:
-			http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		case etcdserver.ErrLearnerNotReady:
-			http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		default:
-			WriteError(h.lg, w, r, err)
-		}
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to promote a member",
-				zap.String("member-id", types.ID(id).String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("error promoting member %s (%v)", types.ID(id).String(), err)
-		}
-		return
-	}
-
-	w.Header().Set("Content-Type", "application/json")
-	w.WriteHeader(http.StatusOK)
-	if err := json.NewEncoder(w).Encode(resp); err != nil {
-		if h.lg != nil {
-			h.lg.Warn("failed to encode members response", zap.Error(err))
-		} else {
-			plog.Warningf("failed to encode members response (%v)", err)
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/cluster.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/cluster.go
deleted file mode 100644
index 89a6edd..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/cluster.go
+++ /dev/null
@@ -1,841 +0,0 @@
-// Copyright 2015 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 membership
-
-import (
-	"bytes"
-	"context"
-	"crypto/sha1"
-	"encoding/binary"
-	"encoding/json"
-	"fmt"
-	"path"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/pkg/netutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/version"
-
-	"github.com/coreos/go-semver/semver"
-	"github.com/prometheus/client_golang/prometheus"
-	"go.uber.org/zap"
-)
-
-const maxLearners = 1
-
-// RaftCluster is a list of Members that belong to the same raft cluster
-type RaftCluster struct {
-	lg *zap.Logger
-
-	localID types.ID
-	cid     types.ID
-	token   string
-
-	v2store v2store.Store
-	be      backend.Backend
-
-	sync.Mutex // guards the fields below
-	version    *semver.Version
-	members    map[types.ID]*Member
-	// removed contains the ids of removed members in the cluster.
-	// removed id cannot be reused.
-	removed map[types.ID]bool
-}
-
-// ConfigChangeContext represents a context for confChange.
-type ConfigChangeContext struct {
-	Member
-	// IsPromote indicates if the config change is for promoting a learner member.
-	// This flag is needed because both adding a new member and promoting a learner member
-	// uses the same config change type 'ConfChangeAddNode'.
-	IsPromote bool `json:"isPromote"`
-}
-
-// NewClusterFromURLsMap creates a new raft cluster using provided urls map. Currently, it does not support creating
-// cluster with raft learner member.
-func NewClusterFromURLsMap(lg *zap.Logger, token string, urlsmap types.URLsMap) (*RaftCluster, error) {
-	c := NewCluster(lg, token)
-	for name, urls := range urlsmap {
-		m := NewMember(name, urls, token, nil)
-		if _, ok := c.members[m.ID]; ok {
-			return nil, fmt.Errorf("member exists with identical ID %v", m)
-		}
-		if uint64(m.ID) == raft.None {
-			return nil, fmt.Errorf("cannot use %x as member id", raft.None)
-		}
-		c.members[m.ID] = m
-	}
-	c.genID()
-	return c, nil
-}
-
-func NewClusterFromMembers(lg *zap.Logger, token string, id types.ID, membs []*Member) *RaftCluster {
-	c := NewCluster(lg, token)
-	c.cid = id
-	for _, m := range membs {
-		c.members[m.ID] = m
-	}
-	return c
-}
-
-func NewCluster(lg *zap.Logger, token string) *RaftCluster {
-	return &RaftCluster{
-		lg:      lg,
-		token:   token,
-		members: make(map[types.ID]*Member),
-		removed: make(map[types.ID]bool),
-	}
-}
-
-func (c *RaftCluster) ID() types.ID { return c.cid }
-
-func (c *RaftCluster) Members() []*Member {
-	c.Lock()
-	defer c.Unlock()
-	var ms MembersByID
-	for _, m := range c.members {
-		ms = append(ms, m.Clone())
-	}
-	sort.Sort(ms)
-	return []*Member(ms)
-}
-
-func (c *RaftCluster) Member(id types.ID) *Member {
-	c.Lock()
-	defer c.Unlock()
-	return c.members[id].Clone()
-}
-
-func (c *RaftCluster) VotingMembers() []*Member {
-	c.Lock()
-	defer c.Unlock()
-	var ms MembersByID
-	for _, m := range c.members {
-		if !m.IsLearner {
-			ms = append(ms, m.Clone())
-		}
-	}
-	sort.Sort(ms)
-	return []*Member(ms)
-}
-
-// MemberByName returns a Member with the given name if exists.
-// If more than one member has the given name, it will panic.
-func (c *RaftCluster) MemberByName(name string) *Member {
-	c.Lock()
-	defer c.Unlock()
-	var memb *Member
-	for _, m := range c.members {
-		if m.Name == name {
-			if memb != nil {
-				if c.lg != nil {
-					c.lg.Panic("two member with same name found", zap.String("name", name))
-				} else {
-					plog.Panicf("two members with the given name %q exist", name)
-				}
-			}
-			memb = m
-		}
-	}
-	return memb.Clone()
-}
-
-func (c *RaftCluster) MemberIDs() []types.ID {
-	c.Lock()
-	defer c.Unlock()
-	var ids []types.ID
-	for _, m := range c.members {
-		ids = append(ids, m.ID)
-	}
-	sort.Sort(types.IDSlice(ids))
-	return ids
-}
-
-func (c *RaftCluster) IsIDRemoved(id types.ID) bool {
-	c.Lock()
-	defer c.Unlock()
-	return c.removed[id]
-}
-
-// PeerURLs returns a list of all peer addresses.
-// The returned list is sorted in ascending lexicographical order.
-func (c *RaftCluster) PeerURLs() []string {
-	c.Lock()
-	defer c.Unlock()
-	urls := make([]string, 0)
-	for _, p := range c.members {
-		urls = append(urls, p.PeerURLs...)
-	}
-	sort.Strings(urls)
-	return urls
-}
-
-// ClientURLs returns a list of all client addresses.
-// The returned list is sorted in ascending lexicographical order.
-func (c *RaftCluster) ClientURLs() []string {
-	c.Lock()
-	defer c.Unlock()
-	urls := make([]string, 0)
-	for _, p := range c.members {
-		urls = append(urls, p.ClientURLs...)
-	}
-	sort.Strings(urls)
-	return urls
-}
-
-func (c *RaftCluster) String() string {
-	c.Lock()
-	defer c.Unlock()
-	b := &bytes.Buffer{}
-	fmt.Fprintf(b, "{ClusterID:%s ", c.cid)
-	var ms []string
-	for _, m := range c.members {
-		ms = append(ms, fmt.Sprintf("%+v", m))
-	}
-	fmt.Fprintf(b, "Members:[%s] ", strings.Join(ms, " "))
-	var ids []string
-	for id := range c.removed {
-		ids = append(ids, id.String())
-	}
-	fmt.Fprintf(b, "RemovedMemberIDs:[%s]}", strings.Join(ids, " "))
-	return b.String()
-}
-
-func (c *RaftCluster) genID() {
-	mIDs := c.MemberIDs()
-	b := make([]byte, 8*len(mIDs))
-	for i, id := range mIDs {
-		binary.BigEndian.PutUint64(b[8*i:], uint64(id))
-	}
-	hash := sha1.Sum(b)
-	c.cid = types.ID(binary.BigEndian.Uint64(hash[:8]))
-}
-
-func (c *RaftCluster) SetID(localID, cid types.ID) {
-	c.localID = localID
-	c.cid = cid
-}
-
-func (c *RaftCluster) SetStore(st v2store.Store) { c.v2store = st }
-
-func (c *RaftCluster) SetBackend(be backend.Backend) {
-	c.be = be
-	mustCreateBackendBuckets(c.be)
-}
-
-func (c *RaftCluster) Recover(onSet func(*zap.Logger, *semver.Version)) {
-	c.Lock()
-	defer c.Unlock()
-
-	c.members, c.removed = membersFromStore(c.lg, c.v2store)
-	c.version = clusterVersionFromStore(c.lg, c.v2store)
-	mustDetectDowngrade(c.lg, c.version)
-	onSet(c.lg, c.version)
-
-	for _, m := range c.members {
-		if c.lg != nil {
-			c.lg.Info(
-				"recovered/added member from store",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("recovered-remote-peer-id", m.ID.String()),
-				zap.Strings("recovered-remote-peer-urls", m.PeerURLs),
-			)
-		} else {
-			plog.Infof("added member %s %v to cluster %s from store", m.ID, m.PeerURLs, c.cid)
-		}
-	}
-	if c.version != nil {
-		if c.lg != nil {
-			c.lg.Info(
-				"set cluster version from store",
-				zap.String("cluster-version", version.Cluster(c.version.String())),
-			)
-		} else {
-			plog.Infof("set the cluster version to %v from store", version.Cluster(c.version.String()))
-		}
-	}
-}
-
-// ValidateConfigurationChange takes a proposed ConfChange and
-// ensures that it is still valid.
-func (c *RaftCluster) ValidateConfigurationChange(cc raftpb.ConfChange) error {
-	members, removed := membersFromStore(c.lg, c.v2store)
-	id := types.ID(cc.NodeID)
-	if removed[id] {
-		return ErrIDRemoved
-	}
-	switch cc.Type {
-	case raftpb.ConfChangeAddNode, raftpb.ConfChangeAddLearnerNode:
-		confChangeContext := new(ConfigChangeContext)
-		if err := json.Unmarshal(cc.Context, confChangeContext); err != nil {
-			if c.lg != nil {
-				c.lg.Panic("failed to unmarshal confChangeContext", zap.Error(err))
-			} else {
-				plog.Panicf("unmarshal confChangeContext should never fail: %v", err)
-			}
-		}
-
-		if confChangeContext.IsPromote { // promoting a learner member to voting member
-			if members[id] == nil {
-				return ErrIDNotFound
-			}
-			if !members[id].IsLearner {
-				return ErrMemberNotLearner
-			}
-		} else { // adding a new member
-			if members[id] != nil {
-				return ErrIDExists
-			}
-
-			urls := make(map[string]bool)
-			for _, m := range members {
-				for _, u := range m.PeerURLs {
-					urls[u] = true
-				}
-			}
-			for _, u := range confChangeContext.Member.PeerURLs {
-				if urls[u] {
-					return ErrPeerURLexists
-				}
-			}
-
-			if confChangeContext.Member.IsLearner { // the new member is a learner
-				numLearners := 0
-				for _, m := range members {
-					if m.IsLearner {
-						numLearners++
-					}
-				}
-				if numLearners+1 > maxLearners {
-					return ErrTooManyLearners
-				}
-			}
-		}
-	case raftpb.ConfChangeRemoveNode:
-		if members[id] == nil {
-			return ErrIDNotFound
-		}
-
-	case raftpb.ConfChangeUpdateNode:
-		if members[id] == nil {
-			return ErrIDNotFound
-		}
-		urls := make(map[string]bool)
-		for _, m := range members {
-			if m.ID == id {
-				continue
-			}
-			for _, u := range m.PeerURLs {
-				urls[u] = true
-			}
-		}
-		m := new(Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			if c.lg != nil {
-				c.lg.Panic("failed to unmarshal member", zap.Error(err))
-			} else {
-				plog.Panicf("unmarshal member should never fail: %v", err)
-			}
-		}
-		for _, u := range m.PeerURLs {
-			if urls[u] {
-				return ErrPeerURLexists
-			}
-		}
-
-	default:
-		if c.lg != nil {
-			c.lg.Panic("unknown ConfChange type", zap.String("type", cc.Type.String()))
-		} else {
-			plog.Panicf("ConfChange type should be either AddNode, RemoveNode or UpdateNode")
-		}
-	}
-	return nil
-}
-
-// AddMember adds a new Member into the cluster, and saves the given member's
-// raftAttributes into the store. The given member should have empty attributes.
-// A Member with a matching id must not exist.
-func (c *RaftCluster) AddMember(m *Member) {
-	c.Lock()
-	defer c.Unlock()
-	if c.v2store != nil {
-		mustSaveMemberToStore(c.v2store, m)
-	}
-	if c.be != nil {
-		mustSaveMemberToBackend(c.be, m)
-	}
-
-	c.members[m.ID] = m
-
-	if c.lg != nil {
-		c.lg.Info(
-			"added member",
-			zap.String("cluster-id", c.cid.String()),
-			zap.String("local-member-id", c.localID.String()),
-			zap.String("added-peer-id", m.ID.String()),
-			zap.Strings("added-peer-peer-urls", m.PeerURLs),
-		)
-	} else {
-		plog.Infof("added member %s %v to cluster %s", m.ID, m.PeerURLs, c.cid)
-	}
-}
-
-// RemoveMember removes a member from the store.
-// The given id MUST exist, or the function panics.
-func (c *RaftCluster) RemoveMember(id types.ID) {
-	c.Lock()
-	defer c.Unlock()
-	if c.v2store != nil {
-		mustDeleteMemberFromStore(c.v2store, id)
-	}
-	if c.be != nil {
-		mustDeleteMemberFromBackend(c.be, id)
-	}
-
-	m, ok := c.members[id]
-	delete(c.members, id)
-	c.removed[id] = true
-
-	if c.lg != nil {
-		if ok {
-			c.lg.Info(
-				"removed member",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("removed-remote-peer-id", id.String()),
-				zap.Strings("removed-remote-peer-urls", m.PeerURLs),
-			)
-		} else {
-			c.lg.Warn(
-				"skipped removing already removed member",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("removed-remote-peer-id", id.String()),
-			)
-		}
-	} else {
-		plog.Infof("removed member %s from cluster %s", id, c.cid)
-	}
-}
-
-func (c *RaftCluster) UpdateAttributes(id types.ID, attr Attributes) {
-	c.Lock()
-	defer c.Unlock()
-
-	if m, ok := c.members[id]; ok {
-		m.Attributes = attr
-		if c.v2store != nil {
-			mustUpdateMemberAttrInStore(c.v2store, m)
-		}
-		if c.be != nil {
-			mustSaveMemberToBackend(c.be, m)
-		}
-		return
-	}
-
-	_, ok := c.removed[id]
-	if !ok {
-		if c.lg != nil {
-			c.lg.Panic(
-				"failed to update; member unknown",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("unknown-remote-peer-id", id.String()),
-			)
-		} else {
-			plog.Panicf("error updating attributes of unknown member %s", id)
-		}
-	}
-
-	if c.lg != nil {
-		c.lg.Warn(
-			"skipped attributes update of removed member",
-			zap.String("cluster-id", c.cid.String()),
-			zap.String("local-member-id", c.localID.String()),
-			zap.String("updated-peer-id", id.String()),
-		)
-	} else {
-		plog.Warningf("skipped updating attributes of removed member %s", id)
-	}
-}
-
-// PromoteMember marks the member's IsLearner RaftAttributes to false.
-func (c *RaftCluster) PromoteMember(id types.ID) {
-	c.Lock()
-	defer c.Unlock()
-
-	c.members[id].RaftAttributes.IsLearner = false
-	if c.v2store != nil {
-		mustUpdateMemberInStore(c.v2store, c.members[id])
-	}
-	if c.be != nil {
-		mustSaveMemberToBackend(c.be, c.members[id])
-	}
-
-	if c.lg != nil {
-		c.lg.Info(
-			"promote member",
-			zap.String("cluster-id", c.cid.String()),
-			zap.String("local-member-id", c.localID.String()),
-		)
-	} else {
-		plog.Noticef("promote member %s in cluster %s", id, c.cid)
-	}
-}
-
-func (c *RaftCluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) {
-	c.Lock()
-	defer c.Unlock()
-
-	c.members[id].RaftAttributes = raftAttr
-	if c.v2store != nil {
-		mustUpdateMemberInStore(c.v2store, c.members[id])
-	}
-	if c.be != nil {
-		mustSaveMemberToBackend(c.be, c.members[id])
-	}
-
-	if c.lg != nil {
-		c.lg.Info(
-			"updated member",
-			zap.String("cluster-id", c.cid.String()),
-			zap.String("local-member-id", c.localID.String()),
-			zap.String("updated-remote-peer-id", id.String()),
-			zap.Strings("updated-remote-peer-urls", raftAttr.PeerURLs),
-		)
-	} else {
-		plog.Noticef("updated member %s %v in cluster %s", id, raftAttr.PeerURLs, c.cid)
-	}
-}
-
-func (c *RaftCluster) Version() *semver.Version {
-	c.Lock()
-	defer c.Unlock()
-	if c.version == nil {
-		return nil
-	}
-	return semver.Must(semver.NewVersion(c.version.String()))
-}
-
-func (c *RaftCluster) SetVersion(ver *semver.Version, onSet func(*zap.Logger, *semver.Version)) {
-	c.Lock()
-	defer c.Unlock()
-	if c.version != nil {
-		if c.lg != nil {
-			c.lg.Info(
-				"updated cluster version",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("from", version.Cluster(c.version.String())),
-				zap.String("from", version.Cluster(ver.String())),
-			)
-		} else {
-			plog.Noticef("updated the cluster version from %v to %v", version.Cluster(c.version.String()), version.Cluster(ver.String()))
-		}
-	} else {
-		if c.lg != nil {
-			c.lg.Info(
-				"set initial cluster version",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-				zap.String("cluster-version", version.Cluster(ver.String())),
-			)
-		} else {
-			plog.Noticef("set the initial cluster version to %v", version.Cluster(ver.String()))
-		}
-	}
-	c.version = ver
-	mustDetectDowngrade(c.lg, c.version)
-	if c.v2store != nil {
-		mustSaveClusterVersionToStore(c.v2store, ver)
-	}
-	if c.be != nil {
-		mustSaveClusterVersionToBackend(c.be, ver)
-	}
-	ClusterVersionMetrics.With(prometheus.Labels{"cluster_version": ver.String()}).Set(1)
-	onSet(c.lg, ver)
-}
-
-func (c *RaftCluster) IsReadyToAddVotingMember() bool {
-	nmembers := 1
-	nstarted := 0
-
-	for _, member := range c.VotingMembers() {
-		if member.IsStarted() {
-			nstarted++
-		}
-		nmembers++
-	}
-
-	if nstarted == 1 && nmembers == 2 {
-		// a case of adding a new node to 1-member cluster for restoring cluster data
-		// https://github.com/etcd-io/etcd/blob/master/Documentation/v2/admin_guide.md#restoring-the-cluster
-		if c.lg != nil {
-			c.lg.Debug("number of started member is 1; can accept add member request")
-		} else {
-			plog.Debugf("The number of started member is 1. This cluster can accept add member request.")
-		}
-		return true
-	}
-
-	nquorum := nmembers/2 + 1
-	if nstarted < nquorum {
-		if c.lg != nil {
-			c.lg.Warn(
-				"rejecting member add; started member will be less than quorum",
-				zap.Int("number-of-started-member", nstarted),
-				zap.Int("quorum", nquorum),
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-			)
-		} else {
-			plog.Warningf("Reject add member request: the number of started member (%d) will be less than the quorum number of the cluster (%d)", nstarted, nquorum)
-		}
-		return false
-	}
-
-	return true
-}
-
-func (c *RaftCluster) IsReadyToRemoveVotingMember(id uint64) bool {
-	nmembers := 0
-	nstarted := 0
-
-	for _, member := range c.VotingMembers() {
-		if uint64(member.ID) == id {
-			continue
-		}
-
-		if member.IsStarted() {
-			nstarted++
-		}
-		nmembers++
-	}
-
-	nquorum := nmembers/2 + 1
-	if nstarted < nquorum {
-		if c.lg != nil {
-			c.lg.Warn(
-				"rejecting member remove; started member will be less than quorum",
-				zap.Int("number-of-started-member", nstarted),
-				zap.Int("quorum", nquorum),
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-			)
-		} else {
-			plog.Warningf("Reject remove member request: the number of started member (%d) will be less than the quorum number of the cluster (%d)", nstarted, nquorum)
-		}
-		return false
-	}
-
-	return true
-}
-
-func (c *RaftCluster) IsReadyToPromoteMember(id uint64) bool {
-	nmembers := 1
-	nstarted := 0
-
-	for _, member := range c.VotingMembers() {
-		if member.IsStarted() {
-			nstarted++
-		}
-		nmembers++
-	}
-
-	nquorum := nmembers/2 + 1
-	if nstarted < nquorum {
-		if c.lg != nil {
-			c.lg.Warn(
-				"rejecting member promote; started member will be less than quorum",
-				zap.Int("number-of-started-member", nstarted),
-				zap.Int("quorum", nquorum),
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-			)
-		} else {
-			plog.Warningf("Reject promote member request: the number of started member (%d) will be less than the quorum number of the cluster (%d)", nstarted, nquorum)
-		}
-		return false
-	}
-
-	return true
-}
-
-func membersFromStore(lg *zap.Logger, st v2store.Store) (map[types.ID]*Member, map[types.ID]bool) {
-	members := make(map[types.ID]*Member)
-	removed := make(map[types.ID]bool)
-	e, err := st.Get(StoreMembersPrefix, true, true)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return members, removed
-		}
-		if lg != nil {
-			lg.Panic("failed to get members from store", zap.String("path", StoreMembersPrefix), zap.Error(err))
-		} else {
-			plog.Panicf("get storeMembers should never fail: %v", err)
-		}
-	}
-	for _, n := range e.Node.Nodes {
-		var m *Member
-		m, err = nodeToMember(n)
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to nodeToMember", zap.Error(err))
-			} else {
-				plog.Panicf("nodeToMember should never fail: %v", err)
-			}
-		}
-		members[m.ID] = m
-	}
-
-	e, err = st.Get(storeRemovedMembersPrefix, true, true)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return members, removed
-		}
-		if lg != nil {
-			lg.Panic(
-				"failed to get removed members from store",
-				zap.String("path", storeRemovedMembersPrefix),
-				zap.Error(err),
-			)
-		} else {
-			plog.Panicf("get storeRemovedMembers should never fail: %v", err)
-		}
-	}
-	for _, n := range e.Node.Nodes {
-		removed[MustParseMemberIDFromKey(n.Key)] = true
-	}
-	return members, removed
-}
-
-func clusterVersionFromStore(lg *zap.Logger, st v2store.Store) *semver.Version {
-	e, err := st.Get(path.Join(storePrefix, "version"), false, false)
-	if err != nil {
-		if isKeyNotFound(err) {
-			return nil
-		}
-		if lg != nil {
-			lg.Panic(
-				"failed to get cluster version from store",
-				zap.String("path", path.Join(storePrefix, "version")),
-				zap.Error(err),
-			)
-		} else {
-			plog.Panicf("unexpected error (%v) when getting cluster version from store", err)
-		}
-	}
-	return semver.Must(semver.NewVersion(*e.Node.Value))
-}
-
-// ValidateClusterAndAssignIDs validates the local cluster by matching the PeerURLs
-// with the existing cluster. If the validation succeeds, it assigns the IDs
-// from the existing cluster to the local cluster.
-// If the validation fails, an error will be returned.
-func ValidateClusterAndAssignIDs(lg *zap.Logger, local *RaftCluster, existing *RaftCluster) error {
-	ems := existing.Members()
-	lms := local.Members()
-	if len(ems) != len(lms) {
-		return fmt.Errorf("member count is unequal")
-	}
-
-	ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
-	defer cancel()
-	for i := range ems {
-		var err error
-		ok := false
-		for j := range lms {
-			if ok, err = netutil.URLStringsEqual(ctx, lg, ems[i].PeerURLs, lms[j].PeerURLs); ok {
-				lms[j].ID = ems[i].ID
-				break
-			}
-		}
-		if !ok {
-			return fmt.Errorf("PeerURLs: no match found for existing member (%v, %v), last resolver error (%v)", ems[i].ID, ems[i].PeerURLs, err)
-		}
-	}
-	local.members = make(map[types.ID]*Member)
-	for _, m := range lms {
-		local.members[m.ID] = m
-	}
-	return nil
-}
-
-func mustDetectDowngrade(lg *zap.Logger, cv *semver.Version) {
-	lv := semver.Must(semver.NewVersion(version.Version))
-	// only keep major.minor version for comparison against cluster version
-	lv = &semver.Version{Major: lv.Major, Minor: lv.Minor}
-	if cv != nil && lv.LessThan(*cv) {
-		if lg != nil {
-			lg.Fatal(
-				"invalid downgrade; server version is lower than determined cluster version",
-				zap.String("current-server-version", version.Version),
-				zap.String("determined-cluster-version", version.Cluster(cv.String())),
-			)
-		} else {
-			plog.Fatalf("cluster cannot be downgraded (current version: %s is lower than determined cluster version: %s).", version.Version, version.Cluster(cv.String()))
-		}
-	}
-}
-
-// IsLocalMemberLearner returns if the local member is raft learner
-func (c *RaftCluster) IsLocalMemberLearner() bool {
-	c.Lock()
-	defer c.Unlock()
-	localMember, ok := c.members[c.localID]
-	if !ok {
-		if c.lg != nil {
-			c.lg.Panic(
-				"failed to find local ID in cluster members",
-				zap.String("cluster-id", c.cid.String()),
-				zap.String("local-member-id", c.localID.String()),
-			)
-		} else {
-			plog.Panicf("failed to find local ID %s in cluster %s", c.localID.String(), c.cid.String())
-		}
-	}
-	return localMember.IsLearner
-}
-
-// IsMemberExist returns if the member with the given id exists in cluster.
-func (c *RaftCluster) IsMemberExist(id types.ID) bool {
-	c.Lock()
-	defer c.Unlock()
-	_, ok := c.members[id]
-	return ok
-}
-
-// VotingMemberIDs returns the ID of voting members in cluster.
-func (c *RaftCluster) VotingMemberIDs() []types.ID {
-	c.Lock()
-	defer c.Unlock()
-	var ids []types.ID
-	for _, m := range c.members {
-		if !m.IsLearner {
-			ids = append(ids, m.ID)
-		}
-	}
-	sort.Sort(types.IDSlice(ids))
-	return ids
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/doc.go
deleted file mode 100644
index b07fb2d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 membership describes individual etcd members and clusters of members.
-package membership
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/errors.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/errors.go
deleted file mode 100644
index 8f6fe50..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/errors.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 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 membership
-
-import (
-	"errors"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-)
-
-var (
-	ErrIDRemoved        = errors.New("membership: ID removed")
-	ErrIDExists         = errors.New("membership: ID exists")
-	ErrIDNotFound       = errors.New("membership: ID not found")
-	ErrPeerURLexists    = errors.New("membership: peerURL exists")
-	ErrMemberNotLearner = errors.New("membership: can only promote a learner member")
-	ErrTooManyLearners  = errors.New("membership: too many learner members in cluster")
-)
-
-func isKeyNotFound(err error) bool {
-	e, ok := err.(*v2error.Error)
-	return ok && e.ErrorCode == v2error.EcodeKeyNotFound
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/member.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/member.go
deleted file mode 100644
index 896cb36..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/member.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2015 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 membership
-
-import (
-	"crypto/sha1"
-	"encoding/binary"
-	"fmt"
-	"math/rand"
-	"sort"
-	"time"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.etcd.io/etcd/pkg/types"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd/v3", "etcdserver/membership")
-)
-
-// RaftAttributes represents the raft related attributes of an etcd member.
-type RaftAttributes struct {
-	// PeerURLs is the list of peers in the raft cluster.
-	// TODO(philips): ensure these are URLs
-	PeerURLs []string `json:"peerURLs"`
-	// IsLearner indicates if the member is raft learner.
-	IsLearner bool `json:"isLearner,omitempty"`
-}
-
-// Attributes represents all the non-raft related attributes of an etcd member.
-type Attributes struct {
-	Name       string   `json:"name,omitempty"`
-	ClientURLs []string `json:"clientURLs,omitempty"`
-}
-
-type Member struct {
-	ID types.ID `json:"id"`
-	RaftAttributes
-	Attributes
-}
-
-// NewMember creates a Member without an ID and generates one based on the
-// cluster name, peer URLs, and time. This is used for bootstrapping/adding new member.
-func NewMember(name string, peerURLs types.URLs, clusterName string, now *time.Time) *Member {
-	return newMember(name, peerURLs, clusterName, now, false)
-}
-
-// NewMemberAsLearner creates a learner Member without an ID and generates one based on the
-// cluster name, peer URLs, and time. This is used for adding new learner member.
-func NewMemberAsLearner(name string, peerURLs types.URLs, clusterName string, now *time.Time) *Member {
-	return newMember(name, peerURLs, clusterName, now, true)
-}
-
-func newMember(name string, peerURLs types.URLs, clusterName string, now *time.Time, isLearner bool) *Member {
-	m := &Member{
-		RaftAttributes: RaftAttributes{
-			PeerURLs:  peerURLs.StringSlice(),
-			IsLearner: isLearner,
-		},
-		Attributes: Attributes{Name: name},
-	}
-
-	var b []byte
-	sort.Strings(m.PeerURLs)
-	for _, p := range m.PeerURLs {
-		b = append(b, []byte(p)...)
-	}
-
-	b = append(b, []byte(clusterName)...)
-	if now != nil {
-		b = append(b, []byte(fmt.Sprintf("%d", now.Unix()))...)
-	}
-
-	hash := sha1.Sum(b)
-	m.ID = types.ID(binary.BigEndian.Uint64(hash[:8]))
-	return m
-}
-
-// PickPeerURL chooses a random address from a given Member's PeerURLs.
-// It will panic if there is no PeerURLs available in Member.
-func (m *Member) PickPeerURL() string {
-	if len(m.PeerURLs) == 0 {
-		panic("member should always have some peer url")
-	}
-	return m.PeerURLs[rand.Intn(len(m.PeerURLs))]
-}
-
-func (m *Member) Clone() *Member {
-	if m == nil {
-		return nil
-	}
-	mm := &Member{
-		ID: m.ID,
-		RaftAttributes: RaftAttributes{
-			IsLearner: m.IsLearner,
-		},
-		Attributes: Attributes{
-			Name: m.Name,
-		},
-	}
-	if m.PeerURLs != nil {
-		mm.PeerURLs = make([]string, len(m.PeerURLs))
-		copy(mm.PeerURLs, m.PeerURLs)
-	}
-	if m.ClientURLs != nil {
-		mm.ClientURLs = make([]string, len(m.ClientURLs))
-		copy(mm.ClientURLs, m.ClientURLs)
-	}
-	return mm
-}
-
-func (m *Member) IsStarted() bool {
-	return len(m.Name) != 0
-}
-
-// MembersByID implements sort by ID interface
-type MembersByID []*Member
-
-func (ms MembersByID) Len() int           { return len(ms) }
-func (ms MembersByID) Less(i, j int) bool { return ms[i].ID < ms[j].ID }
-func (ms MembersByID) Swap(i, j int)      { ms[i], ms[j] = ms[j], ms[i] }
-
-// MembersByPeerURLs implements sort by peer urls interface
-type MembersByPeerURLs []*Member
-
-func (ms MembersByPeerURLs) Len() int { return len(ms) }
-func (ms MembersByPeerURLs) Less(i, j int) bool {
-	return ms[i].PeerURLs[0] < ms[j].PeerURLs[0]
-}
-func (ms MembersByPeerURLs) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/metrics.go
deleted file mode 100644
index b3212bc..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/metrics.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 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 membership
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	ClusterVersionMetrics = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "cluster",
-		Name:      "version",
-		Help:      "Which version is running. 1 for 'cluster_version' label with current cluster version",
-	},
-		[]string{"cluster_version"})
-)
-
-func init() {
-	prometheus.MustRegister(ClusterVersionMetrics)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/membership/store.go b/vendor/go.etcd.io/etcd/etcdserver/api/membership/store.go
deleted file mode 100644
index 14ab119..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/membership/store.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2016 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 membership
-
-import (
-	"encoding/json"
-	"fmt"
-	"path"
-
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-const (
-	attributesSuffix     = "attributes"
-	raftAttributesSuffix = "raftAttributes"
-
-	// the prefix for stroing membership related information in store provided by store pkg.
-	storePrefix = "/0"
-)
-
-var (
-	membersBucketName        = []byte("members")
-	membersRemovedBucketName = []byte("members_removed")
-	clusterBucketName        = []byte("cluster")
-
-	StoreMembersPrefix        = path.Join(storePrefix, "members")
-	storeRemovedMembersPrefix = path.Join(storePrefix, "removed_members")
-)
-
-func mustSaveMemberToBackend(be backend.Backend, m *Member) {
-	mkey := backendMemberKey(m.ID)
-	mvalue, err := json.Marshal(m)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-
-	tx := be.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(membersBucketName, mkey, mvalue)
-	tx.Unlock()
-}
-
-func mustDeleteMemberFromBackend(be backend.Backend, id types.ID) {
-	mkey := backendMemberKey(id)
-
-	tx := be.BatchTx()
-	tx.Lock()
-	tx.UnsafeDelete(membersBucketName, mkey)
-	tx.UnsafePut(membersRemovedBucketName, mkey, []byte("removed"))
-	tx.Unlock()
-}
-
-func mustSaveClusterVersionToBackend(be backend.Backend, ver *semver.Version) {
-	ckey := backendClusterVersionKey()
-
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	tx.UnsafePut(clusterBucketName, ckey, []byte(ver.String()))
-}
-
-func mustSaveMemberToStore(s v2store.Store, m *Member) {
-	b, err := json.Marshal(m.RaftAttributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix)
-	if _, err := s.Create(p, false, string(b), false, v2store.TTLOptionSet{ExpireTime: v2store.Permanent}); err != nil {
-		plog.Panicf("create raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustDeleteMemberFromStore(s v2store.Store, id types.ID) {
-	if _, err := s.Delete(MemberStoreKey(id), true, true); err != nil {
-		plog.Panicf("delete member should never fail: %v", err)
-	}
-	if _, err := s.Create(RemovedMemberStoreKey(id), false, "", false, v2store.TTLOptionSet{ExpireTime: v2store.Permanent}); err != nil {
-		plog.Panicf("create removedMember should never fail: %v", err)
-	}
-}
-
-func mustUpdateMemberInStore(s v2store.Store, m *Member) {
-	b, err := json.Marshal(m.RaftAttributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix)
-	if _, err := s.Update(p, string(b), v2store.TTLOptionSet{ExpireTime: v2store.Permanent}); err != nil {
-		plog.Panicf("update raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustUpdateMemberAttrInStore(s v2store.Store, m *Member) {
-	b, err := json.Marshal(m.Attributes)
-	if err != nil {
-		plog.Panicf("marshal raftAttributes should never fail: %v", err)
-	}
-	p := path.Join(MemberStoreKey(m.ID), attributesSuffix)
-	if _, err := s.Set(p, false, string(b), v2store.TTLOptionSet{ExpireTime: v2store.Permanent}); err != nil {
-		plog.Panicf("update raftAttributes should never fail: %v", err)
-	}
-}
-
-func mustSaveClusterVersionToStore(s v2store.Store, ver *semver.Version) {
-	if _, err := s.Set(StoreClusterVersionKey(), false, ver.String(), v2store.TTLOptionSet{ExpireTime: v2store.Permanent}); err != nil {
-		plog.Panicf("save cluster version should never fail: %v", err)
-	}
-}
-
-// nodeToMember builds member from a key value node.
-// the child nodes of the given node MUST be sorted by key.
-func nodeToMember(n *v2store.NodeExtern) (*Member, error) {
-	m := &Member{ID: MustParseMemberIDFromKey(n.Key)}
-	attrs := make(map[string][]byte)
-	raftAttrKey := path.Join(n.Key, raftAttributesSuffix)
-	attrKey := path.Join(n.Key, attributesSuffix)
-	for _, nn := range n.Nodes {
-		if nn.Key != raftAttrKey && nn.Key != attrKey {
-			return nil, fmt.Errorf("unknown key %q", nn.Key)
-		}
-		attrs[nn.Key] = []byte(*nn.Value)
-	}
-	if data := attrs[raftAttrKey]; data != nil {
-		if err := json.Unmarshal(data, &m.RaftAttributes); err != nil {
-			return nil, fmt.Errorf("unmarshal raftAttributes error: %v", err)
-		}
-	} else {
-		return nil, fmt.Errorf("raftAttributes key doesn't exist")
-	}
-	if data := attrs[attrKey]; data != nil {
-		if err := json.Unmarshal(data, &m.Attributes); err != nil {
-			return m, fmt.Errorf("unmarshal attributes error: %v", err)
-		}
-	}
-	return m, nil
-}
-
-func backendMemberKey(id types.ID) []byte {
-	return []byte(id.String())
-}
-
-func backendClusterVersionKey() []byte {
-	return []byte("clusterVersion")
-}
-
-func mustCreateBackendBuckets(be backend.Backend) {
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	tx.UnsafeCreateBucket(membersBucketName)
-	tx.UnsafeCreateBucket(membersRemovedBucketName)
-	tx.UnsafeCreateBucket(clusterBucketName)
-}
-
-func MemberStoreKey(id types.ID) string {
-	return path.Join(StoreMembersPrefix, id.String())
-}
-
-func StoreClusterVersionKey() string {
-	return path.Join(storePrefix, "version")
-}
-
-func MemberAttributesStorePath(id types.ID) string {
-	return path.Join(MemberStoreKey(id), attributesSuffix)
-}
-
-func MustParseMemberIDFromKey(key string) types.ID {
-	id, err := types.IDFromString(path.Base(key))
-	if err != nil {
-		plog.Panicf("unexpected parse member id error: %v", err)
-	}
-	return id
-}
-
-func RemovedMemberStoreKey(id types.ID) string {
-	return path.Join(storeRemovedMembersPrefix, id.String())
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/coder.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/coder.go
deleted file mode 100644
index 12c3e44..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/coder.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import "go.etcd.io/etcd/raft/raftpb"
-
-type encoder interface {
-	// encode encodes the given message to an output stream.
-	encode(m *raftpb.Message) error
-}
-
-type decoder interface {
-	// decode decodes the message from an input stream.
-	decode() (raftpb.Message, error)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/doc.go
deleted file mode 100644
index a9486a8..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 rafthttp implements HTTP transportation layer for etcd/raft pkg.
-package rafthttp
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go
deleted file mode 100644
index d0e0c81..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/http.go
+++ /dev/null
@@ -1,577 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"path"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	pioutil "go.etcd.io/etcd/pkg/ioutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/version"
-
-	humanize "github.com/dustin/go-humanize"
-	"go.uber.org/zap"
-)
-
-const (
-	// connReadLimitByte limits the number of bytes
-	// a single read can read out.
-	//
-	// 64KB should be large enough for not causing
-	// throughput bottleneck as well as small enough
-	// for not causing a read timeout.
-	connReadLimitByte = 64 * 1024
-)
-
-var (
-	RaftPrefix         = "/raft"
-	ProbingPrefix      = path.Join(RaftPrefix, "probing")
-	RaftStreamPrefix   = path.Join(RaftPrefix, "stream")
-	RaftSnapshotPrefix = path.Join(RaftPrefix, "snapshot")
-
-	errIncompatibleVersion = errors.New("incompatible version")
-	errClusterIDMismatch   = errors.New("cluster ID mismatch")
-)
-
-type peerGetter interface {
-	Get(id types.ID) Peer
-}
-
-type writerToResponse interface {
-	WriteTo(w http.ResponseWriter)
-}
-
-type pipelineHandler struct {
-	lg      *zap.Logger
-	localID types.ID
-	tr      Transporter
-	r       Raft
-	cid     types.ID
-}
-
-// newPipelineHandler returns a handler for handling raft messages
-// from pipeline for RaftPrefix.
-//
-// The handler reads out the raft message from request body,
-// and forwards it to the given raft state machine for processing.
-func newPipelineHandler(t *Transport, r Raft, cid types.ID) http.Handler {
-	return &pipelineHandler{
-		lg:      t.Logger,
-		localID: t.ID,
-		tr:      t,
-		r:       r,
-		cid:     cid,
-	}
-}
-
-func (h *pipelineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		w.Header().Set("Allow", "POST")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(h.lg, h.localID, r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		return
-	}
-
-	addRemoteFromRequest(h.tr, r)
-
-	// Limit the data size that could be read from the request body, which ensures that read from
-	// connection will not time out accidentally due to possible blocking in underlying implementation.
-	limitedr := pioutil.NewLimitedBufferReader(r.Body, connReadLimitByte)
-	b, err := ioutil.ReadAll(limitedr)
-	if err != nil {
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to read Raft message",
-				zap.String("local-member-id", h.localID.String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to read raft message (%v)", err)
-		}
-		http.Error(w, "error reading raft message", http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		return
-	}
-
-	var m raftpb.Message
-	if err := m.Unmarshal(b); err != nil {
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to unmarshal Raft message",
-				zap.String("local-member-id", h.localID.String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to unmarshal raft message (%v)", err)
-		}
-		http.Error(w, "error unmarshalling raft message", http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		return
-	}
-
-	receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(len(b)))
-
-	if err := h.r.Process(context.TODO(), m); err != nil {
-		switch v := err.(type) {
-		case writerToResponse:
-			v.WriteTo(w)
-		default:
-			if h.lg != nil {
-				h.lg.Warn(
-					"failed to process Raft message",
-					zap.String("local-member-id", h.localID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("failed to process raft message (%v)", err)
-			}
-			http.Error(w, "error processing raft message", http.StatusInternalServerError)
-			w.(http.Flusher).Flush()
-			// disconnect the http stream
-			panic(err)
-		}
-		return
-	}
-
-	// Write StatusNoContent header after the message has been processed by
-	// raft, which facilitates the client to report MsgSnap status.
-	w.WriteHeader(http.StatusNoContent)
-}
-
-type snapshotHandler struct {
-	lg          *zap.Logger
-	tr          Transporter
-	r           Raft
-	snapshotter *snap.Snapshotter
-
-	localID types.ID
-	cid     types.ID
-}
-
-func newSnapshotHandler(t *Transport, r Raft, snapshotter *snap.Snapshotter, cid types.ID) http.Handler {
-	return &snapshotHandler{
-		lg:          t.Logger,
-		tr:          t,
-		r:           r,
-		snapshotter: snapshotter,
-		localID:     t.ID,
-		cid:         cid,
-	}
-}
-
-const unknownSnapshotSender = "UNKNOWN_SNAPSHOT_SENDER"
-
-// ServeHTTP serves HTTP request to receive and process snapshot message.
-//
-// If request sender dies without closing underlying TCP connection,
-// the handler will keep waiting for the request body until TCP keepalive
-// finds out that the connection is broken after several minutes.
-// This is acceptable because
-// 1. snapshot messages sent through other TCP connections could still be
-// received and processed.
-// 2. this case should happen rarely, so no further optimization is done.
-func (h *snapshotHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	start := time.Now()
-
-	if r.Method != "POST" {
-		w.Header().Set("Allow", "POST")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc()
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(h.lg, h.localID, r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		snapshotReceiveFailures.WithLabelValues(unknownSnapshotSender).Inc()
-		return
-	}
-
-	addRemoteFromRequest(h.tr, r)
-
-	dec := &messageDecoder{r: r.Body}
-	// let snapshots be very large since they can exceed 512MB for large installations
-	m, err := dec.decodeLimit(uint64(1 << 63))
-	from := types.ID(m.From).String()
-	if err != nil {
-		msg := fmt.Sprintf("failed to decode raft message (%v)", err)
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to decode Raft message",
-				zap.String("local-member-id", h.localID.String()),
-				zap.String("remote-snapshot-sender-id", from),
-				zap.Error(err),
-			)
-		} else {
-			plog.Error(msg)
-		}
-		http.Error(w, msg, http.StatusBadRequest)
-		recvFailures.WithLabelValues(r.RemoteAddr).Inc()
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-
-	msgSize := m.Size()
-	receivedBytes.WithLabelValues(from).Add(float64(msgSize))
-
-	if m.Type != raftpb.MsgSnap {
-		if h.lg != nil {
-			h.lg.Warn(
-				"unexpected Raft message type",
-				zap.String("local-member-id", h.localID.String()),
-				zap.String("remote-snapshot-sender-id", from),
-				zap.String("message-type", m.Type.String()),
-			)
-		} else {
-			plog.Errorf("unexpected raft message type %s on snapshot path", m.Type)
-		}
-		http.Error(w, "wrong raft message type", http.StatusBadRequest)
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-
-	snapshotReceiveInflights.WithLabelValues(from).Inc()
-	defer func() {
-		snapshotReceiveInflights.WithLabelValues(from).Dec()
-	}()
-
-	if h.lg != nil {
-		h.lg.Info(
-			"receiving database snapshot",
-			zap.String("local-member-id", h.localID.String()),
-			zap.String("remote-snapshot-sender-id", from),
-			zap.Uint64("incoming-snapshot-index", m.Snapshot.Metadata.Index),
-			zap.Int("incoming-snapshot-message-size-bytes", msgSize),
-			zap.String("incoming-snapshot-message-size", humanize.Bytes(uint64(msgSize))),
-		)
-	} else {
-		plog.Infof("receiving database snapshot [index:%d, from %s] ...", m.Snapshot.Metadata.Index, types.ID(m.From))
-	}
-
-	// save incoming database snapshot.
-	n, err := h.snapshotter.SaveDBFrom(r.Body, m.Snapshot.Metadata.Index)
-	if err != nil {
-		msg := fmt.Sprintf("failed to save KV snapshot (%v)", err)
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to save incoming database snapshot",
-				zap.String("local-member-id", h.localID.String()),
-				zap.String("remote-snapshot-sender-id", from),
-				zap.Uint64("incoming-snapshot-index", m.Snapshot.Metadata.Index),
-				zap.Error(err),
-			)
-		} else {
-			plog.Error(msg)
-		}
-		http.Error(w, msg, http.StatusInternalServerError)
-		snapshotReceiveFailures.WithLabelValues(from).Inc()
-		return
-	}
-
-	receivedBytes.WithLabelValues(from).Add(float64(n))
-
-	if h.lg != nil {
-		h.lg.Info(
-			"received and saved database snapshot",
-			zap.String("local-member-id", h.localID.String()),
-			zap.String("remote-snapshot-sender-id", from),
-			zap.Uint64("incoming-snapshot-index", m.Snapshot.Metadata.Index),
-			zap.Int64("incoming-snapshot-size-bytes", n),
-			zap.String("incoming-snapshot-size", humanize.Bytes(uint64(n))),
-		)
-	} else {
-		plog.Infof("received and saved database snapshot [index: %d, from: %s] successfully", m.Snapshot.Metadata.Index, types.ID(m.From))
-	}
-
-	if err := h.r.Process(context.TODO(), m); err != nil {
-		switch v := err.(type) {
-		// Process may return writerToResponse error when doing some
-		// additional checks before calling raft.Node.Step.
-		case writerToResponse:
-			v.WriteTo(w)
-		default:
-			msg := fmt.Sprintf("failed to process raft message (%v)", err)
-			if h.lg != nil {
-				h.lg.Warn(
-					"failed to process Raft message",
-					zap.String("local-member-id", h.localID.String()),
-					zap.String("remote-snapshot-sender-id", from),
-					zap.Error(err),
-				)
-			} else {
-				plog.Error(msg)
-			}
-			http.Error(w, msg, http.StatusInternalServerError)
-			snapshotReceiveFailures.WithLabelValues(from).Inc()
-		}
-		return
-	}
-
-	// Write StatusNoContent header after the message has been processed by
-	// raft, which facilitates the client to report MsgSnap status.
-	w.WriteHeader(http.StatusNoContent)
-
-	snapshotReceive.WithLabelValues(from).Inc()
-	snapshotReceiveSeconds.WithLabelValues(from).Observe(time.Since(start).Seconds())
-}
-
-type streamHandler struct {
-	lg         *zap.Logger
-	tr         *Transport
-	peerGetter peerGetter
-	r          Raft
-	id         types.ID
-	cid        types.ID
-}
-
-func newStreamHandler(t *Transport, pg peerGetter, r Raft, id, cid types.ID) http.Handler {
-	return &streamHandler{
-		lg:         t.Logger,
-		tr:         t,
-		peerGetter: pg,
-		r:          r,
-		id:         id,
-		cid:        cid,
-	}
-}
-
-func (h *streamHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "GET" {
-		w.Header().Set("Allow", "GET")
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	w.Header().Set("X-Server-Version", version.Version)
-	w.Header().Set("X-Etcd-Cluster-ID", h.cid.String())
-
-	if err := checkClusterCompatibilityFromHeader(h.lg, h.tr.ID, r.Header, h.cid); err != nil {
-		http.Error(w, err.Error(), http.StatusPreconditionFailed)
-		return
-	}
-
-	var t streamType
-	switch path.Dir(r.URL.Path) {
-	case streamTypeMsgAppV2.endpoint():
-		t = streamTypeMsgAppV2
-	case streamTypeMessage.endpoint():
-		t = streamTypeMessage
-	default:
-		if h.lg != nil {
-			h.lg.Debug(
-				"ignored unexpected streaming request path",
-				zap.String("local-member-id", h.tr.ID.String()),
-				zap.String("remote-peer-id-stream-handler", h.id.String()),
-				zap.String("path", r.URL.Path),
-			)
-		} else {
-			plog.Debugf("ignored unexpected streaming request path %s", r.URL.Path)
-		}
-		http.Error(w, "invalid path", http.StatusNotFound)
-		return
-	}
-
-	fromStr := path.Base(r.URL.Path)
-	from, err := types.IDFromString(fromStr)
-	if err != nil {
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to parse path into ID",
-				zap.String("local-member-id", h.tr.ID.String()),
-				zap.String("remote-peer-id-stream-handler", h.id.String()),
-				zap.String("path", fromStr),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to parse from %s into ID (%v)", fromStr, err)
-		}
-		http.Error(w, "invalid from", http.StatusNotFound)
-		return
-	}
-	if h.r.IsIDRemoved(uint64(from)) {
-		if h.lg != nil {
-			h.lg.Warn(
-				"rejected stream from remote peer because it was removed",
-				zap.String("local-member-id", h.tr.ID.String()),
-				zap.String("remote-peer-id-stream-handler", h.id.String()),
-				zap.String("remote-peer-id-from", from.String()),
-			)
-		} else {
-			plog.Warningf("rejected the stream from peer %s since it was removed", from)
-		}
-		http.Error(w, "removed member", http.StatusGone)
-		return
-	}
-	p := h.peerGetter.Get(from)
-	if p == nil {
-		// This may happen in following cases:
-		// 1. user starts a remote peer that belongs to a different cluster
-		// with the same cluster ID.
-		// 2. local etcd falls behind of the cluster, and cannot recognize
-		// the members that joined after its current progress.
-		if urls := r.Header.Get("X-PeerURLs"); urls != "" {
-			h.tr.AddRemote(from, strings.Split(urls, ","))
-		}
-		if h.lg != nil {
-			h.lg.Warn(
-				"failed to find remote peer in cluster",
-				zap.String("local-member-id", h.tr.ID.String()),
-				zap.String("remote-peer-id-stream-handler", h.id.String()),
-				zap.String("remote-peer-id-from", from.String()),
-				zap.String("cluster-id", h.cid.String()),
-			)
-		} else {
-			plog.Errorf("failed to find member %s in cluster %s", from, h.cid)
-		}
-		http.Error(w, "error sender not found", http.StatusNotFound)
-		return
-	}
-
-	wto := h.id.String()
-	if gto := r.Header.Get("X-Raft-To"); gto != wto {
-		if h.lg != nil {
-			h.lg.Warn(
-				"ignored streaming request; ID mismatch",
-				zap.String("local-member-id", h.tr.ID.String()),
-				zap.String("remote-peer-id-stream-handler", h.id.String()),
-				zap.String("remote-peer-id-header", gto),
-				zap.String("remote-peer-id-from", from.String()),
-				zap.String("cluster-id", h.cid.String()),
-			)
-		} else {
-			plog.Errorf("streaming request ignored (ID mismatch got %s want %s)", gto, wto)
-		}
-		http.Error(w, "to field mismatch", http.StatusPreconditionFailed)
-		return
-	}
-
-	w.WriteHeader(http.StatusOK)
-	w.(http.Flusher).Flush()
-
-	c := newCloseNotifier()
-	conn := &outgoingConn{
-		t:       t,
-		Writer:  w,
-		Flusher: w.(http.Flusher),
-		Closer:  c,
-		localID: h.tr.ID,
-		peerID:  h.id,
-	}
-	p.attachOutgoingConn(conn)
-	<-c.closeNotify()
-}
-
-// checkClusterCompatibilityFromHeader checks the cluster compatibility of
-// the local member from the given header.
-// It checks whether the version of local member is compatible with
-// the versions in the header, and whether the cluster ID of local member
-// matches the one in the header.
-func checkClusterCompatibilityFromHeader(lg *zap.Logger, localID types.ID, header http.Header, cid types.ID) error {
-	remoteName := header.Get("X-Server-From")
-
-	remoteServer := serverVersion(header)
-	remoteVs := ""
-	if remoteServer != nil {
-		remoteVs = remoteServer.String()
-	}
-
-	remoteMinClusterVer := minClusterVersion(header)
-	remoteMinClusterVs := ""
-	if remoteMinClusterVer != nil {
-		remoteMinClusterVs = remoteMinClusterVer.String()
-	}
-
-	localServer, localMinCluster, err := checkVersionCompatibility(remoteName, remoteServer, remoteMinClusterVer)
-
-	localVs := ""
-	if localServer != nil {
-		localVs = localServer.String()
-	}
-	localMinClusterVs := ""
-	if localMinCluster != nil {
-		localMinClusterVs = localMinCluster.String()
-	}
-
-	if err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to check version compatibility",
-				zap.String("local-member-id", localID.String()),
-				zap.String("local-member-cluster-id", cid.String()),
-				zap.String("local-member-server-version", localVs),
-				zap.String("local-member-server-minimum-cluster-version", localMinClusterVs),
-				zap.String("remote-peer-server-name", remoteName),
-				zap.String("remote-peer-server-version", remoteVs),
-				zap.String("remote-peer-server-minimum-cluster-version", remoteMinClusterVs),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("request version incompatibility (%v)", err)
-		}
-		return errIncompatibleVersion
-	}
-	if gcid := header.Get("X-Etcd-Cluster-ID"); gcid != cid.String() {
-		if lg != nil {
-			lg.Warn(
-				"request cluster ID mismatch",
-				zap.String("local-member-id", localID.String()),
-				zap.String("local-member-cluster-id", cid.String()),
-				zap.String("local-member-server-version", localVs),
-				zap.String("local-member-server-minimum-cluster-version", localMinClusterVs),
-				zap.String("remote-peer-server-name", remoteName),
-				zap.String("remote-peer-server-version", remoteVs),
-				zap.String("remote-peer-server-minimum-cluster-version", remoteMinClusterVs),
-				zap.String("remote-peer-cluster-id", gcid),
-			)
-		} else {
-			plog.Errorf("request cluster ID mismatch (got %s want %s)", gcid, cid)
-		}
-		return errClusterIDMismatch
-	}
-	return nil
-}
-
-type closeNotifier struct {
-	done chan struct{}
-}
-
-func newCloseNotifier() *closeNotifier {
-	return &closeNotifier{
-		done: make(chan struct{}),
-	}
-}
-
-func (n *closeNotifier) Close() error {
-	close(n.done)
-	return nil
-}
-
-func (n *closeNotifier) closeNotify() <-chan struct{} { return n.done }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/metrics.go
deleted file mode 100644
index 02fff84..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/metrics.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	activePeers = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "active_peers",
-		Help:      "The current number of active peer connections.",
-	},
-		[]string{"Local", "Remote"},
-	)
-
-	disconnectedPeers = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "disconnected_peers_total",
-		Help:      "The total number of disconnected peers.",
-	},
-		[]string{"Local", "Remote"},
-	)
-
-	sentBytes = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_sent_bytes_total",
-		Help:      "The total number of bytes sent to peers.",
-	},
-		[]string{"To"},
-	)
-
-	receivedBytes = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_received_bytes_total",
-		Help:      "The total number of bytes received from peers.",
-	},
-		[]string{"From"},
-	)
-
-	sentFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_sent_failures_total",
-		Help:      "The total number of send failures from peers.",
-	},
-		[]string{"To"},
-	)
-
-	recvFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_received_failures_total",
-		Help:      "The total number of receive failures from peers.",
-	},
-		[]string{"From"},
-	)
-
-	snapshotSend = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_success",
-		Help:      "Total number of successful snapshot sends",
-	},
-		[]string{"To"},
-	)
-
-	snapshotSendInflights = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_inflights_total",
-		Help:      "Total number of inflight snapshot sends",
-	},
-		[]string{"To"},
-	)
-
-	snapshotSendFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_failures",
-		Help:      "Total number of snapshot send failures",
-	},
-		[]string{"To"},
-	)
-
-	snapshotSendSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_send_total_duration_seconds",
-		Help:      "Total latency distributions of v3 snapshot sends",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	},
-		[]string{"To"},
-	)
-
-	snapshotReceive = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_success",
-		Help:      "Total number of successful snapshot receives",
-	},
-		[]string{"From"},
-	)
-
-	snapshotReceiveInflights = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_inflights_total",
-		Help:      "Total number of inflight snapshot receives",
-	},
-		[]string{"From"},
-	)
-
-	snapshotReceiveFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_failures",
-		Help:      "Total number of snapshot receive failures",
-	},
-		[]string{"From"},
-	)
-
-	snapshotReceiveSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "snapshot_receive_total_duration_seconds",
-		Help:      "Total latency distributions of v3 snapshot receives",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	},
-		[]string{"From"},
-	)
-
-	rttSec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "peer_round_trip_time_seconds",
-		Help:      "Round-Trip-Time histogram between peers",
-
-		// lowest bucket start of upper bound 0.0001 sec (0.1 ms) with factor 2
-		// highest bucket start of 0.0001 sec * 2^15 == 3.2768 sec
-		Buckets: prometheus.ExponentialBuckets(0.0001, 2, 16),
-	},
-		[]string{"To"},
-	)
-)
-
-func init() {
-	prometheus.MustRegister(activePeers)
-	prometheus.MustRegister(disconnectedPeers)
-	prometheus.MustRegister(sentBytes)
-	prometheus.MustRegister(receivedBytes)
-	prometheus.MustRegister(sentFailures)
-	prometheus.MustRegister(recvFailures)
-
-	prometheus.MustRegister(snapshotSend)
-	prometheus.MustRegister(snapshotSendInflights)
-	prometheus.MustRegister(snapshotSendFailures)
-	prometheus.MustRegister(snapshotSendSeconds)
-	prometheus.MustRegister(snapshotReceive)
-	prometheus.MustRegister(snapshotReceiveInflights)
-	prometheus.MustRegister(snapshotReceiveFailures)
-	prometheus.MustRegister(snapshotReceiveSeconds)
-
-	prometheus.MustRegister(rttSec)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msg_codec.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msg_codec.go
deleted file mode 100644
index 2417d22..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msg_codec.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"encoding/binary"
-	"errors"
-	"io"
-
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/raft/raftpb"
-)
-
-// messageEncoder is a encoder that can encode all kinds of messages.
-// It MUST be used with a paired messageDecoder.
-type messageEncoder struct {
-	w io.Writer
-}
-
-func (enc *messageEncoder) encode(m *raftpb.Message) error {
-	if err := binary.Write(enc.w, binary.BigEndian, uint64(m.Size())); err != nil {
-		return err
-	}
-	_, err := enc.w.Write(pbutil.MustMarshal(m))
-	return err
-}
-
-// messageDecoder is a decoder that can decode all kinds of messages.
-type messageDecoder struct {
-	r io.Reader
-}
-
-var (
-	readBytesLimit     uint64 = 512 * 1024 * 1024 // 512 MB
-	ErrExceedSizeLimit        = errors.New("rafthttp: error limit exceeded")
-)
-
-func (dec *messageDecoder) decode() (raftpb.Message, error) {
-	return dec.decodeLimit(readBytesLimit)
-}
-
-func (dec *messageDecoder) decodeLimit(numBytes uint64) (raftpb.Message, error) {
-	var m raftpb.Message
-	var l uint64
-	if err := binary.Read(dec.r, binary.BigEndian, &l); err != nil {
-		return m, err
-	}
-	if l > numBytes {
-		return m, ErrExceedSizeLimit
-	}
-	buf := make([]byte, int(l))
-	if _, err := io.ReadFull(dec.r, buf); err != nil {
-		return m, err
-	}
-	return m, m.Unmarshal(buf)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msgappv2_codec.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msgappv2_codec.go
deleted file mode 100644
index 1fa36de..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/msgappv2_codec.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"encoding/binary"
-	"fmt"
-	"io"
-	"time"
-
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft/raftpb"
-)
-
-const (
-	msgTypeLinkHeartbeat uint8 = 0
-	msgTypeAppEntries    uint8 = 1
-	msgTypeApp           uint8 = 2
-
-	msgAppV2BufSize = 1024 * 1024
-)
-
-// msgappv2 stream sends three types of message: linkHeartbeatMessage,
-// AppEntries and MsgApp. AppEntries is the MsgApp that is sent in
-// replicate state in raft, whose index and term are fully predictable.
-//
-// Data format of linkHeartbeatMessage:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x00        |
-//
-// Data format of AppEntries:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x01        |
-// | 1      | 8     | length of entries |
-// | 9      | 8     | length of first entry |
-// | 17     | n1    | first entry |
-// ...
-// | x      | 8     | length of k-th entry data |
-// | x+8    | nk    | k-th entry data |
-// | x+8+nk | 8     | commit index |
-//
-// Data format of MsgApp:
-// | offset | bytes | description |
-// +--------+-------+-------------+
-// | 0      | 1     | \x02        |
-// | 1      | 8     | length of encoded message |
-// | 9      | n     | encoded message |
-type msgAppV2Encoder struct {
-	w  io.Writer
-	fs *stats.FollowerStats
-
-	term      uint64
-	index     uint64
-	buf       []byte
-	uint64buf []byte
-	uint8buf  []byte
-}
-
-func newMsgAppV2Encoder(w io.Writer, fs *stats.FollowerStats) *msgAppV2Encoder {
-	return &msgAppV2Encoder{
-		w:         w,
-		fs:        fs,
-		buf:       make([]byte, msgAppV2BufSize),
-		uint64buf: make([]byte, 8),
-		uint8buf:  make([]byte, 1),
-	}
-}
-
-func (enc *msgAppV2Encoder) encode(m *raftpb.Message) error {
-	start := time.Now()
-	switch {
-	case isLinkHeartbeatMessage(m):
-		enc.uint8buf[0] = msgTypeLinkHeartbeat
-		if _, err := enc.w.Write(enc.uint8buf); err != nil {
-			return err
-		}
-	case enc.index == m.Index && enc.term == m.LogTerm && m.LogTerm == m.Term:
-		enc.uint8buf[0] = msgTypeAppEntries
-		if _, err := enc.w.Write(enc.uint8buf); err != nil {
-			return err
-		}
-		// write length of entries
-		binary.BigEndian.PutUint64(enc.uint64buf, uint64(len(m.Entries)))
-		if _, err := enc.w.Write(enc.uint64buf); err != nil {
-			return err
-		}
-		for i := 0; i < len(m.Entries); i++ {
-			// write length of entry
-			binary.BigEndian.PutUint64(enc.uint64buf, uint64(m.Entries[i].Size()))
-			if _, err := enc.w.Write(enc.uint64buf); err != nil {
-				return err
-			}
-			if n := m.Entries[i].Size(); n < msgAppV2BufSize {
-				if _, err := m.Entries[i].MarshalTo(enc.buf); err != nil {
-					return err
-				}
-				if _, err := enc.w.Write(enc.buf[:n]); err != nil {
-					return err
-				}
-			} else {
-				if _, err := enc.w.Write(pbutil.MustMarshal(&m.Entries[i])); err != nil {
-					return err
-				}
-			}
-			enc.index++
-		}
-		// write commit index
-		binary.BigEndian.PutUint64(enc.uint64buf, m.Commit)
-		if _, err := enc.w.Write(enc.uint64buf); err != nil {
-			return err
-		}
-		enc.fs.Succ(time.Since(start))
-	default:
-		if err := binary.Write(enc.w, binary.BigEndian, msgTypeApp); err != nil {
-			return err
-		}
-		// write size of message
-		if err := binary.Write(enc.w, binary.BigEndian, uint64(m.Size())); err != nil {
-			return err
-		}
-		// write message
-		if _, err := enc.w.Write(pbutil.MustMarshal(m)); err != nil {
-			return err
-		}
-
-		enc.term = m.Term
-		enc.index = m.Index
-		if l := len(m.Entries); l > 0 {
-			enc.index = m.Entries[l-1].Index
-		}
-		enc.fs.Succ(time.Since(start))
-	}
-	return nil
-}
-
-type msgAppV2Decoder struct {
-	r             io.Reader
-	local, remote types.ID
-
-	term      uint64
-	index     uint64
-	buf       []byte
-	uint64buf []byte
-	uint8buf  []byte
-}
-
-func newMsgAppV2Decoder(r io.Reader, local, remote types.ID) *msgAppV2Decoder {
-	return &msgAppV2Decoder{
-		r:         r,
-		local:     local,
-		remote:    remote,
-		buf:       make([]byte, msgAppV2BufSize),
-		uint64buf: make([]byte, 8),
-		uint8buf:  make([]byte, 1),
-	}
-}
-
-func (dec *msgAppV2Decoder) decode() (raftpb.Message, error) {
-	var (
-		m   raftpb.Message
-		typ uint8
-	)
-	if _, err := io.ReadFull(dec.r, dec.uint8buf); err != nil {
-		return m, err
-	}
-	typ = dec.uint8buf[0]
-	switch typ {
-	case msgTypeLinkHeartbeat:
-		return linkHeartbeatMessage, nil
-	case msgTypeAppEntries:
-		m = raftpb.Message{
-			Type:    raftpb.MsgApp,
-			From:    uint64(dec.remote),
-			To:      uint64(dec.local),
-			Term:    dec.term,
-			LogTerm: dec.term,
-			Index:   dec.index,
-		}
-
-		// decode entries
-		if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-			return m, err
-		}
-		l := binary.BigEndian.Uint64(dec.uint64buf)
-		m.Entries = make([]raftpb.Entry, int(l))
-		for i := 0; i < int(l); i++ {
-			if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-				return m, err
-			}
-			size := binary.BigEndian.Uint64(dec.uint64buf)
-			var buf []byte
-			if size < msgAppV2BufSize {
-				buf = dec.buf[:size]
-				if _, err := io.ReadFull(dec.r, buf); err != nil {
-					return m, err
-				}
-			} else {
-				buf = make([]byte, int(size))
-				if _, err := io.ReadFull(dec.r, buf); err != nil {
-					return m, err
-				}
-			}
-			dec.index++
-			// 1 alloc
-			pbutil.MustUnmarshal(&m.Entries[i], buf)
-		}
-		// decode commit index
-		if _, err := io.ReadFull(dec.r, dec.uint64buf); err != nil {
-			return m, err
-		}
-		m.Commit = binary.BigEndian.Uint64(dec.uint64buf)
-	case msgTypeApp:
-		var size uint64
-		if err := binary.Read(dec.r, binary.BigEndian, &size); err != nil {
-			return m, err
-		}
-		buf := make([]byte, int(size))
-		if _, err := io.ReadFull(dec.r, buf); err != nil {
-			return m, err
-		}
-		pbutil.MustUnmarshal(&m, buf)
-
-		dec.term = m.Term
-		dec.index = m.Index
-		if l := len(m.Entries); l > 0 {
-			dec.index = m.Entries[l-1].Index
-		}
-	default:
-		return m, fmt.Errorf("failed to parse type %d in msgappv2 stream", typ)
-	}
-	return m, nil
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer.go
deleted file mode 100644
index 8130c4a..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"go.uber.org/zap"
-	"golang.org/x/time/rate"
-)
-
-const (
-	// ConnReadTimeout and ConnWriteTimeout are the i/o timeout set on each connection rafthttp pkg creates.
-	// A 5 seconds timeout is good enough for recycling bad connections. Or we have to wait for
-	// tcp keepalive failing to detect a bad connection, which is at minutes level.
-	// For long term streaming connections, rafthttp pkg sends application level linkHeartbeatMessage
-	// to keep the connection alive.
-	// For short term pipeline connections, the connection MUST be killed to avoid it being
-	// put back to http pkg connection pool.
-	ConnReadTimeout  = 5 * time.Second
-	ConnWriteTimeout = 5 * time.Second
-
-	recvBufSize = 4096
-	// maxPendingProposals holds the proposals during one leader election process.
-	// Generally one leader election takes at most 1 sec. It should have
-	// 0-2 election conflicts, and each one takes 0.5 sec.
-	// We assume the number of concurrent proposers is smaller than 4096.
-	// One client blocks on its proposal for at least 1 sec, so 4096 is enough
-	// to hold all proposals.
-	maxPendingProposals = 4096
-
-	streamAppV2 = "streamMsgAppV2"
-	streamMsg   = "streamMsg"
-	pipelineMsg = "pipeline"
-	sendSnap    = "sendMsgSnap"
-)
-
-type Peer interface {
-	// send sends the message to the remote peer. The function is non-blocking
-	// and has no promise that the message will be received by the remote.
-	// When it fails to send message out, it will report the status to underlying
-	// raft.
-	send(m raftpb.Message)
-
-	// sendSnap sends the merged snapshot message to the remote peer. Its behavior
-	// is similar to send.
-	sendSnap(m snap.Message)
-
-	// update updates the urls of remote peer.
-	update(urls types.URLs)
-
-	// attachOutgoingConn attaches the outgoing connection to the peer for
-	// stream usage. After the call, the ownership of the outgoing
-	// connection hands over to the peer. The peer will close the connection
-	// when it is no longer used.
-	attachOutgoingConn(conn *outgoingConn)
-	// activeSince returns the time that the connection with the
-	// peer becomes active.
-	activeSince() time.Time
-	// stop performs any necessary finalization and terminates the peer
-	// elegantly.
-	stop()
-}
-
-// peer is the representative of a remote raft node. Local raft node sends
-// messages to the remote through peer.
-// Each peer has two underlying mechanisms to send out a message: stream and
-// pipeline.
-// A stream is a receiver initialized long-polling connection, which
-// is always open to transfer messages. Besides general stream, peer also has
-// a optimized stream for sending msgApp since msgApp accounts for large part
-// of all messages. Only raft leader uses the optimized stream to send msgApp
-// to the remote follower node.
-// A pipeline is a series of http clients that send http requests to the remote.
-// It is only used when the stream has not been established.
-type peer struct {
-	lg *zap.Logger
-
-	localID types.ID
-	// id of the remote raft peer node
-	id types.ID
-
-	r Raft
-
-	status *peerStatus
-
-	picker *urlPicker
-
-	msgAppV2Writer *streamWriter
-	writer         *streamWriter
-	pipeline       *pipeline
-	snapSender     *snapshotSender // snapshot sender to send v3 snapshot messages
-	msgAppV2Reader *streamReader
-	msgAppReader   *streamReader
-
-	recvc chan raftpb.Message
-	propc chan raftpb.Message
-
-	mu     sync.Mutex
-	paused bool
-
-	cancel context.CancelFunc // cancel pending works in go routine created by peer.
-	stopc  chan struct{}
-}
-
-func startPeer(t *Transport, urls types.URLs, peerID types.ID, fs *stats.FollowerStats) *peer {
-	if t.Logger != nil {
-		t.Logger.Info("starting remote peer", zap.String("remote-peer-id", peerID.String()))
-	} else {
-		plog.Infof("starting peer %s...", peerID)
-	}
-	defer func() {
-		if t.Logger != nil {
-			t.Logger.Info("started remote peer", zap.String("remote-peer-id", peerID.String()))
-		} else {
-			plog.Infof("started peer %s", peerID)
-		}
-	}()
-
-	status := newPeerStatus(t.Logger, t.ID, peerID)
-	picker := newURLPicker(urls)
-	errorc := t.ErrorC
-	r := t.Raft
-	pipeline := &pipeline{
-		peerID:        peerID,
-		tr:            t,
-		picker:        picker,
-		status:        status,
-		followerStats: fs,
-		raft:          r,
-		errorc:        errorc,
-	}
-	pipeline.start()
-
-	p := &peer{
-		lg:             t.Logger,
-		localID:        t.ID,
-		id:             peerID,
-		r:              r,
-		status:         status,
-		picker:         picker,
-		msgAppV2Writer: startStreamWriter(t.Logger, t.ID, peerID, status, fs, r),
-		writer:         startStreamWriter(t.Logger, t.ID, peerID, status, fs, r),
-		pipeline:       pipeline,
-		snapSender:     newSnapshotSender(t, picker, peerID, status),
-		recvc:          make(chan raftpb.Message, recvBufSize),
-		propc:          make(chan raftpb.Message, maxPendingProposals),
-		stopc:          make(chan struct{}),
-	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-	p.cancel = cancel
-	go func() {
-		for {
-			select {
-			case mm := <-p.recvc:
-				if err := r.Process(ctx, mm); err != nil {
-					if t.Logger != nil {
-						t.Logger.Warn("failed to process Raft message", zap.Error(err))
-					} else {
-						plog.Warningf("failed to process raft message (%v)", err)
-					}
-				}
-			case <-p.stopc:
-				return
-			}
-		}
-	}()
-
-	// r.Process might block for processing proposal when there is no leader.
-	// Thus propc must be put into a separate routine with recvc to avoid blocking
-	// processing other raft messages.
-	go func() {
-		for {
-			select {
-			case mm := <-p.propc:
-				if err := r.Process(ctx, mm); err != nil {
-					plog.Warningf("failed to process raft message (%v)", err)
-				}
-			case <-p.stopc:
-				return
-			}
-		}
-	}()
-
-	p.msgAppV2Reader = &streamReader{
-		lg:     t.Logger,
-		peerID: peerID,
-		typ:    streamTypeMsgAppV2,
-		tr:     t,
-		picker: picker,
-		status: status,
-		recvc:  p.recvc,
-		propc:  p.propc,
-		rl:     rate.NewLimiter(t.DialRetryFrequency, 1),
-	}
-	p.msgAppReader = &streamReader{
-		lg:     t.Logger,
-		peerID: peerID,
-		typ:    streamTypeMessage,
-		tr:     t,
-		picker: picker,
-		status: status,
-		recvc:  p.recvc,
-		propc:  p.propc,
-		rl:     rate.NewLimiter(t.DialRetryFrequency, 1),
-	}
-
-	p.msgAppV2Reader.start()
-	p.msgAppReader.start()
-
-	return p
-}
-
-func (p *peer) send(m raftpb.Message) {
-	p.mu.Lock()
-	paused := p.paused
-	p.mu.Unlock()
-
-	if paused {
-		return
-	}
-
-	writec, name := p.pick(m)
-	select {
-	case writec <- m:
-	default:
-		p.r.ReportUnreachable(m.To)
-		if isMsgSnap(m) {
-			p.r.ReportSnapshot(m.To, raft.SnapshotFailure)
-		}
-		if p.status.isActive() {
-			if p.lg != nil {
-				p.lg.Warn(
-					"dropped internal Raft message since sending buffer is full (overloaded network)",
-					zap.String("message-type", m.Type.String()),
-					zap.String("local-member-id", p.localID.String()),
-					zap.String("from", types.ID(m.From).String()),
-					zap.String("remote-peer-id", p.id.String()),
-					zap.Bool("remote-peer-active", p.status.isActive()),
-				)
-			} else {
-				plog.MergeWarningf("dropped internal raft message to %s since %s's sending buffer is full (bad/overloaded network)", p.id, name)
-			}
-		} else {
-			if p.lg != nil {
-				p.lg.Warn(
-					"dropped internal Raft message since sending buffer is full (overloaded network)",
-					zap.String("message-type", m.Type.String()),
-					zap.String("local-member-id", p.localID.String()),
-					zap.String("from", types.ID(m.From).String()),
-					zap.String("remote-peer-id", p.id.String()),
-					zap.Bool("remote-peer-active", p.status.isActive()),
-				)
-			} else {
-				plog.Debugf("dropped %s to %s since %s's sending buffer is full", m.Type, p.id, name)
-			}
-		}
-		sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-	}
-}
-
-func (p *peer) sendSnap(m snap.Message) {
-	go p.snapSender.send(m)
-}
-
-func (p *peer) update(urls types.URLs) {
-	p.picker.update(urls)
-}
-
-func (p *peer) attachOutgoingConn(conn *outgoingConn) {
-	var ok bool
-	switch conn.t {
-	case streamTypeMsgAppV2:
-		ok = p.msgAppV2Writer.attach(conn)
-	case streamTypeMessage:
-		ok = p.writer.attach(conn)
-	default:
-		if p.lg != nil {
-			p.lg.Panic("unknown stream type", zap.String("type", conn.t.String()))
-		} else {
-			plog.Panicf("unhandled stream type %s", conn.t)
-		}
-	}
-	if !ok {
-		conn.Close()
-	}
-}
-
-func (p *peer) activeSince() time.Time { return p.status.activeSince() }
-
-// Pause pauses the peer. The peer will simply drops all incoming
-// messages without returning an error.
-func (p *peer) Pause() {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.paused = true
-	p.msgAppReader.pause()
-	p.msgAppV2Reader.pause()
-}
-
-// Resume resumes a paused peer.
-func (p *peer) Resume() {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.paused = false
-	p.msgAppReader.resume()
-	p.msgAppV2Reader.resume()
-}
-
-func (p *peer) stop() {
-	if p.lg != nil {
-		p.lg.Info("stopping remote peer", zap.String("remote-peer-id", p.id.String()))
-	} else {
-		plog.Infof("stopping peer %s...", p.id)
-	}
-
-	defer func() {
-		if p.lg != nil {
-			p.lg.Info("stopped remote peer", zap.String("remote-peer-id", p.id.String()))
-		} else {
-			plog.Infof("stopped peer %s", p.id)
-		}
-	}()
-
-	close(p.stopc)
-	p.cancel()
-	p.msgAppV2Writer.stop()
-	p.writer.stop()
-	p.pipeline.stop()
-	p.snapSender.stop()
-	p.msgAppV2Reader.stop()
-	p.msgAppReader.stop()
-}
-
-// pick picks a chan for sending the given message. The picked chan and the picked chan
-// string name are returned.
-func (p *peer) pick(m raftpb.Message) (writec chan<- raftpb.Message, picked string) {
-	var ok bool
-	// Considering MsgSnap may have a big size, e.g., 1G, and will block
-	// stream for a long time, only use one of the N pipelines to send MsgSnap.
-	if isMsgSnap(m) {
-		return p.pipeline.msgc, pipelineMsg
-	} else if writec, ok = p.msgAppV2Writer.writec(); ok && isMsgApp(m) {
-		return writec, streamAppV2
-	} else if writec, ok = p.writer.writec(); ok {
-		return writec, streamMsg
-	}
-	return p.pipeline.msgc, pipelineMsg
-}
-
-func isMsgApp(m raftpb.Message) bool { return m.Type == raftpb.MsgApp }
-
-func isMsgSnap(m raftpb.Message) bool { return m.Type == raftpb.MsgSnap }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer_status.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer_status.go
deleted file mode 100644
index 66149ff..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/peer_status.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"errors"
-	"fmt"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/pkg/types"
-
-	"go.uber.org/zap"
-)
-
-type failureType struct {
-	source string
-	action string
-}
-
-type peerStatus struct {
-	lg     *zap.Logger
-	local  types.ID
-	id     types.ID
-	mu     sync.Mutex // protect variables below
-	active bool
-	since  time.Time
-}
-
-func newPeerStatus(lg *zap.Logger, local, id types.ID) *peerStatus {
-	return &peerStatus{lg: lg, local: local, id: id}
-}
-
-func (s *peerStatus) activate() {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if !s.active {
-		if s.lg != nil {
-			s.lg.Info("peer became active", zap.String("peer-id", s.id.String()))
-		} else {
-			plog.Infof("peer %s became active", s.id)
-		}
-		s.active = true
-		s.since = time.Now()
-
-		activePeers.WithLabelValues(s.local.String(), s.id.String()).Inc()
-	}
-}
-
-func (s *peerStatus) deactivate(failure failureType, reason string) {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	msg := fmt.Sprintf("failed to %s %s on %s (%s)", failure.action, s.id, failure.source, reason)
-	if s.active {
-		if s.lg != nil {
-			s.lg.Warn("peer became inactive (message send to peer failed)", zap.String("peer-id", s.id.String()), zap.Error(errors.New(msg)))
-		} else {
-			plog.Errorf(msg)
-			plog.Infof("peer %s became inactive (message send to peer failed)", s.id)
-		}
-		s.active = false
-		s.since = time.Time{}
-
-		activePeers.WithLabelValues(s.local.String(), s.id.String()).Dec()
-		disconnectedPeers.WithLabelValues(s.local.String(), s.id.String()).Inc()
-		return
-	}
-
-	if s.lg != nil {
-		s.lg.Debug("peer deactivated again", zap.String("peer-id", s.id.String()), zap.Error(errors.New(msg)))
-	}
-}
-
-func (s *peerStatus) isActive() bool {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.active
-}
-
-func (s *peerStatus) activeSince() time.Time {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.since
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/pipeline.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/pipeline.go
deleted file mode 100644
index 70f9257..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/pipeline.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"bytes"
-	"context"
-	"errors"
-	"io/ioutil"
-	"sync"
-	"time"
-
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"go.uber.org/zap"
-)
-
-const (
-	connPerPipeline = 4
-	// pipelineBufSize is the size of pipeline buffer, which helps hold the
-	// temporary network latency.
-	// The size ensures that pipeline does not drop messages when the network
-	// is out of work for less than 1 second in good path.
-	pipelineBufSize = 64
-)
-
-var errStopped = errors.New("stopped")
-
-type pipeline struct {
-	peerID types.ID
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	raft   Raft
-	errorc chan error
-	// deprecate when we depercate v2 API
-	followerStats *stats.FollowerStats
-
-	msgc chan raftpb.Message
-	// wait for the handling routines
-	wg    sync.WaitGroup
-	stopc chan struct{}
-}
-
-func (p *pipeline) start() {
-	p.stopc = make(chan struct{})
-	p.msgc = make(chan raftpb.Message, pipelineBufSize)
-	p.wg.Add(connPerPipeline)
-	for i := 0; i < connPerPipeline; i++ {
-		go p.handle()
-	}
-
-	if p.tr != nil && p.tr.Logger != nil {
-		p.tr.Logger.Info(
-			"started HTTP pipelining with remote peer",
-			zap.String("local-member-id", p.tr.ID.String()),
-			zap.String("remote-peer-id", p.peerID.String()),
-		)
-	} else {
-		plog.Infof("started HTTP pipelining with peer %s", p.peerID)
-	}
-}
-
-func (p *pipeline) stop() {
-	close(p.stopc)
-	p.wg.Wait()
-
-	if p.tr != nil && p.tr.Logger != nil {
-		p.tr.Logger.Info(
-			"stopped HTTP pipelining with remote peer",
-			zap.String("local-member-id", p.tr.ID.String()),
-			zap.String("remote-peer-id", p.peerID.String()),
-		)
-	} else {
-		plog.Infof("stopped HTTP pipelining with peer %s", p.peerID)
-	}
-}
-
-func (p *pipeline) handle() {
-	defer p.wg.Done()
-
-	for {
-		select {
-		case m := <-p.msgc:
-			start := time.Now()
-			err := p.post(pbutil.MustMarshal(&m))
-			end := time.Now()
-
-			if err != nil {
-				p.status.deactivate(failureType{source: pipelineMsg, action: "write"}, err.Error())
-
-				if m.Type == raftpb.MsgApp && p.followerStats != nil {
-					p.followerStats.Fail()
-				}
-				p.raft.ReportUnreachable(m.To)
-				if isMsgSnap(m) {
-					p.raft.ReportSnapshot(m.To, raft.SnapshotFailure)
-				}
-				sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-				continue
-			}
-
-			p.status.activate()
-			if m.Type == raftpb.MsgApp && p.followerStats != nil {
-				p.followerStats.Succ(end.Sub(start))
-			}
-			if isMsgSnap(m) {
-				p.raft.ReportSnapshot(m.To, raft.SnapshotFinish)
-			}
-			sentBytes.WithLabelValues(types.ID(m.To).String()).Add(float64(m.Size()))
-		case <-p.stopc:
-			return
-		}
-	}
-}
-
-// post POSTs a data payload to a url. Returns nil if the POST succeeds,
-// error on any failure.
-func (p *pipeline) post(data []byte) (err error) {
-	u := p.picker.pick()
-	req := createPostRequest(u, RaftPrefix, bytes.NewBuffer(data), "application/protobuf", p.tr.URLs, p.tr.ID, p.tr.ClusterID)
-
-	done := make(chan struct{}, 1)
-	ctx, cancel := context.WithCancel(context.Background())
-	req = req.WithContext(ctx)
-	go func() {
-		select {
-		case <-done:
-		case <-p.stopc:
-			waitSchedule()
-			cancel()
-		}
-	}()
-
-	resp, err := p.tr.pipelineRt.RoundTrip(req)
-	done <- struct{}{}
-	if err != nil {
-		p.picker.unreachable(u)
-		return err
-	}
-	defer resp.Body.Close()
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		p.picker.unreachable(u)
-		return err
-	}
-
-	err = checkPostResponse(resp, b, req, p.peerID)
-	if err != nil {
-		p.picker.unreachable(u)
-		// errMemberRemoved is a critical error since a removed member should
-		// always be stopped. So we use reportCriticalError to report it to errorc.
-		if err == errMemberRemoved {
-			reportCriticalError(err, p.errorc)
-		}
-		return err
-	}
-
-	return nil
-}
-
-// waitSchedule waits other goroutines to be scheduled for a while
-func waitSchedule() { time.Sleep(time.Millisecond) }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/probing_status.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/probing_status.go
deleted file mode 100644
index 474d9a0..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/probing_status.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"time"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"github.com/xiang90/probing"
-	"go.uber.org/zap"
-)
-
-const (
-	// RoundTripperNameRaftMessage is the name of round-tripper that sends
-	// all other Raft messages, other than "snap.Message".
-	RoundTripperNameRaftMessage = "ROUND_TRIPPER_RAFT_MESSAGE"
-	// RoundTripperNameSnapshot is the name of round-tripper that sends merged snapshot message.
-	RoundTripperNameSnapshot = "ROUND_TRIPPER_SNAPSHOT"
-)
-
-var (
-	// proberInterval must be shorter than read timeout.
-	// Or the connection will time-out.
-	proberInterval           = ConnReadTimeout - time.Second
-	statusMonitoringInterval = 30 * time.Second
-	statusErrorInterval      = 5 * time.Second
-)
-
-func addPeerToProber(lg *zap.Logger, p probing.Prober, id string, us []string, roundTripperName string, rttSecProm *prometheus.HistogramVec) {
-	hus := make([]string, len(us))
-	for i := range us {
-		hus[i] = us[i] + ProbingPrefix
-	}
-
-	p.AddHTTP(id, proberInterval, hus)
-
-	s, err := p.Status(id)
-	if err != nil {
-		if lg != nil {
-			lg.Warn("failed to add peer into prober", zap.String("remote-peer-id", id))
-		} else {
-			plog.Errorf("failed to add peer %s into prober", id)
-		}
-		return
-	}
-
-	go monitorProbingStatus(lg, s, id, roundTripperName, rttSecProm)
-}
-
-func monitorProbingStatus(lg *zap.Logger, s probing.Status, id string, roundTripperName string, rttSecProm *prometheus.HistogramVec) {
-	// set the first interval short to log error early.
-	interval := statusErrorInterval
-	for {
-		select {
-		case <-time.After(interval):
-			if !s.Health() {
-				if lg != nil {
-					lg.Warn(
-						"prober detected unhealthy status",
-						zap.String("round-tripper-name", roundTripperName),
-						zap.String("remote-peer-id", id),
-						zap.Duration("rtt", s.SRTT()),
-						zap.Error(s.Err()),
-					)
-				} else {
-					plog.Warningf("health check for peer %s could not connect: %v", id, s.Err())
-				}
-				interval = statusErrorInterval
-			} else {
-				interval = statusMonitoringInterval
-			}
-			if s.ClockDiff() > time.Second {
-				if lg != nil {
-					lg.Warn(
-						"prober found high clock drift",
-						zap.String("round-tripper-name", roundTripperName),
-						zap.String("remote-peer-id", id),
-						zap.Duration("clock-drift", s.ClockDiff()),
-						zap.Duration("rtt", s.SRTT()),
-						zap.Error(s.Err()),
-					)
-				} else {
-					plog.Warningf("the clock difference against peer %s is too high [%v > %v]", id, s.ClockDiff(), time.Second)
-				}
-			}
-			rttSecProm.WithLabelValues(id).Observe(s.SRTT().Seconds())
-
-		case <-s.StopNotify():
-			return
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/remote.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/remote.go
deleted file mode 100644
index 1ef2493..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/remote.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"go.uber.org/zap"
-)
-
-type remote struct {
-	lg       *zap.Logger
-	localID  types.ID
-	id       types.ID
-	status   *peerStatus
-	pipeline *pipeline
-}
-
-func startRemote(tr *Transport, urls types.URLs, id types.ID) *remote {
-	picker := newURLPicker(urls)
-	status := newPeerStatus(tr.Logger, tr.ID, id)
-	pipeline := &pipeline{
-		peerID: id,
-		tr:     tr,
-		picker: picker,
-		status: status,
-		raft:   tr.Raft,
-		errorc: tr.ErrorC,
-	}
-	pipeline.start()
-
-	return &remote{
-		lg:       tr.Logger,
-		localID:  tr.ID,
-		id:       id,
-		status:   status,
-		pipeline: pipeline,
-	}
-}
-
-func (g *remote) send(m raftpb.Message) {
-	select {
-	case g.pipeline.msgc <- m:
-	default:
-		if g.status.isActive() {
-			if g.lg != nil {
-				g.lg.Warn(
-					"dropped internal Raft message since sending buffer is full (overloaded network)",
-					zap.String("message-type", m.Type.String()),
-					zap.String("local-member-id", g.localID.String()),
-					zap.String("from", types.ID(m.From).String()),
-					zap.String("remote-peer-id", g.id.String()),
-					zap.Bool("remote-peer-active", g.status.isActive()),
-				)
-			} else {
-				plog.MergeWarningf("dropped internal raft message to %s since sending buffer is full (bad/overloaded network)", g.id)
-			}
-		} else {
-			if g.lg != nil {
-				g.lg.Warn(
-					"dropped Raft message since sending buffer is full (overloaded network)",
-					zap.String("message-type", m.Type.String()),
-					zap.String("local-member-id", g.localID.String()),
-					zap.String("from", types.ID(m.From).String()),
-					zap.String("remote-peer-id", g.id.String()),
-					zap.Bool("remote-peer-active", g.status.isActive()),
-				)
-			} else {
-				plog.Debugf("dropped %s to %s since sending buffer is full", m.Type, g.id)
-			}
-		}
-		sentFailures.WithLabelValues(types.ID(m.To).String()).Inc()
-	}
-}
-
-func (g *remote) stop() {
-	g.pipeline.stop()
-}
-
-func (g *remote) Pause() {
-	g.stop()
-}
-
-func (g *remote) Resume() {
-	g.pipeline.start()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go
deleted file mode 100644
index 62efb0c..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/snapshot_sender.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"bytes"
-	"context"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	"go.etcd.io/etcd/pkg/httputil"
-	pioutil "go.etcd.io/etcd/pkg/ioutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-
-	"github.com/dustin/go-humanize"
-	"go.uber.org/zap"
-)
-
-var (
-	// timeout for reading snapshot response body
-	snapResponseReadTimeout = 5 * time.Second
-)
-
-type snapshotSender struct {
-	from, to types.ID
-	cid      types.ID
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	r      Raft
-	errorc chan error
-
-	stopc chan struct{}
-}
-
-func newSnapshotSender(tr *Transport, picker *urlPicker, to types.ID, status *peerStatus) *snapshotSender {
-	return &snapshotSender{
-		from:   tr.ID,
-		to:     to,
-		cid:    tr.ClusterID,
-		tr:     tr,
-		picker: picker,
-		status: status,
-		r:      tr.Raft,
-		errorc: tr.ErrorC,
-		stopc:  make(chan struct{}),
-	}
-}
-
-func (s *snapshotSender) stop() { close(s.stopc) }
-
-func (s *snapshotSender) send(merged snap.Message) {
-	start := time.Now()
-
-	m := merged.Message
-	to := types.ID(m.To).String()
-
-	body := createSnapBody(s.tr.Logger, merged)
-	defer body.Close()
-
-	u := s.picker.pick()
-	req := createPostRequest(u, RaftSnapshotPrefix, body, "application/octet-stream", s.tr.URLs, s.from, s.cid)
-
-	if s.tr.Logger != nil {
-		s.tr.Logger.Info(
-			"sending database snapshot",
-			zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index),
-			zap.String("remote-peer-id", to),
-			zap.Int64("bytes", merged.TotalSize),
-			zap.String("size", humanize.Bytes(uint64(merged.TotalSize))),
-		)
-	} else {
-		plog.Infof("start to send database snapshot [index: %d, to %s]...", m.Snapshot.Metadata.Index, types.ID(m.To))
-	}
-
-	snapshotSendInflights.WithLabelValues(to).Inc()
-	defer func() {
-		snapshotSendInflights.WithLabelValues(to).Dec()
-	}()
-
-	err := s.post(req)
-	defer merged.CloseWithError(err)
-	if err != nil {
-		if s.tr.Logger != nil {
-			s.tr.Logger.Warn(
-				"failed to send database snapshot",
-				zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index),
-				zap.String("remote-peer-id", to),
-				zap.Int64("bytes", merged.TotalSize),
-				zap.String("size", humanize.Bytes(uint64(merged.TotalSize))),
-				zap.Error(err),
-			)
-		} else {
-			plog.Warningf("database snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
-		}
-
-		// errMemberRemoved is a critical error since a removed member should
-		// always be stopped. So we use reportCriticalError to report it to errorc.
-		if err == errMemberRemoved {
-			reportCriticalError(err, s.errorc)
-		}
-
-		s.picker.unreachable(u)
-		s.status.deactivate(failureType{source: sendSnap, action: "post"}, err.Error())
-		s.r.ReportUnreachable(m.To)
-		// report SnapshotFailure to raft state machine. After raft state
-		// machine knows about it, it would pause a while and retry sending
-		// new snapshot message.
-		s.r.ReportSnapshot(m.To, raft.SnapshotFailure)
-		sentFailures.WithLabelValues(to).Inc()
-		snapshotSendFailures.WithLabelValues(to).Inc()
-		return
-	}
-	s.status.activate()
-	s.r.ReportSnapshot(m.To, raft.SnapshotFinish)
-
-	if s.tr.Logger != nil {
-		s.tr.Logger.Info(
-			"sent database snapshot",
-			zap.Uint64("snapshot-index", m.Snapshot.Metadata.Index),
-			zap.String("remote-peer-id", to),
-			zap.Int64("bytes", merged.TotalSize),
-			zap.String("size", humanize.Bytes(uint64(merged.TotalSize))),
-		)
-	} else {
-		plog.Infof("database snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To))
-	}
-
-	sentBytes.WithLabelValues(to).Add(float64(merged.TotalSize))
-	snapshotSend.WithLabelValues(to).Inc()
-	snapshotSendSeconds.WithLabelValues(to).Observe(time.Since(start).Seconds())
-}
-
-// post posts the given request.
-// It returns nil when request is sent out and processed successfully.
-func (s *snapshotSender) post(req *http.Request) (err error) {
-	ctx, cancel := context.WithCancel(context.Background())
-	req = req.WithContext(ctx)
-	defer cancel()
-
-	type responseAndError struct {
-		resp *http.Response
-		body []byte
-		err  error
-	}
-	result := make(chan responseAndError, 1)
-
-	go func() {
-		resp, err := s.tr.pipelineRt.RoundTrip(req)
-		if err != nil {
-			result <- responseAndError{resp, nil, err}
-			return
-		}
-
-		// close the response body when timeouts.
-		// prevents from reading the body forever when the other side dies right after
-		// successfully receives the request body.
-		time.AfterFunc(snapResponseReadTimeout, func() { httputil.GracefulClose(resp) })
-		body, err := ioutil.ReadAll(resp.Body)
-		result <- responseAndError{resp, body, err}
-	}()
-
-	select {
-	case <-s.stopc:
-		return errStopped
-	case r := <-result:
-		if r.err != nil {
-			return r.err
-		}
-		return checkPostResponse(r.resp, r.body, req, s.to)
-	}
-}
-
-func createSnapBody(lg *zap.Logger, merged snap.Message) io.ReadCloser {
-	buf := new(bytes.Buffer)
-	enc := &messageEncoder{w: buf}
-	// encode raft message
-	if err := enc.encode(&merged.Message); err != nil {
-		if lg != nil {
-			lg.Panic("failed to encode message", zap.Error(err))
-		} else {
-			plog.Panicf("encode message error (%v)", err)
-		}
-	}
-
-	return &pioutil.ReaderAndCloser{
-		Reader: io.MultiReader(buf, merged.ReadCloser),
-		Closer: merged.ReadCloser,
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/stream.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/stream.go
deleted file mode 100644
index dcb2223..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/stream.go
+++ /dev/null
@@ -1,746 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"context"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"path"
-	"strings"
-	"sync"
-	"time"
-
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/pkg/httputil"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/version"
-
-	"github.com/coreos/go-semver/semver"
-	"go.uber.org/zap"
-	"golang.org/x/time/rate"
-)
-
-const (
-	streamTypeMessage  streamType = "message"
-	streamTypeMsgAppV2 streamType = "msgappv2"
-
-	streamBufSize = 4096
-)
-
-var (
-	errUnsupportedStreamType = fmt.Errorf("unsupported stream type")
-
-	// the key is in string format "major.minor.patch"
-	supportedStream = map[string][]streamType{
-		"2.0.0": {},
-		"2.1.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"2.2.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"2.3.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.0.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.1.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.2.0": {streamTypeMsgAppV2, streamTypeMessage},
-		"3.3.0": {streamTypeMsgAppV2, streamTypeMessage},
-	}
-)
-
-type streamType string
-
-func (t streamType) endpoint() string {
-	switch t {
-	case streamTypeMsgAppV2:
-		return path.Join(RaftStreamPrefix, "msgapp")
-	case streamTypeMessage:
-		return path.Join(RaftStreamPrefix, "message")
-	default:
-		plog.Panicf("unhandled stream type %v", t)
-		return ""
-	}
-}
-
-func (t streamType) String() string {
-	switch t {
-	case streamTypeMsgAppV2:
-		return "stream MsgApp v2"
-	case streamTypeMessage:
-		return "stream Message"
-	default:
-		return "unknown stream"
-	}
-}
-
-var (
-	// linkHeartbeatMessage is a special message used as heartbeat message in
-	// link layer. It never conflicts with messages from raft because raft
-	// doesn't send out messages without From and To fields.
-	linkHeartbeatMessage = raftpb.Message{Type: raftpb.MsgHeartbeat}
-)
-
-func isLinkHeartbeatMessage(m *raftpb.Message) bool {
-	return m.Type == raftpb.MsgHeartbeat && m.From == 0 && m.To == 0
-}
-
-type outgoingConn struct {
-	t streamType
-	io.Writer
-	http.Flusher
-	io.Closer
-
-	localID types.ID
-	peerID  types.ID
-}
-
-// streamWriter writes messages to the attached outgoingConn.
-type streamWriter struct {
-	lg *zap.Logger
-
-	localID types.ID
-	peerID  types.ID
-
-	status *peerStatus
-	fs     *stats.FollowerStats
-	r      Raft
-
-	mu      sync.Mutex // guard field working and closer
-	closer  io.Closer
-	working bool
-
-	msgc  chan raftpb.Message
-	connc chan *outgoingConn
-	stopc chan struct{}
-	done  chan struct{}
-}
-
-// startStreamWriter creates a streamWrite and starts a long running go-routine that accepts
-// messages and writes to the attached outgoing connection.
-func startStreamWriter(lg *zap.Logger, local, id types.ID, status *peerStatus, fs *stats.FollowerStats, r Raft) *streamWriter {
-	w := &streamWriter{
-		lg: lg,
-
-		localID: local,
-		peerID:  id,
-
-		status: status,
-		fs:     fs,
-		r:      r,
-		msgc:   make(chan raftpb.Message, streamBufSize),
-		connc:  make(chan *outgoingConn),
-		stopc:  make(chan struct{}),
-		done:   make(chan struct{}),
-	}
-	go w.run()
-	return w
-}
-
-func (cw *streamWriter) run() {
-	var (
-		msgc       chan raftpb.Message
-		heartbeatc <-chan time.Time
-		t          streamType
-		enc        encoder
-		flusher    http.Flusher
-		batched    int
-	)
-	tickc := time.NewTicker(ConnReadTimeout / 3)
-	defer tickc.Stop()
-	unflushed := 0
-
-	if cw.lg != nil {
-		cw.lg.Info(
-			"started stream writer with remote peer",
-			zap.String("local-member-id", cw.localID.String()),
-			zap.String("remote-peer-id", cw.peerID.String()),
-		)
-	} else {
-		plog.Infof("started streaming with peer %s (writer)", cw.peerID)
-	}
-
-	for {
-		select {
-		case <-heartbeatc:
-			err := enc.encode(&linkHeartbeatMessage)
-			unflushed += linkHeartbeatMessage.Size()
-			if err == nil {
-				flusher.Flush()
-				batched = 0
-				sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed))
-				unflushed = 0
-				continue
-			}
-
-			cw.status.deactivate(failureType{source: t.String(), action: "heartbeat"}, err.Error())
-
-			sentFailures.WithLabelValues(cw.peerID.String()).Inc()
-			cw.close()
-			if cw.lg != nil {
-				cw.lg.Warn(
-					"lost TCP streaming connection with remote peer",
-					zap.String("stream-writer-type", t.String()),
-					zap.String("local-member-id", cw.localID.String()),
-					zap.String("remote-peer-id", cw.peerID.String()),
-				)
-			} else {
-				plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			}
-			heartbeatc, msgc = nil, nil
-
-		case m := <-msgc:
-			err := enc.encode(&m)
-			if err == nil {
-				unflushed += m.Size()
-
-				if len(msgc) == 0 || batched > streamBufSize/2 {
-					flusher.Flush()
-					sentBytes.WithLabelValues(cw.peerID.String()).Add(float64(unflushed))
-					unflushed = 0
-					batched = 0
-				} else {
-					batched++
-				}
-
-				continue
-			}
-
-			cw.status.deactivate(failureType{source: t.String(), action: "write"}, err.Error())
-			cw.close()
-			if cw.lg != nil {
-				cw.lg.Warn(
-					"lost TCP streaming connection with remote peer",
-					zap.String("stream-writer-type", t.String()),
-					zap.String("local-member-id", cw.localID.String()),
-					zap.String("remote-peer-id", cw.peerID.String()),
-				)
-			} else {
-				plog.Warningf("lost the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			}
-			heartbeatc, msgc = nil, nil
-			cw.r.ReportUnreachable(m.To)
-			sentFailures.WithLabelValues(cw.peerID.String()).Inc()
-
-		case conn := <-cw.connc:
-			cw.mu.Lock()
-			closed := cw.closeUnlocked()
-			t = conn.t
-			switch conn.t {
-			case streamTypeMsgAppV2:
-				enc = newMsgAppV2Encoder(conn.Writer, cw.fs)
-			case streamTypeMessage:
-				enc = &messageEncoder{w: conn.Writer}
-			default:
-				plog.Panicf("unhandled stream type %s", conn.t)
-			}
-			if cw.lg != nil {
-				cw.lg.Info(
-					"set message encoder",
-					zap.String("from", conn.localID.String()),
-					zap.String("to", conn.peerID.String()),
-					zap.String("stream-type", t.String()),
-				)
-			}
-			flusher = conn.Flusher
-			unflushed = 0
-			cw.status.activate()
-			cw.closer = conn.Closer
-			cw.working = true
-			cw.mu.Unlock()
-
-			if closed {
-				if cw.lg != nil {
-					cw.lg.Warn(
-						"closed TCP streaming connection with remote peer",
-						zap.String("stream-writer-type", t.String()),
-						zap.String("local-member-id", cw.localID.String()),
-						zap.String("remote-peer-id", cw.peerID.String()),
-					)
-				} else {
-					plog.Warningf("closed an existing TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-				}
-			}
-			if cw.lg != nil {
-				cw.lg.Warn(
-					"established TCP streaming connection with remote peer",
-					zap.String("stream-writer-type", t.String()),
-					zap.String("local-member-id", cw.localID.String()),
-					zap.String("remote-peer-id", cw.peerID.String()),
-				)
-			} else {
-				plog.Infof("established a TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-			}
-			heartbeatc, msgc = tickc.C, cw.msgc
-
-		case <-cw.stopc:
-			if cw.close() {
-				if cw.lg != nil {
-					cw.lg.Warn(
-						"closed TCP streaming connection with remote peer",
-						zap.String("stream-writer-type", t.String()),
-						zap.String("remote-peer-id", cw.peerID.String()),
-					)
-				} else {
-					plog.Infof("closed the TCP streaming connection with peer %s (%s writer)", cw.peerID, t)
-				}
-			}
-			if cw.lg != nil {
-				cw.lg.Warn(
-					"stopped TCP streaming connection with remote peer",
-					zap.String("stream-writer-type", t.String()),
-					zap.String("remote-peer-id", cw.peerID.String()),
-				)
-			} else {
-				plog.Infof("stopped streaming with peer %s (writer)", cw.peerID)
-			}
-			close(cw.done)
-			return
-		}
-	}
-}
-
-func (cw *streamWriter) writec() (chan<- raftpb.Message, bool) {
-	cw.mu.Lock()
-	defer cw.mu.Unlock()
-	return cw.msgc, cw.working
-}
-
-func (cw *streamWriter) close() bool {
-	cw.mu.Lock()
-	defer cw.mu.Unlock()
-	return cw.closeUnlocked()
-}
-
-func (cw *streamWriter) closeUnlocked() bool {
-	if !cw.working {
-		return false
-	}
-	if err := cw.closer.Close(); err != nil {
-		if cw.lg != nil {
-			cw.lg.Warn(
-				"failed to close connection with remote peer",
-				zap.String("remote-peer-id", cw.peerID.String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("peer %s (writer) connection close error: %v", cw.peerID, err)
-		}
-	}
-	if len(cw.msgc) > 0 {
-		cw.r.ReportUnreachable(uint64(cw.peerID))
-	}
-	cw.msgc = make(chan raftpb.Message, streamBufSize)
-	cw.working = false
-	return true
-}
-
-func (cw *streamWriter) attach(conn *outgoingConn) bool {
-	select {
-	case cw.connc <- conn:
-		return true
-	case <-cw.done:
-		return false
-	}
-}
-
-func (cw *streamWriter) stop() {
-	close(cw.stopc)
-	<-cw.done
-}
-
-// streamReader is a long-running go-routine that dials to the remote stream
-// endpoint and reads messages from the response body returned.
-type streamReader struct {
-	lg *zap.Logger
-
-	peerID types.ID
-	typ    streamType
-
-	tr     *Transport
-	picker *urlPicker
-	status *peerStatus
-	recvc  chan<- raftpb.Message
-	propc  chan<- raftpb.Message
-
-	rl *rate.Limiter // alters the frequency of dial retrial attempts
-
-	errorc chan<- error
-
-	mu     sync.Mutex
-	paused bool
-	closer io.Closer
-
-	ctx    context.Context
-	cancel context.CancelFunc
-	done   chan struct{}
-}
-
-func (cr *streamReader) start() {
-	cr.done = make(chan struct{})
-	if cr.errorc == nil {
-		cr.errorc = cr.tr.ErrorC
-	}
-	if cr.ctx == nil {
-		cr.ctx, cr.cancel = context.WithCancel(context.Background())
-	}
-	go cr.run()
-}
-
-func (cr *streamReader) run() {
-	t := cr.typ
-
-	if cr.lg != nil {
-		cr.lg.Info(
-			"started stream reader with remote peer",
-			zap.String("stream-reader-type", t.String()),
-			zap.String("local-member-id", cr.tr.ID.String()),
-			zap.String("remote-peer-id", cr.peerID.String()),
-		)
-	} else {
-		plog.Infof("started streaming with peer %s (%s reader)", cr.peerID, t)
-	}
-
-	for {
-		rc, err := cr.dial(t)
-		if err != nil {
-			if err != errUnsupportedStreamType {
-				cr.status.deactivate(failureType{source: t.String(), action: "dial"}, err.Error())
-			}
-		} else {
-			cr.status.activate()
-			if cr.lg != nil {
-				cr.lg.Info(
-					"established TCP streaming connection with remote peer",
-					zap.String("stream-reader-type", cr.typ.String()),
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-				)
-			} else {
-				plog.Infof("established a TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ)
-			}
-			err = cr.decodeLoop(rc, t)
-			if cr.lg != nil {
-				cr.lg.Warn(
-					"lost TCP streaming connection with remote peer",
-					zap.String("stream-reader-type", cr.typ.String()),
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("lost the TCP streaming connection with peer %s (%s reader)", cr.peerID, cr.typ)
-			}
-			switch {
-			// all data is read out
-			case err == io.EOF:
-			// connection is closed by the remote
-			case transport.IsClosedConnError(err):
-			default:
-				cr.status.deactivate(failureType{source: t.String(), action: "read"}, err.Error())
-			}
-		}
-		// Wait for a while before new dial attempt
-		err = cr.rl.Wait(cr.ctx)
-		if cr.ctx.Err() != nil {
-			if cr.lg != nil {
-				cr.lg.Info(
-					"stopped stream reader with remote peer",
-					zap.String("stream-reader-type", t.String()),
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-				)
-			} else {
-				plog.Infof("stopped streaming with peer %s (%s reader)", cr.peerID, t)
-			}
-			close(cr.done)
-			return
-		}
-		if err != nil {
-			if cr.lg != nil {
-				cr.lg.Warn(
-					"rate limit on stream reader with remote peer",
-					zap.String("stream-reader-type", t.String()),
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("streaming with peer %s (%s reader) rate limiter error: %v", cr.peerID, t, err)
-			}
-		}
-	}
-}
-
-func (cr *streamReader) decodeLoop(rc io.ReadCloser, t streamType) error {
-	var dec decoder
-	cr.mu.Lock()
-	switch t {
-	case streamTypeMsgAppV2:
-		dec = newMsgAppV2Decoder(rc, cr.tr.ID, cr.peerID)
-	case streamTypeMessage:
-		dec = &messageDecoder{r: rc}
-	default:
-		if cr.lg != nil {
-			cr.lg.Panic("unknown stream type", zap.String("type", t.String()))
-		} else {
-			plog.Panicf("unhandled stream type %s", t)
-		}
-	}
-	select {
-	case <-cr.ctx.Done():
-		cr.mu.Unlock()
-		if err := rc.Close(); err != nil {
-			return err
-		}
-		return io.EOF
-	default:
-		cr.closer = rc
-	}
-	cr.mu.Unlock()
-
-	// gofail: labelRaftDropHeartbeat:
-	for {
-		m, err := dec.decode()
-		if err != nil {
-			cr.mu.Lock()
-			cr.close()
-			cr.mu.Unlock()
-			return err
-		}
-
-		// gofail-go: var raftDropHeartbeat struct{}
-		// continue labelRaftDropHeartbeat
-		receivedBytes.WithLabelValues(types.ID(m.From).String()).Add(float64(m.Size()))
-
-		cr.mu.Lock()
-		paused := cr.paused
-		cr.mu.Unlock()
-
-		if paused {
-			continue
-		}
-
-		if isLinkHeartbeatMessage(&m) {
-			// raft is not interested in link layer
-			// heartbeat message, so we should ignore
-			// it.
-			continue
-		}
-
-		recvc := cr.recvc
-		if m.Type == raftpb.MsgProp {
-			recvc = cr.propc
-		}
-
-		select {
-		case recvc <- m:
-		default:
-			if cr.status.isActive() {
-				if cr.lg != nil {
-					cr.lg.Warn(
-						"dropped internal Raft message since receiving buffer is full (overloaded network)",
-						zap.String("message-type", m.Type.String()),
-						zap.String("local-member-id", cr.tr.ID.String()),
-						zap.String("from", types.ID(m.From).String()),
-						zap.String("remote-peer-id", types.ID(m.To).String()),
-						zap.Bool("remote-peer-active", cr.status.isActive()),
-					)
-				} else {
-					plog.MergeWarningf("dropped internal raft message from %s since receiving buffer is full (overloaded network)", types.ID(m.From))
-				}
-			} else {
-				if cr.lg != nil {
-					cr.lg.Warn(
-						"dropped Raft message since receiving buffer is full (overloaded network)",
-						zap.String("message-type", m.Type.String()),
-						zap.String("local-member-id", cr.tr.ID.String()),
-						zap.String("from", types.ID(m.From).String()),
-						zap.String("remote-peer-id", types.ID(m.To).String()),
-						zap.Bool("remote-peer-active", cr.status.isActive()),
-					)
-				} else {
-					plog.Debugf("dropped %s from %s since receiving buffer is full", m.Type, types.ID(m.From))
-				}
-			}
-			recvFailures.WithLabelValues(types.ID(m.From).String()).Inc()
-		}
-	}
-}
-
-func (cr *streamReader) stop() {
-	cr.mu.Lock()
-	cr.cancel()
-	cr.close()
-	cr.mu.Unlock()
-	<-cr.done
-}
-
-func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) {
-	u := cr.picker.pick()
-	uu := u
-	uu.Path = path.Join(t.endpoint(), cr.tr.ID.String())
-
-	if cr.lg != nil {
-		cr.lg.Debug(
-			"dial stream reader",
-			zap.String("from", cr.tr.ID.String()),
-			zap.String("to", cr.peerID.String()),
-			zap.String("address", uu.String()),
-		)
-	}
-	req, err := http.NewRequest("GET", uu.String(), nil)
-	if err != nil {
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("failed to make http request to %v (%v)", u, err)
-	}
-	req.Header.Set("X-Server-From", cr.tr.ID.String())
-	req.Header.Set("X-Server-Version", version.Version)
-	req.Header.Set("X-Min-Cluster-Version", version.MinClusterVersion)
-	req.Header.Set("X-Etcd-Cluster-ID", cr.tr.ClusterID.String())
-	req.Header.Set("X-Raft-To", cr.peerID.String())
-
-	setPeerURLsHeader(req, cr.tr.URLs)
-
-	req = req.WithContext(cr.ctx)
-
-	cr.mu.Lock()
-	select {
-	case <-cr.ctx.Done():
-		cr.mu.Unlock()
-		return nil, fmt.Errorf("stream reader is stopped")
-	default:
-	}
-	cr.mu.Unlock()
-
-	resp, err := cr.tr.streamRt.RoundTrip(req)
-	if err != nil {
-		cr.picker.unreachable(u)
-		return nil, err
-	}
-
-	rv := serverVersion(resp.Header)
-	lv := semver.Must(semver.NewVersion(version.Version))
-	if compareMajorMinorVersion(rv, lv) == -1 && !checkStreamSupport(rv, t) {
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, errUnsupportedStreamType
-	}
-
-	switch resp.StatusCode {
-	case http.StatusGone:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		reportCriticalError(errMemberRemoved, cr.errorc)
-		return nil, errMemberRemoved
-
-	case http.StatusOK:
-		return resp.Body, nil
-
-	case http.StatusNotFound:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("peer %s failed to find local node %s", cr.peerID, cr.tr.ID)
-
-	case http.StatusPreconditionFailed:
-		b, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			cr.picker.unreachable(u)
-			return nil, err
-		}
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-
-		switch strings.TrimSuffix(string(b), "\n") {
-		case errIncompatibleVersion.Error():
-			if cr.lg != nil {
-				cr.lg.Warn(
-					"request sent was ignored by remote peer due to server version incompatibility",
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-					zap.Error(errIncompatibleVersion),
-				)
-			} else {
-				plog.Errorf("request sent was ignored by peer %s (server version incompatible)", cr.peerID)
-			}
-			return nil, errIncompatibleVersion
-
-		case errClusterIDMismatch.Error():
-			if cr.lg != nil {
-				cr.lg.Warn(
-					"request sent was ignored by remote peer due to cluster ID mismatch",
-					zap.String("remote-peer-id", cr.peerID.String()),
-					zap.String("remote-peer-cluster-id", resp.Header.Get("X-Etcd-Cluster-ID")),
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("local-member-cluster-id", cr.tr.ClusterID.String()),
-					zap.Error(errClusterIDMismatch),
-				)
-			} else {
-				plog.Errorf("request sent was ignored (cluster ID mismatch: peer[%s]=%s, local=%s)",
-					cr.peerID, resp.Header.Get("X-Etcd-Cluster-ID"), cr.tr.ClusterID)
-			}
-			return nil, errClusterIDMismatch
-
-		default:
-			return nil, fmt.Errorf("unhandled error %q when precondition failed", string(b))
-		}
-
-	default:
-		httputil.GracefulClose(resp)
-		cr.picker.unreachable(u)
-		return nil, fmt.Errorf("unhandled http status %d", resp.StatusCode)
-	}
-}
-
-func (cr *streamReader) close() {
-	if cr.closer != nil {
-		if err := cr.closer.Close(); err != nil {
-			if cr.lg != nil {
-				cr.lg.Warn(
-					"failed to close remote peer connection",
-					zap.String("local-member-id", cr.tr.ID.String()),
-					zap.String("remote-peer-id", cr.peerID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("peer %s (reader) connection close error: %v", cr.peerID, err)
-			}
-		}
-	}
-	cr.closer = nil
-}
-
-func (cr *streamReader) pause() {
-	cr.mu.Lock()
-	defer cr.mu.Unlock()
-	cr.paused = true
-}
-
-func (cr *streamReader) resume() {
-	cr.mu.Lock()
-	defer cr.mu.Unlock()
-	cr.paused = false
-}
-
-// checkStreamSupport checks whether the stream type is supported in the
-// given version.
-func checkStreamSupport(v *semver.Version, t streamType) bool {
-	nv := &semver.Version{Major: v.Major, Minor: v.Minor}
-	for _, s := range supportedStream[nv.String()] {
-		if s == t {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/transport.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/transport.go
deleted file mode 100644
index 7191c3d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/transport.go
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"context"
-	"net/http"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/pkg/logutil"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/xiang90/probing"
-	"go.uber.org/zap"
-	"golang.org/x/time/rate"
-)
-
-var plog = logutil.NewMergeLogger(capnslog.NewPackageLogger("go.etcd.io/etcd", "rafthttp"))
-
-type Raft interface {
-	Process(ctx context.Context, m raftpb.Message) error
-	IsIDRemoved(id uint64) bool
-	ReportUnreachable(id uint64)
-	ReportSnapshot(id uint64, status raft.SnapshotStatus)
-}
-
-type Transporter interface {
-	// Start starts the given Transporter.
-	// Start MUST be called before calling other functions in the interface.
-	Start() error
-	// Handler returns the HTTP handler of the transporter.
-	// A transporter HTTP handler handles the HTTP requests
-	// from remote peers.
-	// The handler MUST be used to handle RaftPrefix(/raft)
-	// endpoint.
-	Handler() http.Handler
-	// Send sends out the given messages to the remote peers.
-	// Each message has a To field, which is an id that maps
-	// to an existing peer in the transport.
-	// If the id cannot be found in the transport, the message
-	// will be ignored.
-	Send(m []raftpb.Message)
-	// SendSnapshot sends out the given snapshot message to a remote peer.
-	// The behavior of SendSnapshot is similar to Send.
-	SendSnapshot(m snap.Message)
-	// AddRemote adds a remote with given peer urls into the transport.
-	// A remote helps newly joined member to catch up the progress of cluster,
-	// and will not be used after that.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	AddRemote(id types.ID, urls []string)
-	// AddPeer adds a peer with given peer urls into the transport.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	// Peer urls are used to connect to the remote peer.
-	AddPeer(id types.ID, urls []string)
-	// RemovePeer removes the peer with given id.
-	RemovePeer(id types.ID)
-	// RemoveAllPeers removes all the existing peers in the transport.
-	RemoveAllPeers()
-	// UpdatePeer updates the peer urls of the peer with the given id.
-	// It is the caller's responsibility to ensure the urls are all valid,
-	// or it panics.
-	UpdatePeer(id types.ID, urls []string)
-	// ActiveSince returns the time that the connection with the peer
-	// of the given id becomes active.
-	// If the connection is active since peer was added, it returns the adding time.
-	// If the connection is currently inactive, it returns zero time.
-	ActiveSince(id types.ID) time.Time
-	// ActivePeers returns the number of active peers.
-	ActivePeers() int
-	// Stop closes the connections and stops the transporter.
-	Stop()
-}
-
-// Transport implements Transporter interface. It provides the functionality
-// to send raft messages to peers, and receive raft messages from peers.
-// User should call Handler method to get a handler to serve requests
-// received from peerURLs.
-// User needs to call Start before calling other functions, and call
-// Stop when the Transport is no longer used.
-type Transport struct {
-	Logger *zap.Logger
-
-	DialTimeout time.Duration // maximum duration before timing out dial of the request
-	// DialRetryFrequency defines the frequency of streamReader dial retrial attempts;
-	// a distinct rate limiter is created per every peer (default value: 10 events/sec)
-	DialRetryFrequency rate.Limit
-
-	TLSInfo transport.TLSInfo // TLS information used when creating connection
-
-	ID          types.ID   // local member ID
-	URLs        types.URLs // local peer URLs
-	ClusterID   types.ID   // raft cluster ID for request validation
-	Raft        Raft       // raft state machine, to which the Transport forwards received messages and reports status
-	Snapshotter *snap.Snapshotter
-	ServerStats *stats.ServerStats // used to record general transportation statistics
-	// used to record transportation statistics with followers when
-	// performing as leader in raft protocol
-	LeaderStats *stats.LeaderStats
-	// ErrorC is used to report detected critical errors, e.g.,
-	// the member has been permanently removed from the cluster
-	// When an error is received from ErrorC, user should stop raft state
-	// machine and thus stop the Transport.
-	ErrorC chan error
-
-	streamRt   http.RoundTripper // roundTripper used by streams
-	pipelineRt http.RoundTripper // roundTripper used by pipelines
-
-	mu      sync.RWMutex         // protect the remote and peer map
-	remotes map[types.ID]*remote // remotes map that helps newly joined member to catch up
-	peers   map[types.ID]Peer    // peers map
-
-	pipelineProber probing.Prober
-	streamProber   probing.Prober
-}
-
-func (t *Transport) Start() error {
-	var err error
-	t.streamRt, err = newStreamRoundTripper(t.TLSInfo, t.DialTimeout)
-	if err != nil {
-		return err
-	}
-	t.pipelineRt, err = NewRoundTripper(t.TLSInfo, t.DialTimeout)
-	if err != nil {
-		return err
-	}
-	t.remotes = make(map[types.ID]*remote)
-	t.peers = make(map[types.ID]Peer)
-	t.pipelineProber = probing.NewProber(t.pipelineRt)
-	t.streamProber = probing.NewProber(t.streamRt)
-
-	// If client didn't provide dial retry frequency, use the default
-	// (100ms backoff between attempts to create a new stream),
-	// so it doesn't bring too much overhead when retry.
-	if t.DialRetryFrequency == 0 {
-		t.DialRetryFrequency = rate.Every(100 * time.Millisecond)
-	}
-	return nil
-}
-
-func (t *Transport) Handler() http.Handler {
-	pipelineHandler := newPipelineHandler(t, t.Raft, t.ClusterID)
-	streamHandler := newStreamHandler(t, t, t.Raft, t.ID, t.ClusterID)
-	snapHandler := newSnapshotHandler(t, t.Raft, t.Snapshotter, t.ClusterID)
-	mux := http.NewServeMux()
-	mux.Handle(RaftPrefix, pipelineHandler)
-	mux.Handle(RaftStreamPrefix+"/", streamHandler)
-	mux.Handle(RaftSnapshotPrefix, snapHandler)
-	mux.Handle(ProbingPrefix, probing.NewHandler())
-	return mux
-}
-
-func (t *Transport) Get(id types.ID) Peer {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	return t.peers[id]
-}
-
-func (t *Transport) Send(msgs []raftpb.Message) {
-	for _, m := range msgs {
-		if m.To == 0 {
-			// ignore intentionally dropped message
-			continue
-		}
-		to := types.ID(m.To)
-
-		t.mu.RLock()
-		p, pok := t.peers[to]
-		g, rok := t.remotes[to]
-		t.mu.RUnlock()
-
-		if pok {
-			if m.Type == raftpb.MsgApp {
-				t.ServerStats.SendAppendReq(m.Size())
-			}
-			p.send(m)
-			continue
-		}
-
-		if rok {
-			g.send(m)
-			continue
-		}
-
-		if t.Logger != nil {
-			t.Logger.Debug(
-				"ignored message send request; unknown remote peer target",
-				zap.String("type", m.Type.String()),
-				zap.String("unknown-target-peer-id", to.String()),
-			)
-		} else {
-			plog.Debugf("ignored message %s (sent to unknown peer %s)", m.Type, to)
-		}
-	}
-}
-
-func (t *Transport) Stop() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	for _, r := range t.remotes {
-		r.stop()
-	}
-	for _, p := range t.peers {
-		p.stop()
-	}
-	t.pipelineProber.RemoveAll()
-	t.streamProber.RemoveAll()
-	if tr, ok := t.streamRt.(*http.Transport); ok {
-		tr.CloseIdleConnections()
-	}
-	if tr, ok := t.pipelineRt.(*http.Transport); ok {
-		tr.CloseIdleConnections()
-	}
-	t.peers = nil
-	t.remotes = nil
-}
-
-// CutPeer drops messages to the specified peer.
-func (t *Transport) CutPeer(id types.ID) {
-	t.mu.RLock()
-	p, pok := t.peers[id]
-	g, gok := t.remotes[id]
-	t.mu.RUnlock()
-
-	if pok {
-		p.(Pausable).Pause()
-	}
-	if gok {
-		g.Pause()
-	}
-}
-
-// MendPeer recovers the message dropping behavior of the given peer.
-func (t *Transport) MendPeer(id types.ID) {
-	t.mu.RLock()
-	p, pok := t.peers[id]
-	g, gok := t.remotes[id]
-	t.mu.RUnlock()
-
-	if pok {
-		p.(Pausable).Resume()
-	}
-	if gok {
-		g.Resume()
-	}
-}
-
-func (t *Transport) AddRemote(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	if t.remotes == nil {
-		// there's no clean way to shutdown the golang http server
-		// (see: https://github.com/golang/go/issues/4674) before
-		// stopping the transport; ignore any new connections.
-		return
-	}
-	if _, ok := t.peers[id]; ok {
-		return
-	}
-	if _, ok := t.remotes[id]; ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		if t.Logger != nil {
-			t.Logger.Panic("failed NewURLs", zap.Strings("urls", us), zap.Error(err))
-		} else {
-			plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-		}
-	}
-	t.remotes[id] = startRemote(t, urls, id)
-
-	if t.Logger != nil {
-		t.Logger.Info(
-			"added new remote peer",
-			zap.String("local-member-id", t.ID.String()),
-			zap.String("remote-peer-id", id.String()),
-			zap.Strings("remote-peer-urls", us),
-		)
-	}
-}
-
-func (t *Transport) AddPeer(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-
-	if t.peers == nil {
-		panic("transport stopped")
-	}
-	if _, ok := t.peers[id]; ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		if t.Logger != nil {
-			t.Logger.Panic("failed NewURLs", zap.Strings("urls", us), zap.Error(err))
-		} else {
-			plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-		}
-	}
-	fs := t.LeaderStats.Follower(id.String())
-	t.peers[id] = startPeer(t, urls, id, fs)
-	addPeerToProber(t.Logger, t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rttSec)
-	addPeerToProber(t.Logger, t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rttSec)
-
-	if t.Logger != nil {
-		t.Logger.Info(
-			"added remote peer",
-			zap.String("local-member-id", t.ID.String()),
-			zap.String("remote-peer-id", id.String()),
-			zap.Strings("remote-peer-urls", us),
-		)
-	} else {
-		plog.Infof("added peer %s", id)
-	}
-}
-
-func (t *Transport) RemovePeer(id types.ID) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	t.removePeer(id)
-}
-
-func (t *Transport) RemoveAllPeers() {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	for id := range t.peers {
-		t.removePeer(id)
-	}
-}
-
-// the caller of this function must have the peers mutex.
-func (t *Transport) removePeer(id types.ID) {
-	if peer, ok := t.peers[id]; ok {
-		peer.stop()
-	} else {
-		if t.Logger != nil {
-			t.Logger.Panic("unexpected removal of unknown remote peer", zap.String("remote-peer-id", id.String()))
-		} else {
-			plog.Panicf("unexpected removal of unknown peer '%d'", id)
-		}
-	}
-	delete(t.peers, id)
-	delete(t.LeaderStats.Followers, id.String())
-	t.pipelineProber.Remove(id.String())
-	t.streamProber.Remove(id.String())
-
-	if t.Logger != nil {
-		t.Logger.Info(
-			"removed remote peer",
-			zap.String("local-member-id", t.ID.String()),
-			zap.String("removed-remote-peer-id", id.String()),
-		)
-	} else {
-		plog.Infof("removed peer %s", id)
-	}
-}
-
-func (t *Transport) UpdatePeer(id types.ID, us []string) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	// TODO: return error or just panic?
-	if _, ok := t.peers[id]; !ok {
-		return
-	}
-	urls, err := types.NewURLs(us)
-	if err != nil {
-		if t.Logger != nil {
-			t.Logger.Panic("failed NewURLs", zap.Strings("urls", us), zap.Error(err))
-		} else {
-			plog.Panicf("newURLs %+v should never fail: %+v", us, err)
-		}
-	}
-	t.peers[id].update(urls)
-
-	t.pipelineProber.Remove(id.String())
-	addPeerToProber(t.Logger, t.pipelineProber, id.String(), us, RoundTripperNameSnapshot, rttSec)
-	t.streamProber.Remove(id.String())
-	addPeerToProber(t.Logger, t.streamProber, id.String(), us, RoundTripperNameRaftMessage, rttSec)
-
-	if t.Logger != nil {
-		t.Logger.Info(
-			"updated remote peer",
-			zap.String("local-member-id", t.ID.String()),
-			zap.String("updated-remote-peer-id", id.String()),
-			zap.Strings("updated-remote-peer-urls", us),
-		)
-	} else {
-		plog.Infof("updated peer %s", id)
-	}
-}
-
-func (t *Transport) ActiveSince(id types.ID) time.Time {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	if p, ok := t.peers[id]; ok {
-		return p.activeSince()
-	}
-	return time.Time{}
-}
-
-func (t *Transport) SendSnapshot(m snap.Message) {
-	t.mu.Lock()
-	defer t.mu.Unlock()
-	p := t.peers[types.ID(m.To)]
-	if p == nil {
-		m.CloseWithError(errMemberNotFound)
-		return
-	}
-	p.sendSnap(m)
-}
-
-// Pausable is a testing interface for pausing transport traffic.
-type Pausable interface {
-	Pause()
-	Resume()
-}
-
-func (t *Transport) Pause() {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	for _, p := range t.peers {
-		p.(Pausable).Pause()
-	}
-}
-
-func (t *Transport) Resume() {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	for _, p := range t.peers {
-		p.(Pausable).Resume()
-	}
-}
-
-// ActivePeers returns a channel that closes when an initial
-// peer connection has been established. Use this to wait until the
-// first peer connection becomes active.
-func (t *Transport) ActivePeers() (cnt int) {
-	t.mu.RLock()
-	defer t.mu.RUnlock()
-	for _, p := range t.peers {
-		if !p.activeSince().IsZero() {
-			cnt++
-		}
-	}
-	return cnt
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/urlpick.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/urlpick.go
deleted file mode 100644
index 61ef468..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/urlpick.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"net/url"
-	"sync"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-type urlPicker struct {
-	mu     sync.Mutex // guards urls and picked
-	urls   types.URLs
-	picked int
-}
-
-func newURLPicker(urls types.URLs) *urlPicker {
-	return &urlPicker{
-		urls: urls,
-	}
-}
-
-func (p *urlPicker) update(urls types.URLs) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	p.urls = urls
-	p.picked = 0
-}
-
-func (p *urlPicker) pick() url.URL {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	return p.urls[p.picked]
-}
-
-// unreachable notices the picker that the given url is unreachable,
-// and it should use other possible urls.
-func (p *urlPicker) unreachable(u url.URL) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if u == p.urls[p.picked] {
-		p.picked = (p.picked + 1) % len(p.urls)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/util.go b/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/util.go
deleted file mode 100644
index 2093864..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/rafthttp/util.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2015 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 rafthttp
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/version"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-var (
-	errMemberRemoved  = fmt.Errorf("the member has been permanently removed from the cluster")
-	errMemberNotFound = fmt.Errorf("member not found")
-)
-
-// NewListener returns a listener for raft message transfer between peers.
-// It uses timeout listener to identify broken streams promptly.
-func NewListener(u url.URL, tlsinfo *transport.TLSInfo) (net.Listener, error) {
-	return transport.NewTimeoutListener(u.Host, u.Scheme, tlsinfo, ConnReadTimeout, ConnWriteTimeout)
-}
-
-// NewRoundTripper returns a roundTripper used to send requests
-// to rafthttp listener of remote peers.
-func NewRoundTripper(tlsInfo transport.TLSInfo, dialTimeout time.Duration) (http.RoundTripper, error) {
-	// It uses timeout transport to pair with remote timeout listeners.
-	// It sets no read/write timeout, because message in requests may
-	// take long time to write out before reading out the response.
-	return transport.NewTimeoutTransport(tlsInfo, dialTimeout, 0, 0)
-}
-
-// newStreamRoundTripper returns a roundTripper used to send stream requests
-// to rafthttp listener of remote peers.
-// Read/write timeout is set for stream roundTripper to promptly
-// find out broken status, which minimizes the number of messages
-// sent on broken connection.
-func newStreamRoundTripper(tlsInfo transport.TLSInfo, dialTimeout time.Duration) (http.RoundTripper, error) {
-	return transport.NewTimeoutTransport(tlsInfo, dialTimeout, ConnReadTimeout, ConnWriteTimeout)
-}
-
-// createPostRequest creates a HTTP POST request that sends raft message.
-func createPostRequest(u url.URL, path string, body io.Reader, ct string, urls types.URLs, from, cid types.ID) *http.Request {
-	uu := u
-	uu.Path = path
-	req, err := http.NewRequest("POST", uu.String(), body)
-	if err != nil {
-		plog.Panicf("unexpected new request error (%v)", err)
-	}
-	req.Header.Set("Content-Type", ct)
-	req.Header.Set("X-Server-From", from.String())
-	req.Header.Set("X-Server-Version", version.Version)
-	req.Header.Set("X-Min-Cluster-Version", version.MinClusterVersion)
-	req.Header.Set("X-Etcd-Cluster-ID", cid.String())
-	setPeerURLsHeader(req, urls)
-
-	return req
-}
-
-// checkPostResponse checks the response of the HTTP POST request that sends
-// raft message.
-func checkPostResponse(resp *http.Response, body []byte, req *http.Request, to types.ID) error {
-	switch resp.StatusCode {
-	case http.StatusPreconditionFailed:
-		switch strings.TrimSuffix(string(body), "\n") {
-		case errIncompatibleVersion.Error():
-			plog.Errorf("request sent was ignored by peer %s (server version incompatible)", to)
-			return errIncompatibleVersion
-		case errClusterIDMismatch.Error():
-			plog.Errorf("request sent was ignored (cluster ID mismatch: remote[%s]=%s, local=%s)",
-				to, resp.Header.Get("X-Etcd-Cluster-ID"), req.Header.Get("X-Etcd-Cluster-ID"))
-			return errClusterIDMismatch
-		default:
-			return fmt.Errorf("unhandled error %q when precondition failed", string(body))
-		}
-	case http.StatusForbidden:
-		return errMemberRemoved
-	case http.StatusNoContent:
-		return nil
-	default:
-		return fmt.Errorf("unexpected http status %s while posting to %q", http.StatusText(resp.StatusCode), req.URL.String())
-	}
-}
-
-// reportCriticalError reports the given error through sending it into
-// the given error channel.
-// If the error channel is filled up when sending error, it drops the error
-// because the fact that error has happened is reported, which is
-// good enough.
-func reportCriticalError(err error, errc chan<- error) {
-	select {
-	case errc <- err:
-	default:
-	}
-}
-
-// compareMajorMinorVersion returns an integer comparing two versions based on
-// their major and minor version. The result will be 0 if a==b, -1 if a < b,
-// and 1 if a > b.
-func compareMajorMinorVersion(a, b *semver.Version) int {
-	na := &semver.Version{Major: a.Major, Minor: a.Minor}
-	nb := &semver.Version{Major: b.Major, Minor: b.Minor}
-	switch {
-	case na.LessThan(*nb):
-		return -1
-	case nb.LessThan(*na):
-		return 1
-	default:
-		return 0
-	}
-}
-
-// serverVersion returns the server version from the given header.
-func serverVersion(h http.Header) *semver.Version {
-	verStr := h.Get("X-Server-Version")
-	// backward compatibility with etcd 2.0
-	if verStr == "" {
-		verStr = "2.0.0"
-	}
-	return semver.Must(semver.NewVersion(verStr))
-}
-
-// serverVersion returns the min cluster version from the given header.
-func minClusterVersion(h http.Header) *semver.Version {
-	verStr := h.Get("X-Min-Cluster-Version")
-	// backward compatibility with etcd 2.0
-	if verStr == "" {
-		verStr = "2.0.0"
-	}
-	return semver.Must(semver.NewVersion(verStr))
-}
-
-// checkVersionCompatibility checks whether the given version is compatible
-// with the local version.
-func checkVersionCompatibility(name string, server, minCluster *semver.Version) (
-	localServer *semver.Version,
-	localMinCluster *semver.Version,
-	err error) {
-	localServer = semver.Must(semver.NewVersion(version.Version))
-	localMinCluster = semver.Must(semver.NewVersion(version.MinClusterVersion))
-	if compareMajorMinorVersion(server, localMinCluster) == -1 {
-		return localServer, localMinCluster, fmt.Errorf("remote version is too low: remote[%s]=%s, local=%s", name, server, localServer)
-	}
-	if compareMajorMinorVersion(minCluster, localServer) == 1 {
-		return localServer, localMinCluster, fmt.Errorf("local version is too low: remote[%s]=%s, local=%s", name, server, localServer)
-	}
-	return localServer, localMinCluster, nil
-}
-
-// setPeerURLsHeader reports local urls for peer discovery
-func setPeerURLsHeader(req *http.Request, urls types.URLs) {
-	if urls == nil {
-		// often not set in unit tests
-		return
-	}
-	peerURLs := make([]string, urls.Len())
-	for i := range urls {
-		peerURLs[i] = urls[i].String()
-	}
-	req.Header.Set("X-PeerURLs", strings.Join(peerURLs, ","))
-}
-
-// addRemoteFromRequest adds a remote peer according to an http request header
-func addRemoteFromRequest(tr Transporter, r *http.Request) {
-	if from, err := types.IDFromString(r.Header.Get("X-Server-From")); err == nil {
-		if urls := r.Header.Get("X-PeerURLs"); urls != "" {
-			tr.AddRemote(from, strings.Split(urls, ","))
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/db.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/db.go
deleted file mode 100644
index 3002ccd..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/db.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2015 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 snap
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"time"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-
-	humanize "github.com/dustin/go-humanize"
-	"go.uber.org/zap"
-)
-
-var ErrNoDBSnapshot = errors.New("snap: snapshot file doesn't exist")
-
-// SaveDBFrom saves snapshot of the database from the given reader. It
-// guarantees the save operation is atomic.
-func (s *Snapshotter) SaveDBFrom(r io.Reader, id uint64) (int64, error) {
-	start := time.Now()
-
-	f, err := ioutil.TempFile(s.dir, "tmp")
-	if err != nil {
-		return 0, err
-	}
-	var n int64
-	n, err = io.Copy(f, r)
-	if err == nil {
-		fsyncStart := time.Now()
-		err = fileutil.Fsync(f)
-		snapDBFsyncSec.Observe(time.Since(fsyncStart).Seconds())
-	}
-	f.Close()
-	if err != nil {
-		os.Remove(f.Name())
-		return n, err
-	}
-	fn := s.dbFilePath(id)
-	if fileutil.Exist(fn) {
-		os.Remove(f.Name())
-		return n, nil
-	}
-	err = os.Rename(f.Name(), fn)
-	if err != nil {
-		os.Remove(f.Name())
-		return n, err
-	}
-
-	if s.lg != nil {
-		s.lg.Info(
-			"saved database snapshot to disk",
-			zap.String("path", fn),
-			zap.Int64("bytes", n),
-			zap.String("size", humanize.Bytes(uint64(n))),
-		)
-	} else {
-		plog.Infof("saved database snapshot to disk [total bytes: %d]", n)
-	}
-
-	snapDBSaveSec.Observe(time.Since(start).Seconds())
-	return n, nil
-}
-
-// DBFilePath returns the file path for the snapshot of the database with
-// given id. If the snapshot does not exist, it returns error.
-func (s *Snapshotter) DBFilePath(id uint64) (string, error) {
-	if _, err := fileutil.ReadDir(s.dir); err != nil {
-		return "", err
-	}
-	fn := s.dbFilePath(id)
-	if fileutil.Exist(fn) {
-		return fn, nil
-	}
-	if s.lg != nil {
-		s.lg.Warn(
-			"failed to find [SNAPSHOT-INDEX].snap.db",
-			zap.Uint64("snapshot-index", id),
-			zap.String("snapshot-file-path", fn),
-			zap.Error(ErrNoDBSnapshot),
-		)
-	}
-	return "", ErrNoDBSnapshot
-}
-
-func (s *Snapshotter) dbFilePath(id uint64) string {
-	return filepath.Join(s.dir, fmt.Sprintf("%016x.snap.db", id))
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/doc.go
deleted file mode 100644
index dcc5db5..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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 snap handles Raft nodes' states with snapshots.
-// The snapshot logic is internal to etcd server and raft package.
-package snap
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/message.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/message.go
deleted file mode 100644
index c1151e2..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/message.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 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 snap
-
-import (
-	"io"
-
-	"go.etcd.io/etcd/pkg/ioutil"
-	"go.etcd.io/etcd/raft/raftpb"
-)
-
-// Message is a struct that contains a raft Message and a ReadCloser. The type
-// of raft message MUST be MsgSnap, which contains the raft meta-data and an
-// additional data []byte field that contains the snapshot of the actual state
-// machine.
-// Message contains the ReadCloser field for handling large snapshot. This avoid
-// copying the entire snapshot into a byte array, which consumes a lot of memory.
-//
-// User of Message should close the Message after sending it.
-type Message struct {
-	raftpb.Message
-	ReadCloser io.ReadCloser
-	TotalSize  int64
-	closeC     chan bool
-}
-
-func NewMessage(rs raftpb.Message, rc io.ReadCloser, rcSize int64) *Message {
-	return &Message{
-		Message:    rs,
-		ReadCloser: ioutil.NewExactReadCloser(rc, rcSize),
-		TotalSize:  int64(rs.Size()) + rcSize,
-		closeC:     make(chan bool, 1),
-	}
-}
-
-// CloseNotify returns a channel that receives a single value
-// when the message sent is finished. true indicates the sent
-// is successful.
-func (m Message) CloseNotify() <-chan bool {
-	return m.closeC
-}
-
-func (m Message) CloseWithError(err error) {
-	if cerr := m.ReadCloser.Close(); cerr != nil {
-		err = cerr
-	}
-	if err == nil {
-		m.closeC <- true
-	} else {
-		m.closeC <- false
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/metrics.go
deleted file mode 100644
index 2affecf..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/metrics.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2015 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 snap
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	snapMarshallingSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "snap",
-		Name:      "save_marshalling_duration_seconds",
-		Help:      "The marshalling cost distributions of save called by snapshot.",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	snapSaveSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "snap",
-		Name:      "save_total_duration_seconds",
-		Help:      "The total latency distributions of save called by snapshot.",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	snapFsyncSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "snap",
-		Name:      "fsync_duration_seconds",
-		Help:      "The latency distributions of fsync called by snap.",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-
-	snapDBSaveSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "snap_db",
-		Name:      "save_total_duration_seconds",
-		Help:      "The total latency distributions of v3 snapshot save",
-
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^9 == 51.2 sec
-		Buckets: prometheus.ExponentialBuckets(0.1, 2, 10),
-	})
-
-	snapDBFsyncSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "snap_db",
-		Name:      "fsync_duration_seconds",
-		Help:      "The latency distributions of fsyncing .snap.db file",
-
-		// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
-		// highest bucket start of 0.001 sec * 2^13 == 8.192 sec
-		Buckets: prometheus.ExponentialBuckets(0.001, 2, 14),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(snapMarshallingSec)
-	prometheus.MustRegister(snapSaveSec)
-	prometheus.MustRegister(snapFsyncSec)
-	prometheus.MustRegister(snapDBSaveSec)
-	prometheus.MustRegister(snapDBFsyncSec)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.pb.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.pb.go
deleted file mode 100644
index e72b577..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.pb.go
+++ /dev/null
@@ -1,336 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: snap.proto
-
-/*
-	Package snappb is a generated protocol buffer package.
-
-	It is generated from these files:
-		snap.proto
-
-	It has these top-level messages:
-		Snapshot
-*/
-package snappb
-
-import (
-	"fmt"
-
-	proto "github.com/golang/protobuf/proto"
-
-	math "math"
-
-	_ "github.com/gogo/protobuf/gogoproto"
-
-	io "io"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type Snapshot struct {
-	Crc              uint32 `protobuf:"varint,1,opt,name=crc" json:"crc"`
-	Data             []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Snapshot) Reset()                    { *m = Snapshot{} }
-func (m *Snapshot) String() string            { return proto.CompactTextString(m) }
-func (*Snapshot) ProtoMessage()               {}
-func (*Snapshot) Descriptor() ([]byte, []int) { return fileDescriptorSnap, []int{0} }
-
-func init() {
-	proto.RegisterType((*Snapshot)(nil), "snappb.snapshot")
-}
-func (m *Snapshot) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *Snapshot) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintSnap(dAtA, i, uint64(m.Crc))
-	if m.Data != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintSnap(dAtA, i, uint64(len(m.Data)))
-		i += copy(dAtA[i:], m.Data)
-	}
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func encodeVarintSnap(dAtA []byte, offset int, v uint64) int {
-	for v >= 1<<7 {
-		dAtA[offset] = uint8(v&0x7f | 0x80)
-		v >>= 7
-		offset++
-	}
-	dAtA[offset] = uint8(v)
-	return offset + 1
-}
-func (m *Snapshot) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovSnap(uint64(m.Crc))
-	if m.Data != nil {
-		l = len(m.Data)
-		n += 1 + l + sovSnap(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func sovSnap(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozSnap(x uint64) (n int) {
-	return sovSnap(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *Snapshot) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowSnap
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: snapshot: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: snapshot: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Crc", wireType)
-			}
-			m.Crc = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowSnap
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Crc |= (uint32(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowSnap
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthSnap
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
-			if m.Data == nil {
-				m.Data = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipSnap(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthSnap
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipSnap(dAtA []byte) (n int, err error) {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return 0, ErrIntOverflowSnap
-			}
-			if iNdEx >= l {
-				return 0, io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		wireType := int(wire & 0x7)
-		switch wireType {
-		case 0:
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowSnap
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				iNdEx++
-				if dAtA[iNdEx-1] < 0x80 {
-					break
-				}
-			}
-			return iNdEx, nil
-		case 1:
-			iNdEx += 8
-			return iNdEx, nil
-		case 2:
-			var length int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowSnap
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				length |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			iNdEx += length
-			if length < 0 {
-				return 0, ErrInvalidLengthSnap
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowSnap
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipSnap(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
-		case 4:
-			return iNdEx, nil
-		case 5:
-			iNdEx += 4
-			return iNdEx, nil
-		default:
-			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
-		}
-	}
-	panic("unreachable")
-}
-
-var (
-	ErrInvalidLengthSnap = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowSnap   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("snap.proto", fileDescriptorSnap) }
-
-var fileDescriptorSnap = []byte{
-	// 126 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xce, 0x4b, 0x2c,
-	0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0xb1, 0x0b, 0x92, 0xa4, 0x44, 0xd2, 0xf3,
-	0xd3, 0xf3, 0xc1, 0x42, 0xfa, 0x20, 0x16, 0x44, 0x56, 0xc9, 0x8c, 0x8b, 0x03, 0x24, 0x5f, 0x9c,
-	0x91, 0x5f, 0x22, 0x24, 0xc6, 0xc5, 0x9c, 0x5c, 0x94, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xeb,
-	0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x48, 0x40, 0x48, 0x88, 0x8b, 0x25, 0x25, 0xb1, 0x24,
-	0x51, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xcc, 0x76, 0x12, 0x39, 0xf1, 0x50, 0x8e, 0xe1,
-	0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf1, 0x58, 0x8e,
-	0x01, 0x10, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x0f, 0x32, 0xb2, 0x78, 0x00, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.proto b/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.proto
deleted file mode 100644
index cd3d21d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snappb/snap.proto
+++ /dev/null
@@ -1,14 +0,0 @@
-syntax = "proto2";
-package snappb;
-
-import "gogoproto/gogo.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-
-message snapshot {
-	optional uint32 crc  = 1 [(gogoproto.nullable) = false];
-	optional bytes data  = 2;
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go b/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go
deleted file mode 100644
index 7e79333..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/snap/snapshotter.go
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2015 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 snap
-
-import (
-	"errors"
-	"fmt"
-	"hash/crc32"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap/snappb"
-	pioutil "go.etcd.io/etcd/pkg/ioutil"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-)
-
-const snapSuffix = ".snap"
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd/v3", "snap")
-
-	ErrNoSnapshot    = errors.New("snap: no available snapshot")
-	ErrEmptySnapshot = errors.New("snap: empty snapshot")
-	ErrCRCMismatch   = errors.New("snap: crc mismatch")
-	crcTable         = crc32.MakeTable(crc32.Castagnoli)
-
-	// A map of valid files that can be present in the snap folder.
-	validFiles = map[string]bool{
-		"db": true,
-	}
-)
-
-type Snapshotter struct {
-	lg  *zap.Logger
-	dir string
-}
-
-func New(lg *zap.Logger, dir string) *Snapshotter {
-	return &Snapshotter{
-		lg:  lg,
-		dir: dir,
-	}
-}
-
-func (s *Snapshotter) SaveSnap(snapshot raftpb.Snapshot) error {
-	if raft.IsEmptySnap(snapshot) {
-		return nil
-	}
-	return s.save(&snapshot)
-}
-
-func (s *Snapshotter) save(snapshot *raftpb.Snapshot) error {
-	start := time.Now()
-
-	fname := fmt.Sprintf("%016x-%016x%s", snapshot.Metadata.Term, snapshot.Metadata.Index, snapSuffix)
-	b := pbutil.MustMarshal(snapshot)
-	crc := crc32.Update(0, crcTable, b)
-	snap := snappb.Snapshot{Crc: crc, Data: b}
-	d, err := snap.Marshal()
-	if err != nil {
-		return err
-	}
-	snapMarshallingSec.Observe(time.Since(start).Seconds())
-
-	spath := filepath.Join(s.dir, fname)
-
-	fsyncStart := time.Now()
-	err = pioutil.WriteAndSyncFile(spath, d, 0666)
-	snapFsyncSec.Observe(time.Since(fsyncStart).Seconds())
-
-	if err != nil {
-		if s.lg != nil {
-			s.lg.Warn("failed to write a snap file", zap.String("path", spath), zap.Error(err))
-		}
-		rerr := os.Remove(spath)
-		if rerr != nil {
-			if s.lg != nil {
-				s.lg.Warn("failed to remove a broken snap file", zap.String("path", spath), zap.Error(err))
-			} else {
-				plog.Errorf("failed to remove broken snapshot file %s", spath)
-			}
-		}
-		return err
-	}
-
-	snapSaveSec.Observe(time.Since(start).Seconds())
-	return nil
-}
-
-func (s *Snapshotter) Load() (*raftpb.Snapshot, error) {
-	names, err := s.snapNames()
-	if err != nil {
-		return nil, err
-	}
-	var snap *raftpb.Snapshot
-	for _, name := range names {
-		if snap, err = loadSnap(s.lg, s.dir, name); err == nil {
-			break
-		}
-	}
-	if err != nil {
-		return nil, ErrNoSnapshot
-	}
-	return snap, nil
-}
-
-func loadSnap(lg *zap.Logger, dir, name string) (*raftpb.Snapshot, error) {
-	fpath := filepath.Join(dir, name)
-	snap, err := Read(lg, fpath)
-	if err != nil {
-		brokenPath := fpath + ".broken"
-		if lg != nil {
-			lg.Warn("failed to read a snap file", zap.String("path", fpath), zap.Error(err))
-		}
-		if rerr := os.Rename(fpath, brokenPath); rerr != nil {
-			if lg != nil {
-				lg.Warn("failed to rename a broken snap file", zap.String("path", fpath), zap.String("broken-path", brokenPath), zap.Error(rerr))
-			} else {
-				plog.Warningf("cannot rename broken snapshot file %v to %v: %v", fpath, brokenPath, rerr)
-			}
-		} else {
-			if lg != nil {
-				lg.Warn("renamed to a broken snap file", zap.String("path", fpath), zap.String("broken-path", brokenPath))
-			}
-		}
-	}
-	return snap, err
-}
-
-// Read reads the snapshot named by snapname and returns the snapshot.
-func Read(lg *zap.Logger, snapname string) (*raftpb.Snapshot, error) {
-	b, err := ioutil.ReadFile(snapname)
-	if err != nil {
-		if lg != nil {
-			lg.Warn("failed to read a snap file", zap.String("path", snapname), zap.Error(err))
-		} else {
-			plog.Errorf("cannot read file %v: %v", snapname, err)
-		}
-		return nil, err
-	}
-
-	if len(b) == 0 {
-		if lg != nil {
-			lg.Warn("failed to read empty snapshot file", zap.String("path", snapname))
-		} else {
-			plog.Errorf("unexpected empty snapshot")
-		}
-		return nil, ErrEmptySnapshot
-	}
-
-	var serializedSnap snappb.Snapshot
-	if err = serializedSnap.Unmarshal(b); err != nil {
-		if lg != nil {
-			lg.Warn("failed to unmarshal snappb.Snapshot", zap.String("path", snapname), zap.Error(err))
-		} else {
-			plog.Errorf("corrupted snapshot file %v: %v", snapname, err)
-		}
-		return nil, err
-	}
-
-	if len(serializedSnap.Data) == 0 || serializedSnap.Crc == 0 {
-		if lg != nil {
-			lg.Warn("failed to read empty snapshot data", zap.String("path", snapname))
-		} else {
-			plog.Errorf("unexpected empty snapshot")
-		}
-		return nil, ErrEmptySnapshot
-	}
-
-	crc := crc32.Update(0, crcTable, serializedSnap.Data)
-	if crc != serializedSnap.Crc {
-		if lg != nil {
-			lg.Warn("snap file is corrupt",
-				zap.String("path", snapname),
-				zap.Uint32("prev-crc", serializedSnap.Crc),
-				zap.Uint32("new-crc", crc),
-			)
-		} else {
-			plog.Errorf("corrupted snapshot file %v: crc mismatch", snapname)
-		}
-		return nil, ErrCRCMismatch
-	}
-
-	var snap raftpb.Snapshot
-	if err = snap.Unmarshal(serializedSnap.Data); err != nil {
-		if lg != nil {
-			lg.Warn("failed to unmarshal raftpb.Snapshot", zap.String("path", snapname), zap.Error(err))
-		} else {
-			plog.Errorf("corrupted snapshot file %v: %v", snapname, err)
-		}
-		return nil, err
-	}
-	return &snap, nil
-}
-
-// snapNames returns the filename of the snapshots in logical time order (from newest to oldest).
-// If there is no available snapshots, an ErrNoSnapshot will be returned.
-func (s *Snapshotter) snapNames() ([]string, error) {
-	dir, err := os.Open(s.dir)
-	if err != nil {
-		return nil, err
-	}
-	defer dir.Close()
-	names, err := dir.Readdirnames(-1)
-	if err != nil {
-		return nil, err
-	}
-	snaps := checkSuffix(s.lg, names)
-	if len(snaps) == 0 {
-		return nil, ErrNoSnapshot
-	}
-	sort.Sort(sort.Reverse(sort.StringSlice(snaps)))
-	return snaps, nil
-}
-
-func checkSuffix(lg *zap.Logger, names []string) []string {
-	snaps := []string{}
-	for i := range names {
-		if strings.HasSuffix(names[i], snapSuffix) {
-			snaps = append(snaps, names[i])
-		} else {
-			// If we find a file which is not a snapshot then check if it's
-			// a vaild file. If not throw out a warning.
-			if _, ok := validFiles[names[i]]; !ok {
-				if lg != nil {
-					lg.Warn("found unexpected non-snap file; skipping", zap.String("path", names[i]))
-				} else {
-					plog.Warningf("skipped unexpected non snapshot file %v", names[i])
-				}
-			}
-		}
-	}
-	return snaps
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth.go
deleted file mode 100644
index b438074..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth.go
+++ /dev/null
@@ -1,736 +0,0 @@
-// Copyright 2015 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 v2auth implements etcd authentication.
-package v2auth
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"path"
-	"reflect"
-	"sort"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-	"golang.org/x/crypto/bcrypt"
-)
-
-const (
-	// StorePermsPrefix is the internal prefix of the storage layer dedicated to storing user data.
-	StorePermsPrefix = "/2"
-
-	// RootRoleName is the name of the ROOT role, with privileges to manage the cluster.
-	RootRoleName = "root"
-
-	// GuestRoleName is the name of the role that defines the privileges of an unauthenticated user.
-	GuestRoleName = "guest"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd/v3", "etcdserver/auth")
-)
-
-var rootRole = Role{
-	Role: RootRoleName,
-	Permissions: Permissions{
-		KV: RWPermission{
-			Read:  []string{"/*"},
-			Write: []string{"/*"},
-		},
-	},
-}
-
-var guestRole = Role{
-	Role: GuestRoleName,
-	Permissions: Permissions{
-		KV: RWPermission{
-			Read:  []string{"/*"},
-			Write: []string{"/*"},
-		},
-	},
-}
-
-type doer interface {
-	Do(context.Context, etcdserverpb.Request) (etcdserver.Response, error)
-}
-
-type Store interface {
-	AllUsers() ([]string, error)
-	GetUser(name string) (User, error)
-	CreateOrUpdateUser(user User) (out User, created bool, err error)
-	CreateUser(user User) (User, error)
-	DeleteUser(name string) error
-	UpdateUser(user User) (User, error)
-	AllRoles() ([]string, error)
-	GetRole(name string) (Role, error)
-	CreateRole(role Role) error
-	DeleteRole(name string) error
-	UpdateRole(role Role) (Role, error)
-	AuthEnabled() bool
-	EnableAuth() error
-	DisableAuth() error
-	PasswordStore
-}
-
-type PasswordStore interface {
-	CheckPassword(user User, password string) bool
-	HashPassword(password string) (string, error)
-}
-
-type store struct {
-	lg          *zap.Logger
-	server      doer
-	timeout     time.Duration
-	ensuredOnce bool
-
-	PasswordStore
-}
-
-type User struct {
-	User     string   `json:"user"`
-	Password string   `json:"password,omitempty"`
-	Roles    []string `json:"roles"`
-	Grant    []string `json:"grant,omitempty"`
-	Revoke   []string `json:"revoke,omitempty"`
-}
-
-type Role struct {
-	Role        string       `json:"role"`
-	Permissions Permissions  `json:"permissions"`
-	Grant       *Permissions `json:"grant,omitempty"`
-	Revoke      *Permissions `json:"revoke,omitempty"`
-}
-
-type Permissions struct {
-	KV RWPermission `json:"kv"`
-}
-
-func (p *Permissions) IsEmpty() bool {
-	return p == nil || (len(p.KV.Read) == 0 && len(p.KV.Write) == 0)
-}
-
-type RWPermission struct {
-	Read  []string `json:"read"`
-	Write []string `json:"write"`
-}
-
-type Error struct {
-	Status int
-	Errmsg string
-}
-
-func (ae Error) Error() string   { return ae.Errmsg }
-func (ae Error) HTTPStatus() int { return ae.Status }
-
-func authErr(hs int, s string, v ...interface{}) Error {
-	return Error{Status: hs, Errmsg: fmt.Sprintf("auth: "+s, v...)}
-}
-
-func NewStore(lg *zap.Logger, server doer, timeout time.Duration) Store {
-	s := &store{
-		lg:            lg,
-		server:        server,
-		timeout:       timeout,
-		PasswordStore: passwordStore{},
-	}
-	return s
-}
-
-// passwordStore implements PasswordStore using bcrypt to hash user passwords
-type passwordStore struct{}
-
-func (passwordStore) CheckPassword(user User, password string) bool {
-	err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
-	return err == nil
-}
-
-func (passwordStore) HashPassword(password string) (string, error) {
-	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
-	return string(hash), err
-}
-
-func (s *store) AllUsers() ([]string, error) {
-	resp, err := s.requestResource("/users/", false)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return []string{}, nil
-			}
-		}
-		return nil, err
-	}
-	var nodes []string
-	for _, n := range resp.Event.Node.Nodes {
-		_, user := path.Split(n.Key)
-		nodes = append(nodes, user)
-	}
-	sort.Strings(nodes)
-	return nodes, nil
-}
-
-func (s *store) GetUser(name string) (User, error) { return s.getUser(name, false) }
-
-// CreateOrUpdateUser should be only used for creating the new user or when you are not
-// sure if it is a create or update. (When only password is passed in, we are not sure
-// if it is a update or create)
-func (s *store) CreateOrUpdateUser(user User) (out User, created bool, err error) {
-	_, err = s.getUser(user.User, true)
-	if err == nil {
-		out, err = s.UpdateUser(user)
-		return out, false, err
-	}
-	u, err := s.CreateUser(user)
-	return u, true, err
-}
-
-func (s *store) CreateUser(user User) (User, error) {
-	// Attach root role to root user.
-	if user.User == "root" {
-		user = attachRootRole(user)
-	}
-	u, err := s.createUserInternal(user)
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("created a user", zap.String("user-name", user.User))
-		} else {
-			plog.Noticef("created user %s", user.User)
-		}
-	}
-	return u, err
-}
-
-func (s *store) createUserInternal(user User) (User, error) {
-	if user.Password == "" {
-		return user, authErr(http.StatusBadRequest, "Cannot create user %s with an empty password", user.User)
-	}
-	hash, err := s.HashPassword(user.Password)
-	if err != nil {
-		return user, err
-	}
-	user.Password = hash
-
-	_, err = s.createResource("/users/"+user.User, user)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeNodeExist {
-				return user, authErr(http.StatusConflict, "User %s already exists.", user.User)
-			}
-		}
-	}
-	return user, err
-}
-
-func (s *store) DeleteUser(name string) error {
-	if s.AuthEnabled() && name == "root" {
-		return authErr(http.StatusForbidden, "Cannot delete root user while auth is enabled.")
-	}
-	err := s.deleteResource("/users/" + name)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return authErr(http.StatusNotFound, "User %s does not exist", name)
-			}
-		}
-		return err
-	}
-	if s.lg != nil {
-		s.lg.Info("deleted a user", zap.String("user-name", name))
-	} else {
-		plog.Noticef("deleted user %s", name)
-	}
-	return nil
-}
-
-func (s *store) UpdateUser(user User) (User, error) {
-	old, err := s.getUser(user.User, true)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return user, authErr(http.StatusNotFound, "User %s doesn't exist.", user.User)
-			}
-		}
-		return old, err
-	}
-
-	newUser, err := old.merge(s.lg, user, s.PasswordStore)
-	if err != nil {
-		return old, err
-	}
-	if reflect.DeepEqual(old, newUser) {
-		return old, authErr(http.StatusBadRequest, "User not updated. Use grant/revoke/password to update the user.")
-	}
-	_, err = s.updateResource("/users/"+user.User, newUser)
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("updated a user", zap.String("user-name", user.User))
-		} else {
-			plog.Noticef("updated user %s", user.User)
-		}
-	}
-	return newUser, err
-}
-
-func (s *store) AllRoles() ([]string, error) {
-	nodes := []string{RootRoleName}
-	resp, err := s.requestResource("/roles/", false)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return nodes, nil
-			}
-		}
-		return nil, err
-	}
-	for _, n := range resp.Event.Node.Nodes {
-		_, role := path.Split(n.Key)
-		nodes = append(nodes, role)
-	}
-	sort.Strings(nodes)
-	return nodes, nil
-}
-
-func (s *store) GetRole(name string) (Role, error) { return s.getRole(name, false) }
-
-func (s *store) CreateRole(role Role) error {
-	if role.Role == RootRoleName {
-		return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
-	}
-	_, err := s.createResource("/roles/"+role.Role, role)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeNodeExist {
-				return authErr(http.StatusConflict, "Role %s already exists.", role.Role)
-			}
-		}
-	}
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("created a new role", zap.String("role-name", role.Role))
-		} else {
-			plog.Noticef("created new role %s", role.Role)
-		}
-	}
-	return err
-}
-
-func (s *store) DeleteRole(name string) error {
-	if name == RootRoleName {
-		return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", name)
-	}
-	err := s.deleteResource("/roles/" + name)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return authErr(http.StatusNotFound, "Role %s doesn't exist.", name)
-			}
-		}
-	}
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("delete a new role", zap.String("role-name", name))
-		} else {
-			plog.Noticef("deleted role %s", name)
-		}
-	}
-	return err
-}
-
-func (s *store) UpdateRole(role Role) (Role, error) {
-	if role.Role == RootRoleName {
-		return Role{}, authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
-	}
-	old, err := s.getRole(role.Role, true)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return role, authErr(http.StatusNotFound, "Role %s doesn't exist.", role.Role)
-			}
-		}
-		return old, err
-	}
-	newRole, err := old.merge(s.lg, role)
-	if err != nil {
-		return old, err
-	}
-	if reflect.DeepEqual(old, newRole) {
-		return old, authErr(http.StatusBadRequest, "Role not updated. Use grant/revoke to update the role.")
-	}
-	_, err = s.updateResource("/roles/"+role.Role, newRole)
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("updated a new role", zap.String("role-name", role.Role))
-		} else {
-			plog.Noticef("updated role %s", role.Role)
-		}
-	}
-	return newRole, err
-}
-
-func (s *store) AuthEnabled() bool {
-	return s.detectAuth()
-}
-
-func (s *store) EnableAuth() error {
-	if s.AuthEnabled() {
-		return authErr(http.StatusConflict, "already enabled")
-	}
-
-	if _, err := s.getUser("root", true); err != nil {
-		return authErr(http.StatusConflict, "No root user available, please create one")
-	}
-	if _, err := s.getRole(GuestRoleName, true); err != nil {
-		if s.lg != nil {
-			s.lg.Info(
-				"no guest role access found; creating default",
-				zap.String("role-name", GuestRoleName),
-			)
-		} else {
-			plog.Printf("no guest role access found, creating default")
-		}
-		if err := s.CreateRole(guestRole); err != nil {
-			if s.lg != nil {
-				s.lg.Warn(
-					"failed to create a guest role; aborting auth enable",
-					zap.String("role-name", GuestRoleName),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("error creating guest role. aborting auth enable.")
-			}
-			return err
-		}
-	}
-
-	if err := s.enableAuth(); err != nil {
-		if s.lg != nil {
-			s.lg.Warn("failed to enable auth", zap.Error(err))
-		} else {
-			plog.Errorf("error enabling auth (%v)", err)
-		}
-		return err
-	}
-
-	if s.lg != nil {
-		s.lg.Info("enabled auth")
-	} else {
-		plog.Noticef("auth: enabled auth")
-	}
-	return nil
-}
-
-func (s *store) DisableAuth() error {
-	if !s.AuthEnabled() {
-		return authErr(http.StatusConflict, "already disabled")
-	}
-
-	err := s.disableAuth()
-	if err == nil {
-		if s.lg != nil {
-			s.lg.Info("disabled auth")
-		} else {
-			plog.Noticef("auth: disabled auth")
-		}
-	} else {
-		if s.lg != nil {
-			s.lg.Warn("failed to disable auth", zap.Error(err))
-		} else {
-			plog.Errorf("error disabling auth (%v)", err)
-		}
-	}
-	return err
-}
-
-// merge applies the properties of the passed-in User to the User on which it
-// is called and returns a new User with these modifications applied. Think of
-// all Users as immutable sets of data. Merge allows you to perform the set
-// operations (desired grants and revokes) atomically
-func (ou User) merge(lg *zap.Logger, nu User, s PasswordStore) (User, error) {
-	var out User
-	if ou.User != nu.User {
-		return out, authErr(http.StatusConflict, "Merging user data with conflicting usernames: %s %s", ou.User, nu.User)
-	}
-	out.User = ou.User
-	if nu.Password != "" {
-		hash, err := s.HashPassword(nu.Password)
-		if err != nil {
-			return ou, err
-		}
-		out.Password = hash
-	} else {
-		out.Password = ou.Password
-	}
-	currentRoles := types.NewUnsafeSet(ou.Roles...)
-	for _, g := range nu.Grant {
-		if currentRoles.Contains(g) {
-			if lg != nil {
-				lg.Warn(
-					"attempted to grant a duplicate role for a user",
-					zap.String("user-name", nu.User),
-					zap.String("role-name", g),
-				)
-			} else {
-				plog.Noticef("granting duplicate role %s for user %s", g, nu.User)
-			}
-			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Granting duplicate role %s for user %s", g, nu.User))
-		}
-		currentRoles.Add(g)
-	}
-	for _, r := range nu.Revoke {
-		if !currentRoles.Contains(r) {
-			if lg != nil {
-				lg.Warn(
-					"attempted to revoke a ungranted role for a user",
-					zap.String("user-name", nu.User),
-					zap.String("role-name", r),
-				)
-			} else {
-				plog.Noticef("revoking ungranted role %s for user %s", r, nu.User)
-			}
-			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Revoking ungranted role %s for user %s", r, nu.User))
-		}
-		currentRoles.Remove(r)
-	}
-	out.Roles = currentRoles.Values()
-	sort.Strings(out.Roles)
-	return out, nil
-}
-
-// merge for a role works the same as User above -- atomic Role application to
-// each of the substructures.
-func (r Role) merge(lg *zap.Logger, n Role) (Role, error) {
-	var out Role
-	var err error
-	if r.Role != n.Role {
-		return out, authErr(http.StatusConflict, "Merging role with conflicting names: %s %s", r.Role, n.Role)
-	}
-	out.Role = r.Role
-	out.Permissions, err = r.Permissions.Grant(n.Grant)
-	if err != nil {
-		return out, err
-	}
-	out.Permissions, err = out.Permissions.Revoke(lg, n.Revoke)
-	return out, err
-}
-
-func (r Role) HasKeyAccess(key string, write bool) bool {
-	if r.Role == RootRoleName {
-		return true
-	}
-	return r.Permissions.KV.HasAccess(key, write)
-}
-
-func (r Role) HasRecursiveAccess(key string, write bool) bool {
-	if r.Role == RootRoleName {
-		return true
-	}
-	return r.Permissions.KV.HasRecursiveAccess(key, write)
-}
-
-// Grant adds a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (p Permissions) Grant(n *Permissions) (Permissions, error) {
-	var out Permissions
-	var err error
-	if n == nil {
-		return p, nil
-	}
-	out.KV, err = p.KV.Grant(n.KV)
-	return out, err
-}
-
-// Revoke removes a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (p Permissions) Revoke(lg *zap.Logger, n *Permissions) (Permissions, error) {
-	var out Permissions
-	var err error
-	if n == nil {
-		return p, nil
-	}
-	out.KV, err = p.KV.Revoke(lg, n.KV)
-	return out, err
-}
-
-// Grant adds a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (rw RWPermission) Grant(n RWPermission) (RWPermission, error) {
-	var out RWPermission
-	currentRead := types.NewUnsafeSet(rw.Read...)
-	for _, r := range n.Read {
-		if currentRead.Contains(r) {
-			return out, authErr(http.StatusConflict, "Granting duplicate read permission %s", r)
-		}
-		currentRead.Add(r)
-	}
-	currentWrite := types.NewUnsafeSet(rw.Write...)
-	for _, w := range n.Write {
-		if currentWrite.Contains(w) {
-			return out, authErr(http.StatusConflict, "Granting duplicate write permission %s", w)
-		}
-		currentWrite.Add(w)
-	}
-	out.Read = currentRead.Values()
-	out.Write = currentWrite.Values()
-	sort.Strings(out.Read)
-	sort.Strings(out.Write)
-	return out, nil
-}
-
-// Revoke removes a set of permissions to the permission object on which it is called,
-// returning a new permission object.
-func (rw RWPermission) Revoke(lg *zap.Logger, n RWPermission) (RWPermission, error) {
-	var out RWPermission
-	currentRead := types.NewUnsafeSet(rw.Read...)
-	for _, r := range n.Read {
-		if !currentRead.Contains(r) {
-			if lg != nil {
-				lg.Info(
-					"revoking ungranted read permission",
-					zap.String("read-permission", r),
-				)
-			} else {
-				plog.Noticef("revoking ungranted read permission %s", r)
-			}
-			continue
-		}
-		currentRead.Remove(r)
-	}
-	currentWrite := types.NewUnsafeSet(rw.Write...)
-	for _, w := range n.Write {
-		if !currentWrite.Contains(w) {
-			if lg != nil {
-				lg.Info(
-					"revoking ungranted write permission",
-					zap.String("write-permission", w),
-				)
-			} else {
-				plog.Noticef("revoking ungranted write permission %s", w)
-			}
-			continue
-		}
-		currentWrite.Remove(w)
-	}
-	out.Read = currentRead.Values()
-	out.Write = currentWrite.Values()
-	sort.Strings(out.Read)
-	sort.Strings(out.Write)
-	return out, nil
-}
-
-func (rw RWPermission) HasAccess(key string, write bool) bool {
-	var list []string
-	if write {
-		list = rw.Write
-	} else {
-		list = rw.Read
-	}
-	for _, pat := range list {
-		match, err := simpleMatch(pat, key)
-		if err == nil && match {
-			return true
-		}
-	}
-	return false
-}
-
-func (rw RWPermission) HasRecursiveAccess(key string, write bool) bool {
-	list := rw.Read
-	if write {
-		list = rw.Write
-	}
-	for _, pat := range list {
-		match, err := prefixMatch(pat, key)
-		if err == nil && match {
-			return true
-		}
-	}
-	return false
-}
-
-func simpleMatch(pattern string, key string) (match bool, err error) {
-	if pattern[len(pattern)-1] == '*' {
-		return strings.HasPrefix(key, pattern[:len(pattern)-1]), nil
-	}
-	return key == pattern, nil
-}
-
-func prefixMatch(pattern string, key string) (match bool, err error) {
-	if pattern[len(pattern)-1] != '*' {
-		return false, nil
-	}
-	return strings.HasPrefix(key, pattern[:len(pattern)-1]), nil
-}
-
-func attachRootRole(u User) User {
-	inRoles := false
-	for _, r := range u.Roles {
-		if r == RootRoleName {
-			inRoles = true
-			break
-		}
-	}
-	if !inRoles {
-		u.Roles = append(u.Roles, RootRoleName)
-	}
-	return u
-}
-
-func (s *store) getUser(name string, quorum bool) (User, error) {
-	resp, err := s.requestResource("/users/"+name, quorum)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return User{}, authErr(http.StatusNotFound, "User %s does not exist.", name)
-			}
-		}
-		return User{}, err
-	}
-	var u User
-	err = json.Unmarshal([]byte(*resp.Event.Node.Value), &u)
-	if err != nil {
-		return u, err
-	}
-	// Attach root role to root user.
-	if u.User == "root" {
-		u = attachRootRole(u)
-	}
-	return u, nil
-}
-
-func (s *store) getRole(name string, quorum bool) (Role, error) {
-	if name == RootRoleName {
-		return rootRole, nil
-	}
-	resp, err := s.requestResource("/roles/"+name, quorum)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return Role{}, authErr(http.StatusNotFound, "Role %s does not exist.", name)
-			}
-		}
-		return Role{}, err
-	}
-	var r Role
-	err = json.Unmarshal([]byte(*resp.Event.Node.Value), &r)
-	return r, err
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth_requests.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth_requests.go
deleted file mode 100644
index d6574ec..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2auth/auth_requests.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2015 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 v2auth
-
-import (
-	"context"
-	"encoding/json"
-	"path"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"go.uber.org/zap"
-)
-
-func (s *store) ensureAuthDirectories() error {
-	if s.ensuredOnce {
-		return nil
-	}
-	for _, res := range []string{StorePermsPrefix, StorePermsPrefix + "/users/", StorePermsPrefix + "/roles/"} {
-		ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-		pe := false
-		rr := etcdserverpb.Request{
-			Method:    "PUT",
-			Path:      res,
-			Dir:       true,
-			PrevExist: &pe,
-		}
-		_, err := s.server.Do(ctx, rr)
-		cancel()
-		if err != nil {
-			if e, ok := err.(*v2error.Error); ok {
-				if e.ErrorCode == v2error.EcodeNodeExist {
-					continue
-				}
-			}
-			if s.lg != nil {
-				s.lg.Warn(
-					"failed to create auth directories",
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("failed to create auth directories in the store (%v)", err)
-			}
-			return err
-		}
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	pe := false
-	rr := etcdserverpb.Request{
-		Method:    "PUT",
-		Path:      StorePermsPrefix + "/enabled",
-		Val:       "false",
-		PrevExist: &pe,
-	}
-	_, err := s.server.Do(ctx, rr)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeNodeExist {
-				s.ensuredOnce = true
-				return nil
-			}
-		}
-		return err
-	}
-	s.ensuredOnce = true
-	return nil
-}
-
-func (s *store) enableAuth() error {
-	_, err := s.updateResource("/enabled", true)
-	return err
-}
-func (s *store) disableAuth() error {
-	_, err := s.updateResource("/enabled", false)
-	return err
-}
-
-func (s *store) detectAuth() bool {
-	if s.server == nil {
-		return false
-	}
-	value, err := s.requestResource("/enabled", false)
-	if err != nil {
-		if e, ok := err.(*v2error.Error); ok {
-			if e.ErrorCode == v2error.EcodeKeyNotFound {
-				return false
-			}
-		}
-		if s.lg != nil {
-			s.lg.Warn(
-				"failed to detect auth settings",
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to detect auth settings (%s)", err)
-		}
-		return false
-	}
-
-	var u bool
-	err = json.Unmarshal([]byte(*value.Event.Node.Value), &u)
-	if err != nil {
-		if s.lg != nil {
-			s.lg.Warn(
-				"internal bookkeeping value for enabled isn't valid JSON",
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("internal bookkeeping value for enabled isn't valid JSON (%v)", err)
-		}
-		return false
-	}
-	return u
-}
-
-func (s *store) requestResource(res string, quorum bool) (etcdserver.Response, error) {
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	p := path.Join(StorePermsPrefix, res)
-	method := "GET"
-	if quorum {
-		method = "QGET"
-	}
-	rr := etcdserverpb.Request{
-		Method: method,
-		Path:   p,
-		Dir:    false, // TODO: always false?
-	}
-	return s.server.Do(ctx, rr)
-}
-
-func (s *store) updateResource(res string, value interface{}) (etcdserver.Response, error) {
-	return s.setResource(res, value, true)
-}
-func (s *store) createResource(res string, value interface{}) (etcdserver.Response, error) {
-	return s.setResource(res, value, false)
-}
-func (s *store) setResource(res string, value interface{}, prevexist bool) (etcdserver.Response, error) {
-	err := s.ensureAuthDirectories()
-	if err != nil {
-		return etcdserver.Response{}, err
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	data, err := json.Marshal(value)
-	if err != nil {
-		return etcdserver.Response{}, err
-	}
-	p := path.Join(StorePermsPrefix, res)
-	rr := etcdserverpb.Request{
-		Method:    "PUT",
-		Path:      p,
-		Val:       string(data),
-		PrevExist: &prevexist,
-	}
-	return s.server.Do(ctx, rr)
-}
-
-func (s *store) deleteResource(res string) error {
-	err := s.ensureAuthDirectories()
-	if err != nil {
-		return err
-	}
-	ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
-	defer cancel()
-	pex := true
-	p := path.Join(StorePermsPrefix, res)
-	_, err = s.server.Do(ctx, etcdserverpb.Request{
-		Method:    "DELETE",
-		Path:      p,
-		PrevExist: &pex,
-	})
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2discovery/discovery.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2discovery/discovery.go
deleted file mode 100644
index cf770b3..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2discovery/discovery.go
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2015 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 v2discovery provides an implementation of the cluster discovery that
-// is used by etcd with v2 client.
-package v2discovery
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"math"
-	"net/http"
-	"net/url"
-	"path"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/client"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/jonboulle/clockwork"
-	"go.uber.org/zap"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "discovery")
-
-	ErrInvalidURL           = errors.New("discovery: invalid URL")
-	ErrBadSizeKey           = errors.New("discovery: size key is bad")
-	ErrSizeNotFound         = errors.New("discovery: size key not found")
-	ErrTokenNotFound        = errors.New("discovery: token not found")
-	ErrDuplicateID          = errors.New("discovery: found duplicate id")
-	ErrDuplicateName        = errors.New("discovery: found duplicate name")
-	ErrFullCluster          = errors.New("discovery: cluster is full")
-	ErrTooManyRetries       = errors.New("discovery: too many retries")
-	ErrBadDiscoveryEndpoint = errors.New("discovery: bad discovery endpoint")
-)
-
-var (
-	// Number of retries discovery will attempt before giving up and erroring out.
-	nRetries             = uint(math.MaxUint32)
-	maxExpoentialRetries = uint(8)
-)
-
-// JoinCluster will connect to the discovery service at the given url, and
-// register the server represented by the given id and config to the cluster
-func JoinCluster(lg *zap.Logger, durl, dproxyurl string, id types.ID, config string) (string, error) {
-	d, err := newDiscovery(lg, durl, dproxyurl, id)
-	if err != nil {
-		return "", err
-	}
-	return d.joinCluster(config)
-}
-
-// GetCluster will connect to the discovery service at the given url and
-// retrieve a string describing the cluster
-func GetCluster(lg *zap.Logger, durl, dproxyurl string) (string, error) {
-	d, err := newDiscovery(lg, durl, dproxyurl, 0)
-	if err != nil {
-		return "", err
-	}
-	return d.getCluster()
-}
-
-type discovery struct {
-	lg      *zap.Logger
-	cluster string
-	id      types.ID
-	c       client.KeysAPI
-	retries uint
-	url     *url.URL
-
-	clock clockwork.Clock
-}
-
-// newProxyFunc builds a proxy function from the given string, which should
-// represent a URL that can be used as a proxy. It performs basic
-// sanitization of the URL and returns any error encountered.
-func newProxyFunc(lg *zap.Logger, proxy string) (func(*http.Request) (*url.URL, error), error) {
-	if proxy == "" {
-		return nil, nil
-	}
-	// Do a small amount of URL sanitization to help the user
-	// Derived from net/http.ProxyFromEnvironment
-	proxyURL, err := url.Parse(proxy)
-	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
-		// proxy was bogus. Try prepending "http://" to it and
-		// see if that parses correctly. If not, we ignore the
-		// error and complain about the original one
-		var err2 error
-		proxyURL, err2 = url.Parse("http://" + proxy)
-		if err2 == nil {
-			err = nil
-		}
-	}
-	if err != nil {
-		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
-	}
-
-	if lg != nil {
-		lg.Info("running proxy with discovery", zap.String("proxy-url", proxyURL.String()))
-	} else {
-		plog.Infof("using proxy %q", proxyURL.String())
-	}
-	return http.ProxyURL(proxyURL), nil
-}
-
-func newDiscovery(lg *zap.Logger, durl, dproxyurl string, id types.ID) (*discovery, error) {
-	u, err := url.Parse(durl)
-	if err != nil {
-		return nil, err
-	}
-	token := u.Path
-	u.Path = ""
-	pf, err := newProxyFunc(lg, dproxyurl)
-	if err != nil {
-		return nil, err
-	}
-
-	// TODO: add ResponseHeaderTimeout back when watch on discovery service writes header early
-	tr, err := transport.NewTransport(transport.TLSInfo{}, 30*time.Second)
-	if err != nil {
-		return nil, err
-	}
-	tr.Proxy = pf
-	cfg := client.Config{
-		Transport: tr,
-		Endpoints: []string{u.String()},
-	}
-	c, err := client.New(cfg)
-	if err != nil {
-		return nil, err
-	}
-	dc := client.NewKeysAPIWithPrefix(c, "")
-	return &discovery{
-		lg:      lg,
-		cluster: token,
-		c:       dc,
-		id:      id,
-		url:     u,
-		clock:   clockwork.NewRealClock(),
-	}, nil
-}
-
-func (d *discovery) joinCluster(config string) (string, error) {
-	// fast path: if the cluster is full, return the error
-	// do not need to register to the cluster in this case.
-	if _, _, _, err := d.checkCluster(); err != nil {
-		return "", err
-	}
-
-	if err := d.createSelf(config); err != nil {
-		// Fails, even on a timeout, if createSelf times out.
-		// TODO(barakmich): Retrying the same node might want to succeed here
-		// (ie, createSelf should be idempotent for discovery).
-		return "", err
-	}
-
-	nodes, size, index, err := d.checkCluster()
-	if err != nil {
-		return "", err
-	}
-
-	all, err := d.waitNodes(nodes, size, index)
-	if err != nil {
-		return "", err
-	}
-
-	return nodesToCluster(all, size)
-}
-
-func (d *discovery) getCluster() (string, error) {
-	nodes, size, index, err := d.checkCluster()
-	if err != nil {
-		if err == ErrFullCluster {
-			return nodesToCluster(nodes, size)
-		}
-		return "", err
-	}
-
-	all, err := d.waitNodes(nodes, size, index)
-	if err != nil {
-		return "", err
-	}
-	return nodesToCluster(all, size)
-}
-
-func (d *discovery) createSelf(contents string) error {
-	ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	resp, err := d.c.Create(ctx, d.selfKey(), contents)
-	cancel()
-	if err != nil {
-		if eerr, ok := err.(client.Error); ok && eerr.Code == client.ErrorCodeNodeExist {
-			return ErrDuplicateID
-		}
-		return err
-	}
-
-	// ensure self appears on the server we connected to
-	w := d.c.Watcher(d.selfKey(), &client.WatcherOptions{AfterIndex: resp.Node.CreatedIndex - 1})
-	_, err = w.Next(context.Background())
-	return err
-}
-
-func (d *discovery) checkCluster() ([]*client.Node, int, uint64, error) {
-	configKey := path.Join("/", d.cluster, "_config")
-	ctx, cancel := context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	// find cluster size
-	resp, err := d.c.Get(ctx, path.Join(configKey, "size"), nil)
-	cancel()
-	if err != nil {
-		if eerr, ok := err.(*client.Error); ok && eerr.Code == client.ErrorCodeKeyNotFound {
-			return nil, 0, 0, ErrSizeNotFound
-		}
-		if err == client.ErrInvalidJSON {
-			return nil, 0, 0, ErrBadDiscoveryEndpoint
-		}
-		if ce, ok := err.(*client.ClusterError); ok {
-			if d.lg != nil {
-				d.lg.Warn(
-					"failed to get from discovery server",
-					zap.String("discovery-url", d.url.String()),
-					zap.String("path", path.Join(configKey, "size")),
-					zap.Error(err),
-					zap.String("err-detail", ce.Detail()),
-				)
-			} else {
-				plog.Error(ce.Detail())
-			}
-			return d.checkClusterRetry()
-		}
-		return nil, 0, 0, err
-	}
-	size, err := strconv.Atoi(resp.Node.Value)
-	if err != nil {
-		return nil, 0, 0, ErrBadSizeKey
-	}
-
-	ctx, cancel = context.WithTimeout(context.Background(), client.DefaultRequestTimeout)
-	resp, err = d.c.Get(ctx, d.cluster, nil)
-	cancel()
-	if err != nil {
-		if ce, ok := err.(*client.ClusterError); ok {
-			if d.lg != nil {
-				d.lg.Warn(
-					"failed to get from discovery server",
-					zap.String("discovery-url", d.url.String()),
-					zap.String("path", d.cluster),
-					zap.Error(err),
-					zap.String("err-detail", ce.Detail()),
-				)
-			} else {
-				plog.Error(ce.Detail())
-			}
-			return d.checkClusterRetry()
-		}
-		return nil, 0, 0, err
-	}
-	var nodes []*client.Node
-	// append non-config keys to nodes
-	for _, n := range resp.Node.Nodes {
-		if path.Base(n.Key) != path.Base(configKey) {
-			nodes = append(nodes, n)
-		}
-	}
-
-	snodes := sortableNodes{nodes}
-	sort.Sort(snodes)
-
-	// find self position
-	for i := range nodes {
-		if path.Base(nodes[i].Key) == path.Base(d.selfKey()) {
-			break
-		}
-		if i >= size-1 {
-			return nodes[:size], size, resp.Index, ErrFullCluster
-		}
-	}
-	return nodes, size, resp.Index, nil
-}
-
-func (d *discovery) logAndBackoffForRetry(step string) {
-	d.retries++
-	// logAndBackoffForRetry stops exponential backoff when the retries are more than maxExpoentialRetries and is set to a constant backoff afterward.
-	retries := d.retries
-	if retries > maxExpoentialRetries {
-		retries = maxExpoentialRetries
-	}
-	retryTimeInSecond := time.Duration(0x1<<retries) * time.Second
-	if d.lg != nil {
-		d.lg.Info(
-			"retry connecting to discovery service",
-			zap.String("url", d.url.String()),
-			zap.String("reason", step),
-			zap.Duration("backoff", retryTimeInSecond),
-		)
-	} else {
-		plog.Infof("%s: error connecting to %s, retrying in %s", step, d.url, retryTimeInSecond)
-	}
-	d.clock.Sleep(retryTimeInSecond)
-}
-
-func (d *discovery) checkClusterRetry() ([]*client.Node, int, uint64, error) {
-	if d.retries < nRetries {
-		d.logAndBackoffForRetry("cluster status check")
-		return d.checkCluster()
-	}
-	return nil, 0, 0, ErrTooManyRetries
-}
-
-func (d *discovery) waitNodesRetry() ([]*client.Node, error) {
-	if d.retries < nRetries {
-		d.logAndBackoffForRetry("waiting for other nodes")
-		nodes, n, index, err := d.checkCluster()
-		if err != nil {
-			return nil, err
-		}
-		return d.waitNodes(nodes, n, index)
-	}
-	return nil, ErrTooManyRetries
-}
-
-func (d *discovery) waitNodes(nodes []*client.Node, size int, index uint64) ([]*client.Node, error) {
-	if len(nodes) > size {
-		nodes = nodes[:size]
-	}
-	// watch from the next index
-	w := d.c.Watcher(d.cluster, &client.WatcherOptions{AfterIndex: index, Recursive: true})
-	all := make([]*client.Node, len(nodes))
-	copy(all, nodes)
-	for _, n := range all {
-		if path.Base(n.Key) == path.Base(d.selfKey()) {
-			if d.lg != nil {
-				d.lg.Info(
-					"found self from discovery server",
-					zap.String("discovery-url", d.url.String()),
-					zap.String("self", path.Base(d.selfKey())),
-				)
-			} else {
-				plog.Noticef("found self %s in the cluster", path.Base(d.selfKey()))
-			}
-		} else {
-			if d.lg != nil {
-				d.lg.Info(
-					"found peer from discovery server",
-					zap.String("discovery-url", d.url.String()),
-					zap.String("peer", path.Base(n.Key)),
-				)
-			} else {
-				plog.Noticef("found peer %s in the cluster", path.Base(n.Key))
-			}
-		}
-	}
-
-	// wait for others
-	for len(all) < size {
-		if d.lg != nil {
-			d.lg.Info(
-				"found peers from discovery server; waiting for more",
-				zap.String("discovery-url", d.url.String()),
-				zap.Int("found-peers", len(all)),
-				zap.Int("needed-peers", size-len(all)),
-			)
-		} else {
-			plog.Noticef("found %d peer(s), waiting for %d more", len(all), size-len(all))
-		}
-		resp, err := w.Next(context.Background())
-		if err != nil {
-			if ce, ok := err.(*client.ClusterError); ok {
-				plog.Error(ce.Detail())
-				return d.waitNodesRetry()
-			}
-			return nil, err
-		}
-		if d.lg != nil {
-			d.lg.Info(
-				"found peer from discovery server",
-				zap.String("discovery-url", d.url.String()),
-				zap.String("peer", path.Base(resp.Node.Key)),
-			)
-		} else {
-			plog.Noticef("found peer %s in the cluster", path.Base(resp.Node.Key))
-		}
-		all = append(all, resp.Node)
-	}
-	if d.lg != nil {
-		d.lg.Info(
-			"found all needed peers from discovery server",
-			zap.String("discovery-url", d.url.String()),
-			zap.Int("found-peers", len(all)),
-		)
-	} else {
-		plog.Noticef("found %d needed peer(s)", len(all))
-	}
-	return all, nil
-}
-
-func (d *discovery) selfKey() string {
-	return path.Join("/", d.cluster, d.id.String())
-}
-
-func nodesToCluster(ns []*client.Node, size int) (string, error) {
-	s := make([]string, len(ns))
-	for i, n := range ns {
-		s[i] = n.Value
-	}
-	us := strings.Join(s, ",")
-	m, err := types.NewURLsMap(us)
-	if err != nil {
-		return us, ErrInvalidURL
-	}
-	if m.Len() != size {
-		return us, ErrDuplicateName
-	}
-	return us, nil
-}
-
-type sortableNodes struct{ Nodes []*client.Node }
-
-func (ns sortableNodes) Len() int { return len(ns.Nodes) }
-func (ns sortableNodes) Less(i, j int) bool {
-	return ns.Nodes[i].CreatedIndex < ns.Nodes[j].CreatedIndex
-}
-func (ns sortableNodes) Swap(i, j int) { ns.Nodes[i], ns.Nodes[j] = ns.Nodes[j], ns.Nodes[i] }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2error/error.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2error/error.go
deleted file mode 100644
index 1244290..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2error/error.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2015 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 v2error describes errors in etcd project. When any change happens,
-// Documentation/v2/errorcode.md needs to be updated correspondingly.
-// To be deprecated in favor of v3 APIs.
-package v2error
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-)
-
-var errors = map[int]string{
-	// command related errors
-	EcodeKeyNotFound:      "Key not found",
-	EcodeTestFailed:       "Compare failed", //test and set
-	EcodeNotFile:          "Not a file",
-	ecodeNoMorePeer:       "Reached the max number of peers in the cluster",
-	EcodeNotDir:           "Not a directory",
-	EcodeNodeExist:        "Key already exists", // create
-	ecodeKeyIsPreserved:   "The prefix of given key is a keyword in etcd",
-	EcodeRootROnly:        "Root is read only",
-	EcodeDirNotEmpty:      "Directory not empty",
-	ecodeExistingPeerAddr: "Peer address has existed",
-	EcodeUnauthorized:     "The request requires user authentication",
-
-	// Post form related errors
-	ecodeValueRequired:        "Value is Required in POST form",
-	EcodePrevValueRequired:    "PrevValue is Required in POST form",
-	EcodeTTLNaN:               "The given TTL in POST form is not a number",
-	EcodeIndexNaN:             "The given index in POST form is not a number",
-	ecodeValueOrTTLRequired:   "Value or TTL is required in POST form",
-	ecodeTimeoutNaN:           "The given timeout in POST form is not a number",
-	ecodeNameRequired:         "Name is required in POST form",
-	ecodeIndexOrValueRequired: "Index or value is required",
-	ecodeIndexValueMutex:      "Index and value cannot both be specified",
-	EcodeInvalidField:         "Invalid field",
-	EcodeInvalidForm:          "Invalid POST form",
-	EcodeRefreshValue:         "Value provided on refresh",
-	EcodeRefreshTTLRequired:   "A TTL must be provided on refresh",
-
-	// raft related errors
-	EcodeRaftInternal: "Raft Internal Error",
-	EcodeLeaderElect:  "During Leader Election",
-
-	// etcd related errors
-	EcodeWatcherCleared:     "watcher is cleared due to etcd recovery",
-	EcodeEventIndexCleared:  "The event in requested index is outdated and cleared",
-	ecodeStandbyInternal:    "Standby Internal Error",
-	ecodeInvalidActiveSize:  "Invalid active size",
-	ecodeInvalidRemoveDelay: "Standby remove delay",
-
-	// client related errors
-	ecodeClientInternal: "Client Internal Error",
-}
-
-var errorStatus = map[int]int{
-	EcodeKeyNotFound:  http.StatusNotFound,
-	EcodeNotFile:      http.StatusForbidden,
-	EcodeDirNotEmpty:  http.StatusForbidden,
-	EcodeUnauthorized: http.StatusUnauthorized,
-	EcodeTestFailed:   http.StatusPreconditionFailed,
-	EcodeNodeExist:    http.StatusPreconditionFailed,
-	EcodeRaftInternal: http.StatusInternalServerError,
-	EcodeLeaderElect:  http.StatusInternalServerError,
-}
-
-const (
-	EcodeKeyNotFound      = 100
-	EcodeTestFailed       = 101
-	EcodeNotFile          = 102
-	ecodeNoMorePeer       = 103
-	EcodeNotDir           = 104
-	EcodeNodeExist        = 105
-	ecodeKeyIsPreserved   = 106
-	EcodeRootROnly        = 107
-	EcodeDirNotEmpty      = 108
-	ecodeExistingPeerAddr = 109
-	EcodeUnauthorized     = 110
-
-	ecodeValueRequired        = 200
-	EcodePrevValueRequired    = 201
-	EcodeTTLNaN               = 202
-	EcodeIndexNaN             = 203
-	ecodeValueOrTTLRequired   = 204
-	ecodeTimeoutNaN           = 205
-	ecodeNameRequired         = 206
-	ecodeIndexOrValueRequired = 207
-	ecodeIndexValueMutex      = 208
-	EcodeInvalidField         = 209
-	EcodeInvalidForm          = 210
-	EcodeRefreshValue         = 211
-	EcodeRefreshTTLRequired   = 212
-
-	EcodeRaftInternal = 300
-	EcodeLeaderElect  = 301
-
-	EcodeWatcherCleared     = 400
-	EcodeEventIndexCleared  = 401
-	ecodeStandbyInternal    = 402
-	ecodeInvalidActiveSize  = 403
-	ecodeInvalidRemoveDelay = 404
-
-	ecodeClientInternal = 500
-)
-
-type Error struct {
-	ErrorCode int    `json:"errorCode"`
-	Message   string `json:"message"`
-	Cause     string `json:"cause,omitempty"`
-	Index     uint64 `json:"index"`
-}
-
-func NewRequestError(errorCode int, cause string) *Error {
-	return NewError(errorCode, cause, 0)
-}
-
-func NewError(errorCode int, cause string, index uint64) *Error {
-	return &Error{
-		ErrorCode: errorCode,
-		Message:   errors[errorCode],
-		Cause:     cause,
-		Index:     index,
-	}
-}
-
-// Error is for the error interface
-func (e Error) Error() string {
-	return e.Message + " (" + e.Cause + ")"
-}
-
-func (e Error) toJsonString() string {
-	b, _ := json.Marshal(e)
-	return string(b)
-}
-
-func (e Error) StatusCode() int {
-	status, ok := errorStatus[e.ErrorCode]
-	if !ok {
-		status = http.StatusBadRequest
-	}
-	return status
-}
-
-func (e Error) WriteTo(w http.ResponseWriter) error {
-	w.Header().Add("X-Etcd-Index", fmt.Sprint(e.Index))
-	w.Header().Set("Content-Type", "application/json")
-	w.WriteHeader(e.StatusCode())
-	_, err := w.Write([]byte(e.toJsonString() + "\n"))
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/capability.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/capability.go
deleted file mode 100644
index ed6c456..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/capability.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 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 v2http
-
-import (
-	"fmt"
-	"net/http"
-
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-)
-
-func authCapabilityHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		if !api.IsCapabilityEnabled(api.AuthCapability) {
-			notCapable(w, r, api.AuthCapability)
-			return
-		}
-		fn(w, r)
-	}
-}
-
-func notCapable(w http.ResponseWriter, r *http.Request, c api.Capability) {
-	herr := httptypes.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Not capable of accessing %s feature during rolling upgrades.", c))
-	if err := herr.WriteTo(w); err != nil {
-		plog.Debugf("error writing HTTPError (%v) to %s", err, r.RemoteAddr)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client.go
deleted file mode 100644
index 1d1e592..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client.go
+++ /dev/null
@@ -1,788 +0,0 @@
-// Copyright 2015 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 v2http
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"path"
-	"strconv"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/etcdhttp"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/v2auth"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-	stats "go.etcd.io/etcd/etcdserver/api/v2stats"
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/jonboulle/clockwork"
-	"go.uber.org/zap"
-)
-
-const (
-	authPrefix     = "/v2/auth"
-	keysPrefix     = "/v2/keys"
-	machinesPrefix = "/v2/machines"
-	membersPrefix  = "/v2/members"
-	statsPrefix    = "/v2/stats"
-)
-
-// NewClientHandler generates a muxed http.Handler with the given parameters to serve etcd client requests.
-func NewClientHandler(lg *zap.Logger, server etcdserver.ServerPeer, timeout time.Duration) http.Handler {
-	mux := http.NewServeMux()
-	etcdhttp.HandleBasic(mux, server)
-	handleV2(lg, mux, server, timeout)
-	return requestLogger(lg, mux)
-}
-
-func handleV2(lg *zap.Logger, mux *http.ServeMux, server etcdserver.ServerV2, timeout time.Duration) {
-	sec := v2auth.NewStore(lg, server, timeout)
-	kh := &keysHandler{
-		lg:                    lg,
-		sec:                   sec,
-		server:                server,
-		cluster:               server.Cluster(),
-		timeout:               timeout,
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-
-	sh := &statsHandler{
-		lg:    lg,
-		stats: server,
-	}
-
-	mh := &membersHandler{
-		lg:                    lg,
-		sec:                   sec,
-		server:                server,
-		cluster:               server.Cluster(),
-		timeout:               timeout,
-		clock:                 clockwork.NewRealClock(),
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-
-	mah := &machinesHandler{cluster: server.Cluster()}
-
-	sech := &authHandler{
-		lg:                    lg,
-		sec:                   sec,
-		cluster:               server.Cluster(),
-		clientCertAuthEnabled: server.ClientCertAuthEnabled(),
-	}
-	mux.HandleFunc("/", http.NotFound)
-	mux.Handle(keysPrefix, kh)
-	mux.Handle(keysPrefix+"/", kh)
-	mux.HandleFunc(statsPrefix+"/store", sh.serveStore)
-	mux.HandleFunc(statsPrefix+"/self", sh.serveSelf)
-	mux.HandleFunc(statsPrefix+"/leader", sh.serveLeader)
-	mux.Handle(membersPrefix, mh)
-	mux.Handle(membersPrefix+"/", mh)
-	mux.Handle(machinesPrefix, mah)
-	handleAuth(mux, sech)
-}
-
-type keysHandler struct {
-	lg                    *zap.Logger
-	sec                   v2auth.Store
-	server                etcdserver.ServerV2
-	cluster               api.Cluster
-	timeout               time.Duration
-	clientCertAuthEnabled bool
-}
-
-func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "HEAD", "GET", "PUT", "POST", "DELETE") {
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
-	defer cancel()
-	clock := clockwork.NewRealClock()
-	startTime := clock.Now()
-	rr, noValueOnSuccess, err := parseKeyRequest(r, clock)
-	if err != nil {
-		writeKeyError(h.lg, w, err)
-		return
-	}
-	// The path must be valid at this point (we've parsed the request successfully).
-	if !hasKeyPrefixAccess(h.lg, h.sec, r, r.URL.Path[len(keysPrefix):], rr.Recursive, h.clientCertAuthEnabled) {
-		writeKeyNoAuth(w)
-		return
-	}
-	if !rr.Wait {
-		reportRequestReceived(rr)
-	}
-	resp, err := h.server.Do(ctx, rr)
-	if err != nil {
-		err = trimErrorPrefix(err, etcdserver.StoreKeysPrefix)
-		writeKeyError(h.lg, w, err)
-		reportRequestFailed(rr, err)
-		return
-	}
-	switch {
-	case resp.Event != nil:
-		if err := writeKeyEvent(w, resp, noValueOnSuccess); err != nil {
-			// Should never be reached
-			if h.lg != nil {
-				h.lg.Warn("failed to write key event", zap.Error(err))
-			} else {
-				plog.Errorf("error writing event (%v)", err)
-			}
-		}
-		reportRequestCompleted(rr, startTime)
-	case resp.Watcher != nil:
-		ctx, cancel := context.WithTimeout(context.Background(), defaultWatchTimeout)
-		defer cancel()
-		handleKeyWatch(ctx, h.lg, w, resp, rr.Stream)
-	default:
-		writeKeyError(h.lg, w, errors.New("received response with no Event/Watcher"))
-	}
-}
-
-type machinesHandler struct {
-	cluster api.Cluster
-}
-
-func (h *machinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "HEAD") {
-		return
-	}
-	endpoints := h.cluster.ClientURLs()
-	w.Write([]byte(strings.Join(endpoints, ", ")))
-}
-
-type membersHandler struct {
-	lg                    *zap.Logger
-	sec                   v2auth.Store
-	server                etcdserver.ServerV2
-	cluster               api.Cluster
-	timeout               time.Duration
-	clock                 clockwork.Clock
-	clientCertAuthEnabled bool
-}
-
-func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "POST", "DELETE", "PUT") {
-		return
-	}
-	if !hasWriteRootAccess(h.lg, h.sec, r, h.clientCertAuthEnabled) {
-		writeNoAuth(h.lg, w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", h.cluster.ID().String())
-
-	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
-	defer cancel()
-
-	switch r.Method {
-	case "GET":
-		switch trimPrefix(r.URL.Path, membersPrefix) {
-		case "":
-			mc := newMemberCollection(h.cluster.Members())
-			w.Header().Set("Content-Type", "application/json")
-			if err := json.NewEncoder(w).Encode(mc); err != nil {
-				if h.lg != nil {
-					h.lg.Warn("failed to encode members response", zap.Error(err))
-				} else {
-					plog.Warningf("failed to encode members response (%v)", err)
-				}
-			}
-		case "leader":
-			id := h.server.Leader()
-			if id == 0 {
-				writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusServiceUnavailable, "During election"))
-				return
-			}
-			m := newMember(h.cluster.Member(id))
-			w.Header().Set("Content-Type", "application/json")
-			if err := json.NewEncoder(w).Encode(m); err != nil {
-				if h.lg != nil {
-					h.lg.Warn("failed to encode members response", zap.Error(err))
-				} else {
-					plog.Warningf("failed to encode members response (%v)", err)
-				}
-			}
-		default:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusNotFound, "Not found"))
-		}
-
-	case "POST":
-		req := httptypes.MemberCreateRequest{}
-		if ok := unmarshalRequest(h.lg, r, &req, w); !ok {
-			return
-		}
-		now := h.clock.Now()
-		m := membership.NewMember("", req.PeerURLs, "", &now)
-		_, err := h.server.AddMember(ctx, *m)
-		switch {
-		case err == membership.ErrIDExists || err == membership.ErrPeerURLexists:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error()))
-			return
-		case err != nil:
-			if h.lg != nil {
-				h.lg.Warn(
-					"failed to add a member",
-					zap.String("member-id", m.ID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("error adding member %s (%v)", m.ID, err)
-			}
-			writeError(h.lg, w, r, err)
-			return
-		}
-		res := newMember(m)
-		w.Header().Set("Content-Type", "application/json")
-		w.WriteHeader(http.StatusCreated)
-		if err := json.NewEncoder(w).Encode(res); err != nil {
-			if h.lg != nil {
-				h.lg.Warn("failed to encode members response", zap.Error(err))
-			} else {
-				plog.Warningf("failed to encode members response (%v)", err)
-			}
-		}
-
-	case "DELETE":
-		id, ok := getID(h.lg, r.URL.Path, w)
-		if !ok {
-			return
-		}
-		_, err := h.server.RemoveMember(ctx, uint64(id))
-		switch {
-		case err == membership.ErrIDRemoved:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusGone, fmt.Sprintf("Member permanently removed: %s", id)))
-		case err == membership.ErrIDNotFound:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id)))
-		case err != nil:
-			if h.lg != nil {
-				h.lg.Warn(
-					"failed to remove a member",
-					zap.String("member-id", id.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("error removing member %s (%v)", id, err)
-			}
-			writeError(h.lg, w, r, err)
-		default:
-			w.WriteHeader(http.StatusNoContent)
-		}
-
-	case "PUT":
-		id, ok := getID(h.lg, r.URL.Path, w)
-		if !ok {
-			return
-		}
-		req := httptypes.MemberUpdateRequest{}
-		if ok := unmarshalRequest(h.lg, r, &req, w); !ok {
-			return
-		}
-		m := membership.Member{
-			ID:             id,
-			RaftAttributes: membership.RaftAttributes{PeerURLs: req.PeerURLs.StringSlice()},
-		}
-		_, err := h.server.UpdateMember(ctx, m)
-		switch {
-		case err == membership.ErrPeerURLexists:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error()))
-		case err == membership.ErrIDNotFound:
-			writeError(h.lg, w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id)))
-		case err != nil:
-			if h.lg != nil {
-				h.lg.Warn(
-					"failed to update a member",
-					zap.String("member-id", m.ID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("error updating member %s (%v)", m.ID, err)
-			}
-			writeError(h.lg, w, r, err)
-		default:
-			w.WriteHeader(http.StatusNoContent)
-		}
-	}
-}
-
-type statsHandler struct {
-	lg    *zap.Logger
-	stats stats.Stats
-}
-
-func (h *statsHandler) serveStore(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(h.stats.StoreStats())
-}
-
-func (h *statsHandler) serveSelf(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(h.stats.SelfStats())
-}
-
-func (h *statsHandler) serveLeader(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	stats := h.stats.LeaderStats()
-	if stats == nil {
-		etcdhttp.WriteError(h.lg, w, r, httptypes.NewHTTPError(http.StatusForbidden, "not current leader"))
-		return
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Write(stats)
-}
-
-// parseKeyRequest converts a received http.Request on keysPrefix to
-// a server Request, performing validation of supplied fields as appropriate.
-// If any validation fails, an empty Request and non-nil error is returned.
-func parseKeyRequest(r *http.Request, clock clockwork.Clock) (etcdserverpb.Request, bool, error) {
-	var noValueOnSuccess bool
-	emptyReq := etcdserverpb.Request{}
-
-	err := r.ParseForm()
-	if err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidForm,
-			err.Error(),
-		)
-	}
-
-	if !strings.HasPrefix(r.URL.Path, keysPrefix) {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidForm,
-			"incorrect key prefix",
-		)
-	}
-	p := path.Join(etcdserver.StoreKeysPrefix, r.URL.Path[len(keysPrefix):])
-
-	var pIdx, wIdx uint64
-	if pIdx, err = getUint64(r.Form, "prevIndex"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeIndexNaN,
-			`invalid value for "prevIndex"`,
-		)
-	}
-	if wIdx, err = getUint64(r.Form, "waitIndex"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeIndexNaN,
-			`invalid value for "waitIndex"`,
-		)
-	}
-
-	var rec, sort, wait, dir, quorum, stream bool
-	if rec, err = getBool(r.Form, "recursive"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "recursive"`,
-		)
-	}
-	if sort, err = getBool(r.Form, "sorted"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "sorted"`,
-		)
-	}
-	if wait, err = getBool(r.Form, "wait"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "wait"`,
-		)
-	}
-	// TODO(jonboulle): define what parameters dir is/isn't compatible with?
-	if dir, err = getBool(r.Form, "dir"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "dir"`,
-		)
-	}
-	if quorum, err = getBool(r.Form, "quorum"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "quorum"`,
-		)
-	}
-	if stream, err = getBool(r.Form, "stream"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "stream"`,
-		)
-	}
-
-	if wait && r.Method != "GET" {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`"wait" can only be used with GET requests`,
-		)
-	}
-
-	pV := r.FormValue("prevValue")
-	if _, ok := r.Form["prevValue"]; ok && pV == "" {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodePrevValueRequired,
-			`"prevValue" cannot be empty`,
-		)
-	}
-
-	if noValueOnSuccess, err = getBool(r.Form, "noValueOnSuccess"); err != nil {
-		return emptyReq, false, v2error.NewRequestError(
-			v2error.EcodeInvalidField,
-			`invalid value for "noValueOnSuccess"`,
-		)
-	}
-
-	// TTL is nullable, so leave it null if not specified
-	// or an empty string
-	var ttl *uint64
-	if len(r.FormValue("ttl")) > 0 {
-		i, err := getUint64(r.Form, "ttl")
-		if err != nil {
-			return emptyReq, false, v2error.NewRequestError(
-				v2error.EcodeTTLNaN,
-				`invalid value for "ttl"`,
-			)
-		}
-		ttl = &i
-	}
-
-	// prevExist is nullable, so leave it null if not specified
-	var pe *bool
-	if _, ok := r.Form["prevExist"]; ok {
-		bv, err := getBool(r.Form, "prevExist")
-		if err != nil {
-			return emptyReq, false, v2error.NewRequestError(
-				v2error.EcodeInvalidField,
-				"invalid value for prevExist",
-			)
-		}
-		pe = &bv
-	}
-
-	// refresh is nullable, so leave it null if not specified
-	var refresh *bool
-	if _, ok := r.Form["refresh"]; ok {
-		bv, err := getBool(r.Form, "refresh")
-		if err != nil {
-			return emptyReq, false, v2error.NewRequestError(
-				v2error.EcodeInvalidField,
-				"invalid value for refresh",
-			)
-		}
-		refresh = &bv
-		if refresh != nil && *refresh {
-			val := r.FormValue("value")
-			if _, ok := r.Form["value"]; ok && val != "" {
-				return emptyReq, false, v2error.NewRequestError(
-					v2error.EcodeRefreshValue,
-					`A value was provided on a refresh`,
-				)
-			}
-			if ttl == nil {
-				return emptyReq, false, v2error.NewRequestError(
-					v2error.EcodeRefreshTTLRequired,
-					`No TTL value set`,
-				)
-			}
-		}
-	}
-
-	rr := etcdserverpb.Request{
-		Method:    r.Method,
-		Path:      p,
-		Val:       r.FormValue("value"),
-		Dir:       dir,
-		PrevValue: pV,
-		PrevIndex: pIdx,
-		PrevExist: pe,
-		Wait:      wait,
-		Since:     wIdx,
-		Recursive: rec,
-		Sorted:    sort,
-		Quorum:    quorum,
-		Stream:    stream,
-	}
-
-	if pe != nil {
-		rr.PrevExist = pe
-	}
-
-	if refresh != nil {
-		rr.Refresh = refresh
-	}
-
-	// Null TTL is equivalent to unset Expiration
-	if ttl != nil {
-		expr := time.Duration(*ttl) * time.Second
-		rr.Expiration = clock.Now().Add(expr).UnixNano()
-	}
-
-	return rr, noValueOnSuccess, nil
-}
-
-// writeKeyEvent trims the prefix of key path in a single Event under
-// StoreKeysPrefix, serializes it and writes the resulting JSON to the given
-// ResponseWriter, along with the appropriate headers.
-func writeKeyEvent(w http.ResponseWriter, resp etcdserver.Response, noValueOnSuccess bool) error {
-	ev := resp.Event
-	if ev == nil {
-		return errors.New("cannot write empty Event")
-	}
-	w.Header().Set("Content-Type", "application/json")
-	w.Header().Set("X-Etcd-Index", fmt.Sprint(ev.EtcdIndex))
-	w.Header().Set("X-Raft-Index", fmt.Sprint(resp.Index))
-	w.Header().Set("X-Raft-Term", fmt.Sprint(resp.Term))
-
-	if ev.IsCreated() {
-		w.WriteHeader(http.StatusCreated)
-	}
-
-	ev = trimEventPrefix(ev, etcdserver.StoreKeysPrefix)
-	if noValueOnSuccess &&
-		(ev.Action == v2store.Set || ev.Action == v2store.CompareAndSwap ||
-			ev.Action == v2store.Create || ev.Action == v2store.Update) {
-		ev.Node = nil
-		ev.PrevNode = nil
-	}
-	return json.NewEncoder(w).Encode(ev)
-}
-
-func writeKeyNoAuth(w http.ResponseWriter) {
-	e := v2error.NewError(v2error.EcodeUnauthorized, "Insufficient credentials", 0)
-	e.WriteTo(w)
-}
-
-// writeKeyError logs and writes the given Error to the ResponseWriter.
-// If Error is not an etcdErr, the error will be converted to an etcd error.
-func writeKeyError(lg *zap.Logger, w http.ResponseWriter, err error) {
-	if err == nil {
-		return
-	}
-	switch e := err.(type) {
-	case *v2error.Error:
-		e.WriteTo(w)
-	default:
-		switch err {
-		case etcdserver.ErrTimeoutDueToLeaderFail, etcdserver.ErrTimeoutDueToConnectionLost:
-			if lg != nil {
-				lg.Warn(
-					"v2 response error",
-					zap.String("internal-server-error", err.Error()),
-				)
-			} else {
-				mlog.MergeError(err)
-			}
-		default:
-			if lg != nil {
-				lg.Warn(
-					"unexpected v2 response error",
-					zap.String("internal-server-error", err.Error()),
-				)
-			} else {
-				mlog.MergeErrorf("got unexpected response error (%v)", err)
-			}
-		}
-		ee := v2error.NewError(v2error.EcodeRaftInternal, err.Error(), 0)
-		ee.WriteTo(w)
-	}
-}
-
-func handleKeyWatch(ctx context.Context, lg *zap.Logger, w http.ResponseWriter, resp etcdserver.Response, stream bool) {
-	wa := resp.Watcher
-	defer wa.Remove()
-	ech := wa.EventChan()
-	var nch <-chan bool
-	if x, ok := w.(http.CloseNotifier); ok {
-		nch = x.CloseNotify()
-	}
-
-	w.Header().Set("Content-Type", "application/json")
-	w.Header().Set("X-Etcd-Index", fmt.Sprint(wa.StartIndex()))
-	w.Header().Set("X-Raft-Index", fmt.Sprint(resp.Index))
-	w.Header().Set("X-Raft-Term", fmt.Sprint(resp.Term))
-	w.WriteHeader(http.StatusOK)
-
-	// Ensure headers are flushed early, in case of long polling
-	w.(http.Flusher).Flush()
-
-	for {
-		select {
-		case <-nch:
-			// Client closed connection. Nothing to do.
-			return
-		case <-ctx.Done():
-			// Timed out. net/http will close the connection for us, so nothing to do.
-			return
-		case ev, ok := <-ech:
-			if !ok {
-				// If the channel is closed this may be an indication of
-				// that notifications are much more than we are able to
-				// send to the client in time. Then we simply end streaming.
-				return
-			}
-			ev = trimEventPrefix(ev, etcdserver.StoreKeysPrefix)
-			if err := json.NewEncoder(w).Encode(ev); err != nil {
-				// Should never be reached
-				if lg != nil {
-					lg.Warn("failed to encode event", zap.Error(err))
-				} else {
-					plog.Warningf("error writing event (%v)", err)
-				}
-				return
-			}
-			if !stream {
-				return
-			}
-			w.(http.Flusher).Flush()
-		}
-	}
-}
-
-func trimEventPrefix(ev *v2store.Event, prefix string) *v2store.Event {
-	if ev == nil {
-		return nil
-	}
-	// Since the *Event may reference one in the store history
-	// history, we must copy it before modifying
-	e := ev.Clone()
-	trimNodeExternPrefix(e.Node, prefix)
-	trimNodeExternPrefix(e.PrevNode, prefix)
-	return e
-}
-
-func trimNodeExternPrefix(n *v2store.NodeExtern, prefix string) {
-	if n == nil {
-		return
-	}
-	n.Key = strings.TrimPrefix(n.Key, prefix)
-	for _, nn := range n.Nodes {
-		trimNodeExternPrefix(nn, prefix)
-	}
-}
-
-func trimErrorPrefix(err error, prefix string) error {
-	if e, ok := err.(*v2error.Error); ok {
-		e.Cause = strings.TrimPrefix(e.Cause, prefix)
-	}
-	return err
-}
-
-func unmarshalRequest(lg *zap.Logger, r *http.Request, req json.Unmarshaler, w http.ResponseWriter) bool {
-	ctype := r.Header.Get("Content-Type")
-	semicolonPosition := strings.Index(ctype, ";")
-	if semicolonPosition != -1 {
-		ctype = strings.TrimSpace(strings.ToLower(ctype[0:semicolonPosition]))
-	}
-	if ctype != "application/json" {
-		writeError(lg, w, r, httptypes.NewHTTPError(http.StatusUnsupportedMediaType, fmt.Sprintf("Bad Content-Type %s, accept application/json", ctype)))
-		return false
-	}
-	b, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		writeError(lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, err.Error()))
-		return false
-	}
-	if err := req.UnmarshalJSON(b); err != nil {
-		writeError(lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, err.Error()))
-		return false
-	}
-	return true
-}
-
-func getID(lg *zap.Logger, p string, w http.ResponseWriter) (types.ID, bool) {
-	idStr := trimPrefix(p, membersPrefix)
-	if idStr == "" {
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return 0, false
-	}
-	id, err := types.IDFromString(idStr)
-	if err != nil {
-		writeError(lg, w, nil, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", idStr)))
-		return 0, false
-	}
-	return id, true
-}
-
-// getUint64 extracts a uint64 by the given key from a Form. If the key does
-// not exist in the form, 0 is returned. If the key exists but the value is
-// badly formed, an error is returned. If multiple values are present only the
-// first is considered.
-func getUint64(form url.Values, key string) (i uint64, err error) {
-	if vals, ok := form[key]; ok {
-		i, err = strconv.ParseUint(vals[0], 10, 64)
-	}
-	return
-}
-
-// getBool extracts a bool by the given key from a Form. If the key does not
-// exist in the form, false is returned. If the key exists but the value is
-// badly formed, an error is returned. If multiple values are present only the
-// first is considered.
-func getBool(form url.Values, key string) (b bool, err error) {
-	if vals, ok := form[key]; ok {
-		b, err = strconv.ParseBool(vals[0])
-	}
-	return
-}
-
-// trimPrefix removes a given prefix and any slash following the prefix
-// e.g.: trimPrefix("foo", "foo") == trimPrefix("foo/", "foo") == ""
-func trimPrefix(p, prefix string) (s string) {
-	s = strings.TrimPrefix(p, prefix)
-	s = strings.TrimPrefix(s, "/")
-	return
-}
-
-func newMemberCollection(ms []*membership.Member) *httptypes.MemberCollection {
-	c := httptypes.MemberCollection(make([]httptypes.Member, len(ms)))
-
-	for i, m := range ms {
-		c[i] = newMember(m)
-	}
-
-	return &c
-}
-
-func newMember(m *membership.Member) httptypes.Member {
-	tm := httptypes.Member{
-		ID:         m.ID.String(),
-		Name:       m.Name,
-		PeerURLs:   make([]string, len(m.PeerURLs)),
-		ClientURLs: make([]string, len(m.ClientURLs)),
-	}
-
-	copy(tm.PeerURLs, m.PeerURLs)
-	copy(tm.ClientURLs, m.ClientURLs)
-
-	return tm
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client_auth.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client_auth.go
deleted file mode 100644
index d8d6a88..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/client_auth.go
+++ /dev/null
@@ -1,664 +0,0 @@
-// Copyright 2015 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 v2http
-
-import (
-	"encoding/json"
-	"net/http"
-	"path"
-	"strings"
-
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/v2auth"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-
-	"go.uber.org/zap"
-)
-
-type authHandler struct {
-	lg                    *zap.Logger
-	sec                   v2auth.Store
-	cluster               api.Cluster
-	clientCertAuthEnabled bool
-}
-
-func hasWriteRootAccess(lg *zap.Logger, sec v2auth.Store, r *http.Request, clientCertAuthEnabled bool) bool {
-	if r.Method == "GET" || r.Method == "HEAD" {
-		return true
-	}
-	return hasRootAccess(lg, sec, r, clientCertAuthEnabled)
-}
-
-func userFromBasicAuth(lg *zap.Logger, sec v2auth.Store, r *http.Request) *v2auth.User {
-	username, password, ok := r.BasicAuth()
-	if !ok {
-		if lg != nil {
-			lg.Warn("malformed basic auth encoding")
-		} else {
-			plog.Warningf("auth: malformed basic auth encoding")
-		}
-		return nil
-	}
-	user, err := sec.GetUser(username)
-	if err != nil {
-		return nil
-	}
-
-	ok = sec.CheckPassword(user, password)
-	if !ok {
-		if lg != nil {
-			lg.Warn("incorrect password", zap.String("user-name", username))
-		} else {
-			plog.Warningf("auth: incorrect password for user: %s", username)
-		}
-		return nil
-	}
-	return &user
-}
-
-func userFromClientCertificate(lg *zap.Logger, sec v2auth.Store, r *http.Request) *v2auth.User {
-	if r.TLS == nil {
-		return nil
-	}
-
-	for _, chains := range r.TLS.VerifiedChains {
-		for _, chain := range chains {
-			if lg != nil {
-				lg.Debug("found common name", zap.String("common-name", chain.Subject.CommonName))
-			} else {
-				plog.Debugf("auth: found common name %s.\n", chain.Subject.CommonName)
-			}
-			user, err := sec.GetUser(chain.Subject.CommonName)
-			if err == nil {
-				if lg != nil {
-					lg.Debug(
-						"authenticated a user via common name",
-						zap.String("user-name", user.User),
-						zap.String("common-name", chain.Subject.CommonName),
-					)
-				} else {
-					plog.Debugf("auth: authenticated user %s by cert common name.", user.User)
-				}
-				return &user
-			}
-		}
-	}
-	return nil
-}
-
-func hasRootAccess(lg *zap.Logger, sec v2auth.Store, r *http.Request, clientCertAuthEnabled bool) bool {
-	if sec == nil {
-		// No store means no auth available, eg, tests.
-		return true
-	}
-	if !sec.AuthEnabled() {
-		return true
-	}
-
-	var rootUser *v2auth.User
-	if r.Header.Get("Authorization") == "" && clientCertAuthEnabled {
-		rootUser = userFromClientCertificate(lg, sec, r)
-		if rootUser == nil {
-			return false
-		}
-	} else {
-		rootUser = userFromBasicAuth(lg, sec, r)
-		if rootUser == nil {
-			return false
-		}
-	}
-
-	for _, role := range rootUser.Roles {
-		if role == v2auth.RootRoleName {
-			return true
-		}
-	}
-
-	if lg != nil {
-		lg.Warn(
-			"a user does not have root role for resource",
-			zap.String("root-user", rootUser.User),
-			zap.String("root-role-name", v2auth.RootRoleName),
-			zap.String("resource-path", r.URL.Path),
-		)
-	} else {
-		plog.Warningf("auth: user %s does not have the %s role for resource %s.", rootUser.User, v2auth.RootRoleName, r.URL.Path)
-	}
-	return false
-}
-
-func hasKeyPrefixAccess(lg *zap.Logger, sec v2auth.Store, r *http.Request, key string, recursive, clientCertAuthEnabled bool) bool {
-	if sec == nil {
-		// No store means no auth available, eg, tests.
-		return true
-	}
-	if !sec.AuthEnabled() {
-		return true
-	}
-
-	var user *v2auth.User
-	if r.Header.Get("Authorization") == "" {
-		if clientCertAuthEnabled {
-			user = userFromClientCertificate(lg, sec, r)
-		}
-		if user == nil {
-			return hasGuestAccess(lg, sec, r, key)
-		}
-	} else {
-		user = userFromBasicAuth(lg, sec, r)
-		if user == nil {
-			return false
-		}
-	}
-
-	writeAccess := r.Method != "GET" && r.Method != "HEAD"
-	for _, roleName := range user.Roles {
-		role, err := sec.GetRole(roleName)
-		if err != nil {
-			continue
-		}
-		if recursive {
-			if role.HasRecursiveAccess(key, writeAccess) {
-				return true
-			}
-		} else if role.HasKeyAccess(key, writeAccess) {
-			return true
-		}
-	}
-
-	if lg != nil {
-		lg.Warn(
-			"invalid access for user on key",
-			zap.String("user-name", user.User),
-			zap.String("key", key),
-		)
-	} else {
-		plog.Warningf("auth: invalid access for user %s on key %s.", user.User, key)
-	}
-	return false
-}
-
-func hasGuestAccess(lg *zap.Logger, sec v2auth.Store, r *http.Request, key string) bool {
-	writeAccess := r.Method != "GET" && r.Method != "HEAD"
-	role, err := sec.GetRole(v2auth.GuestRoleName)
-	if err != nil {
-		return false
-	}
-	if role.HasKeyAccess(key, writeAccess) {
-		return true
-	}
-
-	if lg != nil {
-		lg.Warn(
-			"invalid access for a guest role on key",
-			zap.String("role-name", v2auth.GuestRoleName),
-			zap.String("key", key),
-		)
-	} else {
-		plog.Warningf("auth: invalid access for unauthenticated user on resource %s.", key)
-	}
-	return false
-}
-
-func writeNoAuth(lg *zap.Logger, w http.ResponseWriter, r *http.Request) {
-	herr := httptypes.NewHTTPError(http.StatusUnauthorized, "Insufficient credentials")
-	if err := herr.WriteTo(w); err != nil {
-		if lg != nil {
-			lg.Debug(
-				"failed to write v2 HTTP error",
-				zap.String("remote-addr", r.RemoteAddr),
-				zap.Error(err),
-			)
-		} else {
-			plog.Debugf("error writing HTTPError (%v) to %s", err, r.RemoteAddr)
-		}
-	}
-}
-
-func handleAuth(mux *http.ServeMux, sh *authHandler) {
-	mux.HandleFunc(authPrefix+"/roles", authCapabilityHandler(sh.baseRoles))
-	mux.HandleFunc(authPrefix+"/roles/", authCapabilityHandler(sh.handleRoles))
-	mux.HandleFunc(authPrefix+"/users", authCapabilityHandler(sh.baseUsers))
-	mux.HandleFunc(authPrefix+"/users/", authCapabilityHandler(sh.handleUsers))
-	mux.HandleFunc(authPrefix+"/enable", authCapabilityHandler(sh.enableDisable))
-}
-
-func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	if !hasRootAccess(sh.lg, sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(sh.lg, w, r)
-		return
-	}
-
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	roles, err := sh.sec.AllRoles()
-	if err != nil {
-		writeError(sh.lg, w, r, err)
-		return
-	}
-	if roles == nil {
-		roles = make([]string, 0)
-	}
-
-	err = r.ParseForm()
-	if err != nil {
-		writeError(sh.lg, w, r, err)
-		return
-	}
-
-	var rolesCollections struct {
-		Roles []v2auth.Role `json:"roles"`
-	}
-	for _, roleName := range roles {
-		var role v2auth.Role
-		role, err = sh.sec.GetRole(roleName)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-		rolesCollections.Roles = append(rolesCollections.Roles, role)
-	}
-	err = json.NewEncoder(w).Encode(rolesCollections)
-
-	if err != nil {
-		if sh.lg != nil {
-			sh.lg.Warn(
-				"failed to encode base roles",
-				zap.String("url", r.URL.String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Warningf("baseRoles error encoding on %s", r.URL)
-		}
-		writeError(sh.lg, w, r, err)
-		return
-	}
-}
-
-func (sh *authHandler) handleRoles(w http.ResponseWriter, r *http.Request) {
-	subpath := path.Clean(r.URL.Path[len(authPrefix):])
-	// Split "/roles/rolename/command".
-	// First item is an empty string, second is "roles"
-	pieces := strings.Split(subpath, "/")
-	if len(pieces) == 2 {
-		sh.baseRoles(w, r)
-		return
-	}
-	if len(pieces) != 3 {
-		writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid path"))
-		return
-	}
-	sh.forRole(w, r, pieces[2])
-}
-
-func (sh *authHandler) forRole(w http.ResponseWriter, r *http.Request, role string) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasRootAccess(sh.lg, sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(sh.lg, w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	switch r.Method {
-	case "GET":
-		data, err := sh.sec.GetRole(role)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-		err = json.NewEncoder(w).Encode(data)
-		if err != nil {
-			if sh.lg != nil {
-				sh.lg.Warn(
-					"failed to encode a role",
-					zap.String("url", r.URL.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("forRole error encoding on %s", r.URL)
-			}
-			return
-		}
-		return
-
-	case "PUT":
-		var in v2auth.Role
-		err := json.NewDecoder(r.Body).Decode(&in)
-		if err != nil {
-			writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
-			return
-		}
-		if in.Role != role {
-			writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON name does not match the name in the URL"))
-			return
-		}
-
-		var out v2auth.Role
-
-		// create
-		if in.Grant.IsEmpty() && in.Revoke.IsEmpty() {
-			err = sh.sec.CreateRole(in)
-			if err != nil {
-				writeError(sh.lg, w, r, err)
-				return
-			}
-			w.WriteHeader(http.StatusCreated)
-			out = in
-		} else {
-			if !in.Permissions.IsEmpty() {
-				writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON contains both permissions and grant/revoke"))
-				return
-			}
-			out, err = sh.sec.UpdateRole(in)
-			if err != nil {
-				writeError(sh.lg, w, r, err)
-				return
-			}
-			w.WriteHeader(http.StatusOK)
-		}
-
-		err = json.NewEncoder(w).Encode(out)
-		if err != nil {
-			if sh.lg != nil {
-				sh.lg.Warn(
-					"failed to encode a role",
-					zap.String("url", r.URL.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("forRole error encoding on %s", r.URL)
-			}
-			return
-		}
-		return
-
-	case "DELETE":
-		err := sh.sec.DeleteRole(role)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-	}
-}
-
-type userWithRoles struct {
-	User  string        `json:"user"`
-	Roles []v2auth.Role `json:"roles,omitempty"`
-}
-
-type usersCollections struct {
-	Users []userWithRoles `json:"users"`
-}
-
-func (sh *authHandler) baseUsers(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET") {
-		return
-	}
-	if !hasRootAccess(sh.lg, sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(sh.lg, w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	users, err := sh.sec.AllUsers()
-	if err != nil {
-		writeError(sh.lg, w, r, err)
-		return
-	}
-	if users == nil {
-		users = make([]string, 0)
-	}
-
-	err = r.ParseForm()
-	if err != nil {
-		writeError(sh.lg, w, r, err)
-		return
-	}
-
-	ucs := usersCollections{}
-	for _, userName := range users {
-		var user v2auth.User
-		user, err = sh.sec.GetUser(userName)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-
-		uwr := userWithRoles{User: user.User}
-		for _, roleName := range user.Roles {
-			var role v2auth.Role
-			role, err = sh.sec.GetRole(roleName)
-			if err != nil {
-				continue
-			}
-			uwr.Roles = append(uwr.Roles, role)
-		}
-
-		ucs.Users = append(ucs.Users, uwr)
-	}
-	err = json.NewEncoder(w).Encode(ucs)
-
-	if err != nil {
-		if sh.lg != nil {
-			sh.lg.Warn(
-				"failed to encode users",
-				zap.String("url", r.URL.String()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Warningf("baseUsers error encoding on %s", r.URL)
-		}
-		writeError(sh.lg, w, r, err)
-		return
-	}
-}
-
-func (sh *authHandler) handleUsers(w http.ResponseWriter, r *http.Request) {
-	subpath := path.Clean(r.URL.Path[len(authPrefix):])
-	// Split "/users/username".
-	// First item is an empty string, second is "users"
-	pieces := strings.Split(subpath, "/")
-	if len(pieces) == 2 {
-		sh.baseUsers(w, r)
-		return
-	}
-	if len(pieces) != 3 {
-		writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid path"))
-		return
-	}
-	sh.forUser(w, r, pieces[2])
-}
-
-func (sh *authHandler) forUser(w http.ResponseWriter, r *http.Request, user string) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasRootAccess(sh.lg, sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(sh.lg, w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-
-	switch r.Method {
-	case "GET":
-		u, err := sh.sec.GetUser(user)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-
-		err = r.ParseForm()
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-
-		uwr := userWithRoles{User: u.User}
-		for _, roleName := range u.Roles {
-			var role v2auth.Role
-			role, err = sh.sec.GetRole(roleName)
-			if err != nil {
-				writeError(sh.lg, w, r, err)
-				return
-			}
-			uwr.Roles = append(uwr.Roles, role)
-		}
-		err = json.NewEncoder(w).Encode(uwr)
-
-		if err != nil {
-			if sh.lg != nil {
-				sh.lg.Warn(
-					"failed to encode roles",
-					zap.String("url", r.URL.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("forUser error encoding on %s", r.URL)
-			}
-			return
-		}
-		return
-
-	case "PUT":
-		var u v2auth.User
-		err := json.NewDecoder(r.Body).Decode(&u)
-		if err != nil {
-			writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "Invalid JSON in request body."))
-			return
-		}
-		if u.User != user {
-			writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON name does not match the name in the URL"))
-			return
-		}
-
-		var (
-			out     v2auth.User
-			created bool
-		)
-
-		if len(u.Grant) == 0 && len(u.Revoke) == 0 {
-			// create or update
-			if len(u.Roles) != 0 {
-				out, err = sh.sec.CreateUser(u)
-			} else {
-				// if user passes in both password and roles, we are unsure about his/her
-				// intention.
-				out, created, err = sh.sec.CreateOrUpdateUser(u)
-			}
-
-			if err != nil {
-				writeError(sh.lg, w, r, err)
-				return
-			}
-		} else {
-			// update case
-			if len(u.Roles) != 0 {
-				writeError(sh.lg, w, r, httptypes.NewHTTPError(http.StatusBadRequest, "User JSON contains both roles and grant/revoke"))
-				return
-			}
-			out, err = sh.sec.UpdateUser(u)
-			if err != nil {
-				writeError(sh.lg, w, r, err)
-				return
-			}
-		}
-
-		if created {
-			w.WriteHeader(http.StatusCreated)
-		} else {
-			w.WriteHeader(http.StatusOK)
-		}
-
-		out.Password = ""
-
-		err = json.NewEncoder(w).Encode(out)
-		if err != nil {
-			if sh.lg != nil {
-				sh.lg.Warn(
-					"failed to encode a user",
-					zap.String("url", r.URL.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("forUser error encoding on %s", r.URL)
-			}
-			return
-		}
-		return
-
-	case "DELETE":
-		err := sh.sec.DeleteUser(user)
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-	}
-}
-
-type enabled struct {
-	Enabled bool `json:"enabled"`
-}
-
-func (sh *authHandler) enableDisable(w http.ResponseWriter, r *http.Request) {
-	if !allowMethod(w, r.Method, "GET", "PUT", "DELETE") {
-		return
-	}
-	if !hasWriteRootAccess(sh.lg, sh.sec, r, sh.clientCertAuthEnabled) {
-		writeNoAuth(sh.lg, w, r)
-		return
-	}
-	w.Header().Set("X-Etcd-Cluster-ID", sh.cluster.ID().String())
-	w.Header().Set("Content-Type", "application/json")
-	isEnabled := sh.sec.AuthEnabled()
-	switch r.Method {
-	case "GET":
-		jsonDict := enabled{isEnabled}
-		err := json.NewEncoder(w).Encode(jsonDict)
-		if err != nil {
-			if sh.lg != nil {
-				sh.lg.Warn(
-					"failed to encode a auth state",
-					zap.String("url", r.URL.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("error encoding auth state on %s", r.URL)
-			}
-		}
-
-	case "PUT":
-		err := sh.sec.EnableAuth()
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-
-	case "DELETE":
-		err := sh.sec.DisableAuth()
-		if err != nil {
-			writeError(sh.lg, w, r, err)
-			return
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/doc.go
deleted file mode 100644
index 475c4b1..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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 v2http provides etcd client and server implementations.
-package v2http
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/http.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/http.go
deleted file mode 100644
index c695689..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/http.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2015 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 v2http
-
-import (
-	"math"
-	"net/http"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/etcdhttp"
-	"go.etcd.io/etcd/etcdserver/api/v2auth"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-	"go.etcd.io/etcd/pkg/logutil"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-)
-
-const (
-	// time to wait for a Watch request
-	defaultWatchTimeout = time.Duration(math.MaxInt64)
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/v2http")
-	mlog = logutil.NewMergeLogger(plog)
-)
-
-func writeError(lg *zap.Logger, w http.ResponseWriter, r *http.Request, err error) {
-	if err == nil {
-		return
-	}
-	if e, ok := err.(v2auth.Error); ok {
-		herr := httptypes.NewHTTPError(e.HTTPStatus(), e.Error())
-		if et := herr.WriteTo(w); et != nil {
-			if lg != nil {
-				lg.Debug(
-					"failed to write v2 HTTP error",
-					zap.String("remote-addr", r.RemoteAddr),
-					zap.String("v2auth-error", e.Error()),
-					zap.Error(et),
-				)
-			} else {
-				plog.Debugf("error writing HTTPError (%v) to %s", et, r.RemoteAddr)
-			}
-		}
-		return
-	}
-	etcdhttp.WriteError(lg, w, r, err)
-}
-
-// allowMethod verifies that the given method is one of the allowed methods,
-// and if not, it writes an error to w.  A boolean is returned indicating
-// whether or not the method is allowed.
-func allowMethod(w http.ResponseWriter, m string, ms ...string) bool {
-	for _, meth := range ms {
-		if m == meth {
-			return true
-		}
-	}
-	w.Header().Set("Allow", strings.Join(ms, ","))
-	http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-	return false
-}
-
-func requestLogger(lg *zap.Logger, handler http.Handler) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if lg != nil {
-			lg.Debug(
-				"handling HTTP request",
-				zap.String("method", r.Method),
-				zap.String("request-uri", r.RequestURI),
-				zap.String("remote-addr", r.RemoteAddr),
-			)
-		} else {
-			plog.Debugf("[%s] %s remote:%s", r.Method, r.RequestURI, r.RemoteAddr)
-		}
-		handler.ServeHTTP(w, r)
-	})
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/errors.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/errors.go
deleted file mode 100644
index 245c089..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/errors.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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 httptypes
-
-import (
-	"encoding/json"
-	"net/http"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/v2http/httptypes")
-)
-
-type HTTPError struct {
-	Message string `json:"message"`
-	// Code is the HTTP status code
-	Code int `json:"-"`
-}
-
-func (e HTTPError) Error() string {
-	return e.Message
-}
-
-func (e HTTPError) WriteTo(w http.ResponseWriter) error {
-	w.Header().Set("Content-Type", "application/json")
-	w.WriteHeader(e.Code)
-	b, err := json.Marshal(e)
-	if err != nil {
-		plog.Panicf("marshal HTTPError should never fail (%v)", err)
-	}
-	if _, err := w.Write(b); err != nil {
-		return err
-	}
-	return nil
-}
-
-func NewHTTPError(code int, m string) *HTTPError {
-	return &HTTPError{
-		Message: m,
-		Code:    code,
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/member.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/member.go
deleted file mode 100644
index 95fd443..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/httptypes/member.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2015 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 httptypes defines how etcd's HTTP API entities are serialized to and
-// deserialized from JSON.
-package httptypes
-
-import (
-	"encoding/json"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-type Member struct {
-	ID         string   `json:"id"`
-	Name       string   `json:"name"`
-	PeerURLs   []string `json:"peerURLs"`
-	ClientURLs []string `json:"clientURLs"`
-}
-
-type MemberCreateRequest struct {
-	PeerURLs types.URLs
-}
-
-type MemberUpdateRequest struct {
-	MemberCreateRequest
-}
-
-func (m *MemberCreateRequest) UnmarshalJSON(data []byte) error {
-	s := struct {
-		PeerURLs []string `json:"peerURLs"`
-	}{}
-
-	err := json.Unmarshal(data, &s)
-	if err != nil {
-		return err
-	}
-
-	urls, err := types.NewURLs(s.PeerURLs)
-	if err != nil {
-		return err
-	}
-
-	m.PeerURLs = urls
-	return nil
-}
-
-type MemberCollection []Member
-
-func (c *MemberCollection) MarshalJSON() ([]byte, error) {
-	d := struct {
-		Members []Member `json:"members"`
-	}{
-		Members: []Member(*c),
-	}
-
-	return json.Marshal(d)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2http/metrics.go
deleted file mode 100644
index 14f7da0..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2http/metrics.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2015 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 v2http
-
-import (
-	"strconv"
-	"time"
-
-	"net/http"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/api/v2http/httptypes"
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	incomingEvents = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "received_total",
-			Help:      "Counter of requests received into the system (successfully parsed and authd).",
-		}, []string{"method"})
-
-	failedEvents = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "failed_total",
-			Help:      "Counter of handle failures of requests (non-watches), by method (GET/PUT etc.) and code (400, 500 etc.).",
-		}, []string{"method", "code"})
-
-	successfulEventsHandlingSec = prometheus.NewHistogramVec(
-		prometheus.HistogramOpts{
-			Namespace: "etcd",
-			Subsystem: "http",
-			Name:      "successful_duration_seconds",
-			Help:      "Bucketed histogram of processing time (s) of successfully handled requests (non-watches), by method (GET/PUT etc.).",
-
-			// lowest bucket start of upper bound 0.0005 sec (0.5 ms) with factor 2
-			// highest bucket start of 0.0005 sec * 2^12 == 2.048 sec
-			Buckets: prometheus.ExponentialBuckets(0.0005, 2, 13),
-		}, []string{"method"})
-)
-
-func init() {
-	prometheus.MustRegister(incomingEvents)
-	prometheus.MustRegister(failedEvents)
-	prometheus.MustRegister(successfulEventsHandlingSec)
-}
-
-func reportRequestReceived(request etcdserverpb.Request) {
-	incomingEvents.WithLabelValues(methodFromRequest(request)).Inc()
-}
-
-func reportRequestCompleted(request etcdserverpb.Request, startTime time.Time) {
-	method := methodFromRequest(request)
-	successfulEventsHandlingSec.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
-}
-
-func reportRequestFailed(request etcdserverpb.Request, err error) {
-	method := methodFromRequest(request)
-	failedEvents.WithLabelValues(method, strconv.Itoa(codeFromError(err))).Inc()
-}
-
-func methodFromRequest(request etcdserverpb.Request) string {
-	if request.Method == "GET" && request.Quorum {
-		return "QGET"
-	}
-	return request.Method
-}
-
-func codeFromError(err error) int {
-	if err == nil {
-		return http.StatusInternalServerError
-	}
-	switch e := err.(type) {
-	case *v2error.Error:
-		return e.StatusCode()
-	case *httptypes.HTTPError:
-		return e.Code
-	default:
-		return http.StatusInternalServerError
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/leader.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/leader.go
deleted file mode 100644
index ca47f0f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/leader.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 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 v2stats
-
-import (
-	"encoding/json"
-	"math"
-	"sync"
-	"time"
-)
-
-// LeaderStats is used by the leader in an etcd cluster, and encapsulates
-// statistics about communication with its followers
-type LeaderStats struct {
-	leaderStats
-	sync.Mutex
-}
-
-type leaderStats struct {
-	// Leader is the ID of the leader in the etcd cluster.
-	// TODO(jonboulle): clarify that these are IDs, not names
-	Leader    string                    `json:"leader"`
-	Followers map[string]*FollowerStats `json:"followers"`
-}
-
-// NewLeaderStats generates a new LeaderStats with the given id as leader
-func NewLeaderStats(id string) *LeaderStats {
-	return &LeaderStats{
-		leaderStats: leaderStats{
-			Leader:    id,
-			Followers: make(map[string]*FollowerStats),
-		},
-	}
-}
-
-func (ls *LeaderStats) JSON() []byte {
-	ls.Lock()
-	stats := ls.leaderStats
-	ls.Unlock()
-	b, err := json.Marshal(stats)
-	// TODO(jonboulle): appropriate error handling?
-	if err != nil {
-		plog.Errorf("error marshalling leader stats (%v)", err)
-	}
-	return b
-}
-
-func (ls *LeaderStats) Follower(name string) *FollowerStats {
-	ls.Lock()
-	defer ls.Unlock()
-	fs, ok := ls.Followers[name]
-	if !ok {
-		fs = &FollowerStats{}
-		fs.Latency.Minimum = 1 << 63
-		ls.Followers[name] = fs
-	}
-	return fs
-}
-
-// FollowerStats encapsulates various statistics about a follower in an etcd cluster
-type FollowerStats struct {
-	Latency LatencyStats `json:"latency"`
-	Counts  CountsStats  `json:"counts"`
-
-	sync.Mutex
-}
-
-// LatencyStats encapsulates latency statistics.
-type LatencyStats struct {
-	Current           float64 `json:"current"`
-	Average           float64 `json:"average"`
-	averageSquare     float64
-	StandardDeviation float64 `json:"standardDeviation"`
-	Minimum           float64 `json:"minimum"`
-	Maximum           float64 `json:"maximum"`
-}
-
-// CountsStats encapsulates raft statistics.
-type CountsStats struct {
-	Fail    uint64 `json:"fail"`
-	Success uint64 `json:"success"`
-}
-
-// Succ updates the FollowerStats with a successful send
-func (fs *FollowerStats) Succ(d time.Duration) {
-	fs.Lock()
-	defer fs.Unlock()
-
-	total := float64(fs.Counts.Success) * fs.Latency.Average
-	totalSquare := float64(fs.Counts.Success) * fs.Latency.averageSquare
-
-	fs.Counts.Success++
-
-	fs.Latency.Current = float64(d) / (1000000.0)
-
-	if fs.Latency.Current > fs.Latency.Maximum {
-		fs.Latency.Maximum = fs.Latency.Current
-	}
-
-	if fs.Latency.Current < fs.Latency.Minimum {
-		fs.Latency.Minimum = fs.Latency.Current
-	}
-
-	fs.Latency.Average = (total + fs.Latency.Current) / float64(fs.Counts.Success)
-	fs.Latency.averageSquare = (totalSquare + fs.Latency.Current*fs.Latency.Current) / float64(fs.Counts.Success)
-
-	// sdv = sqrt(avg(x^2) - avg(x)^2)
-	fs.Latency.StandardDeviation = math.Sqrt(fs.Latency.averageSquare - fs.Latency.Average*fs.Latency.Average)
-}
-
-// Fail updates the FollowerStats with an unsuccessful send
-func (fs *FollowerStats) Fail() {
-	fs.Lock()
-	defer fs.Unlock()
-	fs.Counts.Fail++
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/queue.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/queue.go
deleted file mode 100644
index 2c3dff3..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/queue.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2015 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 v2stats
-
-import (
-	"sync"
-	"time"
-)
-
-const (
-	queueCapacity = 200
-)
-
-// RequestStats represent the stats for a request.
-// It encapsulates the sending time and the size of the request.
-type RequestStats struct {
-	SendingTime time.Time
-	Size        int
-}
-
-type statsQueue struct {
-	items        [queueCapacity]*RequestStats
-	size         int
-	front        int
-	back         int
-	totalReqSize int
-	rwl          sync.RWMutex
-}
-
-func (q *statsQueue) Len() int {
-	return q.size
-}
-
-func (q *statsQueue) ReqSize() int {
-	return q.totalReqSize
-}
-
-// FrontAndBack gets the front and back elements in the queue
-// We must grab front and back together with the protection of the lock
-func (q *statsQueue) frontAndBack() (*RequestStats, *RequestStats) {
-	q.rwl.RLock()
-	defer q.rwl.RUnlock()
-	if q.size != 0 {
-		return q.items[q.front], q.items[q.back]
-	}
-	return nil, nil
-}
-
-// Insert function insert a RequestStats into the queue and update the records
-func (q *statsQueue) Insert(p *RequestStats) {
-	q.rwl.Lock()
-	defer q.rwl.Unlock()
-
-	q.back = (q.back + 1) % queueCapacity
-
-	if q.size == queueCapacity { //dequeue
-		q.totalReqSize -= q.items[q.front].Size
-		q.front = (q.back + 1) % queueCapacity
-	} else {
-		q.size++
-	}
-
-	q.items[q.back] = p
-	q.totalReqSize += q.items[q.back].Size
-
-}
-
-// Rate function returns the package rate and byte rate
-func (q *statsQueue) Rate() (float64, float64) {
-	front, back := q.frontAndBack()
-
-	if front == nil || back == nil {
-		return 0, 0
-	}
-
-	if time.Since(back.SendingTime) > time.Second {
-		q.Clear()
-		return 0, 0
-	}
-
-	sampleDuration := back.SendingTime.Sub(front.SendingTime)
-
-	pr := float64(q.Len()) / float64(sampleDuration) * float64(time.Second)
-
-	br := float64(q.ReqSize()) / float64(sampleDuration) * float64(time.Second)
-
-	return pr, br
-}
-
-// Clear function clear up the statsQueue
-func (q *statsQueue) Clear() {
-	q.rwl.Lock()
-	defer q.rwl.Unlock()
-	q.back = -1
-	q.front = 0
-	q.size = 0
-	q.totalReqSize = 0
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/server.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/server.go
deleted file mode 100644
index c4accc7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/server.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2015 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 v2stats
-
-import (
-	"encoding/json"
-	"log"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/raft"
-)
-
-// ServerStats encapsulates various statistics about an EtcdServer and its
-// communication with other members of the cluster
-type ServerStats struct {
-	serverStats
-	sync.Mutex
-}
-
-func NewServerStats(name, id string) *ServerStats {
-	ss := &ServerStats{
-		serverStats: serverStats{
-			Name: name,
-			ID:   id,
-		},
-	}
-	now := time.Now()
-	ss.StartTime = now
-	ss.LeaderInfo.StartTime = now
-	ss.sendRateQueue = &statsQueue{back: -1}
-	ss.recvRateQueue = &statsQueue{back: -1}
-	return ss
-}
-
-type serverStats struct {
-	Name string `json:"name"`
-	// ID is the raft ID of the node.
-	// TODO(jonboulle): use ID instead of name?
-	ID        string         `json:"id"`
-	State     raft.StateType `json:"state"`
-	StartTime time.Time      `json:"startTime"`
-
-	LeaderInfo struct {
-		Name      string    `json:"leader"`
-		Uptime    string    `json:"uptime"`
-		StartTime time.Time `json:"startTime"`
-	} `json:"leaderInfo"`
-
-	RecvAppendRequestCnt uint64  `json:"recvAppendRequestCnt,"`
-	RecvingPkgRate       float64 `json:"recvPkgRate,omitempty"`
-	RecvingBandwidthRate float64 `json:"recvBandwidthRate,omitempty"`
-
-	SendAppendRequestCnt uint64  `json:"sendAppendRequestCnt"`
-	SendingPkgRate       float64 `json:"sendPkgRate,omitempty"`
-	SendingBandwidthRate float64 `json:"sendBandwidthRate,omitempty"`
-
-	sendRateQueue *statsQueue
-	recvRateQueue *statsQueue
-}
-
-func (ss *ServerStats) JSON() []byte {
-	ss.Lock()
-	stats := ss.serverStats
-	stats.SendingPkgRate, stats.SendingBandwidthRate = stats.sendRateQueue.Rate()
-	stats.RecvingPkgRate, stats.RecvingBandwidthRate = stats.recvRateQueue.Rate()
-	stats.LeaderInfo.Uptime = time.Since(stats.LeaderInfo.StartTime).String()
-	ss.Unlock()
-	b, err := json.Marshal(stats)
-	// TODO(jonboulle): appropriate error handling?
-	if err != nil {
-		log.Printf("stats: error marshalling server stats: %v", err)
-	}
-	return b
-}
-
-// RecvAppendReq updates the ServerStats in response to an AppendRequest
-// from the given leader being received
-func (ss *ServerStats) RecvAppendReq(leader string, reqSize int) {
-	ss.Lock()
-	defer ss.Unlock()
-
-	now := time.Now()
-
-	ss.State = raft.StateFollower
-	if leader != ss.LeaderInfo.Name {
-		ss.LeaderInfo.Name = leader
-		ss.LeaderInfo.StartTime = now
-	}
-
-	ss.recvRateQueue.Insert(
-		&RequestStats{
-			SendingTime: now,
-			Size:        reqSize,
-		},
-	)
-	ss.RecvAppendRequestCnt++
-}
-
-// SendAppendReq updates the ServerStats in response to an AppendRequest
-// being sent by this server
-func (ss *ServerStats) SendAppendReq(reqSize int) {
-	ss.Lock()
-	defer ss.Unlock()
-
-	ss.becomeLeader()
-
-	ss.sendRateQueue.Insert(
-		&RequestStats{
-			SendingTime: time.Now(),
-			Size:        reqSize,
-		},
-	)
-
-	ss.SendAppendRequestCnt++
-}
-
-func (ss *ServerStats) BecomeLeader() {
-	ss.Lock()
-	defer ss.Unlock()
-	ss.becomeLeader()
-}
-
-func (ss *ServerStats) becomeLeader() {
-	if ss.State != raft.StateLeader {
-		ss.State = raft.StateLeader
-		ss.LeaderInfo.Name = ss.ID
-		ss.LeaderInfo.StartTime = time.Now()
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/stats.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/stats.go
deleted file mode 100644
index c50a200..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2stats/stats.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 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 v2stats defines a standard interface for etcd cluster statistics.
-package v2stats
-
-import "github.com/coreos/pkg/capnslog"
-
-var plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/stats")
-
-type Stats interface {
-	// SelfStats returns the struct representing statistics of this server
-	SelfStats() []byte
-	// LeaderStats returns the statistics of all followers in the cluster
-	// if this server is leader. Otherwise, nil is returned.
-	LeaderStats() []byte
-	// StoreStats returns statistics of the store backing this EtcdServer
-	StoreStats() []byte
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/doc.go
deleted file mode 100644
index 1933e4c..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/doc.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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 v2store defines etcd's in-memory key/value store in v2 API.
-// To be deprecated in favor of v3 storage.
-package v2store
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event.go
deleted file mode 100644
index 33e9017..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 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 v2store
-
-const (
-	Get              = "get"
-	Create           = "create"
-	Set              = "set"
-	Update           = "update"
-	Delete           = "delete"
-	CompareAndSwap   = "compareAndSwap"
-	CompareAndDelete = "compareAndDelete"
-	Expire           = "expire"
-)
-
-type Event struct {
-	Action    string      `json:"action"`
-	Node      *NodeExtern `json:"node,omitempty"`
-	PrevNode  *NodeExtern `json:"prevNode,omitempty"`
-	EtcdIndex uint64      `json:"-"`
-	Refresh   bool        `json:"refresh,omitempty"`
-}
-
-func newEvent(action string, key string, modifiedIndex, createdIndex uint64) *Event {
-	n := &NodeExtern{
-		Key:           key,
-		ModifiedIndex: modifiedIndex,
-		CreatedIndex:  createdIndex,
-	}
-
-	return &Event{
-		Action: action,
-		Node:   n,
-	}
-}
-
-func (e *Event) IsCreated() bool {
-	if e.Action == Create {
-		return true
-	}
-	return e.Action == Set && e.PrevNode == nil
-}
-
-func (e *Event) Index() uint64 {
-	return e.Node.ModifiedIndex
-}
-
-func (e *Event) Clone() *Event {
-	return &Event{
-		Action:    e.Action,
-		EtcdIndex: e.EtcdIndex,
-		Node:      e.Node.Clone(),
-		PrevNode:  e.PrevNode.Clone(),
-	}
-}
-
-func (e *Event) SetRefresh() {
-	e.Refresh = true
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_history.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_history.go
deleted file mode 100644
index e4a969f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_history.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"fmt"
-	"path"
-	"strings"
-	"sync"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-)
-
-type EventHistory struct {
-	Queue      eventQueue
-	StartIndex uint64
-	LastIndex  uint64
-	rwl        sync.RWMutex
-}
-
-func newEventHistory(capacity int) *EventHistory {
-	return &EventHistory{
-		Queue: eventQueue{
-			Capacity: capacity,
-			Events:   make([]*Event, capacity),
-		},
-	}
-}
-
-// addEvent function adds event into the eventHistory
-func (eh *EventHistory) addEvent(e *Event) *Event {
-	eh.rwl.Lock()
-	defer eh.rwl.Unlock()
-
-	eh.Queue.insert(e)
-
-	eh.LastIndex = e.Index()
-
-	eh.StartIndex = eh.Queue.Events[eh.Queue.Front].Index()
-
-	return e
-}
-
-// scan enumerates events from the index history and stops at the first point
-// where the key matches.
-func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event, *v2error.Error) {
-	eh.rwl.RLock()
-	defer eh.rwl.RUnlock()
-
-	// index should be after the event history's StartIndex
-	if index < eh.StartIndex {
-		return nil,
-			v2error.NewError(v2error.EcodeEventIndexCleared,
-				fmt.Sprintf("the requested history has been cleared [%v/%v]",
-					eh.StartIndex, index), 0)
-	}
-
-	// the index should come before the size of the queue minus the duplicate count
-	if index > eh.LastIndex { // future index
-		return nil, nil
-	}
-
-	offset := index - eh.StartIndex
-	i := (eh.Queue.Front + int(offset)) % eh.Queue.Capacity
-
-	for {
-		e := eh.Queue.Events[i]
-
-		if !e.Refresh {
-			ok := e.Node.Key == key
-
-			if recursive {
-				// add tailing slash
-				nkey := path.Clean(key)
-				if nkey[len(nkey)-1] != '/' {
-					nkey = nkey + "/"
-				}
-
-				ok = ok || strings.HasPrefix(e.Node.Key, nkey)
-			}
-
-			if (e.Action == Delete || e.Action == Expire) && e.PrevNode != nil && e.PrevNode.Dir {
-				ok = ok || strings.HasPrefix(key, e.PrevNode.Key)
-			}
-
-			if ok {
-				return e, nil
-			}
-		}
-
-		i = (i + 1) % eh.Queue.Capacity
-
-		if i == eh.Queue.Back {
-			return nil, nil
-		}
-	}
-}
-
-// clone will be protected by a stop-world lock
-// do not need to obtain internal lock
-func (eh *EventHistory) clone() *EventHistory {
-	clonedQueue := eventQueue{
-		Capacity: eh.Queue.Capacity,
-		Events:   make([]*Event, eh.Queue.Capacity),
-		Size:     eh.Queue.Size,
-		Front:    eh.Queue.Front,
-		Back:     eh.Queue.Back,
-	}
-
-	copy(clonedQueue.Events, eh.Queue.Events)
-	return &EventHistory{
-		StartIndex: eh.StartIndex,
-		Queue:      clonedQueue,
-		LastIndex:  eh.LastIndex,
-	}
-
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_queue.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_queue.go
deleted file mode 100644
index 7ea03de..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/event_queue.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 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 v2store
-
-type eventQueue struct {
-	Events   []*Event
-	Size     int
-	Front    int
-	Back     int
-	Capacity int
-}
-
-func (eq *eventQueue) insert(e *Event) {
-	eq.Events[eq.Back] = e
-	eq.Back = (eq.Back + 1) % eq.Capacity
-
-	if eq.Size == eq.Capacity { //dequeue
-		eq.Front = (eq.Front + 1) % eq.Capacity
-	} else {
-		eq.Size++
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/metrics.go
deleted file mode 100644
index 5adea1e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/metrics.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2015 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 v2store
-
-import "github.com/prometheus/client_golang/prometheus"
-
-// Set of raw Prometheus metrics.
-// Labels
-// * action = declared in event.go
-// * outcome = Outcome
-// Do not increment directly, use Report* methods.
-var (
-	readCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "reads_total",
-			Help:      "Total number of reads action by (get/getRecursive), local to this member.",
-		}, []string{"action"})
-
-	writeCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "writes_total",
-			Help:      "Total number of writes (e.g. set/compareAndDelete) seen by this member.",
-		}, []string{"action"})
-
-	readFailedCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "reads_failed_total",
-			Help:      "Failed read actions by (get/getRecursive), local to this member.",
-		}, []string{"action"})
-
-	writeFailedCounter = prometheus.NewCounterVec(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "writes_failed_total",
-			Help:      "Failed write actions (e.g. set/compareAndDelete), seen by this member.",
-		}, []string{"action"})
-
-	expireCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "expires_total",
-			Help:      "Total number of expired keys.",
-		})
-
-	watchRequests = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "watch_requests_total",
-			Help:      "Total number of incoming watch requests (new or reestablished).",
-		})
-
-	watcherCount = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "store",
-			Name:      "watchers",
-			Help:      "Count of currently active watchers.",
-		})
-)
-
-const (
-	GetRecursive = "getRecursive"
-)
-
-func init() {
-	if prometheus.Register(readCounter) != nil {
-		// Tests will try to double register since the tests use both
-		// store and store_test packages; ignore second attempts.
-		return
-	}
-	prometheus.MustRegister(writeCounter)
-	prometheus.MustRegister(expireCounter)
-	prometheus.MustRegister(watchRequests)
-	prometheus.MustRegister(watcherCount)
-}
-
-func reportReadSuccess(readAction string) {
-	readCounter.WithLabelValues(readAction).Inc()
-}
-
-func reportReadFailure(readAction string) {
-	readCounter.WithLabelValues(readAction).Inc()
-	readFailedCounter.WithLabelValues(readAction).Inc()
-}
-
-func reportWriteSuccess(writeAction string) {
-	writeCounter.WithLabelValues(writeAction).Inc()
-}
-
-func reportWriteFailure(writeAction string) {
-	writeCounter.WithLabelValues(writeAction).Inc()
-	writeFailedCounter.WithLabelValues(writeAction).Inc()
-}
-
-func reportExpiredKey() {
-	expireCounter.Inc()
-}
-
-func reportWatchRequest() {
-	watchRequests.Inc()
-}
-
-func reportWatcherAdded() {
-	watcherCount.Inc()
-}
-
-func reportWatcherRemoved() {
-	watcherCount.Dec()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node.go
deleted file mode 100644
index 38a6984..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node.go
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"path"
-	"sort"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// explanations of Compare function result
-const (
-	CompareMatch = iota
-	CompareIndexNotMatch
-	CompareValueNotMatch
-	CompareNotMatch
-)
-
-var Permanent time.Time
-
-// node is the basic element in the store system.
-// A key-value pair will have a string value
-// A directory will have a children map
-type node struct {
-	Path string
-
-	CreatedIndex  uint64
-	ModifiedIndex uint64
-
-	Parent *node `json:"-"` // should not encode this field! avoid circular dependency.
-
-	ExpireTime time.Time
-	Value      string           // for key-value pair
-	Children   map[string]*node // for directory
-
-	// A reference to the store this node is attached to.
-	store *store
-}
-
-// newKV creates a Key-Value pair
-func newKV(store *store, nodePath string, value string, createdIndex uint64, parent *node, expireTime time.Time) *node {
-	return &node{
-		Path:          nodePath,
-		CreatedIndex:  createdIndex,
-		ModifiedIndex: createdIndex,
-		Parent:        parent,
-		store:         store,
-		ExpireTime:    expireTime,
-		Value:         value,
-	}
-}
-
-// newDir creates a directory
-func newDir(store *store, nodePath string, createdIndex uint64, parent *node, expireTime time.Time) *node {
-	return &node{
-		Path:          nodePath,
-		CreatedIndex:  createdIndex,
-		ModifiedIndex: createdIndex,
-		Parent:        parent,
-		ExpireTime:    expireTime,
-		Children:      make(map[string]*node),
-		store:         store,
-	}
-}
-
-// IsHidden function checks if the node is a hidden node. A hidden node
-// will begin with '_'
-// A hidden node will not be shown via get command under a directory
-// For example if we have /foo/_hidden and /foo/notHidden, get "/foo"
-// will only return /foo/notHidden
-func (n *node) IsHidden() bool {
-	_, name := path.Split(n.Path)
-
-	return name[0] == '_'
-}
-
-// IsPermanent function checks if the node is a permanent one.
-func (n *node) IsPermanent() bool {
-	// we use a uninitialized time.Time to indicate the node is a
-	// permanent one.
-	// the uninitialized time.Time should equal zero.
-	return n.ExpireTime.IsZero()
-}
-
-// IsDir function checks whether the node is a directory.
-// If the node is a directory, the function will return true.
-// Otherwise the function will return false.
-func (n *node) IsDir() bool {
-	return n.Children != nil
-}
-
-// Read function gets the value of the node.
-// If the receiver node is not a key-value pair, a "Not A File" error will be returned.
-func (n *node) Read() (string, *v2error.Error) {
-	if n.IsDir() {
-		return "", v2error.NewError(v2error.EcodeNotFile, "", n.store.CurrentIndex)
-	}
-
-	return n.Value, nil
-}
-
-// Write function set the value of the node to the given value.
-// If the receiver node is a directory, a "Not A File" error will be returned.
-func (n *node) Write(value string, index uint64) *v2error.Error {
-	if n.IsDir() {
-		return v2error.NewError(v2error.EcodeNotFile, "", n.store.CurrentIndex)
-	}
-
-	n.Value = value
-	n.ModifiedIndex = index
-
-	return nil
-}
-
-func (n *node) expirationAndTTL(clock clockwork.Clock) (*time.Time, int64) {
-	if !n.IsPermanent() {
-		/* compute ttl as:
-		   ceiling( (expireTime - timeNow) / nanosecondsPerSecond )
-		   which ranges from 1..n
-		   rather than as:
-		   ( (expireTime - timeNow) / nanosecondsPerSecond ) + 1
-		   which ranges 1..n+1
-		*/
-		ttlN := n.ExpireTime.Sub(clock.Now())
-		ttl := ttlN / time.Second
-		if (ttlN % time.Second) > 0 {
-			ttl++
-		}
-		t := n.ExpireTime.UTC()
-		return &t, int64(ttl)
-	}
-	return nil, 0
-}
-
-// List function return a slice of nodes under the receiver node.
-// If the receiver node is not a directory, a "Not A Directory" error will be returned.
-func (n *node) List() ([]*node, *v2error.Error) {
-	if !n.IsDir() {
-		return nil, v2error.NewError(v2error.EcodeNotDir, "", n.store.CurrentIndex)
-	}
-
-	nodes := make([]*node, len(n.Children))
-
-	i := 0
-	for _, node := range n.Children {
-		nodes[i] = node
-		i++
-	}
-
-	return nodes, nil
-}
-
-// GetChild function returns the child node under the directory node.
-// On success, it returns the file node
-func (n *node) GetChild(name string) (*node, *v2error.Error) {
-	if !n.IsDir() {
-		return nil, v2error.NewError(v2error.EcodeNotDir, n.Path, n.store.CurrentIndex)
-	}
-
-	child, ok := n.Children[name]
-
-	if ok {
-		return child, nil
-	}
-
-	return nil, nil
-}
-
-// Add function adds a node to the receiver node.
-// If the receiver is not a directory, a "Not A Directory" error will be returned.
-// If there is an existing node with the same name under the directory, a "Already Exist"
-// error will be returned
-func (n *node) Add(child *node) *v2error.Error {
-	if !n.IsDir() {
-		return v2error.NewError(v2error.EcodeNotDir, "", n.store.CurrentIndex)
-	}
-
-	_, name := path.Split(child.Path)
-
-	if _, ok := n.Children[name]; ok {
-		return v2error.NewError(v2error.EcodeNodeExist, "", n.store.CurrentIndex)
-	}
-
-	n.Children[name] = child
-
-	return nil
-}
-
-// Remove function remove the node.
-func (n *node) Remove(dir, recursive bool, callback func(path string)) *v2error.Error {
-	if !n.IsDir() { // key-value pair
-		_, name := path.Split(n.Path)
-
-		// find its parent and remove the node from the map
-		if n.Parent != nil && n.Parent.Children[name] == n {
-			delete(n.Parent.Children, name)
-		}
-
-		if callback != nil {
-			callback(n.Path)
-		}
-
-		if !n.IsPermanent() {
-			n.store.ttlKeyHeap.remove(n)
-		}
-
-		return nil
-	}
-
-	if !dir {
-		// cannot delete a directory without dir set to true
-		return v2error.NewError(v2error.EcodeNotFile, n.Path, n.store.CurrentIndex)
-	}
-
-	if len(n.Children) != 0 && !recursive {
-		// cannot delete a directory if it is not empty and the operation
-		// is not recursive
-		return v2error.NewError(v2error.EcodeDirNotEmpty, n.Path, n.store.CurrentIndex)
-	}
-
-	for _, child := range n.Children { // delete all children
-		child.Remove(true, true, callback)
-	}
-
-	// delete self
-	_, name := path.Split(n.Path)
-	if n.Parent != nil && n.Parent.Children[name] == n {
-		delete(n.Parent.Children, name)
-
-		if callback != nil {
-			callback(n.Path)
-		}
-
-		if !n.IsPermanent() {
-			n.store.ttlKeyHeap.remove(n)
-		}
-	}
-
-	return nil
-}
-
-func (n *node) Repr(recursive, sorted bool, clock clockwork.Clock) *NodeExtern {
-	if n.IsDir() {
-		node := &NodeExtern{
-			Key:           n.Path,
-			Dir:           true,
-			ModifiedIndex: n.ModifiedIndex,
-			CreatedIndex:  n.CreatedIndex,
-		}
-		node.Expiration, node.TTL = n.expirationAndTTL(clock)
-
-		if !recursive {
-			return node
-		}
-
-		children, _ := n.List()
-		node.Nodes = make(NodeExterns, len(children))
-
-		// we do not use the index in the children slice directly
-		// we need to skip the hidden one
-		i := 0
-
-		for _, child := range children {
-
-			if child.IsHidden() { // get will not list hidden node
-				continue
-			}
-
-			node.Nodes[i] = child.Repr(recursive, sorted, clock)
-
-			i++
-		}
-
-		// eliminate hidden nodes
-		node.Nodes = node.Nodes[:i]
-		if sorted {
-			sort.Sort(node.Nodes)
-		}
-
-		return node
-	}
-
-	// since n.Value could be changed later, so we need to copy the value out
-	value := n.Value
-	node := &NodeExtern{
-		Key:           n.Path,
-		Value:         &value,
-		ModifiedIndex: n.ModifiedIndex,
-		CreatedIndex:  n.CreatedIndex,
-	}
-	node.Expiration, node.TTL = n.expirationAndTTL(clock)
-	return node
-}
-
-func (n *node) UpdateTTL(expireTime time.Time) {
-	if !n.IsPermanent() {
-		if expireTime.IsZero() {
-			// from ttl to permanent
-			n.ExpireTime = expireTime
-			// remove from ttl heap
-			n.store.ttlKeyHeap.remove(n)
-			return
-		}
-
-		// update ttl
-		n.ExpireTime = expireTime
-		// update ttl heap
-		n.store.ttlKeyHeap.update(n)
-		return
-	}
-
-	if expireTime.IsZero() {
-		return
-	}
-
-	// from permanent to ttl
-	n.ExpireTime = expireTime
-	// push into ttl heap
-	n.store.ttlKeyHeap.push(n)
-}
-
-// Compare function compares node index and value with provided ones.
-// second result value explains result and equals to one of Compare.. constants
-func (n *node) Compare(prevValue string, prevIndex uint64) (ok bool, which int) {
-	indexMatch := prevIndex == 0 || n.ModifiedIndex == prevIndex
-	valueMatch := prevValue == "" || n.Value == prevValue
-	ok = valueMatch && indexMatch
-	switch {
-	case valueMatch && indexMatch:
-		which = CompareMatch
-	case indexMatch && !valueMatch:
-		which = CompareValueNotMatch
-	case valueMatch && !indexMatch:
-		which = CompareIndexNotMatch
-	default:
-		which = CompareNotMatch
-	}
-	return ok, which
-}
-
-// Clone function clone the node recursively and return the new node.
-// If the node is a directory, it will clone all the content under this directory.
-// If the node is a key-value pair, it will clone the pair.
-func (n *node) Clone() *node {
-	if !n.IsDir() {
-		newkv := newKV(n.store, n.Path, n.Value, n.CreatedIndex, n.Parent, n.ExpireTime)
-		newkv.ModifiedIndex = n.ModifiedIndex
-		return newkv
-	}
-
-	clone := newDir(n.store, n.Path, n.CreatedIndex, n.Parent, n.ExpireTime)
-	clone.ModifiedIndex = n.ModifiedIndex
-
-	for key, child := range n.Children {
-		clone.Children[key] = child.Clone()
-	}
-
-	return clone
-}
-
-// recoverAndclean function help to do recovery.
-// Two things need to be done: 1. recovery structure; 2. delete expired nodes
-//
-// If the node is a directory, it will help recover children's parent pointer and recursively
-// call this function on its children.
-// We check the expire last since we need to recover the whole structure first and add all the
-// notifications into the event history.
-func (n *node) recoverAndclean() {
-	if n.IsDir() {
-		for _, child := range n.Children {
-			child.Parent = n
-			child.store = n.store
-			child.recoverAndclean()
-		}
-	}
-
-	if !n.ExpireTime.IsZero() {
-		n.store.ttlKeyHeap.push(n)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node_extern.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node_extern.go
deleted file mode 100644
index b3bf5f3..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/node_extern.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"sort"
-	"time"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// NodeExtern is the external representation of the
-// internal node with additional fields
-// PrevValue is the previous value of the node
-// TTL is time to live in second
-type NodeExtern struct {
-	Key           string      `json:"key,omitempty"`
-	Value         *string     `json:"value,omitempty"`
-	Dir           bool        `json:"dir,omitempty"`
-	Expiration    *time.Time  `json:"expiration,omitempty"`
-	TTL           int64       `json:"ttl,omitempty"`
-	Nodes         NodeExterns `json:"nodes,omitempty"`
-	ModifiedIndex uint64      `json:"modifiedIndex,omitempty"`
-	CreatedIndex  uint64      `json:"createdIndex,omitempty"`
-}
-
-func (eNode *NodeExtern) loadInternalNode(n *node, recursive, sorted bool, clock clockwork.Clock) {
-	if n.IsDir() { // node is a directory
-		eNode.Dir = true
-
-		children, _ := n.List()
-		eNode.Nodes = make(NodeExterns, len(children))
-
-		// we do not use the index in the children slice directly
-		// we need to skip the hidden one
-		i := 0
-
-		for _, child := range children {
-			if child.IsHidden() { // get will not return hidden nodes
-				continue
-			}
-
-			eNode.Nodes[i] = child.Repr(recursive, sorted, clock)
-			i++
-		}
-
-		// eliminate hidden nodes
-		eNode.Nodes = eNode.Nodes[:i]
-
-		if sorted {
-			sort.Sort(eNode.Nodes)
-		}
-
-	} else { // node is a file
-		value, _ := n.Read()
-		eNode.Value = &value
-	}
-
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(clock)
-}
-
-func (eNode *NodeExtern) Clone() *NodeExtern {
-	if eNode == nil {
-		return nil
-	}
-	nn := &NodeExtern{
-		Key:           eNode.Key,
-		Dir:           eNode.Dir,
-		TTL:           eNode.TTL,
-		ModifiedIndex: eNode.ModifiedIndex,
-		CreatedIndex:  eNode.CreatedIndex,
-	}
-	if eNode.Value != nil {
-		s := *eNode.Value
-		nn.Value = &s
-	}
-	if eNode.Expiration != nil {
-		t := *eNode.Expiration
-		nn.Expiration = &t
-	}
-	if eNode.Nodes != nil {
-		nn.Nodes = make(NodeExterns, len(eNode.Nodes))
-		for i, n := range eNode.Nodes {
-			nn.Nodes[i] = n.Clone()
-		}
-	}
-	return nn
-}
-
-type NodeExterns []*NodeExtern
-
-// interfaces for sorting
-
-func (ns NodeExterns) Len() int {
-	return len(ns)
-}
-
-func (ns NodeExterns) Less(i, j int) bool {
-	return ns[i].Key < ns[j].Key
-}
-
-func (ns NodeExterns) Swap(i, j int) {
-	ns[i], ns[j] = ns[j], ns[i]
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/stats.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/stats.go
deleted file mode 100644
index 45bc97f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/stats.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"encoding/json"
-	"sync/atomic"
-)
-
-const (
-	SetSuccess = iota
-	SetFail
-	DeleteSuccess
-	DeleteFail
-	CreateSuccess
-	CreateFail
-	UpdateSuccess
-	UpdateFail
-	CompareAndSwapSuccess
-	CompareAndSwapFail
-	GetSuccess
-	GetFail
-	ExpireCount
-	CompareAndDeleteSuccess
-	CompareAndDeleteFail
-)
-
-type Stats struct {
-	// Number of get requests
-
-	GetSuccess uint64 `json:"getsSuccess"`
-	GetFail    uint64 `json:"getsFail"`
-
-	// Number of sets requests
-
-	SetSuccess uint64 `json:"setsSuccess"`
-	SetFail    uint64 `json:"setsFail"`
-
-	// Number of delete requests
-
-	DeleteSuccess uint64 `json:"deleteSuccess"`
-	DeleteFail    uint64 `json:"deleteFail"`
-
-	// Number of update requests
-
-	UpdateSuccess uint64 `json:"updateSuccess"`
-	UpdateFail    uint64 `json:"updateFail"`
-
-	// Number of create requests
-
-	CreateSuccess uint64 `json:"createSuccess"`
-	CreateFail    uint64 `json:"createFail"`
-
-	// Number of testAndSet requests
-
-	CompareAndSwapSuccess uint64 `json:"compareAndSwapSuccess"`
-	CompareAndSwapFail    uint64 `json:"compareAndSwapFail"`
-
-	// Number of compareAndDelete requests
-
-	CompareAndDeleteSuccess uint64 `json:"compareAndDeleteSuccess"`
-	CompareAndDeleteFail    uint64 `json:"compareAndDeleteFail"`
-
-	ExpireCount uint64 `json:"expireCount"`
-
-	Watchers uint64 `json:"watchers"`
-}
-
-func newStats() *Stats {
-	s := new(Stats)
-	return s
-}
-
-func (s *Stats) clone() *Stats {
-	return &Stats{
-		GetSuccess:              s.GetSuccess,
-		GetFail:                 s.GetFail,
-		SetSuccess:              s.SetSuccess,
-		SetFail:                 s.SetFail,
-		DeleteSuccess:           s.DeleteSuccess,
-		DeleteFail:              s.DeleteFail,
-		UpdateSuccess:           s.UpdateSuccess,
-		UpdateFail:              s.UpdateFail,
-		CreateSuccess:           s.CreateSuccess,
-		CreateFail:              s.CreateFail,
-		CompareAndSwapSuccess:   s.CompareAndSwapSuccess,
-		CompareAndSwapFail:      s.CompareAndSwapFail,
-		CompareAndDeleteSuccess: s.CompareAndDeleteSuccess,
-		CompareAndDeleteFail:    s.CompareAndDeleteFail,
-		ExpireCount:             s.ExpireCount,
-		Watchers:                s.Watchers,
-	}
-}
-
-func (s *Stats) toJson() []byte {
-	b, _ := json.Marshal(s)
-	return b
-}
-
-func (s *Stats) Inc(field int) {
-	switch field {
-	case SetSuccess:
-		atomic.AddUint64(&s.SetSuccess, 1)
-	case SetFail:
-		atomic.AddUint64(&s.SetFail, 1)
-	case CreateSuccess:
-		atomic.AddUint64(&s.CreateSuccess, 1)
-	case CreateFail:
-		atomic.AddUint64(&s.CreateFail, 1)
-	case DeleteSuccess:
-		atomic.AddUint64(&s.DeleteSuccess, 1)
-	case DeleteFail:
-		atomic.AddUint64(&s.DeleteFail, 1)
-	case GetSuccess:
-		atomic.AddUint64(&s.GetSuccess, 1)
-	case GetFail:
-		atomic.AddUint64(&s.GetFail, 1)
-	case UpdateSuccess:
-		atomic.AddUint64(&s.UpdateSuccess, 1)
-	case UpdateFail:
-		atomic.AddUint64(&s.UpdateFail, 1)
-	case CompareAndSwapSuccess:
-		atomic.AddUint64(&s.CompareAndSwapSuccess, 1)
-	case CompareAndSwapFail:
-		atomic.AddUint64(&s.CompareAndSwapFail, 1)
-	case CompareAndDeleteSuccess:
-		atomic.AddUint64(&s.CompareAndDeleteSuccess, 1)
-	case CompareAndDeleteFail:
-		atomic.AddUint64(&s.CompareAndDeleteFail, 1)
-	case ExpireCount:
-		atomic.AddUint64(&s.ExpireCount, 1)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/store.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/store.go
deleted file mode 100644
index ce94043..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/store.go
+++ /dev/null
@@ -1,791 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"encoding/json"
-	"fmt"
-	"path"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/jonboulle/clockwork"
-)
-
-// The default version to set when the store is first initialized.
-const defaultVersion = 2
-
-var minExpireTime time.Time
-
-func init() {
-	minExpireTime, _ = time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
-}
-
-type Store interface {
-	Version() int
-	Index() uint64
-
-	Get(nodePath string, recursive, sorted bool) (*Event, error)
-	Set(nodePath string, dir bool, value string, expireOpts TTLOptionSet) (*Event, error)
-	Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error)
-	Create(nodePath string, dir bool, value string, unique bool,
-		expireOpts TTLOptionSet) (*Event, error)
-	CompareAndSwap(nodePath string, prevValue string, prevIndex uint64,
-		value string, expireOpts TTLOptionSet) (*Event, error)
-	Delete(nodePath string, dir, recursive bool) (*Event, error)
-	CompareAndDelete(nodePath string, prevValue string, prevIndex uint64) (*Event, error)
-
-	Watch(prefix string, recursive, stream bool, sinceIndex uint64) (Watcher, error)
-
-	Save() ([]byte, error)
-	Recovery(state []byte) error
-
-	Clone() Store
-	SaveNoCopy() ([]byte, error)
-
-	JsonStats() []byte
-	DeleteExpiredKeys(cutoff time.Time)
-
-	HasTTLKeys() bool
-}
-
-type TTLOptionSet struct {
-	ExpireTime time.Time
-	Refresh    bool
-}
-
-type store struct {
-	Root           *node
-	WatcherHub     *watcherHub
-	CurrentIndex   uint64
-	Stats          *Stats
-	CurrentVersion int
-	ttlKeyHeap     *ttlKeyHeap  // need to recovery manually
-	worldLock      sync.RWMutex // stop the world lock
-	clock          clockwork.Clock
-	readonlySet    types.Set
-}
-
-// New creates a store where the given namespaces will be created as initial directories.
-func New(namespaces ...string) Store {
-	s := newStore(namespaces...)
-	s.clock = clockwork.NewRealClock()
-	return s
-}
-
-func newStore(namespaces ...string) *store {
-	s := new(store)
-	s.CurrentVersion = defaultVersion
-	s.Root = newDir(s, "/", s.CurrentIndex, nil, Permanent)
-	for _, namespace := range namespaces {
-		s.Root.Add(newDir(s, namespace, s.CurrentIndex, s.Root, Permanent))
-	}
-	s.Stats = newStats()
-	s.WatcherHub = newWatchHub(1000)
-	s.ttlKeyHeap = newTtlKeyHeap()
-	s.readonlySet = types.NewUnsafeSet(append(namespaces, "/")...)
-	return s
-}
-
-// Version retrieves current version of the store.
-func (s *store) Version() int {
-	return s.CurrentVersion
-}
-
-// Index retrieves the current index of the store.
-func (s *store) Index() uint64 {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-	return s.CurrentIndex
-}
-
-// Get returns a get event.
-// If recursive is true, it will return all the content under the node path.
-// If sorted is true, it will sort the content by keys.
-func (s *store) Get(nodePath string, recursive, sorted bool) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(GetSuccess)
-			if recursive {
-				reportReadSuccess(GetRecursive)
-			} else {
-				reportReadSuccess(Get)
-			}
-			return
-		}
-
-		s.Stats.Inc(GetFail)
-		if recursive {
-			reportReadFailure(GetRecursive)
-		} else {
-			reportReadFailure(Get)
-		}
-	}()
-
-	n, err := s.internalGet(nodePath)
-	if err != nil {
-		return nil, err
-	}
-
-	e := newEvent(Get, nodePath, n.ModifiedIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.Node.loadInternalNode(n, recursive, sorted, s.clock)
-
-	return e, nil
-}
-
-// Create creates the node at nodePath. Create will help to create intermediate directories with no ttl.
-// If the node has already existed, create will fail.
-// If any node on the path is a file, create will fail.
-func (s *store) Create(nodePath string, dir bool, value string, unique bool, expireOpts TTLOptionSet) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CreateSuccess)
-			reportWriteSuccess(Create)
-			return
-		}
-
-		s.Stats.Inc(CreateFail)
-		reportWriteFailure(Create)
-	}()
-
-	e, err := s.internalCreate(nodePath, dir, value, unique, false, expireOpts.ExpireTime, Create)
-	if err != nil {
-		return nil, err
-	}
-
-	e.EtcdIndex = s.CurrentIndex
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-// Set creates or replace the node at nodePath.
-func (s *store) Set(nodePath string, dir bool, value string, expireOpts TTLOptionSet) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(SetSuccess)
-			reportWriteSuccess(Set)
-			return
-		}
-
-		s.Stats.Inc(SetFail)
-		reportWriteFailure(Set)
-	}()
-
-	// Get prevNode value
-	n, getErr := s.internalGet(nodePath)
-	if getErr != nil && getErr.ErrorCode != v2error.EcodeKeyNotFound {
-		err = getErr
-		return nil, err
-	}
-
-	if expireOpts.Refresh {
-		if getErr != nil {
-			err = getErr
-			return nil, err
-		}
-		value = n.Value
-	}
-
-	// Set new value
-	e, err := s.internalCreate(nodePath, dir, value, false, true, expireOpts.ExpireTime, Set)
-	if err != nil {
-		return nil, err
-	}
-	e.EtcdIndex = s.CurrentIndex
-
-	// Put prevNode into event
-	if getErr == nil {
-		prev := newEvent(Get, nodePath, n.ModifiedIndex, n.CreatedIndex)
-		prev.Node.loadInternalNode(n, false, false, s.clock)
-		e.PrevNode = prev.Node
-	}
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	return e, nil
-}
-
-// returns user-readable cause of failed comparison
-func getCompareFailCause(n *node, which int, prevValue string, prevIndex uint64) string {
-	switch which {
-	case CompareIndexNotMatch:
-		return fmt.Sprintf("[%v != %v]", prevIndex, n.ModifiedIndex)
-	case CompareValueNotMatch:
-		return fmt.Sprintf("[%v != %v]", prevValue, n.Value)
-	default:
-		return fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, n.Value, prevIndex, n.ModifiedIndex)
-	}
-}
-
-func (s *store) CompareAndSwap(nodePath string, prevValue string, prevIndex uint64,
-	value string, expireOpts TTLOptionSet) (*Event, error) {
-
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CompareAndSwapSuccess)
-			reportWriteSuccess(CompareAndSwap)
-			return
-		}
-
-		s.Stats.Inc(CompareAndSwapFail)
-		reportWriteFailure(CompareAndSwap)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	n, err := s.internalGet(nodePath)
-	if err != nil {
-		return nil, err
-	}
-	if n.IsDir() { // can only compare and swap file
-		err = v2error.NewError(v2error.EcodeNotFile, nodePath, s.CurrentIndex)
-		return nil, err
-	}
-
-	// If both of the prevValue and prevIndex are given, we will test both of them.
-	// Command will be executed, only if both of the tests are successful.
-	if ok, which := n.Compare(prevValue, prevIndex); !ok {
-		cause := getCompareFailCause(n, which, prevValue, prevIndex)
-		err = v2error.NewError(v2error.EcodeTestFailed, cause, s.CurrentIndex)
-		return nil, err
-	}
-
-	if expireOpts.Refresh {
-		value = n.Value
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	e := newEvent(CompareAndSwap, nodePath, s.CurrentIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	// if test succeed, write the value
-	n.Write(value, s.CurrentIndex)
-	n.UpdateTTL(expireOpts.ExpireTime)
-
-	// copy the value for safety
-	valueCopy := value
-	eNode.Value = &valueCopy
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	return e, nil
-}
-
-// Delete deletes the node at the given path.
-// If the node is a directory, recursive must be true to delete it.
-func (s *store) Delete(nodePath string, dir, recursive bool) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(DeleteSuccess)
-			reportWriteSuccess(Delete)
-			return
-		}
-
-		s.Stats.Inc(DeleteFail)
-		reportWriteFailure(Delete)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	// recursive implies dir
-	if recursive {
-		dir = true
-	}
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-
-	nextIndex := s.CurrentIndex + 1
-	e := newEvent(Delete, nodePath, nextIndex, n.CreatedIndex)
-	e.EtcdIndex = nextIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	if n.IsDir() {
-		eNode.Dir = true
-	}
-
-	callback := func(path string) { // notify function
-		// notify the watchers with deleted set true
-		s.WatcherHub.notifyWatchers(e, path, true)
-	}
-
-	err = n.Remove(dir, recursive, callback)
-	if err != nil {
-		return nil, err
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-func (s *store) CompareAndDelete(nodePath string, prevValue string, prevIndex uint64) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(CompareAndDeleteSuccess)
-			reportWriteSuccess(CompareAndDelete)
-			return
-		}
-
-		s.Stats.Inc(CompareAndDeleteFail)
-		reportWriteFailure(CompareAndDelete)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-	if n.IsDir() { // can only compare and delete file
-		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, s.CurrentIndex)
-	}
-
-	// If both of the prevValue and prevIndex are given, we will test both of them.
-	// Command will be executed, only if both of the tests are successful.
-	if ok, which := n.Compare(prevValue, prevIndex); !ok {
-		cause := getCompareFailCause(n, which, prevValue, prevIndex)
-		return nil, v2error.NewError(v2error.EcodeTestFailed, cause, s.CurrentIndex)
-	}
-
-	// update etcd index
-	s.CurrentIndex++
-
-	e := newEvent(CompareAndDelete, nodePath, s.CurrentIndex, n.CreatedIndex)
-	e.EtcdIndex = s.CurrentIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-
-	callback := func(path string) { // notify function
-		// notify the watchers with deleted set true
-		s.WatcherHub.notifyWatchers(e, path, true)
-	}
-
-	err = n.Remove(false, false, callback)
-	if err != nil {
-		return nil, err
-	}
-
-	s.WatcherHub.notify(e)
-
-	return e, nil
-}
-
-func (s *store) Watch(key string, recursive, stream bool, sinceIndex uint64) (Watcher, error) {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-
-	key = path.Clean(path.Join("/", key))
-	if sinceIndex == 0 {
-		sinceIndex = s.CurrentIndex + 1
-	}
-	// WatcherHub does not know about the current index, so we need to pass it in
-	w, err := s.WatcherHub.watch(key, recursive, stream, sinceIndex, s.CurrentIndex)
-	if err != nil {
-		return nil, err
-	}
-
-	return w, nil
-}
-
-// walk walks all the nodePath and apply the walkFunc on each directory
-func (s *store) walk(nodePath string, walkFunc func(prev *node, component string) (*node, *v2error.Error)) (*node, *v2error.Error) {
-	components := strings.Split(nodePath, "/")
-
-	curr := s.Root
-	var err *v2error.Error
-
-	for i := 1; i < len(components); i++ {
-		if len(components[i]) == 0 { // ignore empty string
-			return curr, nil
-		}
-
-		curr, err = walkFunc(curr, components[i])
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return curr, nil
-}
-
-// Update updates the value/ttl of the node.
-// If the node is a file, the value and the ttl can be updated.
-// If the node is a directory, only the ttl can be updated.
-func (s *store) Update(nodePath string, newValue string, expireOpts TTLOptionSet) (*Event, error) {
-	var err *v2error.Error
-
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	defer func() {
-		if err == nil {
-			s.Stats.Inc(UpdateSuccess)
-			reportWriteSuccess(Update)
-			return
-		}
-
-		s.Stats.Inc(UpdateFail)
-		reportWriteFailure(Update)
-	}()
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", s.CurrentIndex)
-	}
-
-	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1
-
-	n, err := s.internalGet(nodePath)
-	if err != nil { // if the node does not exist, return error
-		return nil, err
-	}
-	if n.IsDir() && len(newValue) != 0 {
-		// if the node is a directory, we cannot update value to non-empty
-		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, currIndex)
-	}
-
-	if expireOpts.Refresh {
-		newValue = n.Value
-	}
-
-	e := newEvent(Update, nodePath, nextIndex, n.CreatedIndex)
-	e.EtcdIndex = nextIndex
-	e.PrevNode = n.Repr(false, false, s.clock)
-	eNode := e.Node
-
-	n.Write(newValue, nextIndex)
-
-	if n.IsDir() {
-		eNode.Dir = true
-	} else {
-		// copy the value for safety
-		newValueCopy := newValue
-		eNode.Value = &newValueCopy
-	}
-
-	// update ttl
-	n.UpdateTTL(expireOpts.ExpireTime)
-
-	eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-
-	if !expireOpts.Refresh {
-		s.WatcherHub.notify(e)
-	} else {
-		e.SetRefresh()
-		s.WatcherHub.add(e)
-	}
-
-	s.CurrentIndex = nextIndex
-
-	return e, nil
-}
-
-func (s *store) internalCreate(nodePath string, dir bool, value string, unique, replace bool,
-	expireTime time.Time, action string) (*Event, *v2error.Error) {
-
-	currIndex, nextIndex := s.CurrentIndex, s.CurrentIndex+1
-
-	if unique { // append unique item under the node path
-		nodePath += "/" + fmt.Sprintf("%020s", strconv.FormatUint(nextIndex, 10))
-	}
-
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	// we do not allow the user to change "/"
-	if s.readonlySet.Contains(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, "/", currIndex)
-	}
-
-	// Assume expire times that are way in the past are
-	// This can occur when the time is serialized to JS
-	if expireTime.Before(minExpireTime) {
-		expireTime = Permanent
-	}
-
-	dirName, nodeName := path.Split(nodePath)
-
-	// walk through the nodePath, create dirs and get the last directory node
-	d, err := s.walk(dirName, s.checkDir)
-
-	if err != nil {
-		s.Stats.Inc(SetFail)
-		reportWriteFailure(action)
-		err.Index = currIndex
-		return nil, err
-	}
-
-	e := newEvent(action, nodePath, nextIndex, nextIndex)
-	eNode := e.Node
-
-	n, _ := d.GetChild(nodeName)
-
-	// force will try to replace an existing file
-	if n != nil {
-		if replace {
-			if n.IsDir() {
-				return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, currIndex)
-			}
-			e.PrevNode = n.Repr(false, false, s.clock)
-
-			n.Remove(false, false, nil)
-		} else {
-			return nil, v2error.NewError(v2error.EcodeNodeExist, nodePath, currIndex)
-		}
-	}
-
-	if !dir { // create file
-		// copy the value for safety
-		valueCopy := value
-		eNode.Value = &valueCopy
-
-		n = newKV(s, nodePath, value, nextIndex, d, expireTime)
-
-	} else { // create directory
-		eNode.Dir = true
-
-		n = newDir(s, nodePath, nextIndex, d, expireTime)
-	}
-
-	// we are sure d is a directory and does not have the children with name n.Name
-	d.Add(n)
-
-	// node with TTL
-	if !n.IsPermanent() {
-		s.ttlKeyHeap.push(n)
-
-		eNode.Expiration, eNode.TTL = n.expirationAndTTL(s.clock)
-	}
-
-	s.CurrentIndex = nextIndex
-
-	return e, nil
-}
-
-// InternalGet gets the node of the given nodePath.
-func (s *store) internalGet(nodePath string) (*node, *v2error.Error) {
-	nodePath = path.Clean(path.Join("/", nodePath))
-
-	walkFunc := func(parent *node, name string) (*node, *v2error.Error) {
-
-		if !parent.IsDir() {
-			err := v2error.NewError(v2error.EcodeNotDir, parent.Path, s.CurrentIndex)
-			return nil, err
-		}
-
-		child, ok := parent.Children[name]
-		if ok {
-			return child, nil
-		}
-
-		return nil, v2error.NewError(v2error.EcodeKeyNotFound, path.Join(parent.Path, name), s.CurrentIndex)
-	}
-
-	f, err := s.walk(nodePath, walkFunc)
-
-	if err != nil {
-		return nil, err
-	}
-	return f, nil
-}
-
-// DeleteExpiredKeys will delete all expired keys
-func (s *store) DeleteExpiredKeys(cutoff time.Time) {
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-
-	for {
-		node := s.ttlKeyHeap.top()
-		if node == nil || node.ExpireTime.After(cutoff) {
-			break
-		}
-
-		s.CurrentIndex++
-		e := newEvent(Expire, node.Path, s.CurrentIndex, node.CreatedIndex)
-		e.EtcdIndex = s.CurrentIndex
-		e.PrevNode = node.Repr(false, false, s.clock)
-		if node.IsDir() {
-			e.Node.Dir = true
-		}
-
-		callback := func(path string) { // notify function
-			// notify the watchers with deleted set true
-			s.WatcherHub.notifyWatchers(e, path, true)
-		}
-
-		s.ttlKeyHeap.pop()
-		node.Remove(true, true, callback)
-
-		reportExpiredKey()
-		s.Stats.Inc(ExpireCount)
-
-		s.WatcherHub.notify(e)
-	}
-
-}
-
-// checkDir will check whether the component is a directory under parent node.
-// If it is a directory, this function will return the pointer to that node.
-// If it does not exist, this function will create a new directory and return the pointer to that node.
-// If it is a file, this function will return error.
-func (s *store) checkDir(parent *node, dirName string) (*node, *v2error.Error) {
-	node, ok := parent.Children[dirName]
-
-	if ok {
-		if node.IsDir() {
-			return node, nil
-		}
-
-		return nil, v2error.NewError(v2error.EcodeNotDir, node.Path, s.CurrentIndex)
-	}
-
-	n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex+1, parent, Permanent)
-
-	parent.Children[dirName] = n
-
-	return n, nil
-}
-
-// Save saves the static state of the store system.
-// It will not be able to save the state of watchers.
-// It will not save the parent field of the node. Or there will
-// be cyclic dependencies issue for the json package.
-func (s *store) Save() ([]byte, error) {
-	b, err := json.Marshal(s.Clone())
-	if err != nil {
-		return nil, err
-	}
-
-	return b, nil
-}
-
-func (s *store) SaveNoCopy() ([]byte, error) {
-	b, err := json.Marshal(s)
-	if err != nil {
-		return nil, err
-	}
-
-	return b, nil
-}
-
-func (s *store) Clone() Store {
-	s.worldLock.Lock()
-
-	clonedStore := newStore()
-	clonedStore.CurrentIndex = s.CurrentIndex
-	clonedStore.Root = s.Root.Clone()
-	clonedStore.WatcherHub = s.WatcherHub.clone()
-	clonedStore.Stats = s.Stats.clone()
-	clonedStore.CurrentVersion = s.CurrentVersion
-
-	s.worldLock.Unlock()
-	return clonedStore
-}
-
-// Recovery recovers the store system from a static state
-// It needs to recover the parent field of the nodes.
-// It needs to delete the expired nodes since the saved time and also
-// needs to create monitoring go routines.
-func (s *store) Recovery(state []byte) error {
-	s.worldLock.Lock()
-	defer s.worldLock.Unlock()
-	err := json.Unmarshal(state, s)
-
-	if err != nil {
-		return err
-	}
-
-	s.ttlKeyHeap = newTtlKeyHeap()
-
-	s.Root.recoverAndclean()
-	return nil
-}
-
-func (s *store) JsonStats() []byte {
-	s.Stats.Watchers = uint64(s.WatcherHub.count)
-	return s.Stats.toJson()
-}
-
-func (s *store) HasTTLKeys() bool {
-	s.worldLock.RLock()
-	defer s.worldLock.RUnlock()
-	return s.ttlKeyHeap.Len() != 0
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/ttl_key_heap.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/ttl_key_heap.go
deleted file mode 100644
index 477d2b9..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/ttl_key_heap.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2015 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 v2store
-
-import "container/heap"
-
-// An TTLKeyHeap is a min-heap of TTLKeys order by expiration time
-type ttlKeyHeap struct {
-	array  []*node
-	keyMap map[*node]int
-}
-
-func newTtlKeyHeap() *ttlKeyHeap {
-	h := &ttlKeyHeap{keyMap: make(map[*node]int)}
-	heap.Init(h)
-	return h
-}
-
-func (h ttlKeyHeap) Len() int {
-	return len(h.array)
-}
-
-func (h ttlKeyHeap) Less(i, j int) bool {
-	return h.array[i].ExpireTime.Before(h.array[j].ExpireTime)
-}
-
-func (h ttlKeyHeap) Swap(i, j int) {
-	// swap node
-	h.array[i], h.array[j] = h.array[j], h.array[i]
-
-	// update map
-	h.keyMap[h.array[i]] = i
-	h.keyMap[h.array[j]] = j
-}
-
-func (h *ttlKeyHeap) Push(x interface{}) {
-	n, _ := x.(*node)
-	h.keyMap[n] = len(h.array)
-	h.array = append(h.array, n)
-}
-
-func (h *ttlKeyHeap) Pop() interface{} {
-	old := h.array
-	n := len(old)
-	x := old[n-1]
-	// Set slice element to nil, so GC can recycle the node.
-	// This is due to golang GC doesn't support partial recycling:
-	// https://github.com/golang/go/issues/9618
-	old[n-1] = nil
-	h.array = old[0 : n-1]
-	delete(h.keyMap, x)
-	return x
-}
-
-func (h *ttlKeyHeap) top() *node {
-	if h.Len() != 0 {
-		return h.array[0]
-	}
-	return nil
-}
-
-func (h *ttlKeyHeap) pop() *node {
-	x := heap.Pop(h)
-	n, _ := x.(*node)
-	return n
-}
-
-func (h *ttlKeyHeap) push(x interface{}) {
-	heap.Push(h, x)
-}
-
-func (h *ttlKeyHeap) update(n *node) {
-	index, ok := h.keyMap[n]
-	if ok {
-		heap.Remove(h, index)
-		heap.Push(h, n)
-	}
-}
-
-func (h *ttlKeyHeap) remove(n *node) {
-	index, ok := h.keyMap[n]
-	if ok {
-		heap.Remove(h, index)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher.go
deleted file mode 100644
index 4b1e846..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 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 v2store
-
-type Watcher interface {
-	EventChan() chan *Event
-	StartIndex() uint64 // The EtcdIndex at which the Watcher was created
-	Remove()
-}
-
-type watcher struct {
-	eventChan  chan *Event
-	stream     bool
-	recursive  bool
-	sinceIndex uint64
-	startIndex uint64
-	hub        *watcherHub
-	removed    bool
-	remove     func()
-}
-
-func (w *watcher) EventChan() chan *Event {
-	return w.eventChan
-}
-
-func (w *watcher) StartIndex() uint64 {
-	return w.startIndex
-}
-
-// notify function notifies the watcher. If the watcher interests in the given path,
-// the function will return true.
-func (w *watcher) notify(e *Event, originalPath bool, deleted bool) bool {
-	// watcher is interested the path in three cases and under one condition
-	// the condition is that the event happens after the watcher's sinceIndex
-
-	// 1. the path at which the event happens is the path the watcher is watching at.
-	// For example if the watcher is watching at "/foo" and the event happens at "/foo",
-	// the watcher must be interested in that event.
-
-	// 2. the watcher is a recursive watcher, it interests in the event happens after
-	// its watching path. For example if watcher A watches at "/foo" and it is a recursive
-	// one, it will interest in the event happens at "/foo/bar".
-
-	// 3. when we delete a directory, we need to force notify all the watchers who watches
-	// at the file we need to delete.
-	// For example a watcher is watching at "/foo/bar". And we deletes "/foo". The watcher
-	// should get notified even if "/foo" is not the path it is watching.
-	if (w.recursive || originalPath || deleted) && e.Index() >= w.sinceIndex {
-		// We cannot block here if the eventChan capacity is full, otherwise
-		// etcd will hang. eventChan capacity is full when the rate of
-		// notifications are higher than our send rate.
-		// If this happens, we close the channel.
-		select {
-		case w.eventChan <- e:
-		default:
-			// We have missed a notification. Remove the watcher.
-			// Removing the watcher also closes the eventChan.
-			w.remove()
-		}
-		return true
-	}
-	return false
-}
-
-// Remove removes the watcher from watcherHub
-// The actual remove function is guaranteed to only be executed once
-func (w *watcher) Remove() {
-	w.hub.mutex.Lock()
-	defer w.hub.mutex.Unlock()
-
-	close(w.eventChan)
-	if w.remove != nil {
-		w.remove()
-	}
-}
-
-// nopWatcher is a watcher that receives nothing, always blocking.
-type nopWatcher struct{}
-
-func NewNopWatcher() Watcher                 { return &nopWatcher{} }
-func (w *nopWatcher) EventChan() chan *Event { return nil }
-func (w *nopWatcher) StartIndex() uint64     { return 0 }
-func (w *nopWatcher) Remove()                {}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher_hub.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher_hub.go
deleted file mode 100644
index a452e7e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2store/watcher_hub.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2015 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 v2store
-
-import (
-	"container/list"
-	"path"
-	"strings"
-	"sync"
-	"sync/atomic"
-
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-)
-
-// A watcherHub contains all subscribed watchers
-// watchers is a map with watched path as key and watcher as value
-// EventHistory keeps the old events for watcherHub. It is used to help
-// watcher to get a continuous event history. Or a watcher might miss the
-// event happens between the end of the first watch command and the start
-// of the second command.
-type watcherHub struct {
-	// count must be the first element to keep 64-bit alignment for atomic
-	// access
-
-	count int64 // current number of watchers.
-
-	mutex        sync.Mutex
-	watchers     map[string]*list.List
-	EventHistory *EventHistory
-}
-
-// newWatchHub creates a watcherHub. The capacity determines how many events we will
-// keep in the eventHistory.
-// Typically, we only need to keep a small size of history[smaller than 20K].
-// Ideally, it should smaller than 20K/s[max throughput] * 2 * 50ms[RTT] = 2000
-func newWatchHub(capacity int) *watcherHub {
-	return &watcherHub{
-		watchers:     make(map[string]*list.List),
-		EventHistory: newEventHistory(capacity),
-	}
-}
-
-// Watch function returns a Watcher.
-// If recursive is true, the first change after index under key will be sent to the event channel of the watcher.
-// If recursive is false, the first change after index at key will be sent to the event channel of the watcher.
-// If index is zero, watch will start from the current index + 1.
-func (wh *watcherHub) watch(key string, recursive, stream bool, index, storeIndex uint64) (Watcher, *v2error.Error) {
-	reportWatchRequest()
-	event, err := wh.EventHistory.scan(key, recursive, index)
-
-	if err != nil {
-		err.Index = storeIndex
-		return nil, err
-	}
-
-	w := &watcher{
-		eventChan:  make(chan *Event, 100), // use a buffered channel
-		recursive:  recursive,
-		stream:     stream,
-		sinceIndex: index,
-		startIndex: storeIndex,
-		hub:        wh,
-	}
-
-	wh.mutex.Lock()
-	defer wh.mutex.Unlock()
-	// If the event exists in the known history, append the EtcdIndex and return immediately
-	if event != nil {
-		ne := event.Clone()
-		ne.EtcdIndex = storeIndex
-		w.eventChan <- ne
-		return w, nil
-	}
-
-	l, ok := wh.watchers[key]
-
-	var elem *list.Element
-
-	if ok { // add the new watcher to the back of the list
-		elem = l.PushBack(w)
-	} else { // create a new list and add the new watcher
-		l = list.New()
-		elem = l.PushBack(w)
-		wh.watchers[key] = l
-	}
-
-	w.remove = func() {
-		if w.removed { // avoid removing it twice
-			return
-		}
-		w.removed = true
-		l.Remove(elem)
-		atomic.AddInt64(&wh.count, -1)
-		reportWatcherRemoved()
-		if l.Len() == 0 {
-			delete(wh.watchers, key)
-		}
-	}
-
-	atomic.AddInt64(&wh.count, 1)
-	reportWatcherAdded()
-
-	return w, nil
-}
-
-func (wh *watcherHub) add(e *Event) {
-	wh.EventHistory.addEvent(e)
-}
-
-// notify function accepts an event and notify to the watchers.
-func (wh *watcherHub) notify(e *Event) {
-	e = wh.EventHistory.addEvent(e) // add event into the eventHistory
-
-	segments := strings.Split(e.Node.Key, "/")
-
-	currPath := "/"
-
-	// walk through all the segments of the path and notify the watchers
-	// if the path is "/foo/bar", it will notify watchers with path "/",
-	// "/foo" and "/foo/bar"
-
-	for _, segment := range segments {
-		currPath = path.Join(currPath, segment)
-		// notify the watchers who interests in the changes of current path
-		wh.notifyWatchers(e, currPath, false)
-	}
-}
-
-func (wh *watcherHub) notifyWatchers(e *Event, nodePath string, deleted bool) {
-	wh.mutex.Lock()
-	defer wh.mutex.Unlock()
-
-	l, ok := wh.watchers[nodePath]
-	if ok {
-		curr := l.Front()
-
-		for curr != nil {
-			next := curr.Next() // save reference to the next one in the list
-
-			w, _ := curr.Value.(*watcher)
-
-			originalPath := e.Node.Key == nodePath
-			if (originalPath || !isHidden(nodePath, e.Node.Key)) && w.notify(e, originalPath, deleted) {
-				if !w.stream { // do not remove the stream watcher
-					// if we successfully notify a watcher
-					// we need to remove the watcher from the list
-					// and decrease the counter
-					w.removed = true
-					l.Remove(curr)
-					atomic.AddInt64(&wh.count, -1)
-					reportWatcherRemoved()
-				}
-			}
-
-			curr = next // update current to the next element in the list
-		}
-
-		if l.Len() == 0 {
-			// if we have notified all watcher in the list
-			// we can delete the list
-			delete(wh.watchers, nodePath)
-		}
-	}
-}
-
-// clone function clones the watcherHub and return the cloned one.
-// only clone the static content. do not clone the current watchers.
-func (wh *watcherHub) clone() *watcherHub {
-	clonedHistory := wh.EventHistory.clone()
-
-	return &watcherHub{
-		EventHistory: clonedHistory,
-	}
-}
-
-// isHidden checks to see if key path is considered hidden to watch path i.e. the
-// last element is hidden or it's within a hidden directory
-func isHidden(watchPath, keyPath string) bool {
-	// When deleting a directory, watchPath might be deeper than the actual keyPath
-	// For example, when deleting /foo we also need to notify watchers on /foo/bar.
-	if len(watchPath) > len(keyPath) {
-		return false
-	}
-	// if watch path is just a "/", after path will start without "/"
-	// add a "/" to deal with the special case when watchPath is "/"
-	afterPath := path.Clean("/" + keyPath[len(watchPath):])
-	return strings.Contains(afterPath, "/_")
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/cluster.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/cluster.go
deleted file mode 100644
index a22e4af..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/cluster.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 v2v3
-
-import (
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-func (s *v2v3Server) ID() types.ID {
-	// TODO: use an actual member ID
-	return types.ID(0xe7cd2f00d)
-}
-func (s *v2v3Server) ClientURLs() []string                  { panic("STUB") }
-func (s *v2v3Server) Members() []*membership.Member         { panic("STUB") }
-func (s *v2v3Server) Member(id types.ID) *membership.Member { panic("STUB") }
-func (s *v2v3Server) Version() *semver.Version              { panic("STUB") }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/doc.go
deleted file mode 100644
index 2ff372f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 v2v3 provides a ServerV2 implementation backed by clientv3.Client.
-package v2v3
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/server.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/server.go
deleted file mode 100644
index 5ff9b96..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/server.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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 v2v3
-
-import (
-	"context"
-	"net/http"
-	"time"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/go-semver/semver"
-	"go.uber.org/zap"
-)
-
-type fakeStats struct{}
-
-func (s *fakeStats) SelfStats() []byte   { return nil }
-func (s *fakeStats) LeaderStats() []byte { return nil }
-func (s *fakeStats) StoreStats() []byte  { return nil }
-
-type v2v3Server struct {
-	lg    *zap.Logger
-	c     *clientv3.Client
-	store *v2v3Store
-	fakeStats
-}
-
-func NewServer(lg *zap.Logger, c *clientv3.Client, pfx string) etcdserver.ServerPeer {
-	return &v2v3Server{lg: lg, c: c, store: newStore(c, pfx)}
-}
-
-func (s *v2v3Server) ClientCertAuthEnabled() bool { return false }
-
-func (s *v2v3Server) LeaseHandler() http.Handler { panic("STUB: lease handler") }
-func (s *v2v3Server) RaftHandler() http.Handler  { panic("STUB: raft handler") }
-
-func (s *v2v3Server) Leader() types.ID {
-	ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
-	defer cancel()
-	resp, err := s.c.Status(ctx, s.c.Endpoints()[0])
-	if err != nil {
-		return 0
-	}
-	return types.ID(resp.Leader)
-}
-
-func (s *v2v3Server) AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	// adding member as learner is not supported by V2 Server.
-	resp, err := s.c.MemberAdd(ctx, memb.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func (s *v2v3Server) RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	resp, err := s.c.MemberRemove(ctx, id)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func (s *v2v3Server) PromoteMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	resp, err := s.c.MemberPromote(ctx, id)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func (s *v2v3Server) UpdateMember(ctx context.Context, m membership.Member) ([]*membership.Member, error) {
-	resp, err := s.c.MemberUpdate(ctx, uint64(m.ID), m.PeerURLs)
-	if err != nil {
-		return nil, err
-	}
-	return v3MembersToMembership(resp.Members), nil
-}
-
-func v3MembersToMembership(v3membs []*pb.Member) []*membership.Member {
-	membs := make([]*membership.Member, len(v3membs))
-	for i, m := range v3membs {
-		membs[i] = &membership.Member{
-			ID: types.ID(m.ID),
-			RaftAttributes: membership.RaftAttributes{
-				PeerURLs:  m.PeerURLs,
-				IsLearner: m.IsLearner,
-			},
-			Attributes: membership.Attributes{
-				Name:       m.Name,
-				ClientURLs: m.ClientURLs,
-			},
-		}
-	}
-	return membs
-}
-
-func (s *v2v3Server) ClusterVersion() *semver.Version { return s.Version() }
-func (s *v2v3Server) Cluster() api.Cluster            { return s }
-func (s *v2v3Server) Alarms() []*pb.AlarmMember       { return nil }
-
-func (s *v2v3Server) Do(ctx context.Context, r pb.Request) (etcdserver.Response, error) {
-	applier := etcdserver.NewApplierV2(s.lg, s.store, nil)
-	reqHandler := etcdserver.NewStoreRequestV2Handler(s.store, applier)
-	req := (*etcdserver.RequestV2)(&r)
-	resp, err := req.Handle(ctx, reqHandler)
-	if resp.Err != nil {
-		return resp, resp.Err
-	}
-	return resp, err
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/store.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/store.go
deleted file mode 100644
index f1c7ab3..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/store.go
+++ /dev/null
@@ -1,638 +0,0 @@
-// 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 v2v3
-
-import (
-	"context"
-	"fmt"
-	"path"
-	"sort"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/clientv3/concurrency"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-// store implements the Store interface for V2 using
-// a v3 client.
-type v2v3Store struct {
-	c *clientv3.Client
-	// pfx is the v3 prefix where keys should be stored.
-	pfx string
-	ctx context.Context
-}
-
-const maxPathDepth = 63
-
-var errUnsupported = fmt.Errorf("TTLs are unsupported")
-
-func NewStore(c *clientv3.Client, pfx string) v2store.Store { return newStore(c, pfx) }
-
-func newStore(c *clientv3.Client, pfx string) *v2v3Store { return &v2v3Store{c, pfx, c.Ctx()} }
-
-func (s *v2v3Store) Index() uint64 { panic("STUB") }
-
-func (s *v2v3Store) Get(nodePath string, recursive, sorted bool) (*v2store.Event, error) {
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).Then(
-		clientv3.OpGet(key+"/"),
-		clientv3.OpGet(key),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-
-	if kvs := resp.Responses[0].GetResponseRange().Kvs; len(kvs) != 0 || isRoot(nodePath) {
-		nodes, err := s.getDir(nodePath, recursive, sorted, resp.Header.Revision)
-		if err != nil {
-			return nil, err
-		}
-		cidx, midx := uint64(0), uint64(0)
-		if len(kvs) > 0 {
-			cidx, midx = mkV2Rev(kvs[0].CreateRevision), mkV2Rev(kvs[0].ModRevision)
-		}
-		return &v2store.Event{
-			Action: v2store.Get,
-			Node: &v2store.NodeExtern{
-				Key:           nodePath,
-				Dir:           true,
-				Nodes:         nodes,
-				CreatedIndex:  cidx,
-				ModifiedIndex: midx,
-			},
-			EtcdIndex: mkV2Rev(resp.Header.Revision),
-		}, nil
-	}
-
-	kvs := resp.Responses[1].GetResponseRange().Kvs
-	if len(kvs) == 0 {
-		return nil, v2error.NewError(v2error.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	return &v2store.Event{
-		Action:    v2store.Get,
-		Node:      s.mkV2Node(kvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) getDir(nodePath string, recursive, sorted bool, rev int64) ([]*v2store.NodeExtern, error) {
-	rootNodes, err := s.getDirDepth(nodePath, 1, rev)
-	if err != nil || !recursive {
-		if sorted {
-			sort.Sort(v2store.NodeExterns(rootNodes))
-		}
-		return rootNodes, err
-	}
-	nextNodes := rootNodes
-	nodes := make(map[string]*v2store.NodeExtern)
-	// Breadth walk the subdirectories
-	for i := 2; len(nextNodes) > 0; i++ {
-		for _, n := range nextNodes {
-			nodes[n.Key] = n
-			if parent := nodes[path.Dir(n.Key)]; parent != nil {
-				parent.Nodes = append(parent.Nodes, n)
-			}
-		}
-		if nextNodes, err = s.getDirDepth(nodePath, i, rev); err != nil {
-			return nil, err
-		}
-	}
-
-	if sorted {
-		sort.Sort(v2store.NodeExterns(rootNodes))
-	}
-	return rootNodes, nil
-}
-
-func (s *v2v3Store) getDirDepth(nodePath string, depth int, rev int64) ([]*v2store.NodeExtern, error) {
-	pd := s.mkPathDepth(nodePath, depth)
-	resp, err := s.c.Get(s.ctx, pd, clientv3.WithPrefix(), clientv3.WithRev(rev))
-	if err != nil {
-		return nil, err
-	}
-
-	nodes := make([]*v2store.NodeExtern, len(resp.Kvs))
-	for i, kv := range resp.Kvs {
-		nodes[i] = s.mkV2Node(kv)
-	}
-	return nodes, nil
-}
-
-func (s *v2v3Store) Set(
-	nodePath string,
-	dir bool,
-	value string,
-	expireOpts v2store.TTLOptionSet,
-) (*v2store.Event, error) {
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		// build path if any directories in path do not exist
-		dirs := []string{}
-		for p := path.Dir(nodePath); !isRoot(p); p = path.Dir(p) {
-			pp := s.mkPath(p)
-			if stm.Rev(pp) > 0 {
-				ecode = v2error.EcodeNotDir
-				return nil
-			}
-			if stm.Rev(pp+"/") == 0 {
-				dirs = append(dirs, pp+"/")
-			}
-		}
-		for _, d := range dirs {
-			stm.Put(d, "")
-		}
-
-		key := s.mkPath(nodePath)
-		if dir {
-			if stm.Rev(key) != 0 {
-				// exists as non-dir
-				ecode = v2error.EcodeNotDir
-				return nil
-			}
-			key = key + "/"
-		} else if stm.Rev(key+"/") != 0 {
-			ecode = v2error.EcodeNotFile
-			return nil
-		}
-		stm.Put(key, value, clientv3.WithPrevKV())
-		stm.Put(s.mkActionKey(), v2store.Set)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, v2error.NewError(ecode, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	createRev := resp.Header.Revision
-	var pn *v2store.NodeExtern
-	if pkv := prevKeyFromPuts(resp); pkv != nil {
-		pn = s.mkV2Node(pkv)
-		createRev = pkv.CreateRevision
-	}
-
-	vp := &value
-	if dir {
-		vp = nil
-	}
-	return &v2store.Event{
-		Action: v2store.Set,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			Value:         vp,
-			Dir:           dir,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(createRev),
-		},
-		PrevNode:  pn,
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Update(nodePath, newValue string, expireOpts v2store.TTLOptionSet) (*v2store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	key := s.mkPath(nodePath)
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		if rev := stm.Rev(key + "/"); rev != 0 {
-			ecode = v2error.EcodeNotFile
-			return nil
-		}
-		if rev := stm.Rev(key); rev == 0 {
-			ecode = v2error.EcodeKeyNotFound
-			return nil
-		}
-		stm.Put(key, newValue, clientv3.WithPrevKV())
-		stm.Put(s.mkActionKey(), v2store.Update)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	pkv := prevKeyFromPuts(resp)
-	return &v2store.Event{
-		Action: v2store.Update,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			Value:         &newValue,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Create(
-	nodePath string,
-	dir bool,
-	value string,
-	unique bool,
-	expireOpts v2store.TTLOptionSet,
-) (*v2store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-	ecode := 0
-	applyf := func(stm concurrency.STM) error {
-		ecode = 0
-		key := s.mkPath(nodePath)
-		if unique {
-			// append unique item under the node path
-			for {
-				key = nodePath + "/" + fmt.Sprintf("%020s", time.Now())
-				key = path.Clean(path.Join("/", key))
-				key = s.mkPath(key)
-				if stm.Rev(key) == 0 {
-					break
-				}
-			}
-		}
-		if stm.Rev(key) > 0 || stm.Rev(key+"/") > 0 {
-			ecode = v2error.EcodeNodeExist
-			return nil
-		}
-		// build path if any directories in path do not exist
-		dirs := []string{}
-		for p := path.Dir(nodePath); !isRoot(p); p = path.Dir(p) {
-			pp := s.mkPath(p)
-			if stm.Rev(pp) > 0 {
-				ecode = v2error.EcodeNotDir
-				return nil
-			}
-			if stm.Rev(pp+"/") == 0 {
-				dirs = append(dirs, pp+"/")
-			}
-		}
-		for _, d := range dirs {
-			stm.Put(d, "")
-		}
-
-		if dir {
-			// directories marked with extra slash in key name
-			key += "/"
-		}
-		stm.Put(key, value)
-		stm.Put(s.mkActionKey(), v2store.Create)
-		return nil
-	}
-
-	resp, err := s.newSTM(applyf)
-	if err != nil {
-		return nil, err
-	}
-	if ecode != 0 {
-		return nil, v2error.NewError(ecode, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-
-	var v *string
-	if !dir {
-		v = &value
-	}
-
-	return &v2store.Event{
-		Action: v2store.Create,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			Value:         v,
-			Dir:           dir,
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-			CreatedIndex:  mkV2Rev(resp.Header.Revision),
-		},
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) CompareAndSwap(
-	nodePath string,
-	prevValue string,
-	prevIndex uint64,
-	value string,
-	expireOpts v2store.TTLOptionSet,
-) (*v2store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-	if expireOpts.Refresh || !expireOpts.ExpireTime.IsZero() {
-		return nil, errUnsupported
-	}
-
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).If(
-		s.mkCompare(nodePath, prevValue, prevIndex)...,
-	).Then(
-		clientv3.OpPut(key, value, clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), v2store.CompareAndSwap),
-	).Else(
-		clientv3.OpGet(key),
-		clientv3.OpGet(key+"/"),
-	).Commit()
-
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, compareFail(nodePath, prevValue, prevIndex, resp)
-	}
-
-	pkv := resp.Responses[0].GetResponsePut().PrevKv
-	return &v2store.Event{
-		Action: v2store.CompareAndSwap,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			Value:         &value,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) Delete(nodePath string, dir, recursive bool) (*v2store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-	if !dir && !recursive {
-		return s.deleteNode(nodePath)
-	}
-	if !recursive {
-		return s.deleteEmptyDir(nodePath)
-	}
-
-	dels := make([]clientv3.Op, maxPathDepth+1)
-	dels[0] = clientv3.OpDelete(s.mkPath(nodePath)+"/", clientv3.WithPrevKV())
-	for i := 1; i < maxPathDepth; i++ {
-		dels[i] = clientv3.OpDelete(s.mkPathDepth(nodePath, i), clientv3.WithPrefix())
-	}
-	dels[maxPathDepth] = clientv3.OpPut(s.mkActionKey(), v2store.Delete)
-
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPath(nodePath)+"/"), ">", 0),
-		clientv3.Compare(clientv3.Version(s.mkPathDepth(nodePath, maxPathDepth)+"/"), "=", 0),
-	).Then(
-		dels...,
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, v2error.NewError(v2error.EcodeNodeExist, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	dresp := resp.Responses[0].GetResponseDeleteRange()
-	return &v2store.Event{
-		Action:    v2store.Delete,
-		PrevNode:  s.mkV2Node(dresp.PrevKvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) deleteEmptyDir(nodePath string) (*v2store.Event, error) {
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPathDepth(nodePath, 1)), "=", 0).WithPrefix(),
-	).Then(
-		clientv3.OpDelete(s.mkPath(nodePath)+"/", clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), v2store.Delete),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, v2error.NewError(v2error.EcodeDirNotEmpty, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	dresp := resp.Responses[0].GetResponseDeleteRange()
-	if len(dresp.PrevKvs) == 0 {
-		return nil, v2error.NewError(v2error.EcodeNodeExist, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	return &v2store.Event{
-		Action:    v2store.Delete,
-		PrevNode:  s.mkV2Node(dresp.PrevKvs[0]),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) deleteNode(nodePath string) (*v2store.Event, error) {
-	resp, err := s.c.Txn(s.ctx).If(
-		clientv3.Compare(clientv3.Version(s.mkPath(nodePath)+"/"), "=", 0),
-	).Then(
-		clientv3.OpDelete(s.mkPath(nodePath), clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), v2store.Delete),
-	).Commit()
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, v2error.NewError(v2error.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	pkvs := resp.Responses[0].GetResponseDeleteRange().PrevKvs
-	if len(pkvs) == 0 {
-		return nil, v2error.NewError(v2error.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	pkv := pkvs[0]
-	return &v2store.Event{
-		Action: v2store.Delete,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func (s *v2v3Store) CompareAndDelete(nodePath, prevValue string, prevIndex uint64) (*v2store.Event, error) {
-	if isRoot(nodePath) {
-		return nil, v2error.NewError(v2error.EcodeRootROnly, nodePath, 0)
-	}
-
-	key := s.mkPath(nodePath)
-	resp, err := s.c.Txn(s.ctx).If(
-		s.mkCompare(nodePath, prevValue, prevIndex)...,
-	).Then(
-		clientv3.OpDelete(key, clientv3.WithPrevKV()),
-		clientv3.OpPut(s.mkActionKey(), v2store.CompareAndDelete),
-	).Else(
-		clientv3.OpGet(key),
-		clientv3.OpGet(key+"/"),
-	).Commit()
-
-	if err != nil {
-		return nil, err
-	}
-	if !resp.Succeeded {
-		return nil, compareFail(nodePath, prevValue, prevIndex, resp)
-	}
-
-	// len(pkvs) > 1 since txn only succeeds when key exists
-	pkv := resp.Responses[0].GetResponseDeleteRange().PrevKvs[0]
-	return &v2store.Event{
-		Action: v2store.CompareAndDelete,
-		Node: &v2store.NodeExtern{
-			Key:           nodePath,
-			CreatedIndex:  mkV2Rev(pkv.CreateRevision),
-			ModifiedIndex: mkV2Rev(resp.Header.Revision),
-		},
-		PrevNode:  s.mkV2Node(pkv),
-		EtcdIndex: mkV2Rev(resp.Header.Revision),
-	}, nil
-}
-
-func compareFail(nodePath, prevValue string, prevIndex uint64, resp *clientv3.TxnResponse) error {
-	if dkvs := resp.Responses[1].GetResponseRange().Kvs; len(dkvs) > 0 {
-		return v2error.NewError(v2error.EcodeNotFile, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	kvs := resp.Responses[0].GetResponseRange().Kvs
-	if len(kvs) == 0 {
-		return v2error.NewError(v2error.EcodeKeyNotFound, nodePath, mkV2Rev(resp.Header.Revision))
-	}
-	kv := kvs[0]
-	indexMatch := prevIndex == 0 || kv.ModRevision == int64(prevIndex)
-	valueMatch := prevValue == "" || string(kv.Value) == prevValue
-	var cause string
-	switch {
-	case indexMatch && !valueMatch:
-		cause = fmt.Sprintf("[%v != %v]", prevValue, string(kv.Value))
-	case valueMatch && !indexMatch:
-		cause = fmt.Sprintf("[%v != %v]", prevIndex, kv.ModRevision)
-	default:
-		cause = fmt.Sprintf("[%v != %v] [%v != %v]", prevValue, string(kv.Value), prevIndex, kv.ModRevision)
-	}
-	return v2error.NewError(v2error.EcodeTestFailed, cause, mkV2Rev(resp.Header.Revision))
-}
-
-func (s *v2v3Store) mkCompare(nodePath, prevValue string, prevIndex uint64) []clientv3.Cmp {
-	key := s.mkPath(nodePath)
-	cmps := []clientv3.Cmp{clientv3.Compare(clientv3.Version(key), ">", 0)}
-	if prevIndex != 0 {
-		cmps = append(cmps, clientv3.Compare(clientv3.ModRevision(key), "=", mkV3Rev(prevIndex)))
-	}
-	if prevValue != "" {
-		cmps = append(cmps, clientv3.Compare(clientv3.Value(key), "=", prevValue))
-	}
-	return cmps
-}
-
-func (s *v2v3Store) JsonStats() []byte                  { panic("STUB") }
-func (s *v2v3Store) DeleteExpiredKeys(cutoff time.Time) { panic("STUB") }
-
-func (s *v2v3Store) Version() int { return 2 }
-
-// TODO: move this out of the Store interface?
-
-func (s *v2v3Store) Save() ([]byte, error)       { panic("STUB") }
-func (s *v2v3Store) Recovery(state []byte) error { panic("STUB") }
-func (s *v2v3Store) Clone() v2store.Store        { panic("STUB") }
-func (s *v2v3Store) SaveNoCopy() ([]byte, error) { panic("STUB") }
-func (s *v2v3Store) HasTTLKeys() bool            { panic("STUB") }
-
-func (s *v2v3Store) mkPath(nodePath string) string { return s.mkPathDepth(nodePath, 0) }
-
-func (s *v2v3Store) mkNodePath(p string) string {
-	return path.Clean(p[len(s.pfx)+len("/k/000/"):])
-}
-
-// mkPathDepth makes a path to a key that encodes its directory depth
-// for fast directory listing. If a depth is provided, it is added
-// to the computed depth.
-func (s *v2v3Store) mkPathDepth(nodePath string, depth int) string {
-	normalForm := path.Clean(path.Join("/", nodePath))
-	n := strings.Count(normalForm, "/") + depth
-	return fmt.Sprintf("%s/%03d/k/%s", s.pfx, n, normalForm)
-}
-
-func (s *v2v3Store) mkActionKey() string { return s.pfx + "/act" }
-
-func isRoot(s string) bool { return len(s) == 0 || s == "/" || s == "/0" || s == "/1" }
-
-func mkV2Rev(v3Rev int64) uint64 {
-	if v3Rev == 0 {
-		return 0
-	}
-	return uint64(v3Rev - 1)
-}
-
-func mkV3Rev(v2Rev uint64) int64 {
-	if v2Rev == 0 {
-		return 0
-	}
-	return int64(v2Rev + 1)
-}
-
-// mkV2Node creates a V2 NodeExtern from a V3 KeyValue
-func (s *v2v3Store) mkV2Node(kv *mvccpb.KeyValue) *v2store.NodeExtern {
-	if kv == nil {
-		return nil
-	}
-	n := &v2store.NodeExtern{
-		Key:           s.mkNodePath(string(kv.Key)),
-		Dir:           kv.Key[len(kv.Key)-1] == '/',
-		CreatedIndex:  mkV2Rev(kv.CreateRevision),
-		ModifiedIndex: mkV2Rev(kv.ModRevision),
-	}
-	if !n.Dir {
-		v := string(kv.Value)
-		n.Value = &v
-	}
-	return n
-}
-
-// prevKeyFromPuts gets the prev key that is being put; ignores
-// the put action response.
-func prevKeyFromPuts(resp *clientv3.TxnResponse) *mvccpb.KeyValue {
-	for _, r := range resp.Responses {
-		pkv := r.GetResponsePut().PrevKv
-		if pkv != nil && pkv.CreateRevision > 0 {
-			return pkv
-		}
-	}
-	return nil
-}
-
-func (s *v2v3Store) newSTM(applyf func(concurrency.STM) error) (*clientv3.TxnResponse, error) {
-	return concurrency.NewSTM(s.c, applyf, concurrency.WithIsolation(concurrency.Serializable))
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/watcher.go b/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/watcher.go
deleted file mode 100644
index e8a3557..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v2v3/watcher.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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 v2v3
-
-import (
-	"context"
-	"strings"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/etcdserver/api/v2error"
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-)
-
-func (s *v2v3Store) Watch(prefix string, recursive, stream bool, sinceIndex uint64) (v2store.Watcher, error) {
-	ctx, cancel := context.WithCancel(s.ctx)
-	wch := s.c.Watch(
-		ctx,
-		// TODO: very pricey; use a single store-wide watch in future
-		s.pfx,
-		clientv3.WithPrefix(),
-		clientv3.WithRev(int64(sinceIndex)),
-		clientv3.WithCreatedNotify(),
-		clientv3.WithPrevKV())
-	resp, ok := <-wch
-	if err := resp.Err(); err != nil || !ok {
-		cancel()
-		return nil, v2error.NewError(v2error.EcodeRaftInternal, prefix, 0)
-	}
-
-	evc, donec := make(chan *v2store.Event), make(chan struct{})
-	go func() {
-		defer func() {
-			close(evc)
-			close(donec)
-		}()
-		for resp := range wch {
-			for _, ev := range s.mkV2Events(resp) {
-				k := ev.Node.Key
-				if recursive {
-					if !strings.HasPrefix(k, prefix) {
-						continue
-					}
-					// accept events on hidden keys given in prefix
-					k = strings.Replace(k, prefix, "/", 1)
-					// ignore hidden keys deeper than prefix
-					if strings.Contains(k, "/_") {
-						continue
-					}
-				}
-				if !recursive && k != prefix {
-					continue
-				}
-				select {
-				case evc <- ev:
-				case <-ctx.Done():
-					return
-				}
-				if !stream {
-					return
-				}
-			}
-		}
-	}()
-
-	return &v2v3Watcher{
-		startRev: resp.Header.Revision,
-		evc:      evc,
-		donec:    donec,
-		cancel:   cancel,
-	}, nil
-}
-
-func (s *v2v3Store) mkV2Events(wr clientv3.WatchResponse) (evs []*v2store.Event) {
-	ak := s.mkActionKey()
-	for _, rev := range mkRevs(wr) {
-		var act, key *clientv3.Event
-		for _, ev := range rev {
-			if string(ev.Kv.Key) == ak {
-				act = ev
-			} else if key != nil && len(key.Kv.Key) < len(ev.Kv.Key) {
-				// use longest key to ignore intermediate new
-				// directories from Create.
-				key = ev
-			} else if key == nil {
-				key = ev
-			}
-		}
-		v2ev := &v2store.Event{
-			Action:    string(act.Kv.Value),
-			Node:      s.mkV2Node(key.Kv),
-			PrevNode:  s.mkV2Node(key.PrevKv),
-			EtcdIndex: mkV2Rev(wr.Header.Revision),
-		}
-		evs = append(evs, v2ev)
-	}
-	return evs
-}
-
-func mkRevs(wr clientv3.WatchResponse) (revs [][]*clientv3.Event) {
-	var curRev []*clientv3.Event
-	for _, ev := range wr.Events {
-		if curRev != nil && ev.Kv.ModRevision != curRev[0].Kv.ModRevision {
-			revs = append(revs, curRev)
-			curRev = nil
-		}
-		curRev = append(curRev, ev)
-	}
-	if curRev != nil {
-		revs = append(revs, curRev)
-	}
-	return revs
-}
-
-type v2v3Watcher struct {
-	startRev int64
-	evc      chan *v2store.Event
-	donec    chan struct{}
-	cancel   context.CancelFunc
-}
-
-func (w *v2v3Watcher) StartIndex() uint64 { return mkV2Rev(w.startRev) }
-
-func (w *v2v3Watcher) Remove() {
-	w.cancel()
-	<-w.donec
-}
-
-func (w *v2v3Watcher) EventChan() chan *v2store.Event { return w.evc }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3alarm/alarms.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3alarm/alarms.go
deleted file mode 100644
index 2b085a8..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3alarm/alarms.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 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 v3alarm manages health status alarms in etcd.
-package v3alarm
-
-import (
-	"sync"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	alarmBucketName = []byte("alarm")
-	plog            = capnslog.NewPackageLogger("go.etcd.io/etcd", "alarm")
-)
-
-type BackendGetter interface {
-	Backend() backend.Backend
-}
-
-type alarmSet map[types.ID]*pb.AlarmMember
-
-// AlarmStore persists alarms to the backend.
-type AlarmStore struct {
-	mu    sync.Mutex
-	types map[pb.AlarmType]alarmSet
-
-	bg BackendGetter
-}
-
-func NewAlarmStore(bg BackendGetter) (*AlarmStore, error) {
-	ret := &AlarmStore{types: make(map[pb.AlarmType]alarmSet), bg: bg}
-	err := ret.restore()
-	return ret, err
-}
-
-func (a *AlarmStore) Activate(id types.ID, at pb.AlarmType) *pb.AlarmMember {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-
-	newAlarm := &pb.AlarmMember{MemberID: uint64(id), Alarm: at}
-	if m := a.addToMap(newAlarm); m != newAlarm {
-		return m
-	}
-
-	v, err := newAlarm.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal alarm member")
-	}
-
-	b := a.bg.Backend()
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafePut(alarmBucketName, v, nil)
-	b.BatchTx().Unlock()
-
-	return newAlarm
-}
-
-func (a *AlarmStore) Deactivate(id types.ID, at pb.AlarmType) *pb.AlarmMember {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-
-	t := a.types[at]
-	if t == nil {
-		t = make(alarmSet)
-		a.types[at] = t
-	}
-	m := t[id]
-	if m == nil {
-		return nil
-	}
-
-	delete(t, id)
-
-	v, err := m.Marshal()
-	if err != nil {
-		plog.Panicf("failed to marshal alarm member")
-	}
-
-	b := a.bg.Backend()
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafeDelete(alarmBucketName, v)
-	b.BatchTx().Unlock()
-
-	return m
-}
-
-func (a *AlarmStore) Get(at pb.AlarmType) (ret []*pb.AlarmMember) {
-	a.mu.Lock()
-	defer a.mu.Unlock()
-	if at == pb.AlarmType_NONE {
-		for _, t := range a.types {
-			for _, m := range t {
-				ret = append(ret, m)
-			}
-		}
-		return ret
-	}
-	for _, m := range a.types[at] {
-		ret = append(ret, m)
-	}
-	return ret
-}
-
-func (a *AlarmStore) restore() error {
-	b := a.bg.Backend()
-	tx := b.BatchTx()
-
-	tx.Lock()
-	tx.UnsafeCreateBucket(alarmBucketName)
-	err := tx.UnsafeForEach(alarmBucketName, func(k, v []byte) error {
-		var m pb.AlarmMember
-		if err := m.Unmarshal(k); err != nil {
-			return err
-		}
-		a.addToMap(&m)
-		return nil
-	})
-	tx.Unlock()
-
-	b.ForceCommit()
-	return err
-}
-
-func (a *AlarmStore) addToMap(newAlarm *pb.AlarmMember) *pb.AlarmMember {
-	t := a.types[newAlarm.Alarm]
-	if t == nil {
-		t = make(alarmSet)
-		a.types[newAlarm.Alarm] = t
-	}
-	m := t[types.ID(newAlarm.MemberID)]
-	if m != nil {
-		return m
-	}
-	t[types.ID(newAlarm.MemberID)] = newAlarm
-	return newAlarm
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3client/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3client/doc.go
deleted file mode 100644
index 47922c4..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3client/doc.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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 v3client provides clientv3 interfaces from an etcdserver.
-//
-// Use v3client by creating an EtcdServer instance, then wrapping it with v3client.New:
-//
-//	import (
-//		"context"
-//
-//		"go.etcd.io/etcd/embed"
-//		"go.etcd.io/etcd/etcdserver/api/v3client"
-//	)
-//
-//	...
-//
-//	// create an embedded EtcdServer from the default configuration
-//	cfg := embed.NewConfig()
-//	cfg.Dir = "default.etcd"
-//	e, err := embed.StartEtcd(cfg)
-//	if err != nil {
-//		// handle error!
-//	}
-//
-//	// wrap the EtcdServer with v3client
-//	cli := v3client.New(e.Server)
-//
-//	// use like an ordinary clientv3
-//	resp, err := cli.Put(context.TODO(), "some-key", "it works!")
-//	if err != nil {
-//		// handle error!
-//	}
-//
-package v3client
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3client/v3client.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3client/v3client.go
deleted file mode 100644
index d203121..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3client/v3client.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 v3client
-
-import (
-	"context"
-	"time"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc"
-	"go.etcd.io/etcd/proxy/grpcproxy/adapter"
-)
-
-// New creates a clientv3 client that wraps an in-process EtcdServer. Instead
-// of making gRPC calls through sockets, the client makes direct function calls
-// to the etcd server through its api/v3rpc function interfaces.
-func New(s *etcdserver.EtcdServer) *clientv3.Client {
-	c := clientv3.NewCtxClient(context.Background())
-
-	kvc := adapter.KvServerToKvClient(v3rpc.NewQuotaKVServer(s))
-	c.KV = clientv3.NewKVFromKVClient(kvc, c)
-
-	lc := adapter.LeaseServerToLeaseClient(v3rpc.NewQuotaLeaseServer(s))
-	c.Lease = clientv3.NewLeaseFromLeaseClient(lc, c, time.Second)
-
-	wc := adapter.WatchServerToWatchClient(v3rpc.NewWatchServer(s))
-	c.Watcher = &watchWrapper{clientv3.NewWatchFromWatchClient(wc, c)}
-
-	mc := adapter.MaintenanceServerToMaintenanceClient(v3rpc.NewMaintenanceServer(s))
-	c.Maintenance = clientv3.NewMaintenanceFromMaintenanceClient(mc, c)
-
-	clc := adapter.ClusterServerToClusterClient(v3rpc.NewClusterServer(s))
-	c.Cluster = clientv3.NewClusterFromClusterClient(clc, c)
-
-	// TODO: implement clientv3.Auth interface?
-
-	return c
-}
-
-// BlankContext implements Stringer on a context so the ctx string doesn't
-// depend on the context's WithValue data, which tends to be unsynchronized
-// (e.g., x/net/trace), causing ctx.String() to throw data races.
-type blankContext struct{ context.Context }
-
-func (*blankContext) String() string { return "(blankCtx)" }
-
-// watchWrapper wraps clientv3 watch calls to blank out the context
-// to avoid races on trace data.
-type watchWrapper struct{ clientv3.Watcher }
-
-func (ww *watchWrapper) Watch(ctx context.Context, key string, opts ...clientv3.OpOption) clientv3.WatchChan {
-	return ww.Watcher.Watch(&blankContext{ctx}, key, opts...)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/compactor.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/compactor.go
deleted file mode 100644
index 73a9684..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/compactor.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2016 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 v3compactor
-
-import (
-	"context"
-	"fmt"
-	"time"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/jonboulle/clockwork"
-	"go.uber.org/zap"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "compactor")
-)
-
-const (
-	ModePeriodic = "periodic"
-	ModeRevision = "revision"
-)
-
-// Compactor purges old log from the storage periodically.
-type Compactor interface {
-	// Run starts the main loop of the compactor in background.
-	// Use Stop() to halt the loop and release the resource.
-	Run()
-	// Stop halts the main loop of the compactor.
-	Stop()
-	// Pause temporally suspend the compactor not to run compaction. Resume() to unpose.
-	Pause()
-	// Resume restarts the compactor suspended by Pause().
-	Resume()
-}
-
-type Compactable interface {
-	Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error)
-}
-
-type RevGetter interface {
-	Rev() int64
-}
-
-// New returns a new Compactor based on given "mode".
-func New(
-	lg *zap.Logger,
-	mode string,
-	retention time.Duration,
-	rg RevGetter,
-	c Compactable,
-) (Compactor, error) {
-	switch mode {
-	case ModePeriodic:
-		return newPeriodic(lg, clockwork.NewRealClock(), retention, rg, c), nil
-	case ModeRevision:
-		return newRevision(lg, clockwork.NewRealClock(), int64(retention), rg, c), nil
-	default:
-		return nil, fmt.Errorf("unsupported compaction mode %s", mode)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/doc.go
deleted file mode 100644
index bb28046..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 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 v3compactor implements automated policies for compacting etcd's mvcc storage.
-package v3compactor
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/periodic.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/periodic.go
deleted file mode 100644
index ab64cb7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/periodic.go
+++ /dev/null
@@ -1,217 +0,0 @@
-// 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 v3compactor
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc"
-
-	"github.com/jonboulle/clockwork"
-	"go.uber.org/zap"
-)
-
-// Periodic compacts the log by purging revisions older than
-// the configured retention time.
-type Periodic struct {
-	lg     *zap.Logger
-	clock  clockwork.Clock
-	period time.Duration
-
-	rg RevGetter
-	c  Compactable
-
-	revs   []int64
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	// mu protects paused
-	mu     sync.RWMutex
-	paused bool
-}
-
-// newPeriodic creates a new instance of Periodic compactor that purges
-// the log older than h Duration.
-func newPeriodic(lg *zap.Logger, clock clockwork.Clock, h time.Duration, rg RevGetter, c Compactable) *Periodic {
-	pc := &Periodic{
-		lg:     lg,
-		clock:  clock,
-		period: h,
-		rg:     rg,
-		c:      c,
-		revs:   make([]int64, 0),
-	}
-	pc.ctx, pc.cancel = context.WithCancel(context.Background())
-	return pc
-}
-
-/*
-Compaction period 1-hour:
-  1. compute compaction period, which is 1-hour
-  2. record revisions for every 1/10 of 1-hour (6-minute)
-  3. keep recording revisions with no compaction for first 1-hour
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 1-hour (6-minute)
-
-Compaction period 24-hour:
-  1. compute compaction period, which is 1-hour
-  2. record revisions for every 1/10 of 1-hour (6-minute)
-  3. keep recording revisions with no compaction for first 24-hour
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 1-hour (6-minute)
-
-Compaction period 59-min:
-  1. compute compaction period, which is 59-min
-  2. record revisions for every 1/10 of 59-min (5.9-min)
-  3. keep recording revisions with no compaction for first 59-min
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 59-min (5.9-min)
-
-Compaction period 5-sec:
-  1. compute compaction period, which is 5-sec
-  2. record revisions for every 1/10 of 5-sec (0.5-sec)
-  3. keep recording revisions with no compaction for first 5-sec
-  4. do compact with revs[0]
-	- success? contiue on for-loop and move sliding window; revs = revs[1:]
-	- failure? update revs, and retry after 1/10 of 5-sec (0.5-sec)
-*/
-
-// Run runs periodic compactor.
-func (pc *Periodic) Run() {
-	compactInterval := pc.getCompactInterval()
-	retryInterval := pc.getRetryInterval()
-	retentions := pc.getRetentions()
-
-	go func() {
-		lastSuccess := pc.clock.Now()
-		baseInterval := pc.period
-		for {
-			pc.revs = append(pc.revs, pc.rg.Rev())
-			if len(pc.revs) > retentions {
-				pc.revs = pc.revs[1:] // pc.revs[0] is always the rev at pc.period ago
-			}
-
-			select {
-			case <-pc.ctx.Done():
-				return
-			case <-pc.clock.After(retryInterval):
-				pc.mu.Lock()
-				p := pc.paused
-				pc.mu.Unlock()
-				if p {
-					continue
-				}
-			}
-
-			if pc.clock.Now().Sub(lastSuccess) < baseInterval {
-				continue
-			}
-
-			// wait up to initial given period
-			if baseInterval == pc.period {
-				baseInterval = compactInterval
-			}
-			rev := pc.revs[0]
-
-			if pc.lg != nil {
-				pc.lg.Info(
-					"starting auto periodic compaction",
-					zap.Int64("revision", rev),
-					zap.Duration("compact-period", pc.period),
-				)
-			} else {
-				plog.Noticef("Starting auto-compaction at revision %d (retention: %v)", rev, pc.period)
-			}
-			_, err := pc.c.Compact(pc.ctx, &pb.CompactionRequest{Revision: rev})
-			if err == nil || err == mvcc.ErrCompacted {
-				if pc.lg != nil {
-					pc.lg.Info(
-						"completed auto periodic compaction",
-						zap.Int64("revision", rev),
-						zap.Duration("compact-period", pc.period),
-						zap.Duration("took", time.Since(lastSuccess)),
-					)
-				} else {
-					plog.Noticef("Finished auto-compaction at revision %d", rev)
-				}
-				lastSuccess = pc.clock.Now()
-			} else {
-				if pc.lg != nil {
-					pc.lg.Warn(
-						"failed auto periodic compaction",
-						zap.Int64("revision", rev),
-						zap.Duration("compact-period", pc.period),
-						zap.Duration("retry-interval", retryInterval),
-						zap.Error(err),
-					)
-				} else {
-					plog.Noticef("Failed auto-compaction at revision %d (%v)", rev, err)
-					plog.Noticef("Retry after %v", retryInterval)
-				}
-			}
-		}
-	}()
-}
-
-// if given compaction period x is <1-hour, compact every x duration.
-// (e.g. --auto-compaction-mode 'periodic' --auto-compaction-retention='10m', then compact every 10-minute)
-// if given compaction period x is >1-hour, compact every hour.
-// (e.g. --auto-compaction-mode 'periodic' --auto-compaction-retention='2h', then compact every 1-hour)
-func (pc *Periodic) getCompactInterval() time.Duration {
-	itv := pc.period
-	if itv > time.Hour {
-		itv = time.Hour
-	}
-	return itv
-}
-
-func (pc *Periodic) getRetentions() int {
-	return int(pc.period/pc.getRetryInterval()) + 1
-}
-
-const retryDivisor = 10
-
-func (pc *Periodic) getRetryInterval() time.Duration {
-	itv := pc.period
-	if itv > time.Hour {
-		itv = time.Hour
-	}
-	return itv / retryDivisor
-}
-
-// Stop stops periodic compactor.
-func (pc *Periodic) Stop() {
-	pc.cancel()
-}
-
-// Pause pauses periodic compactor.
-func (pc *Periodic) Pause() {
-	pc.mu.Lock()
-	pc.paused = true
-	pc.mu.Unlock()
-}
-
-// Resume resumes periodic compactor.
-func (pc *Periodic) Resume() {
-	pc.mu.Lock()
-	pc.paused = false
-	pc.mu.Unlock()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/revision.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/revision.go
deleted file mode 100644
index cf8ac43..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3compactor/revision.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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 v3compactor
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc"
-
-	"github.com/jonboulle/clockwork"
-	"go.uber.org/zap"
-)
-
-// Revision compacts the log by purging revisions older than
-// the configured reivison number. Compaction happens every 5 minutes.
-type Revision struct {
-	lg *zap.Logger
-
-	clock     clockwork.Clock
-	retention int64
-
-	rg RevGetter
-	c  Compactable
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	mu     sync.Mutex
-	paused bool
-}
-
-// newRevision creates a new instance of Revisonal compactor that purges
-// the log older than retention revisions from the current revision.
-func newRevision(lg *zap.Logger, clock clockwork.Clock, retention int64, rg RevGetter, c Compactable) *Revision {
-	rc := &Revision{
-		lg:        lg,
-		clock:     clock,
-		retention: retention,
-		rg:        rg,
-		c:         c,
-	}
-	rc.ctx, rc.cancel = context.WithCancel(context.Background())
-	return rc
-}
-
-const revInterval = 5 * time.Minute
-
-// Run runs revision-based compactor.
-func (rc *Revision) Run() {
-	prev := int64(0)
-	go func() {
-		for {
-			select {
-			case <-rc.ctx.Done():
-				return
-			case <-rc.clock.After(revInterval):
-				rc.mu.Lock()
-				p := rc.paused
-				rc.mu.Unlock()
-				if p {
-					continue
-				}
-			}
-
-			rev := rc.rg.Rev() - rc.retention
-			if rev <= 0 || rev == prev {
-				continue
-			}
-
-			now := time.Now()
-			if rc.lg != nil {
-				rc.lg.Info(
-					"starting auto revision compaction",
-					zap.Int64("revision", rev),
-					zap.Int64("revision-compaction-retention", rc.retention),
-				)
-			} else {
-				plog.Noticef("Starting auto-compaction at revision %d (retention: %d revisions)", rev, rc.retention)
-			}
-			_, err := rc.c.Compact(rc.ctx, &pb.CompactionRequest{Revision: rev})
-			if err == nil || err == mvcc.ErrCompacted {
-				prev = rev
-				if rc.lg != nil {
-					rc.lg.Info(
-						"completed auto revision compaction",
-						zap.Int64("revision", rev),
-						zap.Int64("revision-compaction-retention", rc.retention),
-						zap.Duration("took", time.Since(now)),
-					)
-				} else {
-					plog.Noticef("Finished auto-compaction at revision %d", rev)
-				}
-			} else {
-				if rc.lg != nil {
-					rc.lg.Warn(
-						"failed auto revision compaction",
-						zap.Int64("revision", rev),
-						zap.Int64("revision-compaction-retention", rc.retention),
-						zap.Duration("retry-interval", revInterval),
-						zap.Error(err),
-					)
-				} else {
-					plog.Noticef("Failed auto-compaction at revision %d (%v)", rev, err)
-					plog.Noticef("Retry after %v", revInterval)
-				}
-			}
-		}
-	}()
-}
-
-// Stop stops revision-based compactor.
-func (rc *Revision) Stop() {
-	rc.cancel()
-}
-
-// Pause pauses revision-based compactor.
-func (rc *Revision) Pause() {
-	rc.mu.Lock()
-	rc.paused = true
-	rc.mu.Unlock()
-}
-
-// Resume resumes revision-based compactor.
-func (rc *Revision) Resume() {
-	rc.mu.Lock()
-	rc.paused = false
-	rc.mu.Unlock()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3election/doc.go
deleted file mode 100644
index d6fefd7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 v3election provides a v3 election service from an etcdserver.
-package v3election
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/election.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3election/election.go
deleted file mode 100644
index f5a3be3..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/election.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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 v3election
-
-import (
-	"context"
-	"errors"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/clientv3/concurrency"
-	epb "go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb"
-)
-
-// ErrMissingLeaderKey is returned when election API request
-// is missing the "leader" field.
-var ErrMissingLeaderKey = errors.New(`"leader" field must be provided`)
-
-type electionServer struct {
-	c *clientv3.Client
-}
-
-func NewElectionServer(c *clientv3.Client) epb.ElectionServer {
-	return &electionServer{c}
-}
-
-func (es *electionServer) Campaign(ctx context.Context, req *epb.CampaignRequest) (*epb.CampaignResponse, error) {
-	s, err := es.session(ctx, req.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.NewElection(s, string(req.Name))
-	if err = e.Campaign(ctx, string(req.Value)); err != nil {
-		return nil, err
-	}
-	return &epb.CampaignResponse{
-		Header: e.Header(),
-		Leader: &epb.LeaderKey{
-			Name:  req.Name,
-			Key:   []byte(e.Key()),
-			Rev:   e.Rev(),
-			Lease: int64(s.Lease()),
-		},
-	}, nil
-}
-
-func (es *electionServer) Proclaim(ctx context.Context, req *epb.ProclaimRequest) (*epb.ProclaimResponse, error) {
-	if req.Leader == nil {
-		return nil, ErrMissingLeaderKey
-	}
-	s, err := es.session(ctx, req.Leader.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.ResumeElection(s, string(req.Leader.Name), string(req.Leader.Key), req.Leader.Rev)
-	if err := e.Proclaim(ctx, string(req.Value)); err != nil {
-		return nil, err
-	}
-	return &epb.ProclaimResponse{Header: e.Header()}, nil
-}
-
-func (es *electionServer) Observe(req *epb.LeaderRequest, stream epb.Election_ObserveServer) error {
-	s, err := es.session(stream.Context(), -1)
-	if err != nil {
-		return err
-	}
-	e := concurrency.NewElection(s, string(req.Name))
-	ch := e.Observe(stream.Context())
-	for stream.Context().Err() == nil {
-		select {
-		case <-stream.Context().Done():
-		case resp, ok := <-ch:
-			if !ok {
-				return nil
-			}
-			lresp := &epb.LeaderResponse{Header: resp.Header, Kv: resp.Kvs[0]}
-			if err := stream.Send(lresp); err != nil {
-				return err
-			}
-		}
-	}
-	return stream.Context().Err()
-}
-
-func (es *electionServer) Leader(ctx context.Context, req *epb.LeaderRequest) (*epb.LeaderResponse, error) {
-	s, err := es.session(ctx, -1)
-	if err != nil {
-		return nil, err
-	}
-	l, lerr := concurrency.NewElection(s, string(req.Name)).Leader(ctx)
-	if lerr != nil {
-		return nil, lerr
-	}
-	return &epb.LeaderResponse{Header: l.Header, Kv: l.Kvs[0]}, nil
-}
-
-func (es *electionServer) Resign(ctx context.Context, req *epb.ResignRequest) (*epb.ResignResponse, error) {
-	if req.Leader == nil {
-		return nil, ErrMissingLeaderKey
-	}
-	s, err := es.session(ctx, req.Leader.Lease)
-	if err != nil {
-		return nil, err
-	}
-	e := concurrency.ResumeElection(s, string(req.Leader.Name), string(req.Leader.Key), req.Leader.Rev)
-	if err := e.Resign(ctx); err != nil {
-		return nil, err
-	}
-	return &epb.ResignResponse{Header: e.Header()}, nil
-}
-
-func (es *electionServer) session(ctx context.Context, lease int64) (*concurrency.Session, error) {
-	s, err := concurrency.NewSession(
-		es.c,
-		concurrency.WithLease(clientv3.LeaseID(lease)),
-		concurrency.WithContext(ctx),
-	)
-	if err != nil {
-		return nil, err
-	}
-	s.Orphan()
-	return s, nil
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go
deleted file mode 100644
index 23551b5..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/gw/v3election.pb.gw.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/api/v3election/v3electionpb/v3election.proto
-
-/*
-Package v3electionpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-func request_Election_Campaign_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.CampaignRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Campaign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Proclaim_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.ProclaimRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Proclaim(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Leader_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.LeaderRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Leader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Election_Observe_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (v3electionpb.Election_ObserveClient, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.LeaderRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	stream, err := client.Observe(ctx, &protoReq)
-	if err != nil {
-		return nil, metadata, err
-	}
-	header, err := stream.Header()
-	if err != nil {
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-
-}
-
-func request_Election_Resign_0(ctx context.Context, marshaler runtime.Marshaler, client v3electionpb.ElectionClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3electionpb.ResignRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Resign(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterElectionHandlerFromEndpoint is same as RegisterElectionHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterElectionHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterElectionHandler(ctx, mux, conn)
-}
-
-// RegisterElectionHandler registers the http handlers for service Election to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterElectionHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterElectionHandlerClient(ctx, mux, v3electionpb.NewElectionClient(conn))
-}
-
-// RegisterElectionHandler registers the http handlers for service Election to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "ElectionClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ElectionClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "ElectionClient" to call the correct interceptors.
-func RegisterElectionHandlerClient(ctx context.Context, mux *runtime.ServeMux, client v3electionpb.ElectionClient) error {
-
-	mux.Handle("POST", pattern_Election_Campaign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Campaign_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Campaign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Proclaim_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Proclaim_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Proclaim_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Leader_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Leader_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Leader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Observe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Observe_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Observe_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Election_Resign_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Election_Resign_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Election_Resign_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Election_Campaign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "election", "campaign"}, ""))
-
-	pattern_Election_Proclaim_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "election", "proclaim"}, ""))
-
-	pattern_Election_Leader_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "election", "leader"}, ""))
-
-	pattern_Election_Observe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "election", "observe"}, ""))
-
-	pattern_Election_Resign_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "election", "resign"}, ""))
-)
-
-var (
-	forward_Election_Campaign_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Proclaim_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Leader_0 = runtime.ForwardResponseMessage
-
-	forward_Election_Observe_0 = runtime.ForwardResponseStream
-
-	forward_Election_Resign_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.pb.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.pb.go
deleted file mode 100644
index 1fc1bce..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.pb.go
+++ /dev/null
@@ -1,2079 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: v3election.proto
-
-/*
-	Package v3electionpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		v3election.proto
-
-	It has these top-level messages:
-		CampaignRequest
-		CampaignResponse
-		LeaderKey
-		LeaderRequest
-		LeaderResponse
-		ResignRequest
-		ResignResponse
-		ProclaimRequest
-		ProclaimResponse
-*/
-package v3electionpb
-
-import (
-	"fmt"
-
-	proto "github.com/golang/protobuf/proto"
-
-	math "math"
-
-	_ "github.com/gogo/protobuf/gogoproto"
-
-	etcdserverpb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	mvccpb "go.etcd.io/etcd/mvcc/mvccpb"
-
-	context "golang.org/x/net/context"
-
-	grpc "google.golang.org/grpc"
-
-	io "io"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type CampaignRequest struct {
-	// name is the election's identifier for the campaign.
-	Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// lease is the ID of the lease attached to leadership of the election. If the
-	// lease expires or is revoked before resigning leadership, then the
-	// leadership is transferred to the next campaigner, if any.
-	Lease int64 `protobuf:"varint,2,opt,name=lease,proto3" json:"lease,omitempty"`
-	// value is the initial proclaimed value set when the campaigner wins the
-	// election.
-	Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
-}
-
-func (m *CampaignRequest) Reset()                    { *m = CampaignRequest{} }
-func (m *CampaignRequest) String() string            { return proto.CompactTextString(m) }
-func (*CampaignRequest) ProtoMessage()               {}
-func (*CampaignRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{0} }
-
-func (m *CampaignRequest) GetName() []byte {
-	if m != nil {
-		return m.Name
-	}
-	return nil
-}
-
-func (m *CampaignRequest) GetLease() int64 {
-	if m != nil {
-		return m.Lease
-	}
-	return 0
-}
-
-func (m *CampaignRequest) GetValue() []byte {
-	if m != nil {
-		return m.Value
-	}
-	return nil
-}
-
-type CampaignResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// leader describes the resources used for holding leadereship of the election.
-	Leader *LeaderKey `protobuf:"bytes,2,opt,name=leader" json:"leader,omitempty"`
-}
-
-func (m *CampaignResponse) Reset()                    { *m = CampaignResponse{} }
-func (m *CampaignResponse) String() string            { return proto.CompactTextString(m) }
-func (*CampaignResponse) ProtoMessage()               {}
-func (*CampaignResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{1} }
-
-func (m *CampaignResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *CampaignResponse) GetLeader() *LeaderKey {
-	if m != nil {
-		return m.Leader
-	}
-	return nil
-}
-
-type LeaderKey struct {
-	// name is the election identifier that correponds to the leadership key.
-	Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// key is an opaque key representing the ownership of the election. If the key
-	// is deleted, then leadership is lost.
-	Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-	// rev is the creation revision of the key. It can be used to test for ownership
-	// of an election during transactions by testing the key's creation revision
-	// matches rev.
-	Rev int64 `protobuf:"varint,3,opt,name=rev,proto3" json:"rev,omitempty"`
-	// lease is the lease ID of the election leader.
-	Lease int64 `protobuf:"varint,4,opt,name=lease,proto3" json:"lease,omitempty"`
-}
-
-func (m *LeaderKey) Reset()                    { *m = LeaderKey{} }
-func (m *LeaderKey) String() string            { return proto.CompactTextString(m) }
-func (*LeaderKey) ProtoMessage()               {}
-func (*LeaderKey) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{2} }
-
-func (m *LeaderKey) GetName() []byte {
-	if m != nil {
-		return m.Name
-	}
-	return nil
-}
-
-func (m *LeaderKey) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *LeaderKey) GetRev() int64 {
-	if m != nil {
-		return m.Rev
-	}
-	return 0
-}
-
-func (m *LeaderKey) GetLease() int64 {
-	if m != nil {
-		return m.Lease
-	}
-	return 0
-}
-
-type LeaderRequest struct {
-	// name is the election identifier for the leadership information.
-	Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-}
-
-func (m *LeaderRequest) Reset()                    { *m = LeaderRequest{} }
-func (m *LeaderRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaderRequest) ProtoMessage()               {}
-func (*LeaderRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{3} }
-
-func (m *LeaderRequest) GetName() []byte {
-	if m != nil {
-		return m.Name
-	}
-	return nil
-}
-
-type LeaderResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// kv is the key-value pair representing the latest leader update.
-	Kv *mvccpb.KeyValue `protobuf:"bytes,2,opt,name=kv" json:"kv,omitempty"`
-}
-
-func (m *LeaderResponse) Reset()                    { *m = LeaderResponse{} }
-func (m *LeaderResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaderResponse) ProtoMessage()               {}
-func (*LeaderResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{4} }
-
-func (m *LeaderResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LeaderResponse) GetKv() *mvccpb.KeyValue {
-	if m != nil {
-		return m.Kv
-	}
-	return nil
-}
-
-type ResignRequest struct {
-	// leader is the leadership to relinquish by resignation.
-	Leader *LeaderKey `protobuf:"bytes,1,opt,name=leader" json:"leader,omitempty"`
-}
-
-func (m *ResignRequest) Reset()                    { *m = ResignRequest{} }
-func (m *ResignRequest) String() string            { return proto.CompactTextString(m) }
-func (*ResignRequest) ProtoMessage()               {}
-func (*ResignRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{5} }
-
-func (m *ResignRequest) GetLeader() *LeaderKey {
-	if m != nil {
-		return m.Leader
-	}
-	return nil
-}
-
-type ResignResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *ResignResponse) Reset()                    { *m = ResignResponse{} }
-func (m *ResignResponse) String() string            { return proto.CompactTextString(m) }
-func (*ResignResponse) ProtoMessage()               {}
-func (*ResignResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{6} }
-
-func (m *ResignResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type ProclaimRequest struct {
-	// leader is the leadership hold on the election.
-	Leader *LeaderKey `protobuf:"bytes,1,opt,name=leader" json:"leader,omitempty"`
-	// value is an update meant to overwrite the leader's current value.
-	Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
-}
-
-func (m *ProclaimRequest) Reset()                    { *m = ProclaimRequest{} }
-func (m *ProclaimRequest) String() string            { return proto.CompactTextString(m) }
-func (*ProclaimRequest) ProtoMessage()               {}
-func (*ProclaimRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{7} }
-
-func (m *ProclaimRequest) GetLeader() *LeaderKey {
-	if m != nil {
-		return m.Leader
-	}
-	return nil
-}
-
-func (m *ProclaimRequest) GetValue() []byte {
-	if m != nil {
-		return m.Value
-	}
-	return nil
-}
-
-type ProclaimResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *ProclaimResponse) Reset()                    { *m = ProclaimResponse{} }
-func (m *ProclaimResponse) String() string            { return proto.CompactTextString(m) }
-func (*ProclaimResponse) ProtoMessage()               {}
-func (*ProclaimResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Election, []int{8} }
-
-func (m *ProclaimResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*CampaignRequest)(nil), "v3electionpb.CampaignRequest")
-	proto.RegisterType((*CampaignResponse)(nil), "v3electionpb.CampaignResponse")
-	proto.RegisterType((*LeaderKey)(nil), "v3electionpb.LeaderKey")
-	proto.RegisterType((*LeaderRequest)(nil), "v3electionpb.LeaderRequest")
-	proto.RegisterType((*LeaderResponse)(nil), "v3electionpb.LeaderResponse")
-	proto.RegisterType((*ResignRequest)(nil), "v3electionpb.ResignRequest")
-	proto.RegisterType((*ResignResponse)(nil), "v3electionpb.ResignResponse")
-	proto.RegisterType((*ProclaimRequest)(nil), "v3electionpb.ProclaimRequest")
-	proto.RegisterType((*ProclaimResponse)(nil), "v3electionpb.ProclaimResponse")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// Client API for Election service
-
-type ElectionClient interface {
-	// Campaign waits to acquire leadership in an election, returning a LeaderKey
-	// representing the leadership if successful. The LeaderKey can then be used
-	// to issue new values on the election, transactionally guard API requests on
-	// leadership still being held, and resign from the election.
-	Campaign(ctx context.Context, in *CampaignRequest, opts ...grpc.CallOption) (*CampaignResponse, error)
-	// Proclaim updates the leader's posted value with a new value.
-	Proclaim(ctx context.Context, in *ProclaimRequest, opts ...grpc.CallOption) (*ProclaimResponse, error)
-	// Leader returns the current election proclamation, if any.
-	Leader(ctx context.Context, in *LeaderRequest, opts ...grpc.CallOption) (*LeaderResponse, error)
-	// Observe streams election proclamations in-order as made by the election's
-	// elected leaders.
-	Observe(ctx context.Context, in *LeaderRequest, opts ...grpc.CallOption) (Election_ObserveClient, error)
-	// Resign releases election leadership so other campaigners may acquire
-	// leadership on the election.
-	Resign(ctx context.Context, in *ResignRequest, opts ...grpc.CallOption) (*ResignResponse, error)
-}
-
-type electionClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewElectionClient(cc *grpc.ClientConn) ElectionClient {
-	return &electionClient{cc}
-}
-
-func (c *electionClient) Campaign(ctx context.Context, in *CampaignRequest, opts ...grpc.CallOption) (*CampaignResponse, error) {
-	out := new(CampaignResponse)
-	err := grpc.Invoke(ctx, "/v3electionpb.Election/Campaign", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *electionClient) Proclaim(ctx context.Context, in *ProclaimRequest, opts ...grpc.CallOption) (*ProclaimResponse, error) {
-	out := new(ProclaimResponse)
-	err := grpc.Invoke(ctx, "/v3electionpb.Election/Proclaim", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *electionClient) Leader(ctx context.Context, in *LeaderRequest, opts ...grpc.CallOption) (*LeaderResponse, error) {
-	out := new(LeaderResponse)
-	err := grpc.Invoke(ctx, "/v3electionpb.Election/Leader", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *electionClient) Observe(ctx context.Context, in *LeaderRequest, opts ...grpc.CallOption) (Election_ObserveClient, error) {
-	stream, err := grpc.NewClientStream(ctx, &_Election_serviceDesc.Streams[0], c.cc, "/v3electionpb.Election/Observe", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &electionObserveClient{stream}
-	if err := x.ClientStream.SendMsg(in); err != nil {
-		return nil, err
-	}
-	if err := x.ClientStream.CloseSend(); err != nil {
-		return nil, err
-	}
-	return x, nil
-}
-
-type Election_ObserveClient interface {
-	Recv() (*LeaderResponse, error)
-	grpc.ClientStream
-}
-
-type electionObserveClient struct {
-	grpc.ClientStream
-}
-
-func (x *electionObserveClient) Recv() (*LeaderResponse, error) {
-	m := new(LeaderResponse)
-	if err := x.ClientStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func (c *electionClient) Resign(ctx context.Context, in *ResignRequest, opts ...grpc.CallOption) (*ResignResponse, error) {
-	out := new(ResignResponse)
-	err := grpc.Invoke(ctx, "/v3electionpb.Election/Resign", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Election service
-
-type ElectionServer interface {
-	// Campaign waits to acquire leadership in an election, returning a LeaderKey
-	// representing the leadership if successful. The LeaderKey can then be used
-	// to issue new values on the election, transactionally guard API requests on
-	// leadership still being held, and resign from the election.
-	Campaign(context.Context, *CampaignRequest) (*CampaignResponse, error)
-	// Proclaim updates the leader's posted value with a new value.
-	Proclaim(context.Context, *ProclaimRequest) (*ProclaimResponse, error)
-	// Leader returns the current election proclamation, if any.
-	Leader(context.Context, *LeaderRequest) (*LeaderResponse, error)
-	// Observe streams election proclamations in-order as made by the election's
-	// elected leaders.
-	Observe(*LeaderRequest, Election_ObserveServer) error
-	// Resign releases election leadership so other campaigners may acquire
-	// leadership on the election.
-	Resign(context.Context, *ResignRequest) (*ResignResponse, error)
-}
-
-func RegisterElectionServer(s *grpc.Server, srv ElectionServer) {
-	s.RegisterService(&_Election_serviceDesc, srv)
-}
-
-func _Election_Campaign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(CampaignRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ElectionServer).Campaign(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3electionpb.Election/Campaign",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ElectionServer).Campaign(ctx, req.(*CampaignRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Election_Proclaim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ProclaimRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ElectionServer).Proclaim(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3electionpb.Election/Proclaim",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ElectionServer).Proclaim(ctx, req.(*ProclaimRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Election_Leader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LeaderRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ElectionServer).Leader(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3electionpb.Election/Leader",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ElectionServer).Leader(ctx, req.(*LeaderRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Election_Observe_Handler(srv interface{}, stream grpc.ServerStream) error {
-	m := new(LeaderRequest)
-	if err := stream.RecvMsg(m); err != nil {
-		return err
-	}
-	return srv.(ElectionServer).Observe(m, &electionObserveServer{stream})
-}
-
-type Election_ObserveServer interface {
-	Send(*LeaderResponse) error
-	grpc.ServerStream
-}
-
-type electionObserveServer struct {
-	grpc.ServerStream
-}
-
-func (x *electionObserveServer) Send(m *LeaderResponse) error {
-	return x.ServerStream.SendMsg(m)
-}
-
-func _Election_Resign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(ResignRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ElectionServer).Resign(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3electionpb.Election/Resign",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ElectionServer).Resign(ctx, req.(*ResignRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Election_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "v3electionpb.Election",
-	HandlerType: (*ElectionServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "Campaign",
-			Handler:    _Election_Campaign_Handler,
-		},
-		{
-			MethodName: "Proclaim",
-			Handler:    _Election_Proclaim_Handler,
-		},
-		{
-			MethodName: "Leader",
-			Handler:    _Election_Leader_Handler,
-		},
-		{
-			MethodName: "Resign",
-			Handler:    _Election_Resign_Handler,
-		},
-	},
-	Streams: []grpc.StreamDesc{
-		{
-			StreamName:    "Observe",
-			Handler:       _Election_Observe_Handler,
-			ServerStreams: true,
-		},
-	},
-	Metadata: "v3election.proto",
-}
-
-func (m *CampaignRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *CampaignRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if m.Lease != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Lease))
-	}
-	if len(m.Value) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
-	}
-	return i, nil
-}
-
-func (m *CampaignResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *CampaignResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Header.Size()))
-		n1, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	if m.Leader != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Leader.Size()))
-		n2, err := m.Leader.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	return i, nil
-}
-
-func (m *LeaderKey) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *LeaderKey) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if m.Rev != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Rev))
-	}
-	if m.Lease != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Lease))
-	}
-	return i, nil
-}
-
-func (m *LeaderRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *LeaderRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	return i, nil
-}
-
-func (m *LeaderResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *LeaderResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Header.Size()))
-		n3, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n3
-	}
-	if m.Kv != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Kv.Size()))
-		n4, err := m.Kv.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n4
-	}
-	return i, nil
-}
-
-func (m *ResignRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *ResignRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Leader != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Leader.Size()))
-		n5, err := m.Leader.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n5
-	}
-	return i, nil
-}
-
-func (m *ResignResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *ResignResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Header.Size()))
-		n6, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n6
-	}
-	return i, nil
-}
-
-func (m *ProclaimRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *ProclaimRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Leader != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Leader.Size()))
-		n7, err := m.Leader.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n7
-	}
-	if len(m.Value) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
-	}
-	return i, nil
-}
-
-func (m *ProclaimResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *ProclaimResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Election(dAtA, i, uint64(m.Header.Size()))
-		n8, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n8
-	}
-	return i, nil
-}
-
-func encodeVarintV3Election(dAtA []byte, offset int, v uint64) int {
-	for v >= 1<<7 {
-		dAtA[offset] = uint8(v&0x7f | 0x80)
-		v >>= 7
-		offset++
-	}
-	dAtA[offset] = uint8(v)
-	return offset + 1
-}
-func (m *CampaignRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	if m.Lease != 0 {
-		n += 1 + sovV3Election(uint64(m.Lease))
-	}
-	l = len(m.Value)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *CampaignResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	if m.Leader != nil {
-		l = m.Leader.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaderKey) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	if m.Rev != 0 {
-		n += 1 + sovV3Election(uint64(m.Rev))
-	}
-	if m.Lease != 0 {
-		n += 1 + sovV3Election(uint64(m.Lease))
-	}
-	return n
-}
-
-func (m *LeaderRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaderResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	if m.Kv != nil {
-		l = m.Kv.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *ResignRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.Leader != nil {
-		l = m.Leader.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *ResignResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *ProclaimRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.Leader != nil {
-		l = m.Leader.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	l = len(m.Value)
-	if l > 0 {
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func (m *ProclaimResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Election(uint64(l))
-	}
-	return n
-}
-
-func sovV3Election(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozV3Election(x uint64) (n int) {
-	return sovV3Election(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *CampaignRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: CampaignRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: CampaignRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
-			if m.Name == nil {
-				m.Name = []byte{}
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Lease", wireType)
-			}
-			m.Lease = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Lease |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
-			if m.Value == nil {
-				m.Value = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *CampaignResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: CampaignResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: CampaignResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Leader == nil {
-				m.Leader = &LeaderKey{}
-			}
-			if err := m.Leader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaderKey) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LeaderKey: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaderKey: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
-			if m.Name == nil {
-				m.Name = []byte{}
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
-			if m.Key == nil {
-				m.Key = []byte{}
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Rev", wireType)
-			}
-			m.Rev = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Rev |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Lease", wireType)
-			}
-			m.Lease = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Lease |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaderRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LeaderRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaderRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
-			if m.Name == nil {
-				m.Name = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaderResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LeaderResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaderResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Kv", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Kv == nil {
-				m.Kv = &mvccpb.KeyValue{}
-			}
-			if err := m.Kv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *ResignRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: ResignRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ResignRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Leader == nil {
-				m.Leader = &LeaderKey{}
-			}
-			if err := m.Leader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *ResignResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: ResignResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ResignResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *ProclaimRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: ProclaimRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ProclaimRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Leader == nil {
-				m.Leader = &LeaderKey{}
-			}
-			if err := m.Leader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
-			if m.Value == nil {
-				m.Value = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *ProclaimResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: ProclaimResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ProclaimResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Election(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Election
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipV3Election(dAtA []byte) (n int, err error) {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return 0, ErrIntOverflowV3Election
-			}
-			if iNdEx >= l {
-				return 0, io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		wireType := int(wire & 0x7)
-		switch wireType {
-		case 0:
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				iNdEx++
-				if dAtA[iNdEx-1] < 0x80 {
-					break
-				}
-			}
-			return iNdEx, nil
-		case 1:
-			iNdEx += 8
-			return iNdEx, nil
-		case 2:
-			var length int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowV3Election
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				length |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			iNdEx += length
-			if length < 0 {
-				return 0, ErrInvalidLengthV3Election
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowV3Election
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipV3Election(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
-		case 4:
-			return iNdEx, nil
-		case 5:
-			iNdEx += 4
-			return iNdEx, nil
-		default:
-			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
-		}
-	}
-	panic("unreachable")
-}
-
-var (
-	ErrInvalidLengthV3Election = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowV3Election   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("v3election.proto", fileDescriptorV3Election) }
-
-var fileDescriptorV3Election = []byte{
-	// 535 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0xcf, 0x6e, 0xd3, 0x40,
-	0x10, 0xc6, 0x59, 0x27, 0x84, 0x32, 0xa4, 0xad, 0x65, 0x82, 0x48, 0x43, 0x30, 0xd1, 0x22, 0xa1,
-	0x2a, 0x07, 0x2f, 0x6a, 0x38, 0xe5, 0x84, 0x40, 0xa0, 0x4a, 0x45, 0x02, 0x7c, 0x40, 0x70, 0xdc,
-	0xb8, 0x23, 0x37, 0x8a, 0xe3, 0x35, 0xb6, 0x6b, 0x29, 0x57, 0x5e, 0x81, 0x03, 0x3c, 0x12, 0x47,
-	0x24, 0x5e, 0x00, 0x05, 0x1e, 0x04, 0xed, 0xae, 0x8d, 0xff, 0x28, 0x41, 0xa8, 0xb9, 0x58, 0xe3,
-	0x9d, 0xcf, 0xf3, 0x9b, 0x6f, 0x76, 0x12, 0x30, 0xb3, 0x09, 0x06, 0xe8, 0xa5, 0x73, 0x11, 0x3a,
-	0x51, 0x2c, 0x52, 0x61, 0x75, 0xcb, 0x93, 0x68, 0x36, 0xe8, 0xf9, 0xc2, 0x17, 0x2a, 0xc1, 0x64,
-	0xa4, 0x35, 0x83, 0x47, 0x98, 0x7a, 0xe7, 0x4c, 0x3e, 0x12, 0x8c, 0x33, 0x8c, 0x2b, 0x61, 0x34,
-	0x63, 0x71, 0xe4, 0xe5, 0xba, 0x23, 0xa5, 0x5b, 0x66, 0x9e, 0xa7, 0x1e, 0xd1, 0x8c, 0x2d, 0xb2,
-	0x3c, 0x35, 0xf4, 0x85, 0xf0, 0x03, 0x64, 0x3c, 0x9a, 0x33, 0x1e, 0x86, 0x22, 0xe5, 0x92, 0x98,
-	0xe8, 0x2c, 0x7d, 0x0b, 0x87, 0xcf, 0xf9, 0x32, 0xe2, 0x73, 0x3f, 0x74, 0xf1, 0xe3, 0x25, 0x26,
-	0xa9, 0x65, 0x41, 0x3b, 0xe4, 0x4b, 0xec, 0x93, 0x11, 0x39, 0xee, 0xba, 0x2a, 0xb6, 0x7a, 0x70,
-	0x3d, 0x40, 0x9e, 0x60, 0xdf, 0x18, 0x91, 0xe3, 0x96, 0xab, 0x5f, 0xe4, 0x69, 0xc6, 0x83, 0x4b,
-	0xec, 0xb7, 0x94, 0x54, 0xbf, 0xd0, 0x15, 0x98, 0x65, 0xc9, 0x24, 0x12, 0x61, 0x82, 0xd6, 0x13,
-	0xe8, 0x5c, 0x20, 0x3f, 0xc7, 0x58, 0x55, 0xbd, 0x75, 0x32, 0x74, 0xaa, 0x46, 0x9c, 0x42, 0x77,
-	0xaa, 0x34, 0x6e, 0xae, 0xb5, 0x18, 0x74, 0x02, 0xfd, 0x95, 0xa1, 0xbe, 0xba, 0xeb, 0x54, 0x47,
-	0xe6, 0xbc, 0x52, 0xb9, 0x33, 0x5c, 0xb9, 0xb9, 0x8c, 0x7e, 0x80, 0x9b, 0x7f, 0x0f, 0x37, 0xfa,
-	0x30, 0xa1, 0xb5, 0xc0, 0x95, 0x2a, 0xd7, 0x75, 0x65, 0x28, 0x4f, 0x62, 0xcc, 0x94, 0x83, 0x96,
-	0x2b, 0xc3, 0xd2, 0x6b, 0xbb, 0xe2, 0x95, 0x3e, 0x84, 0x7d, 0x5d, 0xfa, 0x1f, 0x63, 0xa2, 0x17,
-	0x70, 0x50, 0x88, 0x76, 0x32, 0x3e, 0x02, 0x63, 0x91, 0xe5, 0xa6, 0x4d, 0x47, 0xdf, 0xa8, 0x73,
-	0x86, 0xab, 0x77, 0x72, 0xc0, 0xae, 0xb1, 0xc8, 0xe8, 0x53, 0xd8, 0x77, 0x31, 0xa9, 0xdc, 0x5a,
-	0x39, 0x2b, 0xf2, 0x7f, 0xb3, 0x7a, 0x09, 0x07, 0x45, 0x85, 0x5d, 0x7a, 0xa5, 0xef, 0xe1, 0xf0,
-	0x4d, 0x2c, 0xbc, 0x80, 0xcf, 0x97, 0x57, 0xed, 0xa5, 0x5c, 0x24, 0xa3, 0xba, 0x48, 0xa7, 0x60,
-	0x96, 0x95, 0x77, 0xe9, 0xf1, 0xe4, 0x4b, 0x1b, 0xf6, 0x5e, 0xe4, 0x0d, 0x58, 0x0b, 0xd8, 0x2b,
-	0xf6, 0xd3, 0xba, 0x5f, 0xef, 0xac, 0xf1, 0x53, 0x18, 0xd8, 0xdb, 0xd2, 0x9a, 0x42, 0x47, 0x9f,
-	0x7e, 0xfc, 0xfe, 0x6c, 0x0c, 0xe8, 0x1d, 0x96, 0x4d, 0x58, 0x21, 0x64, 0x5e, 0x2e, 0x9b, 0x92,
-	0xb1, 0x84, 0x15, 0x1e, 0x9a, 0xb0, 0xc6, 0xd4, 0x9a, 0xb0, 0xa6, 0xf5, 0x2d, 0xb0, 0x28, 0x97,
-	0x49, 0x98, 0x07, 0x1d, 0x3d, 0x5b, 0xeb, 0xde, 0xa6, 0x89, 0x17, 0xa0, 0xe1, 0xe6, 0x64, 0x8e,
-	0xb1, 0x15, 0xa6, 0x4f, 0x6f, 0xd7, 0x30, 0xfa, 0xa2, 0x24, 0xc4, 0x87, 0x1b, 0xaf, 0x67, 0x6a,
-	0xe0, 0xbb, 0x50, 0x1e, 0x28, 0xca, 0x11, 0xed, 0xd5, 0x28, 0x42, 0x17, 0x9e, 0x92, 0xf1, 0x63,
-	0x22, 0xdd, 0xe8, 0x05, 0x6d, 0x72, 0x6a, 0x8b, 0xdf, 0xe4, 0xd4, 0x77, 0x7a, 0x8b, 0x9b, 0x58,
-	0x89, 0xa6, 0x64, 0xfc, 0xcc, 0xfc, 0xb6, 0xb6, 0xc9, 0xf7, 0xb5, 0x4d, 0x7e, 0xae, 0x6d, 0xf2,
-	0xf5, 0x97, 0x7d, 0x6d, 0xd6, 0x51, 0x7f, 0x8c, 0x93, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2f,
-	0x1d, 0xfa, 0x11, 0xb1, 0x05, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto b/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto
deleted file mode 100644
index 918f39f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/v3election.proto
+++ /dev/null
@@ -1,119 +0,0 @@
-syntax = "proto3";
-package v3electionpb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-import "etcd/mvcc/mvccpb/kv.proto";
-
-// for grpc-gateway
-import "google/api/annotations.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-
-// The election service exposes client-side election facilities as a gRPC interface.
-service Election {
-  // Campaign waits to acquire leadership in an election, returning a LeaderKey
-  // representing the leadership if successful. The LeaderKey can then be used
-  // to issue new values on the election, transactionally guard API requests on
-  // leadership still being held, and resign from the election.
-  rpc Campaign(CampaignRequest) returns (CampaignResponse) {
-      option (google.api.http) = {
-        post: "/v3/election/campaign"
-        body: "*"
-    };
-  }
-  // Proclaim updates the leader's posted value with a new value.
-  rpc Proclaim(ProclaimRequest) returns (ProclaimResponse) {
-      option (google.api.http) = {
-        post: "/v3/election/proclaim"
-        body: "*"
-    };
-  }
-  // Leader returns the current election proclamation, if any.
-  rpc Leader(LeaderRequest) returns (LeaderResponse) {
-      option (google.api.http) = {
-        post: "/v3/election/leader"
-        body: "*"
-    };
-  }
-  // Observe streams election proclamations in-order as made by the election's
-  // elected leaders.
-  rpc Observe(LeaderRequest) returns (stream LeaderResponse) {
-      option (google.api.http) = {
-        post: "/v3/election/observe"
-        body: "*"
-    };
-  }
-  // Resign releases election leadership so other campaigners may acquire
-  // leadership on the election.
-  rpc Resign(ResignRequest) returns (ResignResponse) {
-      option (google.api.http) = {
-        post: "/v3/election/resign"
-        body: "*"
-    };
-  }
-}
-
-message CampaignRequest {
-  // name is the election's identifier for the campaign.
-  bytes name = 1;
-  // lease is the ID of the lease attached to leadership of the election. If the
-  // lease expires or is revoked before resigning leadership, then the
-  // leadership is transferred to the next campaigner, if any.
-  int64 lease = 2;
-  // value is the initial proclaimed value set when the campaigner wins the
-  // election.
-  bytes value = 3;
-}
-
-message CampaignResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // leader describes the resources used for holding leadereship of the election.
-  LeaderKey leader = 2;
-}
-
-message LeaderKey {
-  // name is the election identifier that correponds to the leadership key.
-  bytes name = 1;
-  // key is an opaque key representing the ownership of the election. If the key
-  // is deleted, then leadership is lost.
-  bytes key = 2;
-  // rev is the creation revision of the key. It can be used to test for ownership
-  // of an election during transactions by testing the key's creation revision
-  // matches rev.
-  int64 rev = 3;
-  // lease is the lease ID of the election leader.
-  int64 lease = 4;
-}
-
-message LeaderRequest {
-  // name is the election identifier for the leadership information.
-  bytes name = 1;
-}
-
-message LeaderResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // kv is the key-value pair representing the latest leader update.
-  mvccpb.KeyValue kv = 2;
-}
-
-message ResignRequest {
-  // leader is the leadership to relinquish by resignation.
-  LeaderKey leader = 1;
-}
-
-message ResignResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
-
-message ProclaimRequest {
-  // leader is the leadership hold on the election.
-  LeaderKey leader = 1;
-  // value is an update meant to overwrite the leader's current value.
-  bytes value = 2;
-}
-
-message ProclaimResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/doc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/doc.go
deleted file mode 100644
index e0a1008..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/doc.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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 v3lock provides a v3 locking service from an etcdserver.
-package v3lock
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/lock.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/lock.go
deleted file mode 100644
index 5a17c86..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/lock.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 v3lock
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/clientv3/concurrency"
-	"go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb"
-)
-
-type lockServer struct {
-	c *clientv3.Client
-}
-
-func NewLockServer(c *clientv3.Client) v3lockpb.LockServer {
-	return &lockServer{c}
-}
-
-func (ls *lockServer) Lock(ctx context.Context, req *v3lockpb.LockRequest) (*v3lockpb.LockResponse, error) {
-	s, err := concurrency.NewSession(
-		ls.c,
-		concurrency.WithLease(clientv3.LeaseID(req.Lease)),
-		concurrency.WithContext(ctx),
-	)
-	if err != nil {
-		return nil, err
-	}
-	s.Orphan()
-	m := concurrency.NewMutex(s, string(req.Name))
-	if err = m.Lock(ctx); err != nil {
-		return nil, err
-	}
-	return &v3lockpb.LockResponse{Header: m.Header(), Key: []byte(m.Key())}, nil
-}
-
-func (ls *lockServer) Unlock(ctx context.Context, req *v3lockpb.UnlockRequest) (*v3lockpb.UnlockResponse, error) {
-	resp, err := ls.c.Delete(ctx, string(req.Key))
-	if err != nil {
-		return nil, err
-	}
-	return &v3lockpb.UnlockResponse{Header: resp.Header}, nil
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go
deleted file mode 100644
index 1eeeff1..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/gw/v3lock.pb.gw.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/api/v3lock/v3lockpb/v3lock.proto
-
-/*
-Package v3lockpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb"
-	"io"
-	"net/http"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/grpc-ecosystem/grpc-gateway/runtime"
-	"github.com/grpc-ecosystem/grpc-gateway/utilities"
-	"golang.org/x/net/context"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/status"
-)
-
-var _ codes.Code
-var _ io.Reader
-var _ status.Status
-var _ = runtime.String
-var _ = utilities.NewDoubleArray
-
-func request_Lock_Lock_0(ctx context.Context, marshaler runtime.Marshaler, client v3lockpb.LockClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3lockpb.LockRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Lock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lock_Unlock_0(ctx context.Context, marshaler runtime.Marshaler, client v3lockpb.LockClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq v3lockpb.UnlockRequest
-	var metadata runtime.ServerMetadata
-
-	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
-		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
-	}
-
-	msg, err := client.Unlock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterLockHandlerFromEndpoint is same as RegisterLockHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterLockHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
-	conn, err := grpc.Dial(endpoint, opts...)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if err != nil {
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-			return
-		}
-		go func() {
-			<-ctx.Done()
-			if cerr := conn.Close(); cerr != nil {
-				grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
-			}
-		}()
-	}()
-
-	return RegisterLockHandler(ctx, mux, conn)
-}
-
-// RegisterLockHandler registers the http handlers for service Lock to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterLockHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterLockHandlerClient(ctx, mux, v3lockpb.NewLockClient(conn))
-}
-
-// RegisterLockHandler registers the http handlers for service Lock to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "LockClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LockClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "LockClient" to call the correct interceptors.
-func RegisterLockHandlerClient(ctx context.Context, mux *runtime.ServeMux, client v3lockpb.LockClient) error {
-
-	mux.Handle("POST", pattern_Lock_Lock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lock_Lock_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lock_Lock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lock_Unlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
-		ctx, cancel := context.WithCancel(req.Context())
-		defer cancel()
-		if cn, ok := w.(http.CloseNotifier); ok {
-			go func(done <-chan struct{}, closed <-chan bool) {
-				select {
-				case <-done:
-				case <-closed:
-					cancel()
-				}
-			}(ctx.Done(), cn.CloseNotify())
-		}
-		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-		resp, md, err := request_Lock_Unlock_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lock_Unlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Lock_Lock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 1}, []string{"v3", "lock"}, ""))
-
-	pattern_Lock_Unlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lock", "unlock"}, ""))
-)
-
-var (
-	forward_Lock_Lock_0 = runtime.ForwardResponseMessage
-
-	forward_Lock_Unlock_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go
deleted file mode 100644
index 36ebdd9..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.pb.go
+++ /dev/null
@@ -1,959 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: v3lock.proto
-
-/*
-	Package v3lockpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		v3lock.proto
-
-	It has these top-level messages:
-		LockRequest
-		LockResponse
-		UnlockRequest
-		UnlockResponse
-*/
-package v3lockpb
-
-import (
-	"fmt"
-
-	proto "github.com/golang/protobuf/proto"
-
-	math "math"
-
-	_ "github.com/gogo/protobuf/gogoproto"
-
-	etcdserverpb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	context "golang.org/x/net/context"
-
-	grpc "google.golang.org/grpc"
-
-	io "io"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type LockRequest struct {
-	// name is the identifier for the distributed shared lock to be acquired.
-	Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// lease is the ID of the lease that will be attached to ownership of the
-	// lock. If the lease expires or is revoked and currently holds the lock,
-	// the lock is automatically released. Calls to Lock with the same lease will
-	// be treated as a single acquisition; locking twice with the same lease is a
-	// no-op.
-	Lease int64 `protobuf:"varint,2,opt,name=lease,proto3" json:"lease,omitempty"`
-}
-
-func (m *LockRequest) Reset()                    { *m = LockRequest{} }
-func (m *LockRequest) String() string            { return proto.CompactTextString(m) }
-func (*LockRequest) ProtoMessage()               {}
-func (*LockRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Lock, []int{0} }
-
-func (m *LockRequest) GetName() []byte {
-	if m != nil {
-		return m.Name
-	}
-	return nil
-}
-
-func (m *LockRequest) GetLease() int64 {
-	if m != nil {
-		return m.Lease
-	}
-	return 0
-}
-
-type LockResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// key is a key that will exist on etcd for the duration that the Lock caller
-	// owns the lock. Users should not modify this key or the lock may exhibit
-	// undefined behavior.
-	Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-}
-
-func (m *LockResponse) Reset()                    { *m = LockResponse{} }
-func (m *LockResponse) String() string            { return proto.CompactTextString(m) }
-func (*LockResponse) ProtoMessage()               {}
-func (*LockResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Lock, []int{1} }
-
-func (m *LockResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LockResponse) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-type UnlockRequest struct {
-	// key is the lock ownership key granted by Lock.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-}
-
-func (m *UnlockRequest) Reset()                    { *m = UnlockRequest{} }
-func (m *UnlockRequest) String() string            { return proto.CompactTextString(m) }
-func (*UnlockRequest) ProtoMessage()               {}
-func (*UnlockRequest) Descriptor() ([]byte, []int) { return fileDescriptorV3Lock, []int{2} }
-
-func (m *UnlockRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-type UnlockResponse struct {
-	Header *etcdserverpb.ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *UnlockResponse) Reset()                    { *m = UnlockResponse{} }
-func (m *UnlockResponse) String() string            { return proto.CompactTextString(m) }
-func (*UnlockResponse) ProtoMessage()               {}
-func (*UnlockResponse) Descriptor() ([]byte, []int) { return fileDescriptorV3Lock, []int{3} }
-
-func (m *UnlockResponse) GetHeader() *etcdserverpb.ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*LockRequest)(nil), "v3lockpb.LockRequest")
-	proto.RegisterType((*LockResponse)(nil), "v3lockpb.LockResponse")
-	proto.RegisterType((*UnlockRequest)(nil), "v3lockpb.UnlockRequest")
-	proto.RegisterType((*UnlockResponse)(nil), "v3lockpb.UnlockResponse")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// Client API for Lock service
-
-type LockClient interface {
-	// Lock acquires a distributed shared lock on a given named lock.
-	// On success, it will return a unique key that exists so long as the
-	// lock is held by the caller. This key can be used in conjunction with
-	// transactions to safely ensure updates to etcd only occur while holding
-	// lock ownership. The lock is held until Unlock is called on the key or the
-	// lease associate with the owner expires.
-	Lock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error)
-	// Unlock takes a key returned by Lock and releases the hold on lock. The
-	// next Lock caller waiting for the lock will then be woken up and given
-	// ownership of the lock.
-	Unlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error)
-}
-
-type lockClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewLockClient(cc *grpc.ClientConn) LockClient {
-	return &lockClient{cc}
-}
-
-func (c *lockClient) Lock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*LockResponse, error) {
-	out := new(LockResponse)
-	err := grpc.Invoke(ctx, "/v3lockpb.Lock/Lock", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *lockClient) Unlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*UnlockResponse, error) {
-	out := new(UnlockResponse)
-	err := grpc.Invoke(ctx, "/v3lockpb.Lock/Unlock", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Lock service
-
-type LockServer interface {
-	// Lock acquires a distributed shared lock on a given named lock.
-	// On success, it will return a unique key that exists so long as the
-	// lock is held by the caller. This key can be used in conjunction with
-	// transactions to safely ensure updates to etcd only occur while holding
-	// lock ownership. The lock is held until Unlock is called on the key or the
-	// lease associate with the owner expires.
-	Lock(context.Context, *LockRequest) (*LockResponse, error)
-	// Unlock takes a key returned by Lock and releases the hold on lock. The
-	// next Lock caller waiting for the lock will then be woken up and given
-	// ownership of the lock.
-	Unlock(context.Context, *UnlockRequest) (*UnlockResponse, error)
-}
-
-func RegisterLockServer(s *grpc.Server, srv LockServer) {
-	s.RegisterService(&_Lock_serviceDesc, srv)
-}
-
-func _Lock_Lock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LockRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LockServer).Lock(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3lockpb.Lock/Lock",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LockServer).Lock(ctx, req.(*LockRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Lock_Unlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(UnlockRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LockServer).Unlock(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/v3lockpb.Lock/Unlock",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LockServer).Unlock(ctx, req.(*UnlockRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Lock_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "v3lockpb.Lock",
-	HandlerType: (*LockServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "Lock",
-			Handler:    _Lock_Lock_Handler,
-		},
-		{
-			MethodName: "Unlock",
-			Handler:    _Lock_Unlock_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "v3lock.proto",
-}
-
-func (m *LockRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *LockRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if m.Lease != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(m.Lease))
-	}
-	return i, nil
-}
-
-func (m *LockResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *LockResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(m.Header.Size()))
-		n1, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	return i, nil
-}
-
-func (m *UnlockRequest) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *UnlockRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	return i, nil
-}
-
-func (m *UnlockResponse) Marshal() (dAtA []byte, err error) {
-	size := m.Size()
-	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
-	if err != nil {
-		return nil, err
-	}
-	return dAtA[:n], nil
-}
-
-func (m *UnlockResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintV3Lock(dAtA, i, uint64(m.Header.Size()))
-		n2, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	return i, nil
-}
-
-func encodeVarintV3Lock(dAtA []byte, offset int, v uint64) int {
-	for v >= 1<<7 {
-		dAtA[offset] = uint8(v&0x7f | 0x80)
-		v >>= 7
-		offset++
-	}
-	dAtA[offset] = uint8(v)
-	return offset + 1
-}
-func (m *LockRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovV3Lock(uint64(l))
-	}
-	if m.Lease != 0 {
-		n += 1 + sovV3Lock(uint64(m.Lease))
-	}
-	return n
-}
-
-func (m *LockResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Lock(uint64(l))
-	}
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovV3Lock(uint64(l))
-	}
-	return n
-}
-
-func (m *UnlockRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovV3Lock(uint64(l))
-	}
-	return n
-}
-
-func (m *UnlockResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovV3Lock(uint64(l))
-	}
-	return n
-}
-
-func sovV3Lock(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozV3Lock(x uint64) (n int) {
-	return sovV3Lock(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *LockRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Lock
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LockRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LockRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = append(m.Name[:0], dAtA[iNdEx:postIndex]...)
-			if m.Name == nil {
-				m.Name = []byte{}
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Lease", wireType)
-			}
-			m.Lease = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Lease |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Lock(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LockResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Lock
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: LockResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LockResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
-			if m.Key == nil {
-				m.Key = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Lock(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *UnlockRequest) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Lock
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: UnlockRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: UnlockRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
-			if m.Key == nil {
-				m.Key = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Lock(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *UnlockResponse) Unmarshal(dAtA []byte) error {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		preIndex := iNdEx
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return ErrIntOverflowV3Lock
-			}
-			if iNdEx >= l {
-				return io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		fieldNum := int32(wire >> 3)
-		wireType := int(wire & 0x7)
-		if wireType == 4 {
-			return fmt.Errorf("proto: UnlockResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: UnlockResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &etcdserverpb.ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipV3Lock(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthV3Lock
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipV3Lock(dAtA []byte) (n int, err error) {
-	l := len(dAtA)
-	iNdEx := 0
-	for iNdEx < l {
-		var wire uint64
-		for shift := uint(0); ; shift += 7 {
-			if shift >= 64 {
-				return 0, ErrIntOverflowV3Lock
-			}
-			if iNdEx >= l {
-				return 0, io.ErrUnexpectedEOF
-			}
-			b := dAtA[iNdEx]
-			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
-			if b < 0x80 {
-				break
-			}
-		}
-		wireType := int(wire & 0x7)
-		switch wireType {
-		case 0:
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				iNdEx++
-				if dAtA[iNdEx-1] < 0x80 {
-					break
-				}
-			}
-			return iNdEx, nil
-		case 1:
-			iNdEx += 8
-			return iNdEx, nil
-		case 2:
-			var length int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return 0, ErrIntOverflowV3Lock
-				}
-				if iNdEx >= l {
-					return 0, io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				length |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			iNdEx += length
-			if length < 0 {
-				return 0, ErrInvalidLengthV3Lock
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowV3Lock
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipV3Lock(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
-		case 4:
-			return iNdEx, nil
-		case 5:
-			iNdEx += 4
-			return iNdEx, nil
-		default:
-			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
-		}
-	}
-	panic("unreachable")
-}
-
-var (
-	ErrInvalidLengthV3Lock = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowV3Lock   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("v3lock.proto", fileDescriptorV3Lock) }
-
-var fileDescriptorV3Lock = []byte{
-	// 331 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x33, 0xce, 0xc9,
-	0x4f, 0xce, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x80, 0xf0, 0x0a, 0x92, 0xa4, 0x44,
-	0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x82, 0xfa, 0x20, 0x16, 0x44, 0x5e, 0x4a, 0x2d, 0xb5, 0x24, 0x39,
-	0x45, 0x1f, 0x44, 0x14, 0xa7, 0x16, 0x95, 0xa5, 0x16, 0x21, 0x31, 0x0b, 0x92, 0xf4, 0x8b, 0x0a,
-	0x92, 0xa1, 0xea, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13, 0x0b, 0x32, 0xf5, 0x13,
-	0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x21, 0xb2, 0x4a, 0xe6, 0x5c, 0xdc,
-	0x3e, 0xf9, 0xc9, 0xd9, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, 0x5c, 0x2c, 0x79,
-	0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x60, 0xb6, 0x90, 0x08, 0x17, 0x6b,
-	0x4e, 0x6a, 0x62, 0x71, 0xaa, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x73, 0x10, 0x84, 0xa3, 0x14, 0xc6,
-	0xc5, 0x03, 0xd1, 0x58, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, 0x64, 0xc2, 0xc5, 0x96, 0x91, 0x9a,
-	0x98, 0x92, 0x5a, 0x04, 0xd6, 0xcb, 0x6d, 0x24, 0xa3, 0x87, 0xec, 0x1e, 0x3d, 0x98, 0x3a, 0x0f,
-	0xb0, 0x9a, 0x20, 0xa8, 0x5a, 0x21, 0x01, 0x2e, 0xe6, 0xec, 0xd4, 0x4a, 0xb0, 0xc9, 0x3c, 0x41,
-	0x20, 0xa6, 0x92, 0x22, 0x17, 0x6f, 0x68, 0x5e, 0x0e, 0x92, 0x93, 0xa0, 0x4a, 0x18, 0x11, 0x4a,
-	0xdc, 0xb8, 0xf8, 0x60, 0x4a, 0x28, 0xb1, 0xdc, 0x68, 0x03, 0x23, 0x17, 0x0b, 0xc8, 0x0f, 0x42,
-	0xfe, 0x50, 0x5a, 0x54, 0x0f, 0x16, 0xe6, 0x7a, 0x48, 0x81, 0x22, 0x25, 0x86, 0x2e, 0x0c, 0x31,
-	0x4d, 0x49, 0xa2, 0xe9, 0xf2, 0x93, 0xc9, 0x4c, 0x42, 0x4a, 0xbc, 0xfa, 0x65, 0xc6, 0xfa, 0x20,
-	0x05, 0x60, 0xc2, 0x8a, 0x51, 0x4b, 0x28, 0x9c, 0x8b, 0x0d, 0xe2, 0x42, 0x21, 0x71, 0x84, 0x5e,
-	0x14, 0x6f, 0x49, 0x49, 0x60, 0x4a, 0x40, 0x8d, 0x95, 0x02, 0x1b, 0x2b, 0xa2, 0xc4, 0x0f, 0x37,
-	0xb6, 0x34, 0x0f, 0x6a, 0xb0, 0x93, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e,
-	0x78, 0x24, 0xc7, 0x38, 0xe3, 0xb1, 0x1c, 0x43, 0x12, 0x1b, 0x38, 0x1e, 0x8d, 0x01, 0x01, 0x00,
-	0x00, 0xff, 0xff, 0x65, 0xa8, 0x61, 0xb1, 0x3d, 0x02, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto b/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto
deleted file mode 100644
index 7220c7f..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/v3lock.proto
+++ /dev/null
@@ -1,65 +0,0 @@
-syntax = "proto3";
-package v3lockpb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-
-// for grpc-gateway
-import "google/api/annotations.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-
-// The lock service exposes client-side locking facilities as a gRPC interface.
-service Lock {
-  // Lock acquires a distributed shared lock on a given named lock.
-  // On success, it will return a unique key that exists so long as the
-  // lock is held by the caller. This key can be used in conjunction with
-  // transactions to safely ensure updates to etcd only occur while holding
-  // lock ownership. The lock is held until Unlock is called on the key or the
-  // lease associate with the owner expires.
-  rpc Lock(LockRequest) returns (LockResponse) {
-      option (google.api.http) = {
-        post: "/v3/lock/lock"
-        body: "*"
-    };
-  }
-
-  // Unlock takes a key returned by Lock and releases the hold on lock. The
-  // next Lock caller waiting for the lock will then be woken up and given
-  // ownership of the lock.
-  rpc Unlock(UnlockRequest) returns (UnlockResponse) {
-      option (google.api.http) = {
-        post: "/v3/lock/unlock"
-        body: "*"
-    };
-  }
-}
-
-message LockRequest {
-  // name is the identifier for the distributed shared lock to be acquired.
-  bytes name = 1;
-  // lease is the ID of the lease that will be attached to ownership of the
-  // lock. If the lease expires or is revoked and currently holds the lock,
-  // the lock is automatically released. Calls to Lock with the same lease will
-  // be treated as a single acquisition; locking twice with the same lease is a
-  // no-op.
-  int64 lease = 2;
-}
-
-message LockResponse {
-  etcdserverpb.ResponseHeader header = 1;
-  // key is a key that will exist on etcd for the duration that the Lock caller
-  // owns the lock. Users should not modify this key or the lock may exhibit
-  // undefined behavior.
-  bytes key = 2;
-}
-
-message UnlockRequest {
-  // key is the lock ownership key granted by Lock.
-  bytes key = 1;
-}
-
-message UnlockResponse {
-  etcdserverpb.ResponseHeader header = 1;
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/auth.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/auth.go
deleted file mode 100644
index 62ce757..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/auth.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/etcdserver"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-)
-
-type AuthServer struct {
-	authenticator etcdserver.Authenticator
-}
-
-func NewAuthServer(s *etcdserver.EtcdServer) *AuthServer {
-	return &AuthServer{authenticator: s}
-}
-
-func (as *AuthServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
-	resp, err := as.authenticator.AuthEnable(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
-	resp, err := as.authenticator.AuthDisable(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	resp, err := as.authenticator.Authenticate(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := as.authenticator.RoleAdd(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := as.authenticator.RoleDelete(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := as.authenticator.RoleGet(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := as.authenticator.RoleList(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := as.authenticator.RoleRevokePermission(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := as.authenticator.RoleGrantPermission(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := as.authenticator.UserAdd(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := as.authenticator.UserDelete(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := as.authenticator.UserGet(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := as.authenticator.UserList(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := as.authenticator.UserGrantRole(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := as.authenticator.UserRevokeRole(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
-
-func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := as.authenticator.UserChangePassword(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return resp, nil
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/codec.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/codec.go
deleted file mode 100644
index 17a2c87..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/codec.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import "github.com/gogo/protobuf/proto"
-
-type codec struct{}
-
-func (c *codec) Marshal(v interface{}) ([]byte, error) {
-	b, err := proto.Marshal(v.(proto.Message))
-	sentBytes.Add(float64(len(b)))
-	return b, err
-}
-
-func (c *codec) Unmarshal(data []byte, v interface{}) error {
-	receivedBytes.Add(float64(len(data)))
-	return proto.Unmarshal(data, v.(proto.Message))
-}
-
-func (c *codec) String() string {
-	return "proto"
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/grpc.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/grpc.go
deleted file mode 100644
index 3332016..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/grpc.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"crypto/tls"
-	"math"
-
-	"go.etcd.io/etcd/etcdserver"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
-	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
-	"go.etcd.io/etcd/clientv3/credentials"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/health"
-	healthpb "google.golang.org/grpc/health/grpc_health_v1"
-)
-
-const (
-	grpcOverheadBytes = 512 * 1024
-	maxStreams        = math.MaxUint32
-	maxSendBytes      = math.MaxInt32
-)
-
-func Server(s *etcdserver.EtcdServer, tls *tls.Config, gopts ...grpc.ServerOption) *grpc.Server {
-	var opts []grpc.ServerOption
-	opts = append(opts, grpc.CustomCodec(&codec{}))
-	if tls != nil {
-		bundle := credentials.NewBundle(credentials.Config{TLSConfig: tls})
-		opts = append(opts, grpc.Creds(bundle.TransportCredentials()))
-	}
-	opts = append(opts, grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
-		newLogUnaryInterceptor(s),
-		newUnaryInterceptor(s),
-		grpc_prometheus.UnaryServerInterceptor,
-	)))
-	opts = append(opts, grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
-		newStreamInterceptor(s),
-		grpc_prometheus.StreamServerInterceptor,
-	)))
-	opts = append(opts, grpc.MaxRecvMsgSize(int(s.Cfg.MaxRequestBytes+grpcOverheadBytes)))
-	opts = append(opts, grpc.MaxSendMsgSize(maxSendBytes))
-	opts = append(opts, grpc.MaxConcurrentStreams(maxStreams))
-	grpcServer := grpc.NewServer(append(opts, gopts...)...)
-
-	pb.RegisterKVServer(grpcServer, NewQuotaKVServer(s))
-	pb.RegisterWatchServer(grpcServer, NewWatchServer(s))
-	pb.RegisterLeaseServer(grpcServer, NewQuotaLeaseServer(s))
-	pb.RegisterClusterServer(grpcServer, NewClusterServer(s))
-	pb.RegisterAuthServer(grpcServer, NewAuthServer(s))
-	pb.RegisterMaintenanceServer(grpcServer, NewMaintenanceServer(s))
-
-	// server should register all the services manually
-	// use empty service name for all etcd services' health status,
-	// see https://github.com/grpc/grpc/blob/master/doc/health-checking.md for more
-	hsrv := health.NewServer()
-	hsrv.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
-	healthpb.RegisterHealthServer(grpcServer, hsrv)
-
-	// set zero values for metrics registered for this grpc server
-	grpc_prometheus.Register(grpcServer)
-
-	return grpcServer
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/header.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/header.go
deleted file mode 100644
index f23b6a7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/header.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"go.etcd.io/etcd/etcdserver"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-)
-
-type header struct {
-	clusterID int64
-	memberID  int64
-	sg        etcdserver.RaftStatusGetter
-	rev       func() int64
-}
-
-func newHeader(s *etcdserver.EtcdServer) header {
-	return header{
-		clusterID: int64(s.Cluster().ID()),
-		memberID:  int64(s.ID()),
-		sg:        s,
-		rev:       func() int64 { return s.KV().Rev() },
-	}
-}
-
-// fill populates pb.ResponseHeader using etcdserver information
-func (h *header) fill(rh *pb.ResponseHeader) {
-	if rh == nil {
-		plog.Panic("unexpected nil resp.Header")
-	}
-	rh.ClusterId = uint64(h.clusterID)
-	rh.MemberId = uint64(h.memberID)
-	rh.RaftTerm = h.sg.Term()
-	if rh.Revision == 0 {
-		rh.Revision = h.rev()
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/interceptor.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/interceptor.go
deleted file mode 100644
index ce9047e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/interceptor.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-
-	"github.com/coreos/pkg/capnslog"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.uber.org/zap"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/peer"
-)
-
-const (
-	maxNoLeaderCnt = 3
-)
-
-type streamsMap struct {
-	mu      sync.Mutex
-	streams map[grpc.ServerStream]struct{}
-}
-
-func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		if !api.IsCapabilityEnabled(api.V3rpcCapability) {
-			return nil, rpctypes.ErrGRPCNotCapable
-		}
-
-		if s.IsMemberExist(s.ID()) && s.IsLearner() && !isRPCSupportedForLearner(req) {
-			return nil, rpctypes.ErrGPRCNotSupportedForLearner
-		}
-
-		md, ok := metadata.FromIncomingContext(ctx)
-		if ok {
-			if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader {
-				if s.Leader() == types.ID(raft.None) {
-					return nil, rpctypes.ErrGRPCNoLeader
-				}
-			}
-		}
-
-		return handler(ctx, req)
-	}
-}
-
-func newLogUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInterceptor {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		startTime := time.Now()
-		resp, err := handler(ctx, req)
-		lg := s.Logger()
-		if (lg != nil && lg.Core().Enabled(zap.DebugLevel)) || // using zap logger and debug level is enabled
-			(lg == nil && plog.LevelAt(capnslog.DEBUG)) { // or, using capnslog and debug level is enabled
-			defer logUnaryRequestStats(ctx, lg, info, startTime, req, resp)
-		}
-		return resp, err
-	}
-}
-
-func logUnaryRequestStats(ctx context.Context, lg *zap.Logger, info *grpc.UnaryServerInfo, startTime time.Time, req interface{}, resp interface{}) {
-	duration := time.Since(startTime)
-	remote := "No remote client info."
-	peerInfo, ok := peer.FromContext(ctx)
-	if ok {
-		remote = peerInfo.Addr.String()
-	}
-	responseType := info.FullMethod
-	var reqCount, respCount int64
-	var reqSize, respSize int
-	var reqContent string
-	switch _resp := resp.(type) {
-	case *pb.RangeResponse:
-		_req, ok := req.(*pb.RangeRequest)
-		if ok {
-			reqCount = 0
-			reqSize = _req.Size()
-			reqContent = _req.String()
-		}
-		if _resp != nil {
-			respCount = _resp.GetCount()
-			respSize = _resp.Size()
-		}
-	case *pb.PutResponse:
-		_req, ok := req.(*pb.PutRequest)
-		if ok {
-			reqCount = 1
-			reqSize = _req.Size()
-			reqContent = pb.NewLoggablePutRequest(_req).String()
-			// redact value field from request content, see PR #9821
-		}
-		if _resp != nil {
-			respCount = 0
-			respSize = _resp.Size()
-		}
-	case *pb.DeleteRangeResponse:
-		_req, ok := req.(*pb.DeleteRangeRequest)
-		if ok {
-			reqCount = 0
-			reqSize = _req.Size()
-			reqContent = _req.String()
-		}
-		if _resp != nil {
-			respCount = _resp.GetDeleted()
-			respSize = _resp.Size()
-		}
-	case *pb.TxnResponse:
-		_req, ok := req.(*pb.TxnRequest)
-		if ok && _resp != nil {
-			if _resp.GetSucceeded() { // determine the 'actual' count and size of request based on success or failure
-				reqCount = int64(len(_req.GetSuccess()))
-				reqSize = 0
-				for _, r := range _req.GetSuccess() {
-					reqSize += r.Size()
-				}
-			} else {
-				reqCount = int64(len(_req.GetFailure()))
-				reqSize = 0
-				for _, r := range _req.GetFailure() {
-					reqSize += r.Size()
-				}
-			}
-			reqContent = pb.NewLoggableTxnRequest(_req).String()
-			// redact value field from request content, see PR #9821
-		}
-		if _resp != nil {
-			respCount = 0
-			respSize = _resp.Size()
-		}
-	default:
-		reqCount = -1
-		reqSize = -1
-		respCount = -1
-		respSize = -1
-	}
-
-	logGenericRequestStats(lg, startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent)
-}
-
-func logGenericRequestStats(lg *zap.Logger, startTime time.Time, duration time.Duration, remote string, responseType string,
-	reqCount int64, reqSize int, respCount int64, respSize int, reqContent string) {
-	if lg == nil {
-		plog.Debugf("start time = %v, "+
-			"time spent = %v, "+
-			"remote = %s, "+
-			"response type = %s, "+
-			"request count = %d, "+
-			"request size = %d, "+
-			"response count = %d, "+
-			"response size = %d, "+
-			"request content = %s",
-			startTime, duration, remote, responseType, reqCount, reqSize, respCount, respSize, reqContent,
-		)
-	} else {
-		lg.Debug("request stats",
-			zap.Time("start time", startTime),
-			zap.Duration("time spent", duration),
-			zap.String("remote", remote),
-			zap.String("response type", responseType),
-			zap.Int64("request count", reqCount),
-			zap.Int("request size", reqSize),
-			zap.Int64("response count", respCount),
-			zap.Int("response size", respSize),
-			zap.String("request content", reqContent),
-		)
-	}
-}
-
-func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor {
-	smap := monitorLeader(s)
-
-	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-		if !api.IsCapabilityEnabled(api.V3rpcCapability) {
-			return rpctypes.ErrGRPCNotCapable
-		}
-
-		if s.IsMemberExist(s.ID()) && s.IsLearner() { // learner does not support stream RPC
-			return rpctypes.ErrGPRCNotSupportedForLearner
-		}
-
-		md, ok := metadata.FromIncomingContext(ss.Context())
-		if ok {
-			if ks := md[rpctypes.MetadataRequireLeaderKey]; len(ks) > 0 && ks[0] == rpctypes.MetadataHasLeader {
-				if s.Leader() == types.ID(raft.None) {
-					return rpctypes.ErrGRPCNoLeader
-				}
-
-				cctx, cancel := context.WithCancel(ss.Context())
-				ss = serverStreamWithCtx{ctx: cctx, cancel: &cancel, ServerStream: ss}
-
-				smap.mu.Lock()
-				smap.streams[ss] = struct{}{}
-				smap.mu.Unlock()
-
-				defer func() {
-					smap.mu.Lock()
-					delete(smap.streams, ss)
-					smap.mu.Unlock()
-					cancel()
-				}()
-
-			}
-		}
-
-		return handler(srv, ss)
-	}
-}
-
-type serverStreamWithCtx struct {
-	grpc.ServerStream
-	ctx    context.Context
-	cancel *context.CancelFunc
-}
-
-func (ssc serverStreamWithCtx) Context() context.Context { return ssc.ctx }
-
-func monitorLeader(s *etcdserver.EtcdServer) *streamsMap {
-	smap := &streamsMap{
-		streams: make(map[grpc.ServerStream]struct{}),
-	}
-
-	go func() {
-		election := time.Duration(s.Cfg.TickMs) * time.Duration(s.Cfg.ElectionTicks) * time.Millisecond
-		noLeaderCnt := 0
-
-		for {
-			select {
-			case <-s.StopNotify():
-				return
-			case <-time.After(election):
-				if s.Leader() == types.ID(raft.None) {
-					noLeaderCnt++
-				} else {
-					noLeaderCnt = 0
-				}
-
-				// We are more conservative on canceling existing streams. Reconnecting streams
-				// cost much more than just rejecting new requests. So we wait until the member
-				// cannot find a leader for maxNoLeaderCnt election timeouts to cancel existing streams.
-				if noLeaderCnt >= maxNoLeaderCnt {
-					smap.mu.Lock()
-					for ss := range smap.streams {
-						if ssWithCtx, ok := ss.(serverStreamWithCtx); ok {
-							(*ssWithCtx.cancel)()
-							<-ss.Context().Done()
-						}
-					}
-					smap.streams = make(map[grpc.ServerStream]struct{})
-					smap.mu.Unlock()
-				}
-			}
-		}
-	}()
-
-	return smap
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/key.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/key.go
deleted file mode 100644
index ff59bac..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/key.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2015 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 v3rpc implements etcd v3 RPC system based on gRPC.
-package v3rpc
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/adt"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver/api/v3rpc")
-)
-
-type kvServer struct {
-	hdr header
-	kv  etcdserver.RaftKV
-	// maxTxnOps is the max operations per txn.
-	// e.g suppose maxTxnOps = 128.
-	// Txn.Success can have at most 128 operations,
-	// and Txn.Failure can have at most 128 operations.
-	maxTxnOps uint
-}
-
-func NewKVServer(s *etcdserver.EtcdServer) pb.KVServer {
-	return &kvServer{hdr: newHeader(s), kv: s, maxTxnOps: s.Cfg.MaxTxnOps}
-}
-
-func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	if err := checkRangeRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Range(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := checkPutRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Put(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	if err := checkDeleteRequest(r); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.DeleteRange(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := checkTxnRequest(r, int(s.maxTxnOps)); err != nil {
-		return nil, err
-	}
-	// check for forbidden put/del overlaps after checking request to avoid quadratic blowup
-	if _, _, err := checkIntervals(r.Success); err != nil {
-		return nil, err
-	}
-	if _, _, err := checkIntervals(r.Failure); err != nil {
-		return nil, err
-	}
-
-	resp, err := s.kv.Txn(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
-	resp, err := s.kv.Compact(ctx, r)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	s.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func checkRangeRequest(r *pb.RangeRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	return nil
-}
-
-func checkPutRequest(r *pb.PutRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	if r.IgnoreValue && len(r.Value) != 0 {
-		return rpctypes.ErrGRPCValueProvided
-	}
-	if r.IgnoreLease && r.Lease != 0 {
-		return rpctypes.ErrGRPCLeaseProvided
-	}
-	return nil
-}
-
-func checkDeleteRequest(r *pb.DeleteRangeRequest) error {
-	if len(r.Key) == 0 {
-		return rpctypes.ErrGRPCEmptyKey
-	}
-	return nil
-}
-
-func checkTxnRequest(r *pb.TxnRequest, maxTxnOps int) error {
-	opc := len(r.Compare)
-	if opc < len(r.Success) {
-		opc = len(r.Success)
-	}
-	if opc < len(r.Failure) {
-		opc = len(r.Failure)
-	}
-	if opc > maxTxnOps {
-		return rpctypes.ErrGRPCTooManyOps
-	}
-
-	for _, c := range r.Compare {
-		if len(c.Key) == 0 {
-			return rpctypes.ErrGRPCEmptyKey
-		}
-	}
-	for _, u := range r.Success {
-		if err := checkRequestOp(u, maxTxnOps-opc); err != nil {
-			return err
-		}
-	}
-	for _, u := range r.Failure {
-		if err := checkRequestOp(u, maxTxnOps-opc); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// checkIntervals tests whether puts and deletes overlap for a list of ops. If
-// there is an overlap, returns an error. If no overlap, return put and delete
-// sets for recursive evaluation.
-func checkIntervals(reqs []*pb.RequestOp) (map[string]struct{}, adt.IntervalTree, error) {
-	dels := adt.NewIntervalTree()
-
-	// collect deletes from this level; build first to check lower level overlapped puts
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestDeleteRange)
-		if !ok {
-			continue
-		}
-		dreq := tv.RequestDeleteRange
-		if dreq == nil {
-			continue
-		}
-		var iv adt.Interval
-		if len(dreq.RangeEnd) != 0 {
-			iv = adt.NewStringAffineInterval(string(dreq.Key), string(dreq.RangeEnd))
-		} else {
-			iv = adt.NewStringAffinePoint(string(dreq.Key))
-		}
-		dels.Insert(iv, struct{}{})
-	}
-
-	// collect children puts/deletes
-	puts := make(map[string]struct{})
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestTxn)
-		if !ok {
-			continue
-		}
-		putsThen, delsThen, err := checkIntervals(tv.RequestTxn.Success)
-		if err != nil {
-			return nil, dels, err
-		}
-		putsElse, delsElse, err := checkIntervals(tv.RequestTxn.Failure)
-		if err != nil {
-			return nil, dels, err
-		}
-		for k := range putsThen {
-			if _, ok := puts[k]; ok {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			if dels.Intersects(adt.NewStringAffinePoint(k)) {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			puts[k] = struct{}{}
-		}
-		for k := range putsElse {
-			if _, ok := puts[k]; ok {
-				// if key is from putsThen, overlap is OK since
-				// either then/else are mutually exclusive
-				if _, isSafe := putsThen[k]; !isSafe {
-					return nil, dels, rpctypes.ErrGRPCDuplicateKey
-				}
-			}
-			if dels.Intersects(adt.NewStringAffinePoint(k)) {
-				return nil, dels, rpctypes.ErrGRPCDuplicateKey
-			}
-			puts[k] = struct{}{}
-		}
-		dels.Union(delsThen, adt.NewStringAffineInterval("\x00", ""))
-		dels.Union(delsElse, adt.NewStringAffineInterval("\x00", ""))
-	}
-
-	// collect and check this level's puts
-	for _, req := range reqs {
-		tv, ok := req.Request.(*pb.RequestOp_RequestPut)
-		if !ok || tv.RequestPut == nil {
-			continue
-		}
-		k := string(tv.RequestPut.Key)
-		if _, ok := puts[k]; ok {
-			return nil, dels, rpctypes.ErrGRPCDuplicateKey
-		}
-		if dels.Intersects(adt.NewStringAffinePoint(k)) {
-			return nil, dels, rpctypes.ErrGRPCDuplicateKey
-		}
-		puts[k] = struct{}{}
-	}
-	return puts, dels, nil
-}
-
-func checkRequestOp(u *pb.RequestOp, maxTxnOps int) error {
-	// TODO: ensure only one of the field is set.
-	switch uv := u.Request.(type) {
-	case *pb.RequestOp_RequestRange:
-		return checkRangeRequest(uv.RequestRange)
-	case *pb.RequestOp_RequestPut:
-		return checkPutRequest(uv.RequestPut)
-	case *pb.RequestOp_RequestDeleteRange:
-		return checkDeleteRequest(uv.RequestDeleteRange)
-	case *pb.RequestOp_RequestTxn:
-		return checkTxnRequest(uv.RequestTxn, maxTxnOps)
-	default:
-		// empty op / nil entry
-		return rpctypes.ErrGRPCKeyNotFound
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/lease.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/lease.go
deleted file mode 100644
index 7441bee..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/lease.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-	"io"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-
-	"go.uber.org/zap"
-)
-
-type LeaseServer struct {
-	lg  *zap.Logger
-	hdr header
-	le  etcdserver.Lessor
-}
-
-func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {
-	return &LeaseServer{lg: s.Cfg.Logger, le: s, hdr: newHeader(s)}
-}
-
-func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	resp, err := ls.le.LeaseGrant(ctx, cr)
-
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	resp, err := ls.le.LeaseRevoke(ctx, rr)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseTimeToLive(ctx context.Context, rr *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
-	resp, err := ls.le.LeaseTimeToLive(ctx, rr)
-	if err != nil && err != lease.ErrLeaseNotFound {
-		return nil, togRPCError(err)
-	}
-	if err == lease.ErrLeaseNotFound {
-		resp = &pb.LeaseTimeToLiveResponse{
-			Header: &pb.ResponseHeader{},
-			ID:     rr.ID,
-			TTL:    -1,
-		}
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseLeases(ctx context.Context, rr *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
-	resp, err := ls.le.LeaseLeases(ctx, rr)
-	if err != nil && err != lease.ErrLeaseNotFound {
-		return nil, togRPCError(err)
-	}
-	if err == lease.ErrLeaseNotFound {
-		resp = &pb.LeaseLeasesResponse{
-			Header: &pb.ResponseHeader{},
-			Leases: []*pb.LeaseStatus{},
-		}
-	}
-	ls.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) (err error) {
-	errc := make(chan error, 1)
-	go func() {
-		errc <- ls.leaseKeepAlive(stream)
-	}()
-	select {
-	case err = <-errc:
-	case <-stream.Context().Done():
-		// the only server-side cancellation is noleader for now.
-		err = stream.Context().Err()
-		if err == context.Canceled {
-			err = rpctypes.ErrGRPCNoLeader
-		}
-	}
-	return err
-}
-
-func (ls *LeaseServer) leaseKeepAlive(stream pb.Lease_LeaseKeepAliveServer) error {
-	for {
-		req, err := stream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			if isClientCtxErr(stream.Context().Err(), err) {
-				if ls.lg != nil {
-					ls.lg.Debug("failed to receive lease keepalive request from gRPC stream", zap.Error(err))
-				} else {
-					plog.Debugf("failed to receive lease keepalive request from gRPC stream (%q)", err.Error())
-				}
-			} else {
-				if ls.lg != nil {
-					ls.lg.Warn("failed to receive lease keepalive request from gRPC stream", zap.Error(err))
-				} else {
-					plog.Warningf("failed to receive lease keepalive request from gRPC stream (%q)", err.Error())
-				}
-				streamFailures.WithLabelValues("receive", "lease-keepalive").Inc()
-			}
-			return err
-		}
-
-		// Create header before we sent out the renew request.
-		// This can make sure that the revision is strictly smaller or equal to
-		// when the keepalive happened at the local server (when the local server is the leader)
-		// or remote leader.
-		// Without this, a lease might be revoked at rev 3 but client can see the keepalive succeeded
-		// at rev 4.
-		resp := &pb.LeaseKeepAliveResponse{ID: req.ID, Header: &pb.ResponseHeader{}}
-		ls.hdr.fill(resp.Header)
-
-		ttl, err := ls.le.LeaseRenew(stream.Context(), lease.LeaseID(req.ID))
-		if err == lease.ErrLeaseNotFound {
-			err = nil
-			ttl = 0
-		}
-
-		if err != nil {
-			return togRPCError(err)
-		}
-
-		resp.TTL = ttl
-		err = stream.Send(resp)
-		if err != nil {
-			if isClientCtxErr(stream.Context().Err(), err) {
-				if ls.lg != nil {
-					ls.lg.Debug("failed to send lease keepalive response to gRPC stream", zap.Error(err))
-				} else {
-					plog.Debugf("failed to send lease keepalive response to gRPC stream (%q)", err.Error())
-				}
-			} else {
-				if ls.lg != nil {
-					ls.lg.Warn("failed to send lease keepalive response to gRPC stream", zap.Error(err))
-				} else {
-					plog.Warningf("failed to send lease keepalive response to gRPC stream (%q)", err.Error())
-				}
-				streamFailures.WithLabelValues("send", "lease-keepalive").Inc()
-			}
-			return err
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go
deleted file mode 100644
index c51271a..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/maintenance.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-	"crypto/sha256"
-	"io"
-
-	"go.etcd.io/etcd/auth"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/version"
-
-	"go.uber.org/zap"
-)
-
-type KVGetter interface {
-	KV() mvcc.ConsistentWatchableKV
-}
-
-type BackendGetter interface {
-	Backend() backend.Backend
-}
-
-type Alarmer interface {
-	// Alarms is implemented in Server interface located in etcdserver/server.go
-	// It returns a list of alarms present in the AlarmStore
-	Alarms() []*pb.AlarmMember
-	Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error)
-}
-
-type LeaderTransferrer interface {
-	MoveLeader(ctx context.Context, lead, target uint64) error
-}
-
-type AuthGetter interface {
-	AuthInfoFromCtx(ctx context.Context) (*auth.AuthInfo, error)
-	AuthStore() auth.AuthStore
-}
-
-type ClusterStatusGetter interface {
-	IsLearner() bool
-}
-
-type maintenanceServer struct {
-	lg  *zap.Logger
-	rg  etcdserver.RaftStatusGetter
-	kg  KVGetter
-	bg  BackendGetter
-	a   Alarmer
-	lt  LeaderTransferrer
-	hdr header
-	cs  ClusterStatusGetter
-}
-
-func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer {
-	srv := &maintenanceServer{lg: s.Cfg.Logger, rg: s, kg: s, bg: s, a: s, lt: s, hdr: newHeader(s), cs: s}
-	return &authMaintenanceServer{srv, s}
-}
-
-func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
-	if ms.lg != nil {
-		ms.lg.Info("starting defragment")
-	} else {
-		plog.Noticef("starting to defragment the storage backend...")
-	}
-	err := ms.bg.Backend().Defrag()
-	if err != nil {
-		if ms.lg != nil {
-			ms.lg.Warn("failed to defragment", zap.Error(err))
-		} else {
-			plog.Errorf("failed to defragment the storage backend (%v)", err)
-		}
-		return nil, err
-	}
-	if ms.lg != nil {
-		ms.lg.Info("finished defragment")
-	} else {
-		plog.Noticef("finished defragmenting the storage backend")
-	}
-	return &pb.DefragmentResponse{}, nil
-}
-
-func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error {
-	snap := ms.bg.Backend().Snapshot()
-	pr, pw := io.Pipe()
-
-	defer pr.Close()
-
-	go func() {
-		snap.WriteTo(pw)
-		if err := snap.Close(); err != nil {
-			if ms.lg != nil {
-				ms.lg.Warn("failed to close snapshot", zap.Error(err))
-			} else {
-				plog.Errorf("error closing snapshot (%v)", err)
-			}
-		}
-		pw.Close()
-	}()
-
-	// send file data
-	h := sha256.New()
-	br := int64(0)
-	buf := make([]byte, 32*1024)
-	sz := snap.Size()
-	for br < sz {
-		n, err := io.ReadFull(pr, buf)
-		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
-			return togRPCError(err)
-		}
-		br += int64(n)
-		resp := &pb.SnapshotResponse{
-			RemainingBytes: uint64(sz - br),
-			Blob:           buf[:n],
-		}
-		if err = srv.Send(resp); err != nil {
-			return togRPCError(err)
-		}
-		h.Write(buf[:n])
-	}
-
-	// send sha
-	sha := h.Sum(nil)
-	hresp := &pb.SnapshotResponse{RemainingBytes: 0, Blob: sha}
-	if err := srv.Send(hresp); err != nil {
-		return togRPCError(err)
-	}
-
-	return nil
-}
-
-func (ms *maintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
-	h, rev, err := ms.kg.KV().Hash()
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	resp := &pb.HashResponse{Header: &pb.ResponseHeader{Revision: rev}, Hash: h}
-	ms.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ms *maintenanceServer) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
-	h, rev, compactRev, err := ms.kg.KV().HashByRev(r.Revision)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-
-	resp := &pb.HashKVResponse{Header: &pb.ResponseHeader{Revision: rev}, Hash: h, CompactRevision: compactRev}
-	ms.hdr.fill(resp.Header)
-	return resp, nil
-}
-
-func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	return ms.a.Alarm(ctx, ar)
-}
-
-func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) {
-	hdr := &pb.ResponseHeader{}
-	ms.hdr.fill(hdr)
-	resp := &pb.StatusResponse{
-		Header:           hdr,
-		Version:          version.Version,
-		Leader:           uint64(ms.rg.Leader()),
-		RaftIndex:        ms.rg.CommittedIndex(),
-		RaftAppliedIndex: ms.rg.AppliedIndex(),
-		RaftTerm:         ms.rg.Term(),
-		DbSize:           ms.bg.Backend().Size(),
-		DbSizeInUse:      ms.bg.Backend().SizeInUse(),
-		IsLearner:        ms.cs.IsLearner(),
-	}
-	if resp.Leader == raft.None {
-		resp.Errors = append(resp.Errors, etcdserver.ErrNoLeader.Error())
-	}
-	for _, a := range ms.a.Alarms() {
-		resp.Errors = append(resp.Errors, a.String())
-	}
-	return resp, nil
-}
-
-func (ms *maintenanceServer) MoveLeader(ctx context.Context, tr *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
-	if ms.rg.ID() != ms.rg.Leader() {
-		return nil, rpctypes.ErrGRPCNotLeader
-	}
-
-	if err := ms.lt.MoveLeader(ctx, uint64(ms.rg.Leader()), tr.TargetID); err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MoveLeaderResponse{}, nil
-}
-
-type authMaintenanceServer struct {
-	*maintenanceServer
-	ag AuthGetter
-}
-
-func (ams *authMaintenanceServer) isAuthenticated(ctx context.Context) error {
-	authInfo, err := ams.ag.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return err
-	}
-
-	return ams.ag.AuthStore().IsAdminPermitted(authInfo)
-}
-
-func (ams *authMaintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-
-	return ams.maintenanceServer.Defragment(ctx, sr)
-}
-
-func (ams *authMaintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error {
-	if err := ams.isAuthenticated(srv.Context()); err != nil {
-		return err
-	}
-
-	return ams.maintenanceServer.Snapshot(sr, srv)
-}
-
-func (ams *authMaintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-
-	return ams.maintenanceServer.Hash(ctx, r)
-}
-
-func (ams *authMaintenanceServer) HashKV(ctx context.Context, r *pb.HashKVRequest) (*pb.HashKVResponse, error) {
-	if err := ams.isAuthenticated(ctx); err != nil {
-		return nil, err
-	}
-	return ams.maintenanceServer.HashKV(ctx, r)
-}
-
-func (ams *authMaintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) {
-	return ams.maintenanceServer.Status(ctx, ar)
-}
-
-func (ams *authMaintenanceServer) MoveLeader(ctx context.Context, tr *pb.MoveLeaderRequest) (*pb.MoveLeaderResponse, error) {
-	return ams.maintenanceServer.MoveLeader(ctx, tr)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/member.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/member.go
deleted file mode 100644
index b2ebc98..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/member.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-)
-
-type ClusterServer struct {
-	cluster api.Cluster
-	server  etcdserver.ServerV3
-}
-
-func NewClusterServer(s etcdserver.ServerV3) *ClusterServer {
-	return &ClusterServer{
-		cluster: s.Cluster(),
-		server:  s,
-	}
-}
-
-func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) (*pb.MemberAddResponse, error) {
-	urls, err := types.NewURLs(r.PeerURLs)
-	if err != nil {
-		return nil, rpctypes.ErrGRPCMemberBadURLs
-	}
-
-	now := time.Now()
-	var m *membership.Member
-	if r.IsLearner {
-		m = membership.NewMemberAsLearner("", urls, "", &now)
-	} else {
-		m = membership.NewMember("", urls, "", &now)
-	}
-	membs, merr := cs.server.AddMember(ctx, *m)
-	if merr != nil {
-		return nil, togRPCError(merr)
-	}
-
-	return &pb.MemberAddResponse{
-		Header: cs.header(),
-		Member: &pb.Member{
-			ID:        uint64(m.ID),
-			PeerURLs:  m.PeerURLs,
-			IsLearner: m.IsLearner,
-		},
-		Members: membersToProtoMembers(membs),
-	}, nil
-}
-
-func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) {
-	membs, err := cs.server.RemoveMember(ctx, r.ID)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MemberRemoveResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
-}
-
-func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) {
-	m := membership.Member{
-		ID:             types.ID(r.ID),
-		RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs},
-	}
-	membs, err := cs.server.UpdateMember(ctx, m)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MemberUpdateResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
-}
-
-func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberListRequest) (*pb.MemberListResponse, error) {
-	membs := membersToProtoMembers(cs.cluster.Members())
-	return &pb.MemberListResponse{Header: cs.header(), Members: membs}, nil
-}
-
-func (cs *ClusterServer) MemberPromote(ctx context.Context, r *pb.MemberPromoteRequest) (*pb.MemberPromoteResponse, error) {
-	membs, err := cs.server.PromoteMember(ctx, r.ID)
-	if err != nil {
-		return nil, togRPCError(err)
-	}
-	return &pb.MemberPromoteResponse{Header: cs.header(), Members: membersToProtoMembers(membs)}, nil
-}
-
-func (cs *ClusterServer) header() *pb.ResponseHeader {
-	return &pb.ResponseHeader{ClusterId: uint64(cs.cluster.ID()), MemberId: uint64(cs.server.ID()), RaftTerm: cs.server.Term()}
-}
-
-func membersToProtoMembers(membs []*membership.Member) []*pb.Member {
-	protoMembs := make([]*pb.Member, len(membs))
-	for i := range membs {
-		protoMembs[i] = &pb.Member{
-			Name:       membs[i].Name,
-			ID:         uint64(membs[i].ID),
-			PeerURLs:   membs[i].PeerURLs,
-			ClientURLs: membs[i].ClientURLs,
-			IsLearner:  membs[i].IsLearner,
-		}
-	}
-	return protoMembs
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/metrics.go
deleted file mode 100644
index d633d27..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/metrics.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	sentBytes = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "client_grpc_sent_bytes_total",
-		Help:      "The total number of bytes sent to grpc clients.",
-	})
-
-	receivedBytes = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "client_grpc_received_bytes_total",
-		Help:      "The total number of bytes received from grpc clients.",
-	})
-
-	streamFailures = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "network",
-		Name:      "server_stream_failures_total",
-		Help:      "The total number of stream failures from the local server.",
-	},
-		[]string{"Type", "API"},
-	)
-)
-
-func init() {
-	prometheus.MustRegister(sentBytes)
-	prometheus.MustRegister(receivedBytes)
-	prometheus.MustRegister(streamFailures)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/quota.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/quota.go
deleted file mode 100644
index a145b8b..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/quota.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-)
-
-type quotaKVServer struct {
-	pb.KVServer
-	qa quotaAlarmer
-}
-
-type quotaAlarmer struct {
-	q  etcdserver.Quota
-	a  Alarmer
-	id types.ID
-}
-
-// check whether request satisfies the quota. If there is not enough space,
-// ignore request and raise the free space alarm.
-func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error {
-	if qa.q.Available(r) {
-		return nil
-	}
-	req := &pb.AlarmRequest{
-		MemberID: uint64(qa.id),
-		Action:   pb.AlarmRequest_ACTIVATE,
-		Alarm:    pb.AlarmType_NOSPACE,
-	}
-	qa.a.Alarm(ctx, req)
-	return rpctypes.ErrGRPCNoSpace
-}
-
-func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer {
-	return &quotaKVServer{
-		NewKVServer(s),
-		quotaAlarmer{etcdserver.NewBackendQuota(s, "kv"), s, s.ID()},
-	}
-}
-
-func (s *quotaKVServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := s.qa.check(ctx, r); err != nil {
-		return nil, err
-	}
-	return s.KVServer.Put(ctx, r)
-}
-
-func (s *quotaKVServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := s.qa.check(ctx, r); err != nil {
-		return nil, err
-	}
-	return s.KVServer.Txn(ctx, r)
-}
-
-type quotaLeaseServer struct {
-	pb.LeaseServer
-	qa quotaAlarmer
-}
-
-func (s *quotaLeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	if err := s.qa.check(ctx, cr); err != nil {
-		return nil, err
-	}
-	return s.LeaseServer.LeaseGrant(ctx, cr)
-}
-
-func NewQuotaLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {
-	return &quotaLeaseServer{
-		NewLeaseServer(s),
-		quotaAlarmer{etcdserver.NewBackendQuota(s, "lease"), s, s.ID()},
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/error.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/error.go
index e6a2814..bc1ad7b 100644
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/error.go
+++ b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/error.go
@@ -40,9 +40,6 @@
 	ErrGRPCMemberNotEnoughStarted = status.New(codes.FailedPrecondition, "etcdserver: re-configuration failed due to not enough started members").Err()
 	ErrGRPCMemberBadURLs          = status.New(codes.InvalidArgument, "etcdserver: given member URLs are invalid").Err()
 	ErrGRPCMemberNotFound         = status.New(codes.NotFound, "etcdserver: member not found").Err()
-	ErrGRPCMemberNotLearner       = status.New(codes.FailedPrecondition, "etcdserver: can only promote a learner member").Err()
-	ErrGRPCLearnerNotReady        = status.New(codes.FailedPrecondition, "etcdserver: can only promote a learner member which is in sync with leader").Err()
-	ErrGRPCTooManyLearners        = status.New(codes.FailedPrecondition, "etcdserver: too many learner members in cluster").Err()
 
 	ErrGRPCRequestTooLarge        = status.New(codes.InvalidArgument, "etcdserver: request is too large").Err()
 	ErrGRPCRequestTooManyRequests = status.New(codes.ResourceExhausted, "etcdserver: too many requests").Err()
@@ -54,7 +51,6 @@
 	ErrGRPCUserNotFound         = status.New(codes.FailedPrecondition, "etcdserver: user name not found").Err()
 	ErrGRPCRoleAlreadyExist     = status.New(codes.FailedPrecondition, "etcdserver: role name already exists").Err()
 	ErrGRPCRoleNotFound         = status.New(codes.FailedPrecondition, "etcdserver: role name not found").Err()
-	ErrGRPCRoleEmpty            = status.New(codes.InvalidArgument, "etcdserver: role name is empty").Err()
 	ErrGRPCAuthFailed           = status.New(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password").Err()
 	ErrGRPCPermissionDenied     = status.New(codes.PermissionDenied, "etcdserver: permission denied").Err()
 	ErrGRPCRoleNotGranted       = status.New(codes.FailedPrecondition, "etcdserver: role is not granted to the user").Err()
@@ -73,8 +69,6 @@
 	ErrGRPCTimeoutDueToConnectionLost = status.New(codes.Unavailable, "etcdserver: request timed out, possibly due to connection lost").Err()
 	ErrGRPCUnhealthy                  = status.New(codes.Unavailable, "etcdserver: unhealthy cluster").Err()
 	ErrGRPCCorrupt                    = status.New(codes.DataLoss, "etcdserver: corrupt cluster").Err()
-	ErrGPRCNotSupportedForLearner     = status.New(codes.Unavailable, "etcdserver: rpc not supported for learner").Err()
-	ErrGRPCBadLeaderTransferee        = status.New(codes.FailedPrecondition, "etcdserver: bad leader transferee").Err()
 
 	errStringToError = map[string]error{
 		ErrorDesc(ErrGRPCEmptyKey):      ErrGRPCEmptyKey,
@@ -97,9 +91,6 @@
 		ErrorDesc(ErrGRPCMemberNotEnoughStarted): ErrGRPCMemberNotEnoughStarted,
 		ErrorDesc(ErrGRPCMemberBadURLs):          ErrGRPCMemberBadURLs,
 		ErrorDesc(ErrGRPCMemberNotFound):         ErrGRPCMemberNotFound,
-		ErrorDesc(ErrGRPCMemberNotLearner):       ErrGRPCMemberNotLearner,
-		ErrorDesc(ErrGRPCLearnerNotReady):        ErrGRPCLearnerNotReady,
-		ErrorDesc(ErrGRPCTooManyLearners):        ErrGRPCTooManyLearners,
 
 		ErrorDesc(ErrGRPCRequestTooLarge):        ErrGRPCRequestTooLarge,
 		ErrorDesc(ErrGRPCRequestTooManyRequests): ErrGRPCRequestTooManyRequests,
@@ -111,7 +102,6 @@
 		ErrorDesc(ErrGRPCUserNotFound):         ErrGRPCUserNotFound,
 		ErrorDesc(ErrGRPCRoleAlreadyExist):     ErrGRPCRoleAlreadyExist,
 		ErrorDesc(ErrGRPCRoleNotFound):         ErrGRPCRoleNotFound,
-		ErrorDesc(ErrGRPCRoleEmpty):            ErrGRPCRoleEmpty,
 		ErrorDesc(ErrGRPCAuthFailed):           ErrGRPCAuthFailed,
 		ErrorDesc(ErrGRPCPermissionDenied):     ErrGRPCPermissionDenied,
 		ErrorDesc(ErrGRPCRoleNotGranted):       ErrGRPCRoleNotGranted,
@@ -122,7 +112,6 @@
 
 		ErrorDesc(ErrGRPCNoLeader):                   ErrGRPCNoLeader,
 		ErrorDesc(ErrGRPCNotLeader):                  ErrGRPCNotLeader,
-		ErrorDesc(ErrGRPCLeaderChanged):              ErrGRPCLeaderChanged,
 		ErrorDesc(ErrGRPCNotCapable):                 ErrGRPCNotCapable,
 		ErrorDesc(ErrGRPCStopped):                    ErrGRPCStopped,
 		ErrorDesc(ErrGRPCTimeout):                    ErrGRPCTimeout,
@@ -130,8 +119,6 @@
 		ErrorDesc(ErrGRPCTimeoutDueToConnectionLost): ErrGRPCTimeoutDueToConnectionLost,
 		ErrorDesc(ErrGRPCUnhealthy):                  ErrGRPCUnhealthy,
 		ErrorDesc(ErrGRPCCorrupt):                    ErrGRPCCorrupt,
-		ErrorDesc(ErrGPRCNotSupportedForLearner):     ErrGPRCNotSupportedForLearner,
-		ErrorDesc(ErrGRPCBadLeaderTransferee):        ErrGRPCBadLeaderTransferee,
 	}
 )
 
@@ -156,9 +143,6 @@
 	ErrMemberNotEnoughStarted = Error(ErrGRPCMemberNotEnoughStarted)
 	ErrMemberBadURLs          = Error(ErrGRPCMemberBadURLs)
 	ErrMemberNotFound         = Error(ErrGRPCMemberNotFound)
-	ErrMemberNotLearner       = Error(ErrGRPCMemberNotLearner)
-	ErrMemberLearnerNotReady  = Error(ErrGRPCLearnerNotReady)
-	ErrTooManyLearners        = Error(ErrGRPCTooManyLearners)
 
 	ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge)
 	ErrTooManyRequests = Error(ErrGRPCRequestTooManyRequests)
@@ -170,7 +154,6 @@
 	ErrUserNotFound         = Error(ErrGRPCUserNotFound)
 	ErrRoleAlreadyExist     = Error(ErrGRPCRoleAlreadyExist)
 	ErrRoleNotFound         = Error(ErrGRPCRoleNotFound)
-	ErrRoleEmpty            = Error(ErrGRPCRoleEmpty)
 	ErrAuthFailed           = Error(ErrGRPCAuthFailed)
 	ErrPermissionDenied     = Error(ErrGRPCPermissionDenied)
 	ErrRoleNotGranted       = Error(ErrGRPCRoleNotGranted)
@@ -189,7 +172,6 @@
 	ErrTimeoutDueToConnectionLost = Error(ErrGRPCTimeoutDueToConnectionLost)
 	ErrUnhealthy                  = Error(ErrGRPCUnhealthy)
 	ErrCorrupt                    = Error(ErrGRPCCorrupt)
-	ErrBadLeaderTransferee        = Error(ErrGRPCBadLeaderTransferee)
 )
 
 // EtcdError defines gRPC server errors.
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/md.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/md.go
index 5c590e1..90b8b83 100644
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/md.go
+++ b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes/md.go
@@ -17,4 +17,6 @@
 var (
 	MetadataRequireLeaderKey = "hasleader"
 	MetadataHasLeader        = "true"
+
+	MetadataClientAPIVersionKey = "client-api-version"
 )
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/util.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/util.go
deleted file mode 100644
index 281ddc7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/util.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2016 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 v3rpc
-
-import (
-	"context"
-	"strings"
-
-	"go.etcd.io/etcd/auth"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc"
-
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/status"
-)
-
-var toGRPCErrorMap = map[error]error{
-	membership.ErrIDRemoved:               rpctypes.ErrGRPCMemberNotFound,
-	membership.ErrIDNotFound:              rpctypes.ErrGRPCMemberNotFound,
-	membership.ErrIDExists:                rpctypes.ErrGRPCMemberExist,
-	membership.ErrPeerURLexists:           rpctypes.ErrGRPCPeerURLExist,
-	membership.ErrMemberNotLearner:        rpctypes.ErrGRPCMemberNotLearner,
-	membership.ErrTooManyLearners:         rpctypes.ErrGRPCTooManyLearners,
-	etcdserver.ErrNotEnoughStartedMembers: rpctypes.ErrMemberNotEnoughStarted,
-	etcdserver.ErrLearnerNotReady:         rpctypes.ErrGRPCLearnerNotReady,
-
-	mvcc.ErrCompacted:             rpctypes.ErrGRPCCompacted,
-	mvcc.ErrFutureRev:             rpctypes.ErrGRPCFutureRev,
-	etcdserver.ErrRequestTooLarge: rpctypes.ErrGRPCRequestTooLarge,
-	etcdserver.ErrNoSpace:         rpctypes.ErrGRPCNoSpace,
-	etcdserver.ErrTooManyRequests: rpctypes.ErrTooManyRequests,
-
-	etcdserver.ErrNoLeader:                   rpctypes.ErrGRPCNoLeader,
-	etcdserver.ErrNotLeader:                  rpctypes.ErrGRPCNotLeader,
-	etcdserver.ErrLeaderChanged:              rpctypes.ErrGRPCLeaderChanged,
-	etcdserver.ErrStopped:                    rpctypes.ErrGRPCStopped,
-	etcdserver.ErrTimeout:                    rpctypes.ErrGRPCTimeout,
-	etcdserver.ErrTimeoutDueToLeaderFail:     rpctypes.ErrGRPCTimeoutDueToLeaderFail,
-	etcdserver.ErrTimeoutDueToConnectionLost: rpctypes.ErrGRPCTimeoutDueToConnectionLost,
-	etcdserver.ErrUnhealthy:                  rpctypes.ErrGRPCUnhealthy,
-	etcdserver.ErrKeyNotFound:                rpctypes.ErrGRPCKeyNotFound,
-	etcdserver.ErrCorrupt:                    rpctypes.ErrGRPCCorrupt,
-	etcdserver.ErrBadLeaderTransferee:        rpctypes.ErrGRPCBadLeaderTransferee,
-
-	lease.ErrLeaseNotFound:    rpctypes.ErrGRPCLeaseNotFound,
-	lease.ErrLeaseExists:      rpctypes.ErrGRPCLeaseExist,
-	lease.ErrLeaseTTLTooLarge: rpctypes.ErrGRPCLeaseTTLTooLarge,
-
-	auth.ErrRootUserNotExist:     rpctypes.ErrGRPCRootUserNotExist,
-	auth.ErrRootRoleNotExist:     rpctypes.ErrGRPCRootRoleNotExist,
-	auth.ErrUserAlreadyExist:     rpctypes.ErrGRPCUserAlreadyExist,
-	auth.ErrUserEmpty:            rpctypes.ErrGRPCUserEmpty,
-	auth.ErrUserNotFound:         rpctypes.ErrGRPCUserNotFound,
-	auth.ErrRoleAlreadyExist:     rpctypes.ErrGRPCRoleAlreadyExist,
-	auth.ErrRoleNotFound:         rpctypes.ErrGRPCRoleNotFound,
-	auth.ErrRoleEmpty:            rpctypes.ErrGRPCRoleEmpty,
-	auth.ErrAuthFailed:           rpctypes.ErrGRPCAuthFailed,
-	auth.ErrPermissionDenied:     rpctypes.ErrGRPCPermissionDenied,
-	auth.ErrRoleNotGranted:       rpctypes.ErrGRPCRoleNotGranted,
-	auth.ErrPermissionNotGranted: rpctypes.ErrGRPCPermissionNotGranted,
-	auth.ErrAuthNotEnabled:       rpctypes.ErrGRPCAuthNotEnabled,
-	auth.ErrInvalidAuthToken:     rpctypes.ErrGRPCInvalidAuthToken,
-	auth.ErrInvalidAuthMgmt:      rpctypes.ErrGRPCInvalidAuthMgmt,
-}
-
-func togRPCError(err error) error {
-	// let gRPC server convert to codes.Canceled, codes.DeadlineExceeded
-	if err == context.Canceled || err == context.DeadlineExceeded {
-		return err
-	}
-	grpcErr, ok := toGRPCErrorMap[err]
-	if !ok {
-		return status.Error(codes.Unknown, err.Error())
-	}
-	return grpcErr
-}
-
-func isClientCtxErr(ctxErr error, err error) bool {
-	if ctxErr != nil {
-		return true
-	}
-
-	ev, ok := status.FromError(err)
-	if !ok {
-		return false
-	}
-
-	switch ev.Code() {
-	case codes.Canceled, codes.DeadlineExceeded:
-		// client-side context cancel or deadline exceeded
-		// "rpc error: code = Canceled desc = context canceled"
-		// "rpc error: code = DeadlineExceeded desc = context deadline exceeded"
-		return true
-	case codes.Unavailable:
-		msg := ev.Message()
-		// client-side context cancel or deadline exceeded with TLS ("http2.errClientDisconnected")
-		// "rpc error: code = Unavailable desc = client disconnected"
-		if msg == "client disconnected" {
-			return true
-		}
-		// "grpc/transport.ClientTransport.CloseStream" on canceled streams
-		// "rpc error: code = Unavailable desc = stream error: stream ID 21; CANCEL")
-		if strings.HasPrefix(msg, "stream error: ") && strings.HasSuffix(msg, "; CANCEL") {
-			return true
-		}
-	}
-	return false
-}
-
-// in v3.4, learner is allowed to serve serializable read and endpoint status
-func isRPCSupportedForLearner(req interface{}) bool {
-	switch r := req.(type) {
-	case *pb.StatusRequest:
-		return true
-	case *pb.RangeRequest:
-		return r.Serializable
-	default:
-		return false
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go b/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go
deleted file mode 100644
index f41cb6c..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/api/v3rpc/watch.go
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright 2015 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 v3rpc
-
-import (
-	"context"
-	"io"
-	"math/rand"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/auth"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-
-	"go.uber.org/zap"
-)
-
-type watchServer struct {
-	lg *zap.Logger
-
-	clusterID int64
-	memberID  int64
-
-	maxRequestBytes int
-
-	sg        etcdserver.RaftStatusGetter
-	watchable mvcc.WatchableKV
-	ag        AuthGetter
-}
-
-// NewWatchServer returns a new watch server.
-func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer {
-	return &watchServer{
-		lg: s.Cfg.Logger,
-
-		clusterID: int64(s.Cluster().ID()),
-		memberID:  int64(s.ID()),
-
-		maxRequestBytes: int(s.Cfg.MaxRequestBytes + grpcOverheadBytes),
-
-		sg:        s,
-		watchable: s.Watchable(),
-		ag:        s,
-	}
-}
-
-var (
-	// External test can read this with GetProgressReportInterval()
-	// and change this to a small value to finish fast with
-	// SetProgressReportInterval().
-	progressReportInterval   = 10 * time.Minute
-	progressReportIntervalMu sync.RWMutex
-)
-
-// GetProgressReportInterval returns the current progress report interval (for testing).
-func GetProgressReportInterval() time.Duration {
-	progressReportIntervalMu.RLock()
-	interval := progressReportInterval
-	progressReportIntervalMu.RUnlock()
-
-	// add rand(1/10*progressReportInterval) as jitter so that etcdserver will not
-	// send progress notifications to watchers around the same time even when watchers
-	// are created around the same time (which is common when a client restarts itself).
-	jitter := time.Duration(rand.Int63n(int64(interval) / 10))
-
-	return interval + jitter
-}
-
-// SetProgressReportInterval updates the current progress report interval (for testing).
-func SetProgressReportInterval(newTimeout time.Duration) {
-	progressReportIntervalMu.Lock()
-	progressReportInterval = newTimeout
-	progressReportIntervalMu.Unlock()
-}
-
-// We send ctrl response inside the read loop. We do not want
-// send to block read, but we still want ctrl response we sent to
-// be serialized. Thus we use a buffered chan to solve the problem.
-// A small buffer should be OK for most cases, since we expect the
-// ctrl requests are infrequent.
-const ctrlStreamBufLen = 16
-
-// serverWatchStream is an etcd server side stream. It receives requests
-// from client side gRPC stream. It receives watch events from mvcc.WatchStream,
-// and creates responses that forwarded to gRPC stream.
-// It also forwards control message like watch created and canceled.
-type serverWatchStream struct {
-	lg *zap.Logger
-
-	clusterID int64
-	memberID  int64
-
-	maxRequestBytes int
-
-	sg        etcdserver.RaftStatusGetter
-	watchable mvcc.WatchableKV
-	ag        AuthGetter
-
-	gRPCStream  pb.Watch_WatchServer
-	watchStream mvcc.WatchStream
-	ctrlStream  chan *pb.WatchResponse
-
-	// mu protects progress, prevKV, fragment
-	mu sync.RWMutex
-	// tracks the watchID that stream might need to send progress to
-	// TODO: combine progress and prevKV into a single struct?
-	progress map[mvcc.WatchID]bool
-	// record watch IDs that need return previous key-value pair
-	prevKV map[mvcc.WatchID]bool
-	// records fragmented watch IDs
-	fragment map[mvcc.WatchID]bool
-
-	// closec indicates the stream is closed.
-	closec chan struct{}
-
-	// wg waits for the send loop to complete
-	wg sync.WaitGroup
-}
-
-func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) {
-	sws := serverWatchStream{
-		lg: ws.lg,
-
-		clusterID: ws.clusterID,
-		memberID:  ws.memberID,
-
-		maxRequestBytes: ws.maxRequestBytes,
-
-		sg:        ws.sg,
-		watchable: ws.watchable,
-		ag:        ws.ag,
-
-		gRPCStream:  stream,
-		watchStream: ws.watchable.NewWatchStream(),
-		// chan for sending control response like watcher created and canceled.
-		ctrlStream: make(chan *pb.WatchResponse, ctrlStreamBufLen),
-
-		progress: make(map[mvcc.WatchID]bool),
-		prevKV:   make(map[mvcc.WatchID]bool),
-		fragment: make(map[mvcc.WatchID]bool),
-
-		closec: make(chan struct{}),
-	}
-
-	sws.wg.Add(1)
-	go func() {
-		sws.sendLoop()
-		sws.wg.Done()
-	}()
-
-	errc := make(chan error, 1)
-	// Ideally recvLoop would also use sws.wg to signal its completion
-	// but when stream.Context().Done() is closed, the stream's recv
-	// may continue to block since it uses a different context, leading to
-	// deadlock when calling sws.close().
-	go func() {
-		if rerr := sws.recvLoop(); rerr != nil {
-			if isClientCtxErr(stream.Context().Err(), rerr) {
-				if sws.lg != nil {
-					sws.lg.Debug("failed to receive watch request from gRPC stream", zap.Error(rerr))
-				} else {
-					plog.Debugf("failed to receive watch request from gRPC stream (%q)", rerr.Error())
-				}
-			} else {
-				if sws.lg != nil {
-					sws.lg.Warn("failed to receive watch request from gRPC stream", zap.Error(rerr))
-				} else {
-					plog.Warningf("failed to receive watch request from gRPC stream (%q)", rerr.Error())
-				}
-				streamFailures.WithLabelValues("receive", "watch").Inc()
-			}
-			errc <- rerr
-		}
-	}()
-
-	select {
-	case err = <-errc:
-		close(sws.ctrlStream)
-
-	case <-stream.Context().Done():
-		err = stream.Context().Err()
-		// the only server-side cancellation is noleader for now.
-		if err == context.Canceled {
-			err = rpctypes.ErrGRPCNoLeader
-		}
-	}
-
-	sws.close()
-	return err
-}
-
-func (sws *serverWatchStream) isWatchPermitted(wcr *pb.WatchCreateRequest) bool {
-	authInfo, err := sws.ag.AuthInfoFromCtx(sws.gRPCStream.Context())
-	if err != nil {
-		return false
-	}
-	if authInfo == nil {
-		// if auth is enabled, IsRangePermitted() can cause an error
-		authInfo = &auth.AuthInfo{}
-	}
-	return sws.ag.AuthStore().IsRangePermitted(authInfo, wcr.Key, wcr.RangeEnd) == nil
-}
-
-func (sws *serverWatchStream) recvLoop() error {
-	for {
-		req, err := sws.gRPCStream.Recv()
-		if err == io.EOF {
-			return nil
-		}
-		if err != nil {
-			return err
-		}
-
-		switch uv := req.RequestUnion.(type) {
-		case *pb.WatchRequest_CreateRequest:
-			if uv.CreateRequest == nil {
-				break
-			}
-
-			creq := uv.CreateRequest
-			if len(creq.Key) == 0 {
-				// \x00 is the smallest key
-				creq.Key = []byte{0}
-			}
-			if len(creq.RangeEnd) == 0 {
-				// force nil since watchstream.Watch distinguishes
-				// between nil and []byte{} for single key / >=
-				creq.RangeEnd = nil
-			}
-			if len(creq.RangeEnd) == 1 && creq.RangeEnd[0] == 0 {
-				// support  >= key queries
-				creq.RangeEnd = []byte{}
-			}
-
-			if !sws.isWatchPermitted(creq) {
-				wr := &pb.WatchResponse{
-					Header:       sws.newResponseHeader(sws.watchStream.Rev()),
-					WatchId:      creq.WatchId,
-					Canceled:     true,
-					Created:      true,
-					CancelReason: rpctypes.ErrGRPCPermissionDenied.Error(),
-				}
-
-				select {
-				case sws.ctrlStream <- wr:
-				case <-sws.closec:
-				}
-				return nil
-			}
-
-			filters := FiltersFromRequest(creq)
-
-			wsrev := sws.watchStream.Rev()
-			rev := creq.StartRevision
-			if rev == 0 {
-				rev = wsrev + 1
-			}
-			id, err := sws.watchStream.Watch(mvcc.WatchID(creq.WatchId), creq.Key, creq.RangeEnd, rev, filters...)
-			if err == nil {
-				sws.mu.Lock()
-				if creq.ProgressNotify {
-					sws.progress[id] = true
-				}
-				if creq.PrevKv {
-					sws.prevKV[id] = true
-				}
-				if creq.Fragment {
-					sws.fragment[id] = true
-				}
-				sws.mu.Unlock()
-			}
-			wr := &pb.WatchResponse{
-				Header:   sws.newResponseHeader(wsrev),
-				WatchId:  int64(id),
-				Created:  true,
-				Canceled: err != nil,
-			}
-			if err != nil {
-				wr.CancelReason = err.Error()
-			}
-			select {
-			case sws.ctrlStream <- wr:
-			case <-sws.closec:
-				return nil
-			}
-
-		case *pb.WatchRequest_CancelRequest:
-			if uv.CancelRequest != nil {
-				id := uv.CancelRequest.WatchId
-				err := sws.watchStream.Cancel(mvcc.WatchID(id))
-				if err == nil {
-					sws.ctrlStream <- &pb.WatchResponse{
-						Header:   sws.newResponseHeader(sws.watchStream.Rev()),
-						WatchId:  id,
-						Canceled: true,
-					}
-					sws.mu.Lock()
-					delete(sws.progress, mvcc.WatchID(id))
-					delete(sws.prevKV, mvcc.WatchID(id))
-					delete(sws.fragment, mvcc.WatchID(id))
-					sws.mu.Unlock()
-				}
-			}
-		case *pb.WatchRequest_ProgressRequest:
-			if uv.ProgressRequest != nil {
-				sws.ctrlStream <- &pb.WatchResponse{
-					Header:  sws.newResponseHeader(sws.watchStream.Rev()),
-					WatchId: -1, // response is not associated with any WatchId and will be broadcast to all watch channels
-				}
-			}
-		default:
-			// we probably should not shutdown the entire stream when
-			// receive an valid command.
-			// so just do nothing instead.
-			continue
-		}
-	}
-}
-
-func (sws *serverWatchStream) sendLoop() {
-	// watch ids that are currently active
-	ids := make(map[mvcc.WatchID]struct{})
-	// watch responses pending on a watch id creation message
-	pending := make(map[mvcc.WatchID][]*pb.WatchResponse)
-
-	interval := GetProgressReportInterval()
-	progressTicker := time.NewTicker(interval)
-
-	defer func() {
-		progressTicker.Stop()
-		// drain the chan to clean up pending events
-		for ws := range sws.watchStream.Chan() {
-			mvcc.ReportEventReceived(len(ws.Events))
-		}
-		for _, wrs := range pending {
-			for _, ws := range wrs {
-				mvcc.ReportEventReceived(len(ws.Events))
-			}
-		}
-	}()
-
-	for {
-		select {
-		case wresp, ok := <-sws.watchStream.Chan():
-			if !ok {
-				return
-			}
-
-			// TODO: evs is []mvccpb.Event type
-			// either return []*mvccpb.Event from the mvcc package
-			// or define protocol buffer with []mvccpb.Event.
-			evs := wresp.Events
-			events := make([]*mvccpb.Event, len(evs))
-			sws.mu.RLock()
-			needPrevKV := sws.prevKV[wresp.WatchID]
-			sws.mu.RUnlock()
-			for i := range evs {
-				events[i] = &evs[i]
-				if needPrevKV {
-					opt := mvcc.RangeOptions{Rev: evs[i].Kv.ModRevision - 1}
-					r, err := sws.watchable.Range(evs[i].Kv.Key, nil, opt)
-					if err == nil && len(r.KVs) != 0 {
-						events[i].PrevKv = &(r.KVs[0])
-					}
-				}
-			}
-
-			canceled := wresp.CompactRevision != 0
-			wr := &pb.WatchResponse{
-				Header:          sws.newResponseHeader(wresp.Revision),
-				WatchId:         int64(wresp.WatchID),
-				Events:          events,
-				CompactRevision: wresp.CompactRevision,
-				Canceled:        canceled,
-			}
-
-			if _, okID := ids[wresp.WatchID]; !okID {
-				// buffer if id not yet announced
-				wrs := append(pending[wresp.WatchID], wr)
-				pending[wresp.WatchID] = wrs
-				continue
-			}
-
-			mvcc.ReportEventReceived(len(evs))
-
-			sws.mu.RLock()
-			fragmented, ok := sws.fragment[wresp.WatchID]
-			sws.mu.RUnlock()
-
-			var serr error
-			if !fragmented && !ok {
-				serr = sws.gRPCStream.Send(wr)
-			} else {
-				serr = sendFragments(wr, sws.maxRequestBytes, sws.gRPCStream.Send)
-			}
-
-			if serr != nil {
-				if isClientCtxErr(sws.gRPCStream.Context().Err(), serr) {
-					if sws.lg != nil {
-						sws.lg.Debug("failed to send watch response to gRPC stream", zap.Error(serr))
-					} else {
-						plog.Debugf("failed to send watch response to gRPC stream (%q)", serr.Error())
-					}
-				} else {
-					if sws.lg != nil {
-						sws.lg.Warn("failed to send watch response to gRPC stream", zap.Error(serr))
-					} else {
-						plog.Warningf("failed to send watch response to gRPC stream (%q)", serr.Error())
-					}
-					streamFailures.WithLabelValues("send", "watch").Inc()
-				}
-				return
-			}
-
-			sws.mu.Lock()
-			if len(evs) > 0 && sws.progress[wresp.WatchID] {
-				// elide next progress update if sent a key update
-				sws.progress[wresp.WatchID] = false
-			}
-			sws.mu.Unlock()
-
-		case c, ok := <-sws.ctrlStream:
-			if !ok {
-				return
-			}
-
-			if err := sws.gRPCStream.Send(c); err != nil {
-				if isClientCtxErr(sws.gRPCStream.Context().Err(), err) {
-					if sws.lg != nil {
-						sws.lg.Debug("failed to send watch control response to gRPC stream", zap.Error(err))
-					} else {
-						plog.Debugf("failed to send watch control response to gRPC stream (%q)", err.Error())
-					}
-				} else {
-					if sws.lg != nil {
-						sws.lg.Warn("failed to send watch control response to gRPC stream", zap.Error(err))
-					} else {
-						plog.Warningf("failed to send watch control response to gRPC stream (%q)", err.Error())
-					}
-					streamFailures.WithLabelValues("send", "watch").Inc()
-				}
-				return
-			}
-
-			// track id creation
-			wid := mvcc.WatchID(c.WatchId)
-			if c.Canceled {
-				delete(ids, wid)
-				continue
-			}
-			if c.Created {
-				// flush buffered events
-				ids[wid] = struct{}{}
-				for _, v := range pending[wid] {
-					mvcc.ReportEventReceived(len(v.Events))
-					if err := sws.gRPCStream.Send(v); err != nil {
-						if isClientCtxErr(sws.gRPCStream.Context().Err(), err) {
-							if sws.lg != nil {
-								sws.lg.Debug("failed to send pending watch response to gRPC stream", zap.Error(err))
-							} else {
-								plog.Debugf("failed to send pending watch response to gRPC stream (%q)", err.Error())
-							}
-						} else {
-							if sws.lg != nil {
-								sws.lg.Warn("failed to send pending watch response to gRPC stream", zap.Error(err))
-							} else {
-								plog.Warningf("failed to send pending watch response to gRPC stream (%q)", err.Error())
-							}
-							streamFailures.WithLabelValues("send", "watch").Inc()
-						}
-						return
-					}
-				}
-				delete(pending, wid)
-			}
-
-		case <-progressTicker.C:
-			sws.mu.Lock()
-			for id, ok := range sws.progress {
-				if ok {
-					sws.watchStream.RequestProgress(id)
-				}
-				sws.progress[id] = true
-			}
-			sws.mu.Unlock()
-
-		case <-sws.closec:
-			return
-		}
-	}
-}
-
-func sendFragments(
-	wr *pb.WatchResponse,
-	maxRequestBytes int,
-	sendFunc func(*pb.WatchResponse) error) error {
-	// no need to fragment if total request size is smaller
-	// than max request limit or response contains only one event
-	if wr.Size() < maxRequestBytes || len(wr.Events) < 2 {
-		return sendFunc(wr)
-	}
-
-	ow := *wr
-	ow.Events = make([]*mvccpb.Event, 0)
-	ow.Fragment = true
-
-	var idx int
-	for {
-		cur := ow
-		for _, ev := range wr.Events[idx:] {
-			cur.Events = append(cur.Events, ev)
-			if len(cur.Events) > 1 && cur.Size() >= maxRequestBytes {
-				cur.Events = cur.Events[:len(cur.Events)-1]
-				break
-			}
-			idx++
-		}
-		if idx == len(wr.Events) {
-			// last response has no more fragment
-			cur.Fragment = false
-		}
-		if err := sendFunc(&cur); err != nil {
-			return err
-		}
-		if !cur.Fragment {
-			break
-		}
-	}
-	return nil
-}
-
-func (sws *serverWatchStream) close() {
-	sws.watchStream.Close()
-	close(sws.closec)
-	sws.wg.Wait()
-}
-
-func (sws *serverWatchStream) newResponseHeader(rev int64) *pb.ResponseHeader {
-	return &pb.ResponseHeader{
-		ClusterId: uint64(sws.clusterID),
-		MemberId:  uint64(sws.memberID),
-		Revision:  rev,
-		RaftTerm:  sws.sg.Term(),
-	}
-}
-
-func filterNoDelete(e mvccpb.Event) bool {
-	return e.Type == mvccpb.DELETE
-}
-
-func filterNoPut(e mvccpb.Event) bool {
-	return e.Type == mvccpb.PUT
-}
-
-// FiltersFromRequest returns "mvcc.FilterFunc" from a given watch create request.
-func FiltersFromRequest(creq *pb.WatchCreateRequest) []mvcc.FilterFunc {
-	filters := make([]mvcc.FilterFunc, 0, len(creq.Filters))
-	for _, ft := range creq.Filters {
-		switch ft {
-		case pb.WatchCreateRequest_NOPUT:
-			filters = append(filters, filterNoPut)
-		case pb.WatchCreateRequest_NODELETE:
-			filters = append(filters, filterNoDelete)
-		default:
-		}
-	}
-	return filters
-}