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
-}
