diff --git a/vendor/go.etcd.io/etcd/NOTICE b/vendor/go.etcd.io/etcd/NOTICE
new file mode 100644
index 0000000..b39ddfa
--- /dev/null
+++ b/vendor/go.etcd.io/etcd/NOTICE
@@ -0,0 +1,5 @@
+CoreOS Project
+Copyright 2014 CoreOS, Inc
+
+This product includes software developed at CoreOS, Inc.
+(http://www.coreos.com/).
diff --git a/vendor/go.etcd.io/etcd/auth/authpb/auth.pb.go b/vendor/go.etcd.io/etcd/auth/authpb/auth.pb.go
deleted file mode 100644
index 7e038df..0000000
--- a/vendor/go.etcd.io/etcd/auth/authpb/auth.pb.go
+++ /dev/null
@@ -1,977 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: auth.proto
-
-/*
-	Package authpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		auth.proto
-
-	It has these top-level messages:
-		UserAddOptions
-		User
-		Permission
-		Role
-*/
-package authpb
-
-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 Permission_Type int32
-
-const (
-	READ      Permission_Type = 0
-	WRITE     Permission_Type = 1
-	READWRITE Permission_Type = 2
-)
-
-var Permission_Type_name = map[int32]string{
-	0: "READ",
-	1: "WRITE",
-	2: "READWRITE",
-}
-var Permission_Type_value = map[string]int32{
-	"READ":      0,
-	"WRITE":     1,
-	"READWRITE": 2,
-}
-
-func (x Permission_Type) String() string {
-	return proto.EnumName(Permission_Type_name, int32(x))
-}
-func (Permission_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorAuth, []int{2, 0} }
-
-type UserAddOptions struct {
-	NoPassword bool `protobuf:"varint,1,opt,name=no_password,json=noPassword,proto3" json:"no_password,omitempty"`
-}
-
-func (m *UserAddOptions) Reset()                    { *m = UserAddOptions{} }
-func (m *UserAddOptions) String() string            { return proto.CompactTextString(m) }
-func (*UserAddOptions) ProtoMessage()               {}
-func (*UserAddOptions) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{0} }
-
-// User is a single entry in the bucket authUsers
-type User struct {
-	Name     []byte          `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Password []byte          `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
-	Roles    []string        `protobuf:"bytes,3,rep,name=roles" json:"roles,omitempty"`
-	Options  *UserAddOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"`
-}
-
-func (m *User) Reset()                    { *m = User{} }
-func (m *User) String() string            { return proto.CompactTextString(m) }
-func (*User) ProtoMessage()               {}
-func (*User) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{1} }
-
-// Permission is a single entity
-type Permission struct {
-	PermType Permission_Type `protobuf:"varint,1,opt,name=permType,proto3,enum=authpb.Permission_Type" json:"permType,omitempty"`
-	Key      []byte          `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-	RangeEnd []byte          `protobuf:"bytes,3,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-}
-
-func (m *Permission) Reset()                    { *m = Permission{} }
-func (m *Permission) String() string            { return proto.CompactTextString(m) }
-func (*Permission) ProtoMessage()               {}
-func (*Permission) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{2} }
-
-// Role is a single entry in the bucket authRoles
-type Role struct {
-	Name          []byte        `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	KeyPermission []*Permission `protobuf:"bytes,2,rep,name=keyPermission" json:"keyPermission,omitempty"`
-}
-
-func (m *Role) Reset()                    { *m = Role{} }
-func (m *Role) String() string            { return proto.CompactTextString(m) }
-func (*Role) ProtoMessage()               {}
-func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorAuth, []int{3} }
-
-func init() {
-	proto.RegisterType((*UserAddOptions)(nil), "authpb.UserAddOptions")
-	proto.RegisterType((*User)(nil), "authpb.User")
-	proto.RegisterType((*Permission)(nil), "authpb.Permission")
-	proto.RegisterType((*Role)(nil), "authpb.Role")
-	proto.RegisterEnum("authpb.Permission_Type", Permission_Type_name, Permission_Type_value)
-}
-func (m *UserAddOptions) 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 *UserAddOptions) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.NoPassword {
-		dAtA[i] = 0x8
-		i++
-		if m.NoPassword {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *User) 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 *User) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Password) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(len(m.Password)))
-		i += copy(dAtA[i:], m.Password)
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			dAtA[i] = 0x1a
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	if m.Options != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(m.Options.Size()))
-		n1, err := m.Options.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	return i, nil
-}
-
-func (m *Permission) 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 *Permission) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.PermType != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(m.PermType))
-	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	return i, nil
-}
-
-func (m *Role) 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 *Role) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintAuth(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.KeyPermission) > 0 {
-		for _, msg := range m.KeyPermission {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintAuth(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func encodeVarintAuth(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 *UserAddOptions) Size() (n int) {
-	var l int
-	_ = l
-	if m.NoPassword {
-		n += 2
-	}
-	return n
-}
-
-func (m *User) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	l = len(m.Password)
-	if l > 0 {
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			l = len(s)
-			n += 1 + l + sovAuth(uint64(l))
-		}
-	}
-	if m.Options != nil {
-		l = m.Options.Size()
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	return n
-}
-
-func (m *Permission) Size() (n int) {
-	var l int
-	_ = l
-	if m.PermType != 0 {
-		n += 1 + sovAuth(uint64(m.PermType))
-	}
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	return n
-}
-
-func (m *Role) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovAuth(uint64(l))
-	}
-	if len(m.KeyPermission) > 0 {
-		for _, e := range m.KeyPermission {
-			l = e.Size()
-			n += 1 + l + sovAuth(uint64(l))
-		}
-	}
-	return n
-}
-
-func sovAuth(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozAuth(x uint64) (n int) {
-	return sovAuth(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *UserAddOptions) 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 ErrIntOverflowAuth
-			}
-			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: UserAddOptions: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: UserAddOptions: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NoPassword", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.NoPassword = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipAuth(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthAuth
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *User) 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 ErrIntOverflowAuth
-			}
-			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: User: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: User: 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 ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			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 Password", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Password = append(m.Password[:0], dAtA[iNdEx:postIndex]...)
-			if m.Password == nil {
-				m.Password = []byte{}
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Options == nil {
-				m.Options = &UserAddOptions{}
-			}
-			if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipAuth(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthAuth
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *Permission) 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 ErrIntOverflowAuth
-			}
-			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: Permission: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Permission: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PermType", wireType)
-			}
-			m.PermType = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.PermType |= (Permission_Type(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		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 ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			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 != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipAuth(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthAuth
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *Role) 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 ErrIntOverflowAuth
-			}
-			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: Role: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Role: 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 ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			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 KeyPermission", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowAuth
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthAuth
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.KeyPermission = append(m.KeyPermission, &Permission{})
-			if err := m.KeyPermission[len(m.KeyPermission)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipAuth(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthAuth
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipAuth(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, ErrIntOverflowAuth
-			}
-			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, ErrIntOverflowAuth
-				}
-				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, ErrIntOverflowAuth
-				}
-				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, ErrInvalidLengthAuth
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowAuth
-					}
-					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 := skipAuth(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 (
-	ErrInvalidLengthAuth = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowAuth   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("auth.proto", fileDescriptorAuth) }
-
-var fileDescriptorAuth = []byte{
-	// 338 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0xcf, 0x4e, 0xea, 0x40,
-	0x14, 0xc6, 0x3b, 0xb4, 0x70, 0xdb, 0xc3, 0x85, 0x90, 0x13, 0x72, 0x6f, 0x83, 0x49, 0x6d, 0xba,
-	0x6a, 0x5c, 0x54, 0x85, 0x8d, 0x5b, 0x8c, 0x2c, 0x5c, 0x49, 0x26, 0x18, 0x97, 0xa4, 0xa4, 0x13,
-	0x24, 0xc0, 0x4c, 0x33, 0x83, 0x31, 0x6c, 0x7c, 0x0e, 0x17, 0x3e, 0x10, 0x4b, 0x1e, 0x41, 0xf0,
-	0x45, 0x4c, 0x67, 0xf8, 0x13, 0xa2, 0xbb, 0xef, 0x7c, 0xe7, 0xfb, 0x66, 0x7e, 0x99, 0x01, 0x48,
-	0x5f, 0x16, 0xcf, 0x49, 0x2e, 0xc5, 0x42, 0x60, 0xa5, 0xd0, 0xf9, 0xa8, 0xd5, 0x1c, 0x8b, 0xb1,
-	0xd0, 0xd6, 0x65, 0xa1, 0xcc, 0x36, 0xba, 0x86, 0xfa, 0xa3, 0x62, 0xb2, 0x9b, 0x65, 0x0f, 0xf9,
-	0x62, 0x22, 0xb8, 0xc2, 0x73, 0xa8, 0x72, 0x31, 0xcc, 0x53, 0xa5, 0x5e, 0x85, 0xcc, 0x7c, 0x12,
-	0x92, 0xd8, 0xa5, 0xc0, 0x45, 0x7f, 0xe7, 0x44, 0x6f, 0xe0, 0x14, 0x15, 0x44, 0x70, 0x78, 0x3a,
-	0x67, 0x3a, 0xf1, 0x97, 0x6a, 0x8d, 0x2d, 0x70, 0x0f, 0xcd, 0x92, 0xf6, 0x0f, 0x33, 0x36, 0xa1,
-	0x2c, 0xc5, 0x8c, 0x29, 0xdf, 0x0e, 0xed, 0xd8, 0xa3, 0x66, 0xc0, 0x2b, 0xf8, 0x23, 0xcc, 0xcd,
-	0xbe, 0x13, 0x92, 0xb8, 0xda, 0xfe, 0x97, 0x18, 0xe0, 0xe4, 0x94, 0x8b, 0xee, 0x63, 0xd1, 0x07,
-	0x01, 0xe8, 0x33, 0x39, 0x9f, 0x28, 0x35, 0x11, 0x1c, 0x3b, 0xe0, 0xe6, 0x4c, 0xce, 0x07, 0xcb,
-	0xdc, 0xa0, 0xd4, 0xdb, 0xff, 0xf7, 0x27, 0x1c, 0x53, 0x49, 0xb1, 0xa6, 0x87, 0x20, 0x36, 0xc0,
-	0x9e, 0xb2, 0xe5, 0x0e, 0xb1, 0x90, 0x78, 0x06, 0x9e, 0x4c, 0xf9, 0x98, 0x0d, 0x19, 0xcf, 0x7c,
-	0xdb, 0xa0, 0x6b, 0xa3, 0xc7, 0xb3, 0xe8, 0x02, 0x1c, 0x5d, 0x73, 0xc1, 0xa1, 0xbd, 0xee, 0x5d,
-	0xc3, 0x42, 0x0f, 0xca, 0x4f, 0xf4, 0x7e, 0xd0, 0x6b, 0x10, 0xac, 0x81, 0x57, 0x98, 0x66, 0x2c,
-	0x45, 0x03, 0x70, 0xa8, 0x98, 0xb1, 0x5f, 0x9f, 0xe7, 0x06, 0x6a, 0x53, 0xb6, 0x3c, 0x62, 0xf9,
-	0xa5, 0xd0, 0x8e, 0xab, 0x6d, 0xfc, 0x09, 0x4c, 0x4f, 0x83, 0xb7, 0xfe, 0x6a, 0x13, 0x58, 0xeb,
-	0x4d, 0x60, 0xad, 0xb6, 0x01, 0x59, 0x6f, 0x03, 0xf2, 0xb9, 0x0d, 0xc8, 0xfb, 0x57, 0x60, 0x8d,
-	0x2a, 0xfa, 0x23, 0x3b, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x61, 0x66, 0xc6, 0x9d, 0xf4, 0x01,
-	0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/auth/authpb/auth.proto b/vendor/go.etcd.io/etcd/auth/authpb/auth.proto
deleted file mode 100644
index 8f82b7c..0000000
--- a/vendor/go.etcd.io/etcd/auth/authpb/auth.proto
+++ /dev/null
@@ -1,42 +0,0 @@
-syntax = "proto3";
-package authpb;
-
-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;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-message UserAddOptions {
-  bool no_password = 1;
-};
-
-// User is a single entry in the bucket authUsers
-message User {
-  bytes name = 1;
-  bytes password = 2;
-  repeated string roles = 3;
-  UserAddOptions options = 4;
-}
-
-// Permission is a single entity
-message Permission {
-  enum Type {
-    READ = 0;
-    WRITE = 1;
-    READWRITE = 2;
-  }
-  Type permType = 1;
-
-  bytes key = 2;
-  bytes range_end = 3;
-}
-
-// Role is a single entry in the bucket authRoles
-message Role {
-  bytes name = 1;
-
-  repeated Permission keyPermission = 2;
-}
diff --git a/vendor/go.etcd.io/etcd/auth/doc.go b/vendor/go.etcd.io/etcd/auth/doc.go
deleted file mode 100644
index 72741a1..0000000
--- a/vendor/go.etcd.io/etcd/auth/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 auth provides client role authentication for accessing keys in etcd.
-package auth
diff --git a/vendor/go.etcd.io/etcd/auth/jwt.go b/vendor/go.etcd.io/etcd/auth/jwt.go
deleted file mode 100644
index c22ef89..0000000
--- a/vendor/go.etcd.io/etcd/auth/jwt.go
+++ /dev/null
@@ -1,184 +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 auth
-
-import (
-	"context"
-	"crypto/ecdsa"
-	"crypto/rsa"
-	"errors"
-	"time"
-
-	jwt "github.com/dgrijalva/jwt-go"
-	"go.uber.org/zap"
-)
-
-type tokenJWT struct {
-	lg         *zap.Logger
-	signMethod jwt.SigningMethod
-	key        interface{}
-	ttl        time.Duration
-	verifyOnly bool
-}
-
-func (t *tokenJWT) enable()                         {}
-func (t *tokenJWT) disable()                        {}
-func (t *tokenJWT) invalidateUser(string)           {}
-func (t *tokenJWT) genTokenPrefix() (string, error) { return "", nil }
-
-func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
-	// rev isn't used in JWT, it is only used in simple token
-	var (
-		username string
-		revision uint64
-	)
-
-	parsed, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
-		if token.Method.Alg() != t.signMethod.Alg() {
-			return nil, errors.New("invalid signing method")
-		}
-		switch k := t.key.(type) {
-		case *rsa.PrivateKey:
-			return &k.PublicKey, nil
-		case *ecdsa.PrivateKey:
-			return &k.PublicKey, nil
-		default:
-			return t.key, nil
-		}
-	})
-
-	if err != nil {
-		if t.lg != nil {
-			t.lg.Warn(
-				"failed to parse a JWT token",
-				zap.String("token", token),
-				zap.Error(err),
-			)
-		} else {
-			plog.Warningf("failed to parse jwt token: %s", err)
-		}
-		return nil, false
-	}
-
-	claims, ok := parsed.Claims.(jwt.MapClaims)
-	if !parsed.Valid || !ok {
-		if t.lg != nil {
-			t.lg.Warn("invalid JWT token", zap.String("token", token))
-		} else {
-			plog.Warningf("invalid jwt token: %s", token)
-		}
-		return nil, false
-	}
-
-	username = claims["username"].(string)
-	revision = uint64(claims["revision"].(float64))
-
-	return &AuthInfo{Username: username, Revision: revision}, true
-}
-
-func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) (string, error) {
-	if t.verifyOnly {
-		return "", ErrVerifyOnly
-	}
-
-	// Future work: let a jwt token include permission information would be useful for
-	// permission checking in proxy side.
-	tk := jwt.NewWithClaims(t.signMethod,
-		jwt.MapClaims{
-			"username": username,
-			"revision": revision,
-			"exp":      time.Now().Add(t.ttl).Unix(),
-		})
-
-	token, err := tk.SignedString(t.key)
-	if err != nil {
-		if t.lg != nil {
-			t.lg.Warn(
-				"failed to sign a JWT token",
-				zap.String("user-name", username),
-				zap.Uint64("revision", revision),
-				zap.Error(err),
-			)
-		} else {
-			plog.Debugf("failed to sign jwt token: %s", err)
-		}
-		return "", err
-	}
-
-	if t.lg != nil {
-		t.lg.Info(
-			"created/assigned a new JWT token",
-			zap.String("user-name", username),
-			zap.Uint64("revision", revision),
-			zap.String("token", token),
-		)
-	} else {
-		plog.Debugf("jwt token: %s", token)
-	}
-	return token, err
-}
-
-func newTokenProviderJWT(lg *zap.Logger, optMap map[string]string) (*tokenJWT, error) {
-	var err error
-	var opts jwtOptions
-	err = opts.ParseWithDefaults(optMap)
-	if err != nil {
-		if lg != nil {
-			lg.Warn("problem loading JWT options", zap.Error(err))
-		} else {
-			plog.Errorf("problem loading JWT options: %s", err)
-		}
-		return nil, ErrInvalidAuthOpts
-	}
-
-	var keys = make([]string, 0, len(optMap))
-	for k := range optMap {
-		if !knownOptions[k] {
-			keys = append(keys, k)
-		}
-	}
-	if len(keys) > 0 {
-		if lg != nil {
-			lg.Warn("unknown JWT options", zap.Strings("keys", keys))
-		} else {
-			plog.Warningf("unknown JWT options: %v", keys)
-		}
-	}
-
-	key, err := opts.Key()
-	if err != nil {
-		return nil, err
-	}
-
-	t := &tokenJWT{
-		lg:         lg,
-		ttl:        opts.TTL,
-		signMethod: opts.SignMethod,
-		key:        key,
-	}
-
-	switch t.signMethod.(type) {
-	case *jwt.SigningMethodECDSA:
-		if _, ok := t.key.(*ecdsa.PublicKey); ok {
-			t.verifyOnly = true
-		}
-	case *jwt.SigningMethodRSA, *jwt.SigningMethodRSAPSS:
-		if _, ok := t.key.(*rsa.PublicKey); ok {
-			t.verifyOnly = true
-		}
-	}
-
-	return t, nil
-}
diff --git a/vendor/go.etcd.io/etcd/auth/nop.go b/vendor/go.etcd.io/etcd/auth/nop.go
deleted file mode 100644
index d437874..0000000
--- a/vendor/go.etcd.io/etcd/auth/nop.go
+++ /dev/null
@@ -1,35 +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 auth
-
-import (
-	"context"
-)
-
-type tokenNop struct{}
-
-func (t *tokenNop) enable()                         {}
-func (t *tokenNop) disable()                        {}
-func (t *tokenNop) invalidateUser(string)           {}
-func (t *tokenNop) genTokenPrefix() (string, error) { return "", nil }
-func (t *tokenNop) info(ctx context.Context, token string, rev uint64) (*AuthInfo, bool) {
-	return nil, false
-}
-func (t *tokenNop) assign(ctx context.Context, username string, revision uint64) (string, error) {
-	return "", ErrAuthFailed
-}
-func newTokenProviderNop() (*tokenNop, error) {
-	return &tokenNop{}, nil
-}
diff --git a/vendor/go.etcd.io/etcd/auth/options.go b/vendor/go.etcd.io/etcd/auth/options.go
deleted file mode 100644
index f40b92d..0000000
--- a/vendor/go.etcd.io/etcd/auth/options.go
+++ /dev/null
@@ -1,192 +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 auth
-
-import (
-	"crypto/ecdsa"
-	"crypto/rsa"
-	"fmt"
-	"io/ioutil"
-	"time"
-
-	jwt "github.com/dgrijalva/jwt-go"
-)
-
-const (
-	optSignMethod = "sign-method"
-	optPublicKey  = "pub-key"
-	optPrivateKey = "priv-key"
-	optTTL        = "ttl"
-)
-
-var knownOptions = map[string]bool{
-	optSignMethod: true,
-	optPublicKey:  true,
-	optPrivateKey: true,
-	optTTL:        true,
-}
-
-var (
-	// DefaultTTL will be used when a 'ttl' is not specified
-	DefaultTTL = 5 * time.Minute
-)
-
-type jwtOptions struct {
-	SignMethod jwt.SigningMethod
-	PublicKey  []byte
-	PrivateKey []byte
-	TTL        time.Duration
-}
-
-// ParseWithDefaults will load options from the specified map or set defaults where appropriate
-func (opts *jwtOptions) ParseWithDefaults(optMap map[string]string) error {
-	if opts.TTL == 0 && optMap[optTTL] == "" {
-		opts.TTL = DefaultTTL
-	}
-
-	return opts.Parse(optMap)
-}
-
-// Parse will load options from the specified map
-func (opts *jwtOptions) Parse(optMap map[string]string) error {
-	var err error
-	if ttl := optMap[optTTL]; ttl != "" {
-		opts.TTL, err = time.ParseDuration(ttl)
-		if err != nil {
-			return err
-		}
-	}
-
-	if file := optMap[optPublicKey]; file != "" {
-		opts.PublicKey, err = ioutil.ReadFile(file)
-		if err != nil {
-			return err
-		}
-	}
-
-	if file := optMap[optPrivateKey]; file != "" {
-		opts.PrivateKey, err = ioutil.ReadFile(file)
-		if err != nil {
-			return err
-		}
-	}
-
-	// signing method is a required field
-	method := optMap[optSignMethod]
-	opts.SignMethod = jwt.GetSigningMethod(method)
-	if opts.SignMethod == nil {
-		return ErrInvalidAuthMethod
-	}
-
-	return nil
-}
-
-// Key will parse and return the appropriately typed key for the selected signature method
-func (opts *jwtOptions) Key() (interface{}, error) {
-	switch opts.SignMethod.(type) {
-	case *jwt.SigningMethodRSA, *jwt.SigningMethodRSAPSS:
-		return opts.rsaKey()
-	case *jwt.SigningMethodECDSA:
-		return opts.ecKey()
-	case *jwt.SigningMethodHMAC:
-		return opts.hmacKey()
-	default:
-		return nil, fmt.Errorf("unsupported signing method: %T", opts.SignMethod)
-	}
-}
-
-func (opts *jwtOptions) hmacKey() (interface{}, error) {
-	if len(opts.PrivateKey) == 0 {
-		return nil, ErrMissingKey
-	}
-	return opts.PrivateKey, nil
-}
-
-func (opts *jwtOptions) rsaKey() (interface{}, error) {
-	var (
-		priv *rsa.PrivateKey
-		pub  *rsa.PublicKey
-		err  error
-	)
-
-	if len(opts.PrivateKey) > 0 {
-		priv, err = jwt.ParseRSAPrivateKeyFromPEM(opts.PrivateKey)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if len(opts.PublicKey) > 0 {
-		pub, err = jwt.ParseRSAPublicKeyFromPEM(opts.PublicKey)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if priv == nil {
-		if pub == nil {
-			// Neither key given
-			return nil, ErrMissingKey
-		}
-		// Public key only, can verify tokens
-		return pub, nil
-	}
-
-	// both keys provided, make sure they match
-	if pub != nil && pub.E != priv.E && pub.N.Cmp(priv.N) != 0 {
-		return nil, ErrKeyMismatch
-	}
-
-	return priv, nil
-}
-
-func (opts *jwtOptions) ecKey() (interface{}, error) {
-	var (
-		priv *ecdsa.PrivateKey
-		pub  *ecdsa.PublicKey
-		err  error
-	)
-
-	if len(opts.PrivateKey) > 0 {
-		priv, err = jwt.ParseECPrivateKeyFromPEM(opts.PrivateKey)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if len(opts.PublicKey) > 0 {
-		pub, err = jwt.ParseECPublicKeyFromPEM(opts.PublicKey)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if priv == nil {
-		if pub == nil {
-			// Neither key given
-			return nil, ErrMissingKey
-		}
-		// Public key only, can verify tokens
-		return pub, nil
-	}
-
-	// both keys provided, make sure they match
-	if pub != nil && pub.Curve != priv.Curve &&
-		pub.X.Cmp(priv.X) != 0 && pub.Y.Cmp(priv.Y) != 0 {
-		return nil, ErrKeyMismatch
-	}
-
-	return priv, nil
-}
diff --git a/vendor/go.etcd.io/etcd/auth/range_perm_cache.go b/vendor/go.etcd.io/etcd/auth/range_perm_cache.go
deleted file mode 100644
index 7b6c182..0000000
--- a/vendor/go.etcd.io/etcd/auth/range_perm_cache.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 auth
-
-import (
-	"go.etcd.io/etcd/auth/authpb"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/pkg/adt"
-
-	"go.uber.org/zap"
-)
-
-func getMergedPerms(lg *zap.Logger, tx backend.BatchTx, userName string) *unifiedRangePermissions {
-	user := getUser(lg, tx, userName)
-	if user == nil {
-		return nil
-	}
-
-	readPerms := adt.NewIntervalTree()
-	writePerms := adt.NewIntervalTree()
-
-	for _, roleName := range user.Roles {
-		role := getRole(tx, roleName)
-		if role == nil {
-			continue
-		}
-
-		for _, perm := range role.KeyPermission {
-			var ivl adt.Interval
-			var rangeEnd []byte
-
-			if len(perm.RangeEnd) != 1 || perm.RangeEnd[0] != 0 {
-				rangeEnd = perm.RangeEnd
-			}
-
-			if len(perm.RangeEnd) != 0 {
-				ivl = adt.NewBytesAffineInterval(perm.Key, rangeEnd)
-			} else {
-				ivl = adt.NewBytesAffinePoint(perm.Key)
-			}
-
-			switch perm.PermType {
-			case authpb.READWRITE:
-				readPerms.Insert(ivl, struct{}{})
-				writePerms.Insert(ivl, struct{}{})
-
-			case authpb.READ:
-				readPerms.Insert(ivl, struct{}{})
-
-			case authpb.WRITE:
-				writePerms.Insert(ivl, struct{}{})
-			}
-		}
-	}
-
-	return &unifiedRangePermissions{
-		readPerms:  readPerms,
-		writePerms: writePerms,
-	}
-}
-
-func checkKeyInterval(
-	lg *zap.Logger,
-	cachedPerms *unifiedRangePermissions,
-	key, rangeEnd []byte,
-	permtyp authpb.Permission_Type) bool {
-	if len(rangeEnd) == 1 && rangeEnd[0] == 0 {
-		rangeEnd = nil
-	}
-
-	ivl := adt.NewBytesAffineInterval(key, rangeEnd)
-	switch permtyp {
-	case authpb.READ:
-		return cachedPerms.readPerms.Contains(ivl)
-	case authpb.WRITE:
-		return cachedPerms.writePerms.Contains(ivl)
-	default:
-		if lg != nil {
-			lg.Panic("unknown auth type", zap.String("auth-type", permtyp.String()))
-		} else {
-			plog.Panicf("unknown auth type: %v", permtyp)
-		}
-	}
-	return false
-}
-
-func checkKeyPoint(lg *zap.Logger, cachedPerms *unifiedRangePermissions, key []byte, permtyp authpb.Permission_Type) bool {
-	pt := adt.NewBytesAffinePoint(key)
-	switch permtyp {
-	case authpb.READ:
-		return cachedPerms.readPerms.Intersects(pt)
-	case authpb.WRITE:
-		return cachedPerms.writePerms.Intersects(pt)
-	default:
-		if lg != nil {
-			lg.Panic("unknown auth type", zap.String("auth-type", permtyp.String()))
-		} else {
-			plog.Panicf("unknown auth type: %v", permtyp)
-		}
-	}
-	return false
-}
-
-func (as *authStore) isRangeOpPermitted(tx backend.BatchTx, userName string, key, rangeEnd []byte, permtyp authpb.Permission_Type) bool {
-	// assumption: tx is Lock()ed
-	_, ok := as.rangePermCache[userName]
-	if !ok {
-		perms := getMergedPerms(as.lg, tx, userName)
-		if perms == nil {
-			if as.lg != nil {
-				as.lg.Warn(
-					"failed to create a merged permission",
-					zap.String("user-name", userName),
-				)
-			} else {
-				plog.Errorf("failed to create a unified permission of user %s", userName)
-			}
-			return false
-		}
-		as.rangePermCache[userName] = perms
-	}
-
-	if len(rangeEnd) == 0 {
-		return checkKeyPoint(as.lg, as.rangePermCache[userName], key, permtyp)
-	}
-
-	return checkKeyInterval(as.lg, as.rangePermCache[userName], key, rangeEnd, permtyp)
-}
-
-func (as *authStore) clearCachedPerm() {
-	as.rangePermCache = make(map[string]*unifiedRangePermissions)
-}
-
-func (as *authStore) invalidateCachedPerm(userName string) {
-	delete(as.rangePermCache, userName)
-}
-
-type unifiedRangePermissions struct {
-	readPerms  adt.IntervalTree
-	writePerms adt.IntervalTree
-}
diff --git a/vendor/go.etcd.io/etcd/auth/simple_token.go b/vendor/go.etcd.io/etcd/auth/simple_token.go
deleted file mode 100644
index 934978c..0000000
--- a/vendor/go.etcd.io/etcd/auth/simple_token.go
+++ /dev/null
@@ -1,243 +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 auth
-
-// CAUTION: This random number based token mechanism is only for testing purpose.
-// JWT based mechanism will be added in the near future.
-
-import (
-	"context"
-	"crypto/rand"
-	"fmt"
-	"math/big"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"go.uber.org/zap"
-)
-
-const (
-	letters                  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-	defaultSimpleTokenLength = 16
-)
-
-// var for testing purposes
-var (
-	simpleTokenTTL           = 5 * time.Minute
-	simpleTokenTTLResolution = 1 * time.Second
-)
-
-type simpleTokenTTLKeeper struct {
-	tokens          map[string]time.Time
-	donec           chan struct{}
-	stopc           chan struct{}
-	deleteTokenFunc func(string)
-	mu              *sync.Mutex
-}
-
-func (tm *simpleTokenTTLKeeper) stop() {
-	select {
-	case tm.stopc <- struct{}{}:
-	case <-tm.donec:
-	}
-	<-tm.donec
-}
-
-func (tm *simpleTokenTTLKeeper) addSimpleToken(token string) {
-	tm.tokens[token] = time.Now().Add(simpleTokenTTL)
-}
-
-func (tm *simpleTokenTTLKeeper) resetSimpleToken(token string) {
-	if _, ok := tm.tokens[token]; ok {
-		tm.tokens[token] = time.Now().Add(simpleTokenTTL)
-	}
-}
-
-func (tm *simpleTokenTTLKeeper) deleteSimpleToken(token string) {
-	delete(tm.tokens, token)
-}
-
-func (tm *simpleTokenTTLKeeper) run() {
-	tokenTicker := time.NewTicker(simpleTokenTTLResolution)
-	defer func() {
-		tokenTicker.Stop()
-		close(tm.donec)
-	}()
-	for {
-		select {
-		case <-tokenTicker.C:
-			nowtime := time.Now()
-			tm.mu.Lock()
-			for t, tokenendtime := range tm.tokens {
-				if nowtime.After(tokenendtime) {
-					tm.deleteTokenFunc(t)
-					delete(tm.tokens, t)
-				}
-			}
-			tm.mu.Unlock()
-		case <-tm.stopc:
-			return
-		}
-	}
-}
-
-type tokenSimple struct {
-	lg                *zap.Logger
-	indexWaiter       func(uint64) <-chan struct{}
-	simpleTokenKeeper *simpleTokenTTLKeeper
-	simpleTokensMu    sync.Mutex
-	simpleTokens      map[string]string // token -> username
-}
-
-func (t *tokenSimple) genTokenPrefix() (string, error) {
-	ret := make([]byte, defaultSimpleTokenLength)
-
-	for i := 0; i < defaultSimpleTokenLength; i++ {
-		bInt, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
-		if err != nil {
-			return "", err
-		}
-
-		ret[i] = letters[bInt.Int64()]
-	}
-
-	return string(ret), nil
-}
-
-func (t *tokenSimple) assignSimpleTokenToUser(username, token string) {
-	t.simpleTokensMu.Lock()
-	defer t.simpleTokensMu.Unlock()
-	if t.simpleTokenKeeper == nil {
-		return
-	}
-
-	_, ok := t.simpleTokens[token]
-	if ok {
-		if t.lg != nil {
-			t.lg.Panic(
-				"failed to assign already-used simple token to a user",
-				zap.String("user-name", username),
-				zap.String("token", token),
-			)
-		} else {
-			plog.Panicf("token %s is already used", token)
-		}
-	}
-
-	t.simpleTokens[token] = username
-	t.simpleTokenKeeper.addSimpleToken(token)
-}
-
-func (t *tokenSimple) invalidateUser(username string) {
-	if t.simpleTokenKeeper == nil {
-		return
-	}
-	t.simpleTokensMu.Lock()
-	for token, name := range t.simpleTokens {
-		if name == username {
-			delete(t.simpleTokens, token)
-			t.simpleTokenKeeper.deleteSimpleToken(token)
-		}
-	}
-	t.simpleTokensMu.Unlock()
-}
-
-func (t *tokenSimple) enable() {
-	delf := func(tk string) {
-		if username, ok := t.simpleTokens[tk]; ok {
-			if t.lg != nil {
-				t.lg.Info(
-					"deleted a simple token",
-					zap.String("user-name", username),
-					zap.String("token", tk),
-				)
-			} else {
-				plog.Infof("deleting token %s for user %s", tk, username)
-			}
-			delete(t.simpleTokens, tk)
-		}
-	}
-	t.simpleTokenKeeper = &simpleTokenTTLKeeper{
-		tokens:          make(map[string]time.Time),
-		donec:           make(chan struct{}),
-		stopc:           make(chan struct{}),
-		deleteTokenFunc: delf,
-		mu:              &t.simpleTokensMu,
-	}
-	go t.simpleTokenKeeper.run()
-}
-
-func (t *tokenSimple) disable() {
-	t.simpleTokensMu.Lock()
-	tk := t.simpleTokenKeeper
-	t.simpleTokenKeeper = nil
-	t.simpleTokens = make(map[string]string) // invalidate all tokens
-	t.simpleTokensMu.Unlock()
-	if tk != nil {
-		tk.stop()
-	}
-}
-
-func (t *tokenSimple) info(ctx context.Context, token string, revision uint64) (*AuthInfo, bool) {
-	if !t.isValidSimpleToken(ctx, token) {
-		return nil, false
-	}
-	t.simpleTokensMu.Lock()
-	username, ok := t.simpleTokens[token]
-	if ok && t.simpleTokenKeeper != nil {
-		t.simpleTokenKeeper.resetSimpleToken(token)
-	}
-	t.simpleTokensMu.Unlock()
-	return &AuthInfo{Username: username, Revision: revision}, ok
-}
-
-func (t *tokenSimple) assign(ctx context.Context, username string, rev uint64) (string, error) {
-	// rev isn't used in simple token, it is only used in JWT
-	index := ctx.Value(AuthenticateParamIndex{}).(uint64)
-	simpleTokenPrefix := ctx.Value(AuthenticateParamSimpleTokenPrefix{}).(string)
-	token := fmt.Sprintf("%s.%d", simpleTokenPrefix, index)
-	t.assignSimpleTokenToUser(username, token)
-
-	return token, nil
-}
-
-func (t *tokenSimple) isValidSimpleToken(ctx context.Context, token string) bool {
-	splitted := strings.Split(token, ".")
-	if len(splitted) != 2 {
-		return false
-	}
-	index, err := strconv.Atoi(splitted[1])
-	if err != nil {
-		return false
-	}
-
-	select {
-	case <-t.indexWaiter(uint64(index)):
-		return true
-	case <-ctx.Done():
-	}
-
-	return false
-}
-
-func newTokenProviderSimple(lg *zap.Logger, indexWaiter func(uint64) <-chan struct{}) *tokenSimple {
-	return &tokenSimple{
-		lg:           lg,
-		simpleTokens: make(map[string]string),
-		indexWaiter:  indexWaiter,
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/auth/store.go b/vendor/go.etcd.io/etcd/auth/store.go
deleted file mode 100644
index 5212255..0000000
--- a/vendor/go.etcd.io/etcd/auth/store.go
+++ /dev/null
@@ -1,1420 +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 auth
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"errors"
-	"sort"
-	"strings"
-	"sync"
-	"sync/atomic"
-
-	"go.etcd.io/etcd/auth/authpb"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc/backend"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-	"golang.org/x/crypto/bcrypt"
-	"google.golang.org/grpc/credentials"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/peer"
-)
-
-var (
-	enableFlagKey = []byte("authEnabled")
-	authEnabled   = []byte{1}
-	authDisabled  = []byte{0}
-
-	revisionKey = []byte("authRevision")
-
-	authBucketName      = []byte("auth")
-	authUsersBucketName = []byte("authUsers")
-	authRolesBucketName = []byte("authRoles")
-
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "auth")
-
-	ErrRootUserNotExist     = errors.New("auth: root user does not exist")
-	ErrRootRoleNotExist     = errors.New("auth: root user does not have root role")
-	ErrUserAlreadyExist     = errors.New("auth: user already exists")
-	ErrUserEmpty            = errors.New("auth: user name is empty")
-	ErrUserNotFound         = errors.New("auth: user not found")
-	ErrRoleAlreadyExist     = errors.New("auth: role already exists")
-	ErrRoleNotFound         = errors.New("auth: role not found")
-	ErrRoleEmpty            = errors.New("auth: role name is empty")
-	ErrAuthFailed           = errors.New("auth: authentication failed, invalid user ID or password")
-	ErrPermissionDenied     = errors.New("auth: permission denied")
-	ErrRoleNotGranted       = errors.New("auth: role is not granted to the user")
-	ErrPermissionNotGranted = errors.New("auth: permission is not granted to the role")
-	ErrAuthNotEnabled       = errors.New("auth: authentication is not enabled")
-	ErrAuthOldRevision      = errors.New("auth: revision in header is old")
-	ErrInvalidAuthToken     = errors.New("auth: invalid auth token")
-	ErrInvalidAuthOpts      = errors.New("auth: invalid auth options")
-	ErrInvalidAuthMgmt      = errors.New("auth: invalid auth management")
-	ErrInvalidAuthMethod    = errors.New("auth: invalid auth signature method")
-	ErrMissingKey           = errors.New("auth: missing key data")
-	ErrKeyMismatch          = errors.New("auth: public and private keys don't match")
-	ErrVerifyOnly           = errors.New("auth: token signing attempted with verify-only key")
-)
-
-const (
-	rootUser = "root"
-	rootRole = "root"
-
-	tokenTypeSimple = "simple"
-	tokenTypeJWT    = "jwt"
-
-	revBytesLen = 8
-)
-
-type AuthInfo struct {
-	Username string
-	Revision uint64
-}
-
-// AuthenticateParamIndex is used for a key of context in the parameters of Authenticate()
-type AuthenticateParamIndex struct{}
-
-// AuthenticateParamSimpleTokenPrefix is used for a key of context in the parameters of Authenticate()
-type AuthenticateParamSimpleTokenPrefix struct{}
-
-// AuthStore defines auth storage interface.
-type AuthStore interface {
-	// AuthEnable turns on the authentication feature
-	AuthEnable() error
-
-	// AuthDisable turns off the authentication feature
-	AuthDisable()
-
-	// IsAuthEnabled returns true if the authentication feature is enabled.
-	IsAuthEnabled() bool
-
-	// Authenticate does authentication based on given user name and password
-	Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error)
-
-	// Recover recovers the state of auth store from the given backend
-	Recover(b backend.Backend)
-
-	// UserAdd adds a new user
-	UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-
-	// UserDelete deletes a user
-	UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-
-	// UserChangePassword changes a password of a user
-	UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-
-	// UserGrantRole grants a role to the user
-	UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-
-	// UserGet gets the detailed information of a users
-	UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-
-	// UserRevokeRole revokes a role of a user
-	UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-
-	// RoleAdd adds a new role
-	RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-
-	// RoleGrantPermission grants a permission to a role
-	RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-
-	// RoleGet gets the detailed information of a role
-	RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-
-	// RoleRevokePermission gets the detailed information of a role
-	RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-
-	// RoleDelete gets the detailed information of a role
-	RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-
-	// UserList gets a list of all users
-	UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-
-	// RoleList gets a list of all roles
-	RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-
-	// IsPutPermitted checks put permission of the user
-	IsPutPermitted(authInfo *AuthInfo, key []byte) error
-
-	// IsRangePermitted checks range permission of the user
-	IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error
-
-	// IsDeleteRangePermitted checks delete-range permission of the user
-	IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error
-
-	// IsAdminPermitted checks admin permission of the user
-	IsAdminPermitted(authInfo *AuthInfo) error
-
-	// GenTokenPrefix produces a random string in a case of simple token
-	// in a case of JWT, it produces an empty string
-	GenTokenPrefix() (string, error)
-
-	// Revision gets current revision of authStore
-	Revision() uint64
-
-	// CheckPassword checks a given pair of username and password is correct
-	CheckPassword(username, password string) (uint64, error)
-
-	// Close does cleanup of AuthStore
-	Close() error
-
-	// AuthInfoFromCtx gets AuthInfo from gRPC's context
-	AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error)
-
-	// AuthInfoFromTLS gets AuthInfo from TLS info of gRPC's context
-	AuthInfoFromTLS(ctx context.Context) *AuthInfo
-
-	// WithRoot generates and installs a token that can be used as a root credential
-	WithRoot(ctx context.Context) context.Context
-
-	// HasRole checks that user has role
-	HasRole(user, role string) bool
-}
-
-type TokenProvider interface {
-	info(ctx context.Context, token string, revision uint64) (*AuthInfo, bool)
-	assign(ctx context.Context, username string, revision uint64) (string, error)
-	enable()
-	disable()
-
-	invalidateUser(string)
-	genTokenPrefix() (string, error)
-}
-
-type authStore struct {
-	// atomic operations; need 64-bit align, or 32-bit tests will crash
-	revision uint64
-
-	lg        *zap.Logger
-	be        backend.Backend
-	enabled   bool
-	enabledMu sync.RWMutex
-
-	rangePermCache map[string]*unifiedRangePermissions // username -> unifiedRangePermissions
-
-	tokenProvider TokenProvider
-	bcryptCost    int // the algorithm cost / strength for hashing auth passwords
-}
-
-func (as *authStore) AuthEnable() error {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if as.enabled {
-		if as.lg != nil {
-			as.lg.Info("authentication is already enabled; ignored auth enable request")
-		} else {
-			plog.Noticef("Authentication already enabled")
-		}
-		return nil
-	}
-	b := as.be
-	tx := b.BatchTx()
-	tx.Lock()
-	defer func() {
-		tx.Unlock()
-		b.ForceCommit()
-	}()
-
-	u := getUser(as.lg, tx, rootUser)
-	if u == nil {
-		return ErrRootUserNotExist
-	}
-
-	if !hasRootRole(u) {
-		return ErrRootRoleNotExist
-	}
-
-	tx.UnsafePut(authBucketName, enableFlagKey, authEnabled)
-
-	as.enabled = true
-	as.tokenProvider.enable()
-
-	as.rangePermCache = make(map[string]*unifiedRangePermissions)
-
-	as.setRevision(getRevision(tx))
-
-	if as.lg != nil {
-		as.lg.Info("enabled authentication")
-	} else {
-		plog.Noticef("Authentication enabled")
-	}
-	return nil
-}
-
-func (as *authStore) AuthDisable() {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if !as.enabled {
-		return
-	}
-	b := as.be
-	tx := b.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(authBucketName, enableFlagKey, authDisabled)
-	as.commitRevision(tx)
-	tx.Unlock()
-	b.ForceCommit()
-
-	as.enabled = false
-	as.tokenProvider.disable()
-
-	if as.lg != nil {
-		as.lg.Info("disabled authentication")
-	} else {
-		plog.Noticef("Authentication disabled")
-	}
-}
-
-func (as *authStore) Close() error {
-	as.enabledMu.Lock()
-	defer as.enabledMu.Unlock()
-	if !as.enabled {
-		return nil
-	}
-	as.tokenProvider.disable()
-	return nil
-}
-
-func (as *authStore) Authenticate(ctx context.Context, username, password string) (*pb.AuthenticateResponse, error) {
-	if !as.IsAuthEnabled() {
-		return nil, ErrAuthNotEnabled
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, username)
-	if user == nil {
-		return nil, ErrAuthFailed
-	}
-
-	if user.Options.NoPassword {
-		return nil, ErrAuthFailed
-	}
-
-	// Password checking is already performed in the API layer, so we don't need to check for now.
-	// Staleness of password can be detected with OCC in the API layer, too.
-
-	token, err := as.tokenProvider.assign(ctx, username, as.Revision())
-	if err != nil {
-		return nil, err
-	}
-
-	if as.lg != nil {
-		as.lg.Debug(
-			"authenticated a user",
-			zap.String("user-name", username),
-			zap.String("token", token),
-		)
-	} else {
-		plog.Debugf("authorized %s, token is %s", username, token)
-	}
-	return &pb.AuthenticateResponse{Token: token}, nil
-}
-
-func (as *authStore) CheckPassword(username, password string) (uint64, error) {
-	if !as.IsAuthEnabled() {
-		return 0, ErrAuthNotEnabled
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, username)
-	if user == nil {
-		return 0, ErrAuthFailed
-	}
-
-	if user.Options.NoPassword {
-		return 0, ErrAuthFailed
-	}
-
-	if bcrypt.CompareHashAndPassword(user.Password, []byte(password)) != nil {
-		if as.lg != nil {
-			as.lg.Info("invalid password", zap.String("user-name", username))
-		} else {
-			plog.Noticef("authentication failed, invalid password for user %s", username)
-		}
-		return 0, ErrAuthFailed
-	}
-	return getRevision(tx), nil
-}
-
-func (as *authStore) Recover(be backend.Backend) {
-	enabled := false
-	as.be = be
-	tx := be.BatchTx()
-	tx.Lock()
-	_, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0)
-	if len(vs) == 1 {
-		if bytes.Equal(vs[0], authEnabled) {
-			enabled = true
-		}
-	}
-
-	as.setRevision(getRevision(tx))
-
-	tx.Unlock()
-
-	as.enabledMu.Lock()
-	as.enabled = enabled
-	as.enabledMu.Unlock()
-}
-
-func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	if len(r.Name) == 0 {
-		return nil, ErrUserEmpty
-	}
-
-	var hashed []byte
-	var err error
-
-	if r.Options != nil && !r.Options.NoPassword {
-		hashed, err = bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
-		if err != nil {
-			if as.lg != nil {
-				as.lg.Warn(
-					"failed to bcrypt hash password",
-					zap.String("user-name", r.Name),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("failed to hash password: %s", err)
-			}
-			return nil, err
-		}
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, r.Name)
-	if user != nil {
-		return nil, ErrUserAlreadyExist
-	}
-
-	options := r.Options
-	if options == nil {
-		options = &authpb.UserAddOptions{
-			NoPassword: false,
-		}
-	}
-
-	newUser := &authpb.User{
-		Name:     []byte(r.Name),
-		Password: hashed,
-		Options:  options,
-	}
-
-	putUser(as.lg, tx, newUser)
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info("added a user", zap.String("user-name", r.Name))
-	} else {
-		plog.Noticef("added a new user: %s", r.Name)
-	}
-	return &pb.AuthUserAddResponse{}, nil
-}
-
-func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	if as.enabled && r.Name == rootUser {
-		if as.lg != nil {
-			as.lg.Warn("cannot delete 'root' user", zap.String("user-name", r.Name))
-		} else {
-			plog.Errorf("the user root must not be deleted")
-		}
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	delUser(tx, r.Name)
-
-	as.commitRevision(tx)
-
-	as.invalidateCachedPerm(r.Name)
-	as.tokenProvider.invalidateUser(r.Name)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"deleted a user",
-			zap.String("user-name", r.Name),
-			zap.Strings("user-roles", user.Roles),
-		)
-	} else {
-		plog.Noticef("deleted a user: %s", r.Name)
-	}
-	return &pb.AuthUserDeleteResponse{}, nil
-}
-
-func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	// TODO(mitake): measure the cost of bcrypt.GenerateFromPassword()
-	// If the cost is too high, we should move the encryption to outside of the raft
-	hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
-	if err != nil {
-		if as.lg != nil {
-			as.lg.Warn(
-				"failed to bcrypt hash password",
-				zap.String("user-name", r.Name),
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to hash password: %s", err)
-		}
-		return nil, err
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	updatedUser := &authpb.User{
-		Name:     []byte(r.Name),
-		Roles:    user.Roles,
-		Password: hashed,
-		Options:  user.Options,
-	}
-
-	putUser(as.lg, tx, updatedUser)
-
-	as.commitRevision(tx)
-
-	as.invalidateCachedPerm(r.Name)
-	as.tokenProvider.invalidateUser(r.Name)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"changed a password of a user",
-			zap.String("user-name", r.Name),
-			zap.Strings("user-roles", user.Roles),
-		)
-	} else {
-		plog.Noticef("changed a password of a user: %s", r.Name)
-	}
-	return &pb.AuthUserChangePasswordResponse{}, nil
-}
-
-func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, r.User)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	if r.Role != rootRole {
-		role := getRole(tx, r.Role)
-		if role == nil {
-			return nil, ErrRoleNotFound
-		}
-	}
-
-	idx := sort.SearchStrings(user.Roles, r.Role)
-	if idx < len(user.Roles) && user.Roles[idx] == r.Role {
-		if as.lg != nil {
-			as.lg.Warn(
-				"ignored grant role request to a user",
-				zap.String("user-name", r.User),
-				zap.Strings("user-roles", user.Roles),
-				zap.String("duplicate-role-name", r.Role),
-			)
-		} else {
-			plog.Warningf("user %s is already granted role %s", r.User, r.Role)
-		}
-		return &pb.AuthUserGrantRoleResponse{}, nil
-	}
-
-	user.Roles = append(user.Roles, r.Role)
-	sort.Strings(user.Roles)
-
-	putUser(as.lg, tx, user)
-
-	as.invalidateCachedPerm(r.User)
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"granted a role to a user",
-			zap.String("user-name", r.User),
-			zap.Strings("user-roles", user.Roles),
-			zap.String("added-role-name", r.Role),
-		)
-	} else {
-		plog.Noticef("granted role %s to user %s", r.Role, r.User)
-	}
-	return &pb.AuthUserGrantRoleResponse{}, nil
-}
-
-func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	user := getUser(as.lg, tx, r.Name)
-	tx.Unlock()
-
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	var resp pb.AuthUserGetResponse
-	resp.Roles = append(resp.Roles, user.Roles...)
-	return &resp, nil
-}
-
-func (as *authStore) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	users := getAllUsers(as.lg, tx)
-	tx.Unlock()
-
-	resp := &pb.AuthUserListResponse{Users: make([]string, len(users))}
-	for i := range users {
-		resp.Users[i] = string(users[i].Name)
-	}
-	return resp, nil
-}
-
-func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	if as.enabled && r.Name == rootUser && r.Role == rootRole {
-		if as.lg != nil {
-			as.lg.Warn(
-				"'root' user cannot revoke 'root' role",
-				zap.String("user-name", r.Name),
-				zap.String("role-name", r.Role),
-			)
-		} else {
-			plog.Errorf("the role root must not be revoked from the user root")
-		}
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, r.Name)
-	if user == nil {
-		return nil, ErrUserNotFound
-	}
-
-	updatedUser := &authpb.User{
-		Name:     user.Name,
-		Password: user.Password,
-		Options:  user.Options,
-	}
-
-	for _, role := range user.Roles {
-		if role != r.Role {
-			updatedUser.Roles = append(updatedUser.Roles, role)
-		}
-	}
-
-	if len(updatedUser.Roles) == len(user.Roles) {
-		return nil, ErrRoleNotGranted
-	}
-
-	putUser(as.lg, tx, updatedUser)
-
-	as.invalidateCachedPerm(r.Name)
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"revoked a role from a user",
-			zap.String("user-name", r.Name),
-			zap.Strings("old-user-roles", user.Roles),
-			zap.Strings("new-user-roles", updatedUser.Roles),
-			zap.String("revoked-role-name", r.Role),
-		)
-	} else {
-		plog.Noticef("revoked role %s from user %s", r.Role, r.Name)
-	}
-	return &pb.AuthUserRevokeRoleResponse{}, nil
-}
-
-func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	var resp pb.AuthRoleGetResponse
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-	resp.Perm = append(resp.Perm, role.KeyPermission...)
-	return &resp, nil
-}
-
-func (as *authStore) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	roles := getAllRoles(as.lg, tx)
-	tx.Unlock()
-
-	resp := &pb.AuthRoleListResponse{Roles: make([]string, len(roles))}
-	for i := range roles {
-		resp.Roles[i] = string(roles[i].Name)
-	}
-	return resp, nil
-}
-
-func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	updatedRole := &authpb.Role{
-		Name: role.Name,
-	}
-
-	for _, perm := range role.KeyPermission {
-		if !bytes.Equal(perm.Key, r.Key) || !bytes.Equal(perm.RangeEnd, r.RangeEnd) {
-			updatedRole.KeyPermission = append(updatedRole.KeyPermission, perm)
-		}
-	}
-
-	if len(role.KeyPermission) == len(updatedRole.KeyPermission) {
-		return nil, ErrPermissionNotGranted
-	}
-
-	putRole(as.lg, tx, updatedRole)
-
-	// TODO(mitake): currently single role update invalidates every cache
-	// It should be optimized.
-	as.clearCachedPerm()
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"revoked a permission on range",
-			zap.String("role-name", r.Role),
-			zap.String("key", string(r.Key)),
-			zap.String("range-end", string(r.RangeEnd)),
-		)
-	} else {
-		plog.Noticef("revoked key %s from role %s", r.Key, r.Role)
-	}
-	return &pb.AuthRoleRevokePermissionResponse{}, nil
-}
-
-func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	if as.enabled && r.Role == rootRole {
-		if as.lg != nil {
-			as.lg.Warn("cannot delete 'root' role", zap.String("role-name", r.Role))
-		} else {
-			plog.Errorf("the role root must not be deleted")
-		}
-		return nil, ErrInvalidAuthMgmt
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Role)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	delRole(tx, r.Role)
-
-	users := getAllUsers(as.lg, tx)
-	for _, user := range users {
-		updatedUser := &authpb.User{
-			Name:     user.Name,
-			Password: user.Password,
-			Options:  user.Options,
-		}
-
-		for _, role := range user.Roles {
-			if role != r.Role {
-				updatedUser.Roles = append(updatedUser.Roles, role)
-			}
-		}
-
-		if len(updatedUser.Roles) == len(user.Roles) {
-			continue
-		}
-
-		putUser(as.lg, tx, updatedUser)
-
-		as.invalidateCachedPerm(string(user.Name))
-	}
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info("deleted a role", zap.String("role-name", r.Role))
-	} else {
-		plog.Noticef("deleted role %s", r.Role)
-	}
-	return &pb.AuthRoleDeleteResponse{}, nil
-}
-
-func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	if len(r.Name) == 0 {
-		return nil, ErrRoleEmpty
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Name)
-	if role != nil {
-		return nil, ErrRoleAlreadyExist
-	}
-
-	newRole := &authpb.Role{
-		Name: []byte(r.Name),
-	}
-
-	putRole(as.lg, tx, newRole)
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info("created a role", zap.String("role-name", r.Name))
-	} else {
-		plog.Noticef("Role %s is created", r.Name)
-	}
-	return &pb.AuthRoleAddResponse{}, nil
-}
-
-func (as *authStore) authInfoFromToken(ctx context.Context, token string) (*AuthInfo, bool) {
-	return as.tokenProvider.info(ctx, token, as.Revision())
-}
-
-type permSlice []*authpb.Permission
-
-func (perms permSlice) Len() int {
-	return len(perms)
-}
-
-func (perms permSlice) Less(i, j int) bool {
-	return bytes.Compare(perms[i].Key, perms[j].Key) < 0
-}
-
-func (perms permSlice) Swap(i, j int) {
-	perms[i], perms[j] = perms[j], perms[i]
-}
-
-func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	role := getRole(tx, r.Name)
-	if role == nil {
-		return nil, ErrRoleNotFound
-	}
-
-	idx := sort.Search(len(role.KeyPermission), func(i int) bool {
-		return bytes.Compare(role.KeyPermission[i].Key, r.Perm.Key) >= 0
-	})
-
-	if idx < len(role.KeyPermission) && bytes.Equal(role.KeyPermission[idx].Key, r.Perm.Key) && bytes.Equal(role.KeyPermission[idx].RangeEnd, r.Perm.RangeEnd) {
-		// update existing permission
-		role.KeyPermission[idx].PermType = r.Perm.PermType
-	} else {
-		// append new permission to the role
-		newPerm := &authpb.Permission{
-			Key:      r.Perm.Key,
-			RangeEnd: r.Perm.RangeEnd,
-			PermType: r.Perm.PermType,
-		}
-
-		role.KeyPermission = append(role.KeyPermission, newPerm)
-		sort.Sort(permSlice(role.KeyPermission))
-	}
-
-	putRole(as.lg, tx, role)
-
-	// TODO(mitake): currently single role update invalidates every cache
-	// It should be optimized.
-	as.clearCachedPerm()
-
-	as.commitRevision(tx)
-
-	if as.lg != nil {
-		as.lg.Info(
-			"granted/updated a permission to a user",
-			zap.String("user-name", r.Name),
-			zap.String("permission-name", authpb.Permission_Type_name[int32(r.Perm.PermType)]),
-		)
-	} else {
-		plog.Noticef("role %s's permission of key %s is updated as %s", r.Name, r.Perm.Key, authpb.Permission_Type_name[int32(r.Perm.PermType)])
-	}
-	return &pb.AuthRoleGrantPermissionResponse{}, nil
-}
-
-func (as *authStore) isOpPermitted(userName string, revision uint64, key, rangeEnd []byte, permTyp authpb.Permission_Type) error {
-	// TODO(mitake): this function would be costly so we need a caching mechanism
-	if !as.IsAuthEnabled() {
-		return nil
-	}
-
-	// only gets rev == 0 when passed AuthInfo{}; no user given
-	if revision == 0 {
-		return ErrUserEmpty
-	}
-
-	if revision < as.Revision() {
-		return ErrAuthOldRevision
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	user := getUser(as.lg, tx, userName)
-	if user == nil {
-		if as.lg != nil {
-			as.lg.Warn("cannot find a user for permission check", zap.String("user-name", userName))
-		} else {
-			plog.Errorf("invalid user name %s for permission checking", userName)
-		}
-		return ErrPermissionDenied
-	}
-
-	// root role should have permission on all ranges
-	if hasRootRole(user) {
-		return nil
-	}
-
-	if as.isRangeOpPermitted(tx, userName, key, rangeEnd, permTyp) {
-		return nil
-	}
-
-	return ErrPermissionDenied
-}
-
-func (as *authStore) IsPutPermitted(authInfo *AuthInfo, key []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, nil, authpb.WRITE)
-}
-
-func (as *authStore) IsRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.READ)
-}
-
-func (as *authStore) IsDeleteRangePermitted(authInfo *AuthInfo, key, rangeEnd []byte) error {
-	return as.isOpPermitted(authInfo.Username, authInfo.Revision, key, rangeEnd, authpb.WRITE)
-}
-
-func (as *authStore) IsAdminPermitted(authInfo *AuthInfo) error {
-	if !as.IsAuthEnabled() {
-		return nil
-	}
-	if authInfo == nil {
-		return ErrUserEmpty
-	}
-
-	tx := as.be.BatchTx()
-	tx.Lock()
-	u := getUser(as.lg, tx, authInfo.Username)
-	tx.Unlock()
-
-	if u == nil {
-		return ErrUserNotFound
-	}
-
-	if !hasRootRole(u) {
-		return ErrPermissionDenied
-	}
-
-	return nil
-}
-
-func getUser(lg *zap.Logger, tx backend.BatchTx, username string) *authpb.User {
-	_, vs := tx.UnsafeRange(authUsersBucketName, []byte(username), nil, 0)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	user := &authpb.User{}
-	err := user.Unmarshal(vs[0])
-	if err != nil {
-		if lg != nil {
-			lg.Panic(
-				"failed to unmarshal 'authpb.User'",
-				zap.String("user-name", username),
-				zap.Error(err),
-			)
-		} else {
-			plog.Panicf("failed to unmarshal user struct (name: %s): %s", username, err)
-		}
-	}
-	return user
-}
-
-func getAllUsers(lg *zap.Logger, tx backend.BatchTx) []*authpb.User {
-	_, vs := tx.UnsafeRange(authUsersBucketName, []byte{0}, []byte{0xff}, -1)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	users := make([]*authpb.User, len(vs))
-	for i := range vs {
-		user := &authpb.User{}
-		err := user.Unmarshal(vs[i])
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to unmarshal 'authpb.User'", zap.Error(err))
-			} else {
-				plog.Panicf("failed to unmarshal user struct: %s", err)
-			}
-		}
-		users[i] = user
-	}
-	return users
-}
-
-func putUser(lg *zap.Logger, tx backend.BatchTx, user *authpb.User) {
-	b, err := user.Marshal()
-	if err != nil {
-		if lg != nil {
-			lg.Panic("failed to unmarshal 'authpb.User'", zap.Error(err))
-		} else {
-			plog.Panicf("failed to marshal user struct (name: %s): %s", user.Name, err)
-		}
-	}
-	tx.UnsafePut(authUsersBucketName, user.Name, b)
-}
-
-func delUser(tx backend.BatchTx, username string) {
-	tx.UnsafeDelete(authUsersBucketName, []byte(username))
-}
-
-func getRole(tx backend.BatchTx, rolename string) *authpb.Role {
-	_, vs := tx.UnsafeRange(authRolesBucketName, []byte(rolename), nil, 0)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	role := &authpb.Role{}
-	err := role.Unmarshal(vs[0])
-	if err != nil {
-		plog.Panicf("failed to unmarshal role struct (name: %s): %s", rolename, err)
-	}
-	return role
-}
-
-func getAllRoles(lg *zap.Logger, tx backend.BatchTx) []*authpb.Role {
-	_, vs := tx.UnsafeRange(authRolesBucketName, []byte{0}, []byte{0xff}, -1)
-	if len(vs) == 0 {
-		return nil
-	}
-
-	roles := make([]*authpb.Role, len(vs))
-	for i := range vs {
-		role := &authpb.Role{}
-		err := role.Unmarshal(vs[i])
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to unmarshal 'authpb.Role'", zap.Error(err))
-			} else {
-				plog.Panicf("failed to unmarshal role struct: %s", err)
-			}
-		}
-		roles[i] = role
-	}
-	return roles
-}
-
-func putRole(lg *zap.Logger, tx backend.BatchTx, role *authpb.Role) {
-	b, err := role.Marshal()
-	if err != nil {
-		if lg != nil {
-			lg.Panic(
-				"failed to marshal 'authpb.Role'",
-				zap.String("role-name", string(role.Name)),
-				zap.Error(err),
-			)
-		} else {
-			plog.Panicf("failed to marshal role struct (name: %s): %s", role.Name, err)
-		}
-	}
-
-	tx.UnsafePut(authRolesBucketName, role.Name, b)
-}
-
-func delRole(tx backend.BatchTx, rolename string) {
-	tx.UnsafeDelete(authRolesBucketName, []byte(rolename))
-}
-
-func (as *authStore) IsAuthEnabled() bool {
-	as.enabledMu.RLock()
-	defer as.enabledMu.RUnlock()
-	return as.enabled
-}
-
-// NewAuthStore creates a new AuthStore.
-func NewAuthStore(lg *zap.Logger, be backend.Backend, tp TokenProvider, bcryptCost int) *authStore {
-	if bcryptCost < bcrypt.MinCost || bcryptCost > bcrypt.MaxCost {
-		if lg != nil {
-			lg.Warn(
-				"use default bcrypt cost instead of the invalid given cost",
-				zap.Int("min-cost", bcrypt.MinCost),
-				zap.Int("max-cost", bcrypt.MaxCost),
-				zap.Int("default-cost", bcrypt.DefaultCost),
-				zap.Int("given-cost", bcryptCost))
-		} else {
-			plog.Warningf("Use default bcrypt-cost %d instead of the invalid value %d",
-				bcrypt.DefaultCost, bcryptCost)
-		}
-
-		bcryptCost = bcrypt.DefaultCost
-	}
-
-	tx := be.BatchTx()
-	tx.Lock()
-
-	tx.UnsafeCreateBucket(authBucketName)
-	tx.UnsafeCreateBucket(authUsersBucketName)
-	tx.UnsafeCreateBucket(authRolesBucketName)
-
-	enabled := false
-	_, vs := tx.UnsafeRange(authBucketName, enableFlagKey, nil, 0)
-	if len(vs) == 1 {
-		if bytes.Equal(vs[0], authEnabled) {
-			enabled = true
-		}
-	}
-
-	as := &authStore{
-		revision:       getRevision(tx),
-		lg:             lg,
-		be:             be,
-		enabled:        enabled,
-		rangePermCache: make(map[string]*unifiedRangePermissions),
-		tokenProvider:  tp,
-		bcryptCost:     bcryptCost,
-	}
-
-	if enabled {
-		as.tokenProvider.enable()
-	}
-
-	if as.Revision() == 0 {
-		as.commitRevision(tx)
-	}
-
-	tx.Unlock()
-	be.ForceCommit()
-
-	return as
-}
-
-func hasRootRole(u *authpb.User) bool {
-	// u.Roles is sorted in UserGrantRole(), so we can use binary search.
-	idx := sort.SearchStrings(u.Roles, rootRole)
-	return idx != len(u.Roles) && u.Roles[idx] == rootRole
-}
-
-func (as *authStore) commitRevision(tx backend.BatchTx) {
-	atomic.AddUint64(&as.revision, 1)
-	revBytes := make([]byte, revBytesLen)
-	binary.BigEndian.PutUint64(revBytes, as.Revision())
-	tx.UnsafePut(authBucketName, revisionKey, revBytes)
-}
-
-func getRevision(tx backend.BatchTx) uint64 {
-	_, vs := tx.UnsafeRange(authBucketName, revisionKey, nil, 0)
-	if len(vs) != 1 {
-		// this can happen in the initialization phase
-		return 0
-	}
-	return binary.BigEndian.Uint64(vs[0])
-}
-
-func (as *authStore) setRevision(rev uint64) {
-	atomic.StoreUint64(&as.revision, rev)
-}
-
-func (as *authStore) Revision() uint64 {
-	return atomic.LoadUint64(&as.revision)
-}
-
-func (as *authStore) AuthInfoFromTLS(ctx context.Context) (ai *AuthInfo) {
-	peer, ok := peer.FromContext(ctx)
-	if !ok || peer == nil || peer.AuthInfo == nil {
-		return nil
-	}
-
-	tlsInfo := peer.AuthInfo.(credentials.TLSInfo)
-	for _, chains := range tlsInfo.State.VerifiedChains {
-		if len(chains) < 1 {
-			continue
-		}
-		ai = &AuthInfo{
-			Username: chains[0].Subject.CommonName,
-			Revision: as.Revision(),
-		}
-		md, ok := metadata.FromIncomingContext(ctx)
-		if !ok {
-			return nil
-		}
-
-		// gRPC-gateway proxy request to etcd server includes Grpcgateway-Accept
-		// header. The proxy uses etcd client server certificate. If the certificate
-		// has a CommonName we should never use this for authentication.
-		if gw := md["grpcgateway-accept"]; len(gw) > 0 {
-			if as.lg != nil {
-				as.lg.Warn(
-					"ignoring common name in gRPC-gateway proxy request",
-					zap.String("common-name", ai.Username),
-					zap.String("user-name", ai.Username),
-					zap.Uint64("revision", ai.Revision),
-				)
-			} else {
-				plog.Warningf("ignoring common name in gRPC-gateway proxy request %s", ai.Username)
-			}
-			return nil
-		}
-		if as.lg != nil {
-			as.lg.Debug(
-				"found command name",
-				zap.String("common-name", ai.Username),
-				zap.String("user-name", ai.Username),
-				zap.Uint64("revision", ai.Revision),
-			)
-		} else {
-			plog.Debugf("found common name %s", ai.Username)
-		}
-		break
-	}
-	return ai
-}
-
-func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, error) {
-	md, ok := metadata.FromIncomingContext(ctx)
-	if !ok {
-		return nil, nil
-	}
-
-	//TODO(mitake|hexfusion) review unifying key names
-	ts, ok := md[rpctypes.TokenFieldNameGRPC]
-	if !ok {
-		ts, ok = md[rpctypes.TokenFieldNameSwagger]
-	}
-	if !ok {
-		return nil, nil
-	}
-
-	token := ts[0]
-	authInfo, uok := as.authInfoFromToken(ctx, token)
-	if !uok {
-		if as.lg != nil {
-			as.lg.Warn("invalid auth token", zap.String("token", token))
-		} else {
-			plog.Warningf("invalid auth token: %s", token)
-		}
-		return nil, ErrInvalidAuthToken
-	}
-
-	return authInfo, nil
-}
-
-func (as *authStore) GenTokenPrefix() (string, error) {
-	return as.tokenProvider.genTokenPrefix()
-}
-
-func decomposeOpts(lg *zap.Logger, optstr string) (string, map[string]string, error) {
-	opts := strings.Split(optstr, ",")
-	tokenType := opts[0]
-
-	typeSpecificOpts := make(map[string]string)
-	for i := 1; i < len(opts); i++ {
-		pair := strings.Split(opts[i], "=")
-
-		if len(pair) != 2 {
-			if lg != nil {
-				lg.Warn("invalid token option", zap.String("option", optstr))
-			} else {
-				plog.Errorf("invalid token specific option: %s", optstr)
-			}
-			return "", nil, ErrInvalidAuthOpts
-		}
-
-		if _, ok := typeSpecificOpts[pair[0]]; ok {
-			if lg != nil {
-				lg.Warn(
-					"invalid token option",
-					zap.String("option", optstr),
-					zap.String("duplicate-parameter", pair[0]),
-				)
-			} else {
-				plog.Errorf("invalid token specific option, duplicated parameters (%s): %s", pair[0], optstr)
-			}
-			return "", nil, ErrInvalidAuthOpts
-		}
-
-		typeSpecificOpts[pair[0]] = pair[1]
-	}
-
-	return tokenType, typeSpecificOpts, nil
-
-}
-
-// NewTokenProvider creates a new token provider.
-func NewTokenProvider(
-	lg *zap.Logger,
-	tokenOpts string,
-	indexWaiter func(uint64) <-chan struct{}) (TokenProvider, error) {
-	tokenType, typeSpecificOpts, err := decomposeOpts(lg, tokenOpts)
-	if err != nil {
-		return nil, ErrInvalidAuthOpts
-	}
-
-	switch tokenType {
-	case tokenTypeSimple:
-		if lg != nil {
-			lg.Warn("simple token is not cryptographically signed")
-		} else {
-			plog.Warningf("simple token is not cryptographically signed")
-		}
-		return newTokenProviderSimple(lg, indexWaiter), nil
-
-	case tokenTypeJWT:
-		return newTokenProviderJWT(lg, typeSpecificOpts)
-
-	case "":
-		return newTokenProviderNop()
-
-	default:
-		if lg != nil {
-			lg.Warn(
-				"unknown token type",
-				zap.String("type", tokenType),
-				zap.Error(ErrInvalidAuthOpts),
-			)
-		} else {
-			plog.Errorf("unknown token type: %s", tokenType)
-		}
-		return nil, ErrInvalidAuthOpts
-	}
-}
-
-func (as *authStore) WithRoot(ctx context.Context) context.Context {
-	if !as.IsAuthEnabled() {
-		return ctx
-	}
-
-	var ctxForAssign context.Context
-	if ts, ok := as.tokenProvider.(*tokenSimple); ok && ts != nil {
-		ctx1 := context.WithValue(ctx, AuthenticateParamIndex{}, uint64(0))
-		prefix, err := ts.genTokenPrefix()
-		if err != nil {
-			if as.lg != nil {
-				as.lg.Warn(
-					"failed to generate prefix of internally used token",
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("failed to generate prefix of internally used token")
-			}
-			return ctx
-		}
-		ctxForAssign = context.WithValue(ctx1, AuthenticateParamSimpleTokenPrefix{}, prefix)
-	} else {
-		ctxForAssign = ctx
-	}
-
-	token, err := as.tokenProvider.assign(ctxForAssign, "root", as.Revision())
-	if err != nil {
-		// this must not happen
-		if as.lg != nil {
-			as.lg.Warn(
-				"failed to assign token for lease revoking",
-				zap.Error(err),
-			)
-		} else {
-			plog.Errorf("failed to assign token for lease revoking: %s", err)
-		}
-		return ctx
-	}
-
-	mdMap := map[string]string{
-		rpctypes.TokenFieldNameGRPC: token,
-	}
-	tokenMD := metadata.New(mdMap)
-
-	// use "mdIncomingKey{}" since it's called from local etcdserver
-	return metadata.NewIncomingContext(ctx, tokenMD)
-}
-
-func (as *authStore) HasRole(user, role string) bool {
-	tx := as.be.BatchTx()
-	tx.Lock()
-	u := getUser(as.lg, tx, user)
-	tx.Unlock()
-
-	if u == nil {
-		if as.lg != nil {
-			as.lg.Warn(
-				"'has-role' requested for non-existing user",
-				zap.String("user-name", user),
-				zap.String("role-name", role),
-			)
-		} else {
-			plog.Warningf("tried to check user %s has role %s, but user %s doesn't exist", user, role, user)
-		}
-		return false
-	}
-
-	for _, r := range u.Roles {
-		if role == r {
-			return true
-		}
-	}
-	return false
-}
-
-func (as *authStore) BcryptCost() int {
-	return as.bcryptCost
-}
diff --git a/vendor/go.etcd.io/etcd/client/README.md b/vendor/go.etcd.io/etcd/client/README.md
deleted file mode 100644
index 521d6c0..0000000
--- a/vendor/go.etcd.io/etcd/client/README.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# etcd/client
-
-etcd/client is the Go client library for etcd.
-
-[![GoDoc](https://godoc.org/go.etcd.io/etcd/client?status.png)](https://godoc.org/go.etcd.io/etcd/client)
-
-For full compatibility, it is recommended to vendor builds using etcd's vendored packages, using tools like `golang/dep`, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories).
-
-## Install
-
-```bash
-go get go.etcd.io/etcd/client
-```
-
-## Usage
-
-```go
-package main
-
-import (
-	"log"
-	"time"
-	"context"
-
-	"go.etcd.io/etcd/client"
-)
-
-func main() {
-	cfg := client.Config{
-		Endpoints:               []string{"http://127.0.0.1:2379"},
-		Transport:               client.DefaultTransport,
-		// set timeout per request to fail fast when the target endpoint is unavailable
-		HeaderTimeoutPerRequest: time.Second,
-	}
-	c, err := client.New(cfg)
-	if err != nil {
-		log.Fatal(err)
-	}
-	kapi := client.NewKeysAPI(c)
-	// set "/foo" key with "bar" value
-	log.Print("Setting '/foo' key with 'bar' value")
-	resp, err := kapi.Set(context.Background(), "/foo", "bar", nil)
-	if err != nil {
-		log.Fatal(err)
-	} else {
-		// print common key info
-		log.Printf("Set is done. Metadata is %q\n", resp)
-	}
-	// get "/foo" key's value
-	log.Print("Getting '/foo' key value")
-	resp, err = kapi.Get(context.Background(), "/foo", nil)
-	if err != nil {
-		log.Fatal(err)
-	} else {
-		// print common key info
-		log.Printf("Get is done. Metadata is %q\n", resp)
-		// print value
-		log.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value)
-	}
-}
-```
-
-## Error Handling
-
-etcd client might return three types of errors.
-
-- context error
-
-Each API call has its first parameter as `context`. A context can be canceled or have an attached deadline. If the context is canceled or reaches its deadline, the responding context error will be returned no matter what internal errors the API call has already encountered.
-
-- cluster error
-
-Each API call tries to send request to the cluster endpoints one by one until it successfully gets a response. If a requests to an endpoint fails, due to exceeding per request timeout or connection issues, the error will be added into a list of errors. If all possible endpoints fail, a cluster error that includes all encountered errors will be returned.
-
-- response error
-
-If the response gets from the cluster is invalid, a plain string error will be returned. For example, it might be a invalid JSON error.
-
-Here is the example code to handle client errors:
-
-```go
-cfg := client.Config{Endpoints: []string{"http://etcd1:2379","http://etcd2:2379","http://etcd3:2379"}}
-c, err := client.New(cfg)
-if err != nil {
-	log.Fatal(err)
-}
-
-kapi := client.NewKeysAPI(c)
-resp, err := kapi.Set(ctx, "test", "bar", nil)
-if err != nil {
-	if err == context.Canceled {
-		// ctx is canceled by another routine
-	} else if err == context.DeadlineExceeded {
-		// ctx is attached with a deadline and it exceeded
-	} else if cerr, ok := err.(*client.ClusterError); ok {
-		// process (cerr.Errors)
-	} else {
-		// bad cluster endpoints, which are not etcd servers
-	}
-}
-```
-
-
-## Caveat
-
-1. etcd/client prefers to use the same endpoint as long as the endpoint continues to work well. This saves socket resources, and improves efficiency for both client and server side. This preference doesn't remove consistency from the data consumed by the client because data replicated to each etcd member has already passed through the consensus process.
-
-2. etcd/client does round-robin rotation on other available endpoints if the preferred endpoint isn't functioning properly. For example, if the member that etcd/client connects to is hard killed, etcd/client will fail on the first attempt with the killed member, and succeed on the second attempt with another member. If it fails to talk to all available endpoints, it will return all errors happened.
-
-3. Default etcd/client cannot handle the case that the remote server is SIGSTOPed now. TCP keepalive mechanism doesn't help in this scenario because operating system may still send TCP keep-alive packets. Over time we'd like to improve this functionality, but solving this issue isn't high priority because a real-life case in which a server is stopped, but the connection is kept alive, hasn't been brought to our attention.
-
-4. etcd/client cannot detect whether a member is healthy with watches and non-quorum read requests. If the member is isolated from the cluster, etcd/client may retrieve outdated data. Instead, users can either issue quorum read requests or monitor the /health endpoint for member health information.
diff --git a/vendor/go.etcd.io/etcd/client/auth_role.go b/vendor/go.etcd.io/etcd/client/auth_role.go
deleted file mode 100644
index b6ba7e1..0000000
--- a/vendor/go.etcd.io/etcd/client/auth_role.go
+++ /dev/null
@@ -1,236 +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 client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"net/http"
-	"net/url"
-)
-
-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"`
-}
-
-type rwPermission struct {
-	Read  []string `json:"read"`
-	Write []string `json:"write"`
-}
-
-type PermissionType int
-
-const (
-	ReadPermission PermissionType = iota
-	WritePermission
-	ReadWritePermission
-)
-
-// NewAuthRoleAPI constructs a new AuthRoleAPI that uses HTTP to
-// interact with etcd's role creation and modification features.
-func NewAuthRoleAPI(c Client) AuthRoleAPI {
-	return &httpAuthRoleAPI{
-		client: c,
-	}
-}
-
-type AuthRoleAPI interface {
-	// AddRole adds a role.
-	AddRole(ctx context.Context, role string) error
-
-	// RemoveRole removes a role.
-	RemoveRole(ctx context.Context, role string) error
-
-	// GetRole retrieves role details.
-	GetRole(ctx context.Context, role string) (*Role, error)
-
-	// GrantRoleKV grants a role some permission prefixes for the KV store.
-	GrantRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
-
-	// RevokeRoleKV revokes some permission prefixes for a role on the KV store.
-	RevokeRoleKV(ctx context.Context, role string, prefixes []string, permType PermissionType) (*Role, error)
-
-	// ListRoles lists roles.
-	ListRoles(ctx context.Context) ([]string, error)
-}
-
-type httpAuthRoleAPI struct {
-	client httpClient
-}
-
-type authRoleAPIAction struct {
-	verb string
-	name string
-	role *Role
-}
-
-type authRoleAPIList struct{}
-
-func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "roles", "")
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "roles", l.name)
-	if l.role == nil {
-		req, _ := http.NewRequest(l.verb, u.String(), nil)
-		return req
-	}
-	b, err := json.Marshal(l.role)
-	if err != nil {
-		panic(err)
-	}
-	body := bytes.NewReader(b)
-	req, _ := http.NewRequest(l.verb, u.String(), body)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) {
-	resp, body, err := r.client.Do(ctx, &authRoleAPIList{})
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-	var roleList struct {
-		Roles []Role `json:"roles"`
-	}
-	if err = json.Unmarshal(body, &roleList); err != nil {
-		return nil, err
-	}
-	ret := make([]string, 0, len(roleList.Roles))
-	for _, r := range roleList.Roles {
-		ret = append(ret, r.Role)
-	}
-	return ret, nil
-}
-
-func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string) error {
-	role := &Role{
-		Role: rolename,
-	}
-	return r.addRemoveRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename string) error {
-	return r.addRemoveRole(ctx, &authRoleAPIAction{
-		verb: "DELETE",
-		name: rolename,
-	})
-}
-
-func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *authRoleAPIAction) error {
-	resp, body, err := r.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err := json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string) (*Role, error) {
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "GET",
-		name: rolename,
-	})
-}
-
-func buildRWPermission(prefixes []string, permType PermissionType) rwPermission {
-	var out rwPermission
-	switch permType {
-	case ReadPermission:
-		out.Read = prefixes
-	case WritePermission:
-		out.Write = prefixes
-	case ReadWritePermission:
-		out.Read = prefixes
-		out.Write = prefixes
-	}
-	return out
-}
-
-func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
-	rwp := buildRWPermission(prefixes, permType)
-	role := &Role{
-		Role: rolename,
-		Grant: &Permissions{
-			KV: rwp,
-		},
-	}
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename string, prefixes []string, permType PermissionType) (*Role, error) {
-	rwp := buildRWPermission(prefixes, permType)
-	role := &Role{
-		Role: rolename,
-		Revoke: &Permissions{
-			KV: rwp,
-		},
-	}
-	return r.modRole(ctx, &authRoleAPIAction{
-		verb: "PUT",
-		name: rolename,
-		role: role,
-	})
-}
-
-func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) (*Role, error) {
-	resp, body, err := r.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-	var role Role
-	if err = json.Unmarshal(body, &role); err != nil {
-		return nil, err
-	}
-	return &role, nil
-}
diff --git a/vendor/go.etcd.io/etcd/client/auth_user.go b/vendor/go.etcd.io/etcd/client/auth_user.go
deleted file mode 100644
index 8e7e2ef..0000000
--- a/vendor/go.etcd.io/etcd/client/auth_user.go
+++ /dev/null
@@ -1,319 +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 client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"net/http"
-	"net/url"
-	"path"
-)
-
-var (
-	defaultV2AuthPrefix = "/v2/auth"
-)
-
-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"`
-}
-
-// userListEntry is the user representation given by the server for ListUsers
-type userListEntry struct {
-	User  string `json:"user"`
-	Roles []Role `json:"roles"`
-}
-
-type UserRoles struct {
-	User  string `json:"user"`
-	Roles []Role `json:"roles"`
-}
-
-func v2AuthURL(ep url.URL, action string, name string) *url.URL {
-	if name != "" {
-		ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name)
-		return &ep
-	}
-	ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action)
-	return &ep
-}
-
-// NewAuthAPI constructs a new AuthAPI that uses HTTP to
-// interact with etcd's general auth features.
-func NewAuthAPI(c Client) AuthAPI {
-	return &httpAuthAPI{
-		client: c,
-	}
-}
-
-type AuthAPI interface {
-	// Enable auth.
-	Enable(ctx context.Context) error
-
-	// Disable auth.
-	Disable(ctx context.Context) error
-}
-
-type httpAuthAPI struct {
-	client httpClient
-}
-
-func (s *httpAuthAPI) Enable(ctx context.Context) error {
-	return s.enableDisable(ctx, &authAPIAction{"PUT"})
-}
-
-func (s *httpAuthAPI) Disable(ctx context.Context) error {
-	return s.enableDisable(ctx, &authAPIAction{"DELETE"})
-}
-
-func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error {
-	resp, body, err := s.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-type authAPIAction struct {
-	verb string
-}
-
-func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "enable", "")
-	req, _ := http.NewRequest(l.verb, u.String(), nil)
-	return req
-}
-
-type authError struct {
-	Message string `json:"message"`
-	Code    int    `json:"-"`
-}
-
-func (e authError) Error() string {
-	return e.Message
-}
-
-// NewAuthUserAPI constructs a new AuthUserAPI that uses HTTP to
-// interact with etcd's user creation and modification features.
-func NewAuthUserAPI(c Client) AuthUserAPI {
-	return &httpAuthUserAPI{
-		client: c,
-	}
-}
-
-type AuthUserAPI interface {
-	// AddUser adds a user.
-	AddUser(ctx context.Context, username string, password string) error
-
-	// RemoveUser removes a user.
-	RemoveUser(ctx context.Context, username string) error
-
-	// GetUser retrieves user details.
-	GetUser(ctx context.Context, username string) (*User, error)
-
-	// GrantUser grants a user some permission roles.
-	GrantUser(ctx context.Context, username string, roles []string) (*User, error)
-
-	// RevokeUser revokes some permission roles from a user.
-	RevokeUser(ctx context.Context, username string, roles []string) (*User, error)
-
-	// ChangePassword changes the user's password.
-	ChangePassword(ctx context.Context, username string, password string) (*User, error)
-
-	// ListUsers lists the users.
-	ListUsers(ctx context.Context) ([]string, error)
-}
-
-type httpAuthUserAPI struct {
-	client httpClient
-}
-
-type authUserAPIAction struct {
-	verb     string
-	username string
-	user     *User
-}
-
-type authUserAPIList struct{}
-
-func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "users", "")
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2AuthURL(ep, "users", l.username)
-	if l.user == nil {
-		req, _ := http.NewRequest(l.verb, u.String(), nil)
-		return req
-	}
-	b, err := json.Marshal(l.user)
-	if err != nil {
-		panic(err)
-	}
-	body := bytes.NewReader(b)
-	req, _ := http.NewRequest(l.verb, u.String(), body)
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) {
-	resp, body, err := u.client.Do(ctx, &authUserAPIList{})
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-
-	var userList struct {
-		Users []userListEntry `json:"users"`
-	}
-
-	if err = json.Unmarshal(body, &userList); err != nil {
-		return nil, err
-	}
-
-	ret := make([]string, 0, len(userList.Users))
-	for _, u := range userList.Users {
-		ret = append(ret, u.User)
-	}
-	return ret, nil
-}
-
-func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string, password string) error {
-	user := &User{
-		User:     username,
-		Password: password,
-	}
-	return u.addRemoveUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username string) error {
-	return u.addRemoveUser(ctx, &authUserAPIAction{
-		verb:     "DELETE",
-		username: username,
-	})
-}
-
-func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAction) error {
-	resp, body, err := u.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return err
-		}
-		return sec
-	}
-	return nil
-}
-
-func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string) (*User, error) {
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "GET",
-		username: username,
-	})
-}
-
-func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username string, roles []string) (*User, error) {
-	user := &User{
-		User:  username,
-		Grant: roles,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username string, roles []string) (*User, error) {
-	user := &User{
-		User:   username,
-		Revoke: roles,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username string, password string) (*User, error) {
-	user := &User{
-		User:     username,
-		Password: password,
-	}
-	return u.modUser(ctx, &authUserAPIAction{
-		verb:     "PUT",
-		username: username,
-		user:     user,
-	})
-}
-
-func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) (*User, error) {
-	resp, body, err := u.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-	if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		var sec authError
-		err = json.Unmarshal(body, &sec)
-		if err != nil {
-			return nil, err
-		}
-		return nil, sec
-	}
-	var user User
-	if err = json.Unmarshal(body, &user); err != nil {
-		var userR UserRoles
-		if urerr := json.Unmarshal(body, &userR); urerr != nil {
-			return nil, err
-		}
-		user.User = userR.User
-		for _, r := range userR.Roles {
-			user.Roles = append(user.Roles, r.Role)
-		}
-	}
-	return &user, nil
-}
diff --git a/vendor/go.etcd.io/etcd/client/cancelreq.go b/vendor/go.etcd.io/etcd/client/cancelreq.go
deleted file mode 100644
index 76d1f04..0000000
--- a/vendor/go.etcd.io/etcd/client/cancelreq.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// borrowed from golang/net/context/ctxhttp/cancelreq.go
-
-package client
-
-import "net/http"
-
-func requestCanceler(tr CancelableTransport, req *http.Request) func() {
-	ch := make(chan struct{})
-	req.Cancel = ch
-
-	return func() {
-		close(ch)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/client/client.go b/vendor/go.etcd.io/etcd/client/client.go
deleted file mode 100644
index de9ab79..0000000
--- a/vendor/go.etcd.io/etcd/client/client.go
+++ /dev/null
@@ -1,710 +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 client
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"math/rand"
-	"net"
-	"net/http"
-	"net/url"
-	"sort"
-	"strconv"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/version"
-)
-
-var (
-	ErrNoEndpoints           = errors.New("client: no endpoints available")
-	ErrTooManyRedirects      = errors.New("client: too many redirects")
-	ErrClusterUnavailable    = errors.New("client: etcd cluster is unavailable or misconfigured")
-	ErrNoLeaderEndpoint      = errors.New("client: no leader endpoint available")
-	errTooManyRedirectChecks = errors.New("client: too many redirect checks")
-
-	// oneShotCtxValue is set on a context using WithValue(&oneShotValue) so
-	// that Do() will not retry a request
-	oneShotCtxValue interface{}
-)
-
-var DefaultRequestTimeout = 5 * time.Second
-
-var DefaultTransport CancelableTransport = &http.Transport{
-	Proxy: http.ProxyFromEnvironment,
-	Dial: (&net.Dialer{
-		Timeout:   30 * time.Second,
-		KeepAlive: 30 * time.Second,
-	}).Dial,
-	TLSHandshakeTimeout: 10 * time.Second,
-}
-
-type EndpointSelectionMode int
-
-const (
-	// EndpointSelectionRandom is the default value of the 'SelectionMode'.
-	// As the name implies, the client object will pick a node from the members
-	// of the cluster in a random fashion. If the cluster has three members, A, B,
-	// and C, the client picks any node from its three members as its request
-	// destination.
-	EndpointSelectionRandom EndpointSelectionMode = iota
-
-	// If 'SelectionMode' is set to 'EndpointSelectionPrioritizeLeader',
-	// requests are sent directly to the cluster leader. This reduces
-	// forwarding roundtrips compared to making requests to etcd followers
-	// who then forward them to the cluster leader. In the event of a leader
-	// failure, however, clients configured this way cannot prioritize among
-	// the remaining etcd followers. Therefore, when a client sets 'SelectionMode'
-	// to 'EndpointSelectionPrioritizeLeader', it must use 'client.AutoSync()' to
-	// maintain its knowledge of current cluster state.
-	//
-	// This mode should be used with Client.AutoSync().
-	EndpointSelectionPrioritizeLeader
-)
-
-type Config struct {
-	// Endpoints defines a set of URLs (schemes, hosts and ports only)
-	// that can be used to communicate with a logical etcd cluster. For
-	// example, a three-node cluster could be provided like so:
-	//
-	// 	Endpoints: []string{
-	//		"http://node1.example.com:2379",
-	//		"http://node2.example.com:2379",
-	//		"http://node3.example.com:2379",
-	//	}
-	//
-	// If multiple endpoints are provided, the Client will attempt to
-	// use them all in the event that one or more of them are unusable.
-	//
-	// If Client.Sync is ever called, the Client may cache an alternate
-	// set of endpoints to continue operation.
-	Endpoints []string
-
-	// Transport is used by the Client to drive HTTP requests. If not
-	// provided, DefaultTransport will be used.
-	Transport CancelableTransport
-
-	// CheckRedirect specifies the policy for handling HTTP redirects.
-	// If CheckRedirect is not nil, the Client calls it before
-	// following an HTTP redirect. The sole argument is the number of
-	// requests that have already been made. If CheckRedirect returns
-	// an error, Client.Do will not make any further requests and return
-	// the error back it to the caller.
-	//
-	// If CheckRedirect is nil, the Client uses its default policy,
-	// which is to stop after 10 consecutive requests.
-	CheckRedirect CheckRedirectFunc
-
-	// Username specifies the user credential to add as an authorization header
-	Username string
-
-	// Password is the password for the specified user to add as an authorization header
-	// to the request.
-	Password string
-
-	// HeaderTimeoutPerRequest specifies the time limit to wait for response
-	// header in a single request made by the Client. The timeout includes
-	// connection time, any redirects, and header wait time.
-	//
-	// For non-watch GET request, server returns the response body immediately.
-	// For PUT/POST/DELETE request, server will attempt to commit request
-	// before responding, which is expected to take `100ms + 2 * RTT`.
-	// For watch request, server returns the header immediately to notify Client
-	// watch start. But if server is behind some kind of proxy, the response
-	// header may be cached at proxy, and Client cannot rely on this behavior.
-	//
-	// Especially, wait request will ignore this timeout.
-	//
-	// One API call may send multiple requests to different etcd servers until it
-	// succeeds. Use context of the API to specify the overall timeout.
-	//
-	// A HeaderTimeoutPerRequest of zero means no timeout.
-	HeaderTimeoutPerRequest time.Duration
-
-	// SelectionMode is an EndpointSelectionMode enum that specifies the
-	// policy for choosing the etcd cluster node to which requests are sent.
-	SelectionMode EndpointSelectionMode
-}
-
-func (cfg *Config) transport() CancelableTransport {
-	if cfg.Transport == nil {
-		return DefaultTransport
-	}
-	return cfg.Transport
-}
-
-func (cfg *Config) checkRedirect() CheckRedirectFunc {
-	if cfg.CheckRedirect == nil {
-		return DefaultCheckRedirect
-	}
-	return cfg.CheckRedirect
-}
-
-// CancelableTransport mimics net/http.Transport, but requires that
-// the object also support request cancellation.
-type CancelableTransport interface {
-	http.RoundTripper
-	CancelRequest(req *http.Request)
-}
-
-type CheckRedirectFunc func(via int) error
-
-// DefaultCheckRedirect follows up to 10 redirects, but no more.
-var DefaultCheckRedirect CheckRedirectFunc = func(via int) error {
-	if via > 10 {
-		return ErrTooManyRedirects
-	}
-	return nil
-}
-
-type Client interface {
-	// Sync updates the internal cache of the etcd cluster's membership.
-	Sync(context.Context) error
-
-	// AutoSync periodically calls Sync() every given interval.
-	// The recommended sync interval is 10 seconds to 1 minute, which does
-	// not bring too much overhead to server and makes client catch up the
-	// cluster change in time.
-	//
-	// The example to use it:
-	//
-	//  for {
-	//      err := client.AutoSync(ctx, 10*time.Second)
-	//      if err == context.DeadlineExceeded || err == context.Canceled {
-	//          break
-	//      }
-	//      log.Print(err)
-	//  }
-	AutoSync(context.Context, time.Duration) error
-
-	// Endpoints returns a copy of the current set of API endpoints used
-	// by Client to resolve HTTP requests. If Sync has ever been called,
-	// this may differ from the initial Endpoints provided in the Config.
-	Endpoints() []string
-
-	// SetEndpoints sets the set of API endpoints used by Client to resolve
-	// HTTP requests. If the given endpoints are not valid, an error will be
-	// returned
-	SetEndpoints(eps []string) error
-
-	// GetVersion retrieves the current etcd server and cluster version
-	GetVersion(ctx context.Context) (*version.Versions, error)
-
-	httpClient
-}
-
-func New(cfg Config) (Client, error) {
-	c := &httpClusterClient{
-		clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest),
-		rand:          rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
-		selectionMode: cfg.SelectionMode,
-	}
-	if cfg.Username != "" {
-		c.credentials = &credentials{
-			username: cfg.Username,
-			password: cfg.Password,
-		}
-	}
-	if err := c.SetEndpoints(cfg.Endpoints); err != nil {
-		return nil, err
-	}
-	return c, nil
-}
-
-type httpClient interface {
-	Do(context.Context, httpAction) (*http.Response, []byte, error)
-}
-
-func newHTTPClientFactory(tr CancelableTransport, cr CheckRedirectFunc, headerTimeout time.Duration) httpClientFactory {
-	return func(ep url.URL) httpClient {
-		return &redirectFollowingHTTPClient{
-			checkRedirect: cr,
-			client: &simpleHTTPClient{
-				transport:     tr,
-				endpoint:      ep,
-				headerTimeout: headerTimeout,
-			},
-		}
-	}
-}
-
-type credentials struct {
-	username string
-	password string
-}
-
-type httpClientFactory func(url.URL) httpClient
-
-type httpAction interface {
-	HTTPRequest(url.URL) *http.Request
-}
-
-type httpClusterClient struct {
-	clientFactory httpClientFactory
-	endpoints     []url.URL
-	pinned        int
-	credentials   *credentials
-	sync.RWMutex
-	rand          *rand.Rand
-	selectionMode EndpointSelectionMode
-}
-
-func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps []url.URL) (string, error) {
-	ceps := make([]url.URL, len(eps))
-	copy(ceps, eps)
-
-	// To perform a lookup on the new endpoint list without using the current
-	// client, we'll copy it
-	clientCopy := &httpClusterClient{
-		clientFactory: c.clientFactory,
-		credentials:   c.credentials,
-		rand:          c.rand,
-
-		pinned:    0,
-		endpoints: ceps,
-	}
-
-	mAPI := NewMembersAPI(clientCopy)
-	leader, err := mAPI.Leader(ctx)
-	if err != nil {
-		return "", err
-	}
-	if len(leader.ClientURLs) == 0 {
-		return "", ErrNoLeaderEndpoint
-	}
-
-	return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs?
-}
-
-func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, error) {
-	if len(eps) == 0 {
-		return []url.URL{}, ErrNoEndpoints
-	}
-
-	neps := make([]url.URL, len(eps))
-	for i, ep := range eps {
-		u, err := url.Parse(ep)
-		if err != nil {
-			return []url.URL{}, err
-		}
-		neps[i] = *u
-	}
-	return neps, nil
-}
-
-func (c *httpClusterClient) SetEndpoints(eps []string) error {
-	neps, err := c.parseEndpoints(eps)
-	if err != nil {
-		return err
-	}
-
-	c.Lock()
-	defer c.Unlock()
-
-	c.endpoints = shuffleEndpoints(c.rand, neps)
-	// We're not doing anything for PrioritizeLeader here. This is
-	// due to not having a context meaning we can't call getLeaderEndpoint
-	// However, if you're using PrioritizeLeader, you've already been told
-	// to regularly call sync, where we do have a ctx, and can figure the
-	// leader. PrioritizeLeader is also quite a loose guarantee, so deal
-	// with it
-	c.pinned = 0
-
-	return nil
-}
-
-func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	action := act
-	c.RLock()
-	leps := len(c.endpoints)
-	eps := make([]url.URL, leps)
-	n := copy(eps, c.endpoints)
-	pinned := c.pinned
-
-	if c.credentials != nil {
-		action = &authedAction{
-			act:         act,
-			credentials: *c.credentials,
-		}
-	}
-	c.RUnlock()
-
-	if leps == 0 {
-		return nil, nil, ErrNoEndpoints
-	}
-
-	if leps != n {
-		return nil, nil, errors.New("unable to pick endpoint: copy failed")
-	}
-
-	var resp *http.Response
-	var body []byte
-	var err error
-	cerr := &ClusterError{}
-	isOneShot := ctx.Value(&oneShotCtxValue) != nil
-
-	for i := pinned; i < leps+pinned; i++ {
-		k := i % leps
-		hc := c.clientFactory(eps[k])
-		resp, body, err = hc.Do(ctx, action)
-		if err != nil {
-			cerr.Errors = append(cerr.Errors, err)
-			if err == ctx.Err() {
-				return nil, nil, ctx.Err()
-			}
-			if err == context.Canceled || err == context.DeadlineExceeded {
-				return nil, nil, err
-			}
-		} else if resp.StatusCode/100 == 5 {
-			switch resp.StatusCode {
-			case http.StatusInternalServerError, http.StatusServiceUnavailable:
-				// TODO: make sure this is a no leader response
-				cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s has no leader", eps[k].String()))
-			default:
-				cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode)))
-			}
-			err = cerr.Errors[0]
-		}
-		if err != nil {
-			if !isOneShot {
-				continue
-			}
-			c.Lock()
-			c.pinned = (k + 1) % leps
-			c.Unlock()
-			return nil, nil, err
-		}
-		if k != pinned {
-			c.Lock()
-			c.pinned = k
-			c.Unlock()
-		}
-		return resp, body, nil
-	}
-
-	return nil, nil, cerr
-}
-
-func (c *httpClusterClient) Endpoints() []string {
-	c.RLock()
-	defer c.RUnlock()
-
-	eps := make([]string, len(c.endpoints))
-	for i, ep := range c.endpoints {
-		eps[i] = ep.String()
-	}
-
-	return eps
-}
-
-func (c *httpClusterClient) Sync(ctx context.Context) error {
-	mAPI := NewMembersAPI(c)
-	ms, err := mAPI.List(ctx)
-	if err != nil {
-		return err
-	}
-
-	var eps []string
-	for _, m := range ms {
-		eps = append(eps, m.ClientURLs...)
-	}
-
-	neps, err := c.parseEndpoints(eps)
-	if err != nil {
-		return err
-	}
-
-	npin := 0
-
-	switch c.selectionMode {
-	case EndpointSelectionRandom:
-		c.RLock()
-		eq := endpointsEqual(c.endpoints, neps)
-		c.RUnlock()
-
-		if eq {
-			return nil
-		}
-		// When items in the endpoint list changes, we choose a new pin
-		neps = shuffleEndpoints(c.rand, neps)
-	case EndpointSelectionPrioritizeLeader:
-		nle, err := c.getLeaderEndpoint(ctx, neps)
-		if err != nil {
-			return ErrNoLeaderEndpoint
-		}
-
-		for i, n := range neps {
-			if n.String() == nle {
-				npin = i
-				break
-			}
-		}
-	default:
-		return fmt.Errorf("invalid endpoint selection mode: %d", c.selectionMode)
-	}
-
-	c.Lock()
-	defer c.Unlock()
-	c.endpoints = neps
-	c.pinned = npin
-
-	return nil
-}
-
-func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error {
-	ticker := time.NewTicker(interval)
-	defer ticker.Stop()
-	for {
-		err := c.Sync(ctx)
-		if err != nil {
-			return err
-		}
-		select {
-		case <-ctx.Done():
-			return ctx.Err()
-		case <-ticker.C:
-		}
-	}
-}
-
-func (c *httpClusterClient) GetVersion(ctx context.Context) (*version.Versions, error) {
-	act := &getAction{Prefix: "/version"}
-
-	resp, body, err := c.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	switch resp.StatusCode {
-	case http.StatusOK:
-		if len(body) == 0 {
-			return nil, ErrEmptyBody
-		}
-		var vresp version.Versions
-		if err := json.Unmarshal(body, &vresp); err != nil {
-			return nil, ErrInvalidJSON
-		}
-		return &vresp, nil
-	default:
-		var etcdErr Error
-		if err := json.Unmarshal(body, &etcdErr); err != nil {
-			return nil, ErrInvalidJSON
-		}
-		return nil, etcdErr
-	}
-}
-
-type roundTripResponse struct {
-	resp *http.Response
-	err  error
-}
-
-type simpleHTTPClient struct {
-	transport     CancelableTransport
-	endpoint      url.URL
-	headerTimeout time.Duration
-}
-
-func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	req := act.HTTPRequest(c.endpoint)
-
-	if err := printcURL(req); err != nil {
-		return nil, nil, err
-	}
-
-	isWait := false
-	if req != nil && req.URL != nil {
-		ws := req.URL.Query().Get("wait")
-		if len(ws) != 0 {
-			var err error
-			isWait, err = strconv.ParseBool(ws)
-			if err != nil {
-				return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req)
-			}
-		}
-	}
-
-	var hctx context.Context
-	var hcancel context.CancelFunc
-	if !isWait && c.headerTimeout > 0 {
-		hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout)
-	} else {
-		hctx, hcancel = context.WithCancel(ctx)
-	}
-	defer hcancel()
-
-	reqcancel := requestCanceler(c.transport, req)
-
-	rtchan := make(chan roundTripResponse, 1)
-	go func() {
-		resp, err := c.transport.RoundTrip(req)
-		rtchan <- roundTripResponse{resp: resp, err: err}
-		close(rtchan)
-	}()
-
-	var resp *http.Response
-	var err error
-
-	select {
-	case rtresp := <-rtchan:
-		resp, err = rtresp.resp, rtresp.err
-	case <-hctx.Done():
-		// cancel and wait for request to actually exit before continuing
-		reqcancel()
-		rtresp := <-rtchan
-		resp = rtresp.resp
-		switch {
-		case ctx.Err() != nil:
-			err = ctx.Err()
-		case hctx.Err() != nil:
-			err = fmt.Errorf("client: endpoint %s exceeded header timeout", c.endpoint.String())
-		default:
-			panic("failed to get error from context")
-		}
-	}
-
-	// always check for resp nil-ness to deal with possible
-	// race conditions between channels above
-	defer func() {
-		if resp != nil {
-			resp.Body.Close()
-		}
-	}()
-
-	if err != nil {
-		return nil, nil, err
-	}
-
-	var body []byte
-	done := make(chan struct{})
-	go func() {
-		body, err = ioutil.ReadAll(resp.Body)
-		done <- struct{}{}
-	}()
-
-	select {
-	case <-ctx.Done():
-		resp.Body.Close()
-		<-done
-		return nil, nil, ctx.Err()
-	case <-done:
-	}
-
-	return resp, body, err
-}
-
-type authedAction struct {
-	act         httpAction
-	credentials credentials
-}
-
-func (a *authedAction) HTTPRequest(url url.URL) *http.Request {
-	r := a.act.HTTPRequest(url)
-	r.SetBasicAuth(a.credentials.username, a.credentials.password)
-	return r
-}
-
-type redirectFollowingHTTPClient struct {
-	client        httpClient
-	checkRedirect CheckRedirectFunc
-}
-
-func (r *redirectFollowingHTTPClient) Do(ctx context.Context, act httpAction) (*http.Response, []byte, error) {
-	next := act
-	for i := 0; i < 100; i++ {
-		if i > 0 {
-			if err := r.checkRedirect(i); err != nil {
-				return nil, nil, err
-			}
-		}
-		resp, body, err := r.client.Do(ctx, next)
-		if err != nil {
-			return nil, nil, err
-		}
-		if resp.StatusCode/100 == 3 {
-			hdr := resp.Header.Get("Location")
-			if hdr == "" {
-				return nil, nil, fmt.Errorf("location header not set")
-			}
-			loc, err := url.Parse(hdr)
-			if err != nil {
-				return nil, nil, fmt.Errorf("location header not valid URL: %s", hdr)
-			}
-			next = &redirectedHTTPAction{
-				action:   act,
-				location: *loc,
-			}
-			continue
-		}
-		return resp, body, nil
-	}
-
-	return nil, nil, errTooManyRedirectChecks
-}
-
-type redirectedHTTPAction struct {
-	action   httpAction
-	location url.URL
-}
-
-func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request {
-	orig := r.action.HTTPRequest(ep)
-	orig.URL = &r.location
-	return orig
-}
-
-func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL {
-	// copied from Go 1.9<= rand.Rand.Perm
-	n := len(eps)
-	p := make([]int, n)
-	for i := 0; i < n; i++ {
-		j := r.Intn(i + 1)
-		p[i] = p[j]
-		p[j] = i
-	}
-	neps := make([]url.URL, n)
-	for i, k := range p {
-		neps[i] = eps[k]
-	}
-	return neps
-}
-
-func endpointsEqual(left, right []url.URL) bool {
-	if len(left) != len(right) {
-		return false
-	}
-
-	sLeft := make([]string, len(left))
-	sRight := make([]string, len(right))
-	for i, l := range left {
-		sLeft[i] = l.String()
-	}
-	for i, r := range right {
-		sRight[i] = r.String()
-	}
-
-	sort.Strings(sLeft)
-	sort.Strings(sRight)
-	for i := range sLeft {
-		if sLeft[i] != sRight[i] {
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/go.etcd.io/etcd/client/cluster_error.go b/vendor/go.etcd.io/etcd/client/cluster_error.go
deleted file mode 100644
index 34618cd..0000000
--- a/vendor/go.etcd.io/etcd/client/cluster_error.go
+++ /dev/null
@@ -1,37 +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 client
-
-import "fmt"
-
-type ClusterError struct {
-	Errors []error
-}
-
-func (ce *ClusterError) Error() string {
-	s := ErrClusterUnavailable.Error()
-	for i, e := range ce.Errors {
-		s += fmt.Sprintf("; error #%d: %s\n", i, e)
-	}
-	return s
-}
-
-func (ce *ClusterError) Detail() string {
-	s := ""
-	for i, e := range ce.Errors {
-		s += fmt.Sprintf("error #%d: %s\n", i, e)
-	}
-	return s
-}
diff --git a/vendor/go.etcd.io/etcd/client/curl.go b/vendor/go.etcd.io/etcd/client/curl.go
deleted file mode 100644
index c8bc9fb..0000000
--- a/vendor/go.etcd.io/etcd/client/curl.go
+++ /dev/null
@@ -1,70 +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 client
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"os"
-)
-
-var (
-	cURLDebug = false
-)
-
-func EnablecURLDebug() {
-	cURLDebug = true
-}
-
-func DisablecURLDebug() {
-	cURLDebug = false
-}
-
-// printcURL prints the cURL equivalent request to stderr.
-// It returns an error if the body of the request cannot
-// be read.
-// The caller MUST cancel the request if there is an error.
-func printcURL(req *http.Request) error {
-	if !cURLDebug {
-		return nil
-	}
-	var (
-		command string
-		b       []byte
-		err     error
-	)
-
-	if req.URL != nil {
-		command = fmt.Sprintf("curl -X %s %s", req.Method, req.URL.String())
-	}
-
-	if req.Body != nil {
-		b, err = ioutil.ReadAll(req.Body)
-		if err != nil {
-			return err
-		}
-		command += fmt.Sprintf(" -d %q", string(b))
-	}
-
-	fmt.Fprintf(os.Stderr, "cURL Command: %s\n", command)
-
-	// reset body
-	body := bytes.NewBuffer(b)
-	req.Body = ioutil.NopCloser(body)
-
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/client/discover.go b/vendor/go.etcd.io/etcd/client/discover.go
deleted file mode 100644
index 580c256..0000000
--- a/vendor/go.etcd.io/etcd/client/discover.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 client
-
-import (
-	"go.etcd.io/etcd/pkg/srv"
-)
-
-// Discoverer is an interface that wraps the Discover method.
-type Discoverer interface {
-	// Discover looks up the etcd servers for the domain.
-	Discover(domain string, serviceName string) ([]string, error)
-}
-
-type srvDiscover struct{}
-
-// NewSRVDiscover constructs a new Discoverer that uses the stdlib to lookup SRV records.
-func NewSRVDiscover() Discoverer {
-	return &srvDiscover{}
-}
-
-func (d *srvDiscover) Discover(domain string, serviceName string) ([]string, error) {
-	srvs, err := srv.GetClient("etcd-client", domain, serviceName)
-	if err != nil {
-		return nil, err
-	}
-	return srvs.Endpoints, nil
-}
diff --git a/vendor/go.etcd.io/etcd/client/doc.go b/vendor/go.etcd.io/etcd/client/doc.go
deleted file mode 100644
index abe5199..0000000
--- a/vendor/go.etcd.io/etcd/client/doc.go
+++ /dev/null
@@ -1,73 +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 client provides bindings for the etcd APIs.
-
-Create a Config and exchange it for a Client:
-
-	import (
-		"net/http"
-		"context"
-
-		"go.etcd.io/etcd/client"
-	)
-
-	cfg := client.Config{
-		Endpoints: []string{"http://127.0.0.1:2379"},
-		Transport: DefaultTransport,
-	}
-
-	c, err := client.New(cfg)
-	if err != nil {
-		// handle error
-	}
-
-Clients are safe for concurrent use by multiple goroutines.
-
-Create a KeysAPI using the Client, then use it to interact with etcd:
-
-	kAPI := client.NewKeysAPI(c)
-
-	// create a new key /foo with the value "bar"
-	_, err = kAPI.Create(context.Background(), "/foo", "bar")
-	if err != nil {
-		// handle error
-	}
-
-	// delete the newly created key only if the value is still "bar"
-	_, err = kAPI.Delete(context.Background(), "/foo", &DeleteOptions{PrevValue: "bar"})
-	if err != nil {
-		// handle error
-	}
-
-Use a custom context to set timeouts on your operations:
-
-	import "time"
-
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-
-	// set a new key, ignoring its previous state
-	_, err := kAPI.Set(ctx, "/ping", "pong", nil)
-	if err != nil {
-		if err == context.DeadlineExceeded {
-			// request took longer than 5s
-		} else {
-			// handle error
-		}
-	}
-
-*/
-package client
diff --git a/vendor/go.etcd.io/etcd/client/json.go b/vendor/go.etcd.io/etcd/client/json.go
deleted file mode 100644
index 97cdbcd..0000000
--- a/vendor/go.etcd.io/etcd/client/json.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 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 client
-
-import (
-	"github.com/json-iterator/go"
-	"github.com/modern-go/reflect2"
-	"strconv"
-	"unsafe"
-)
-
-type customNumberExtension struct {
-	jsoniter.DummyExtension
-}
-
-func (cne *customNumberExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
-	if typ.String() == "interface {}" {
-		return customNumberDecoder{}
-	}
-	return nil
-}
-
-type customNumberDecoder struct {
-}
-
-func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
-	switch iter.WhatIsNext() {
-	case jsoniter.NumberValue:
-		var number jsoniter.Number
-		iter.ReadVal(&number)
-		i64, err := strconv.ParseInt(string(number), 10, 64)
-		if err == nil {
-			*(*interface{})(ptr) = i64
-			return
-		}
-		f64, err := strconv.ParseFloat(string(number), 64)
-		if err == nil {
-			*(*interface{})(ptr) = f64
-			return
-		}
-		iter.ReportError("DecodeNumber", err.Error())
-	default:
-		*(*interface{})(ptr) = iter.Read()
-	}
-}
-
-// caseSensitiveJsonIterator returns a jsoniterator API that's configured to be
-// case-sensitive when unmarshalling, and otherwise compatible with
-// the encoding/json standard library.
-func caseSensitiveJsonIterator() jsoniter.API {
-	config := jsoniter.Config{
-		EscapeHTML:             true,
-		SortMapKeys:            true,
-		ValidateJsonRawMessage: true,
-		CaseSensitive:          true,
-	}.Froze()
-	// Force jsoniter to decode number to interface{} via int64/float64, if possible.
-	config.RegisterExtension(&customNumberExtension{})
-	return config
-}
diff --git a/vendor/go.etcd.io/etcd/client/keys.go b/vendor/go.etcd.io/etcd/client/keys.go
deleted file mode 100644
index ec53830..0000000
--- a/vendor/go.etcd.io/etcd/client/keys.go
+++ /dev/null
@@ -1,679 +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 client
-
-import (
-	"context"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"go.etcd.io/etcd/pkg/pathutil"
-	"net/http"
-	"net/url"
-	"strconv"
-	"strings"
-	"time"
-)
-
-const (
-	ErrorCodeKeyNotFound  = 100
-	ErrorCodeTestFailed   = 101
-	ErrorCodeNotFile      = 102
-	ErrorCodeNotDir       = 104
-	ErrorCodeNodeExist    = 105
-	ErrorCodeRootROnly    = 107
-	ErrorCodeDirNotEmpty  = 108
-	ErrorCodeUnauthorized = 110
-
-	ErrorCodePrevValueRequired = 201
-	ErrorCodeTTLNaN            = 202
-	ErrorCodeIndexNaN          = 203
-	ErrorCodeInvalidField      = 209
-	ErrorCodeInvalidForm       = 210
-
-	ErrorCodeRaftInternal = 300
-	ErrorCodeLeaderElect  = 301
-
-	ErrorCodeWatcherCleared    = 400
-	ErrorCodeEventIndexCleared = 401
-)
-
-type Error struct {
-	Code    int    `json:"errorCode"`
-	Message string `json:"message"`
-	Cause   string `json:"cause"`
-	Index   uint64 `json:"index"`
-}
-
-func (e Error) Error() string {
-	return fmt.Sprintf("%v: %v (%v) [%v]", e.Code, e.Message, e.Cause, e.Index)
-}
-
-var (
-	ErrInvalidJSON = errors.New("client: response is invalid json. The endpoint is probably not valid etcd cluster endpoint")
-	ErrEmptyBody   = errors.New("client: response body is empty")
-)
-
-// PrevExistType is used to define an existence condition when setting
-// or deleting Nodes.
-type PrevExistType string
-
-const (
-	PrevIgnore  = PrevExistType("")
-	PrevExist   = PrevExistType("true")
-	PrevNoExist = PrevExistType("false")
-)
-
-var (
-	defaultV2KeysPrefix = "/v2/keys"
-)
-
-// NewKeysAPI builds a KeysAPI that interacts with etcd's key-value
-// API over HTTP.
-func NewKeysAPI(c Client) KeysAPI {
-	return NewKeysAPIWithPrefix(c, defaultV2KeysPrefix)
-}
-
-// NewKeysAPIWithPrefix acts like NewKeysAPI, but allows the caller
-// to provide a custom base URL path. This should only be used in
-// very rare cases.
-func NewKeysAPIWithPrefix(c Client, p string) KeysAPI {
-	return &httpKeysAPI{
-		client: c,
-		prefix: p,
-	}
-}
-
-type KeysAPI interface {
-	// Get retrieves a set of Nodes from etcd
-	Get(ctx context.Context, key string, opts *GetOptions) (*Response, error)
-
-	// Set assigns a new value to a Node identified by a given key. The caller
-	// may define a set of conditions in the SetOptions. If SetOptions.Dir=true
-	// then value is ignored.
-	Set(ctx context.Context, key, value string, opts *SetOptions) (*Response, error)
-
-	// Delete removes a Node identified by the given key, optionally destroying
-	// all of its children as well. The caller may define a set of required
-	// conditions in an DeleteOptions object.
-	Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error)
-
-	// Create is an alias for Set w/ PrevExist=false
-	Create(ctx context.Context, key, value string) (*Response, error)
-
-	// CreateInOrder is used to atomically create in-order keys within the given directory.
-	CreateInOrder(ctx context.Context, dir, value string, opts *CreateInOrderOptions) (*Response, error)
-
-	// Update is an alias for Set w/ PrevExist=true
-	Update(ctx context.Context, key, value string) (*Response, error)
-
-	// Watcher builds a new Watcher targeted at a specific Node identified
-	// by the given key. The Watcher may be configured at creation time
-	// through a WatcherOptions object. The returned Watcher is designed
-	// to emit events that happen to a Node, and optionally to its children.
-	Watcher(key string, opts *WatcherOptions) Watcher
-}
-
-type WatcherOptions struct {
-	// AfterIndex defines the index after-which the Watcher should
-	// start emitting events. For example, if a value of 5 is
-	// provided, the first event will have an index >= 6.
-	//
-	// Setting AfterIndex to 0 (default) means that the Watcher
-	// should start watching for events starting at the current
-	// index, whatever that may be.
-	AfterIndex uint64
-
-	// Recursive specifies whether or not the Watcher should emit
-	// events that occur in children of the given keyspace. If set
-	// to false (default), events will be limited to those that
-	// occur for the exact key.
-	Recursive bool
-}
-
-type CreateInOrderOptions struct {
-	// TTL defines a period of time after-which the Node should
-	// expire and no longer exist. Values <= 0 are ignored. Given
-	// that the zero-value is ignored, TTL cannot be used to set
-	// a TTL of 0.
-	TTL time.Duration
-}
-
-type SetOptions struct {
-	// PrevValue specifies what the current value of the Node must
-	// be in order for the Set operation to succeed.
-	//
-	// Leaving this field empty means that the caller wishes to
-	// ignore the current value of the Node. This cannot be used
-	// to compare the Node's current value to an empty string.
-	//
-	// PrevValue is ignored if Dir=true
-	PrevValue string
-
-	// PrevIndex indicates what the current ModifiedIndex of the
-	// Node must be in order for the Set operation to succeed.
-	//
-	// If PrevIndex is set to 0 (default), no comparison is made.
-	PrevIndex uint64
-
-	// PrevExist specifies whether the Node must currently exist
-	// (PrevExist) or not (PrevNoExist). If the caller does not
-	// care about existence, set PrevExist to PrevIgnore, or simply
-	// leave it unset.
-	PrevExist PrevExistType
-
-	// TTL defines a period of time after-which the Node should
-	// expire and no longer exist. Values <= 0 are ignored. Given
-	// that the zero-value is ignored, TTL cannot be used to set
-	// a TTL of 0.
-	TTL time.Duration
-
-	// Refresh set to true means a TTL value can be updated
-	// without firing a watch or changing the node value. A
-	// value must not be provided when refreshing a key.
-	Refresh bool
-
-	// Dir specifies whether or not this Node should be created as a directory.
-	Dir bool
-
-	// NoValueOnSuccess specifies whether the response contains the current value of the Node.
-	// If set, the response will only contain the current value when the request fails.
-	NoValueOnSuccess bool
-}
-
-type GetOptions struct {
-	// Recursive defines whether or not all children of the Node
-	// should be returned.
-	Recursive bool
-
-	// Sort instructs the server whether or not to sort the Nodes.
-	// If true, the Nodes are sorted alphabetically by key in
-	// ascending order (A to z). If false (default), the Nodes will
-	// not be sorted and the ordering used should not be considered
-	// predictable.
-	Sort bool
-
-	// Quorum specifies whether it gets the latest committed value that
-	// has been applied in quorum of members, which ensures external
-	// consistency (or linearizability).
-	Quorum bool
-}
-
-type DeleteOptions struct {
-	// PrevValue specifies what the current value of the Node must
-	// be in order for the Delete operation to succeed.
-	//
-	// Leaving this field empty means that the caller wishes to
-	// ignore the current value of the Node. This cannot be used
-	// to compare the Node's current value to an empty string.
-	PrevValue string
-
-	// PrevIndex indicates what the current ModifiedIndex of the
-	// Node must be in order for the Delete operation to succeed.
-	//
-	// If PrevIndex is set to 0 (default), no comparison is made.
-	PrevIndex uint64
-
-	// Recursive defines whether or not all children of the Node
-	// should be deleted. If set to true, all children of the Node
-	// identified by the given key will be deleted. If left unset
-	// or explicitly set to false, only a single Node will be
-	// deleted.
-	Recursive bool
-
-	// Dir specifies whether or not this Node should be removed as a directory.
-	Dir bool
-}
-
-type Watcher interface {
-	// Next blocks until an etcd event occurs, then returns a Response
-	// representing that event. The behavior of Next depends on the
-	// WatcherOptions used to construct the Watcher. Next is designed to
-	// be called repeatedly, each time blocking until a subsequent event
-	// is available.
-	//
-	// If the provided context is cancelled, Next will return a non-nil
-	// error. Any other failures encountered while waiting for the next
-	// event (connection issues, deserialization failures, etc) will
-	// also result in a non-nil error.
-	Next(context.Context) (*Response, error)
-}
-
-type Response struct {
-	// Action is the name of the operation that occurred. Possible values
-	// include get, set, delete, update, create, compareAndSwap,
-	// compareAndDelete and expire.
-	Action string `json:"action"`
-
-	// Node represents the state of the relevant etcd Node.
-	Node *Node `json:"node"`
-
-	// PrevNode represents the previous state of the Node. PrevNode is non-nil
-	// only if the Node existed before the action occurred and the action
-	// caused a change to the Node.
-	PrevNode *Node `json:"prevNode"`
-
-	// Index holds the cluster-level index at the time the Response was generated.
-	// This index is not tied to the Node(s) contained in this Response.
-	Index uint64 `json:"-"`
-
-	// ClusterID holds the cluster-level ID reported by the server.  This
-	// should be different for different etcd clusters.
-	ClusterID string `json:"-"`
-}
-
-type Node struct {
-	// Key represents the unique location of this Node (e.g. "/foo/bar").
-	Key string `json:"key"`
-
-	// Dir reports whether node describes a directory.
-	Dir bool `json:"dir,omitempty"`
-
-	// Value is the current data stored on this Node. If this Node
-	// is a directory, Value will be empty.
-	Value string `json:"value"`
-
-	// Nodes holds the children of this Node, only if this Node is a directory.
-	// This slice of will be arbitrarily deep (children, grandchildren, great-
-	// grandchildren, etc.) if a recursive Get or Watch request were made.
-	Nodes Nodes `json:"nodes"`
-
-	// CreatedIndex is the etcd index at-which this Node was created.
-	CreatedIndex uint64 `json:"createdIndex"`
-
-	// ModifiedIndex is the etcd index at-which this Node was last modified.
-	ModifiedIndex uint64 `json:"modifiedIndex"`
-
-	// Expiration is the server side expiration time of the key.
-	Expiration *time.Time `json:"expiration,omitempty"`
-
-	// TTL is the time to live of the key in second.
-	TTL int64 `json:"ttl,omitempty"`
-}
-
-func (n *Node) String() string {
-	return fmt.Sprintf("{Key: %s, CreatedIndex: %d, ModifiedIndex: %d, TTL: %d}", n.Key, n.CreatedIndex, n.ModifiedIndex, n.TTL)
-}
-
-// TTLDuration returns the Node's TTL as a time.Duration object
-func (n *Node) TTLDuration() time.Duration {
-	return time.Duration(n.TTL) * time.Second
-}
-
-type Nodes []*Node
-
-// interfaces for sorting
-
-func (ns Nodes) Len() int           { return len(ns) }
-func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key }
-func (ns Nodes) Swap(i, j int)      { ns[i], ns[j] = ns[j], ns[i] }
-
-type httpKeysAPI struct {
-	client httpClient
-	prefix string
-}
-
-func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *SetOptions) (*Response, error) {
-	act := &setAction{
-		Prefix: k.prefix,
-		Key:    key,
-		Value:  val,
-	}
-
-	if opts != nil {
-		act.PrevValue = opts.PrevValue
-		act.PrevIndex = opts.PrevIndex
-		act.PrevExist = opts.PrevExist
-		act.TTL = opts.TTL
-		act.Refresh = opts.Refresh
-		act.Dir = opts.Dir
-		act.NoValueOnSuccess = opts.NoValueOnSuccess
-	}
-
-	doCtx := ctx
-	if act.PrevExist == PrevNoExist {
-		doCtx = context.WithValue(doCtx, &oneShotCtxValue, &oneShotCtxValue)
-	}
-	resp, body, err := k.client.Do(doCtx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*Response, error) {
-	return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevNoExist})
-}
-
-func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val string, opts *CreateInOrderOptions) (*Response, error) {
-	act := &createInOrderAction{
-		Prefix: k.prefix,
-		Dir:    dir,
-		Value:  val,
-	}
-
-	if opts != nil {
-		act.TTL = opts.TTL
-	}
-
-	resp, body, err := k.client.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*Response, error) {
-	return k.Set(ctx, key, val, &SetOptions{PrevExist: PrevExist})
-}
-
-func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *DeleteOptions) (*Response, error) {
-	act := &deleteAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.PrevValue = opts.PrevValue
-		act.PrevIndex = opts.PrevIndex
-		act.Dir = opts.Dir
-		act.Recursive = opts.Recursive
-	}
-
-	doCtx := context.WithValue(ctx, &oneShotCtxValue, &oneShotCtxValue)
-	resp, body, err := k.client.Do(doCtx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Get(ctx context.Context, key string, opts *GetOptions) (*Response, error) {
-	act := &getAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.Recursive = opts.Recursive
-		act.Sorted = opts.Sort
-		act.Quorum = opts.Quorum
-	}
-
-	resp, body, err := k.client.Do(ctx, act)
-	if err != nil {
-		return nil, err
-	}
-
-	return unmarshalHTTPResponse(resp.StatusCode, resp.Header, body)
-}
-
-func (k *httpKeysAPI) Watcher(key string, opts *WatcherOptions) Watcher {
-	act := waitAction{
-		Prefix: k.prefix,
-		Key:    key,
-	}
-
-	if opts != nil {
-		act.Recursive = opts.Recursive
-		if opts.AfterIndex > 0 {
-			act.WaitIndex = opts.AfterIndex + 1
-		}
-	}
-
-	return &httpWatcher{
-		client:   k.client,
-		nextWait: act,
-	}
-}
-
-type httpWatcher struct {
-	client   httpClient
-	nextWait waitAction
-}
-
-func (hw *httpWatcher) Next(ctx context.Context) (*Response, error) {
-	for {
-		httpresp, body, err := hw.client.Do(ctx, &hw.nextWait)
-		if err != nil {
-			return nil, err
-		}
-
-		resp, err := unmarshalHTTPResponse(httpresp.StatusCode, httpresp.Header, body)
-		if err != nil {
-			if err == ErrEmptyBody {
-				continue
-			}
-			return nil, err
-		}
-
-		hw.nextWait.WaitIndex = resp.Node.ModifiedIndex + 1
-		return resp, nil
-	}
-}
-
-// v2KeysURL forms a URL representing the location of a key.
-// The endpoint argument represents the base URL of an etcd
-// server. The prefix is the path needed to route from the
-// provided endpoint's path to the root of the keys API
-// (typically "/v2/keys").
-func v2KeysURL(ep url.URL, prefix, key string) *url.URL {
-	// We concatenate all parts together manually. We cannot use
-	// path.Join because it does not reserve trailing slash.
-	// We call CanonicalURLPath to further cleanup the path.
-	if prefix != "" && prefix[0] != '/' {
-		prefix = "/" + prefix
-	}
-	if key != "" && key[0] != '/' {
-		key = "/" + key
-	}
-	ep.Path = pathutil.CanonicalURLPath(ep.Path + prefix + key)
-	return &ep
-}
-
-type getAction struct {
-	Prefix    string
-	Key       string
-	Recursive bool
-	Sorted    bool
-	Quorum    bool
-}
-
-func (g *getAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, g.Prefix, g.Key)
-
-	params := u.Query()
-	params.Set("recursive", strconv.FormatBool(g.Recursive))
-	params.Set("sorted", strconv.FormatBool(g.Sorted))
-	params.Set("quorum", strconv.FormatBool(g.Quorum))
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type waitAction struct {
-	Prefix    string
-	Key       string
-	WaitIndex uint64
-	Recursive bool
-}
-
-func (w *waitAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, w.Prefix, w.Key)
-
-	params := u.Query()
-	params.Set("wait", "true")
-	params.Set("waitIndex", strconv.FormatUint(w.WaitIndex, 10))
-	params.Set("recursive", strconv.FormatBool(w.Recursive))
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type setAction struct {
-	Prefix           string
-	Key              string
-	Value            string
-	PrevValue        string
-	PrevIndex        uint64
-	PrevExist        PrevExistType
-	TTL              time.Duration
-	Refresh          bool
-	Dir              bool
-	NoValueOnSuccess bool
-}
-
-func (a *setAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Key)
-
-	params := u.Query()
-	form := url.Values{}
-
-	// we're either creating a directory or setting a key
-	if a.Dir {
-		params.Set("dir", strconv.FormatBool(a.Dir))
-	} else {
-		// These options are only valid for setting a key
-		if a.PrevValue != "" {
-			params.Set("prevValue", a.PrevValue)
-		}
-		form.Add("value", a.Value)
-	}
-
-	// Options which apply to both setting a key and creating a dir
-	if a.PrevIndex != 0 {
-		params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
-	}
-	if a.PrevExist != PrevIgnore {
-		params.Set("prevExist", string(a.PrevExist))
-	}
-	if a.TTL > 0 {
-		form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
-	}
-
-	if a.Refresh {
-		form.Add("refresh", "true")
-	}
-	if a.NoValueOnSuccess {
-		params.Set("noValueOnSuccess", strconv.FormatBool(a.NoValueOnSuccess))
-	}
-
-	u.RawQuery = params.Encode()
-	body := strings.NewReader(form.Encode())
-
-	req, _ := http.NewRequest("PUT", u.String(), body)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-
-	return req
-}
-
-type deleteAction struct {
-	Prefix    string
-	Key       string
-	PrevValue string
-	PrevIndex uint64
-	Dir       bool
-	Recursive bool
-}
-
-func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Key)
-
-	params := u.Query()
-	if a.PrevValue != "" {
-		params.Set("prevValue", a.PrevValue)
-	}
-	if a.PrevIndex != 0 {
-		params.Set("prevIndex", strconv.FormatUint(a.PrevIndex, 10))
-	}
-	if a.Dir {
-		params.Set("dir", "true")
-	}
-	if a.Recursive {
-		params.Set("recursive", "true")
-	}
-	u.RawQuery = params.Encode()
-
-	req, _ := http.NewRequest("DELETE", u.String(), nil)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-
-	return req
-}
-
-type createInOrderAction struct {
-	Prefix string
-	Dir    string
-	Value  string
-	TTL    time.Duration
-}
-
-func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request {
-	u := v2KeysURL(ep, a.Prefix, a.Dir)
-
-	form := url.Values{}
-	form.Add("value", a.Value)
-	if a.TTL > 0 {
-		form.Add("ttl", strconv.FormatUint(uint64(a.TTL.Seconds()), 10))
-	}
-	body := strings.NewReader(form.Encode())
-
-	req, _ := http.NewRequest("POST", u.String(), body)
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-	return req
-}
-
-func unmarshalHTTPResponse(code int, header http.Header, body []byte) (res *Response, err error) {
-	switch code {
-	case http.StatusOK, http.StatusCreated:
-		if len(body) == 0 {
-			return nil, ErrEmptyBody
-		}
-		res, err = unmarshalSuccessfulKeysResponse(header, body)
-	default:
-		err = unmarshalFailedKeysResponse(body)
-	}
-	return res, err
-}
-
-var jsonIterator = caseSensitiveJsonIterator()
-
-func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*Response, error) {
-	var res Response
-	err := jsonIterator.Unmarshal(body, &res)
-	if err != nil {
-		return nil, ErrInvalidJSON
-	}
-	if header.Get("X-Etcd-Index") != "" {
-		res.Index, err = strconv.ParseUint(header.Get("X-Etcd-Index"), 10, 64)
-		if err != nil {
-			return nil, err
-		}
-	}
-	res.ClusterID = header.Get("X-Etcd-Cluster-ID")
-	return &res, nil
-}
-
-func unmarshalFailedKeysResponse(body []byte) error {
-	var etcdErr Error
-	if err := json.Unmarshal(body, &etcdErr); err != nil {
-		return ErrInvalidJSON
-	}
-	return etcdErr
-}
diff --git a/vendor/go.etcd.io/etcd/client/members.go b/vendor/go.etcd.io/etcd/client/members.go
deleted file mode 100644
index 657131a..0000000
--- a/vendor/go.etcd.io/etcd/client/members.go
+++ /dev/null
@@ -1,303 +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 client
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"net/url"
-	"path"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-var (
-	defaultV2MembersPrefix = "/v2/members"
-	defaultLeaderSuffix    = "/leader"
-)
-
-type Member struct {
-	// ID is the unique identifier of this Member.
-	ID string `json:"id"`
-
-	// Name is a human-readable, non-unique identifier of this Member.
-	Name string `json:"name"`
-
-	// PeerURLs represents the HTTP(S) endpoints this Member uses to
-	// participate in etcd's consensus protocol.
-	PeerURLs []string `json:"peerURLs"`
-
-	// ClientURLs represents the HTTP(S) endpoints on which this Member
-	// serves its client-facing APIs.
-	ClientURLs []string `json:"clientURLs"`
-}
-
-type memberCollection []Member
-
-func (c *memberCollection) UnmarshalJSON(data []byte) error {
-	d := struct {
-		Members []Member
-	}{}
-
-	if err := json.Unmarshal(data, &d); err != nil {
-		return err
-	}
-
-	if d.Members == nil {
-		*c = make([]Member, 0)
-		return nil
-	}
-
-	*c = d.Members
-	return nil
-}
-
-type memberCreateOrUpdateRequest struct {
-	PeerURLs types.URLs
-}
-
-func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) {
-	s := struct {
-		PeerURLs []string `json:"peerURLs"`
-	}{
-		PeerURLs: make([]string, len(m.PeerURLs)),
-	}
-
-	for i, u := range m.PeerURLs {
-		s.PeerURLs[i] = u.String()
-	}
-
-	return json.Marshal(&s)
-}
-
-// NewMembersAPI constructs a new MembersAPI that uses HTTP to
-// interact with etcd's membership API.
-func NewMembersAPI(c Client) MembersAPI {
-	return &httpMembersAPI{
-		client: c,
-	}
-}
-
-type MembersAPI interface {
-	// List enumerates the current cluster membership.
-	List(ctx context.Context) ([]Member, error)
-
-	// Add instructs etcd to accept a new Member into the cluster.
-	Add(ctx context.Context, peerURL string) (*Member, error)
-
-	// Remove demotes an existing Member out of the cluster.
-	Remove(ctx context.Context, mID string) error
-
-	// Update instructs etcd to update an existing Member in the cluster.
-	Update(ctx context.Context, mID string, peerURLs []string) error
-
-	// Leader gets current leader of the cluster
-	Leader(ctx context.Context) (*Member, error)
-}
-
-type httpMembersAPI struct {
-	client httpClient
-}
-
-func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) {
-	req := &membersAPIActionList{}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-
-	var mCollection memberCollection
-	if err := json.Unmarshal(body, &mCollection); err != nil {
-		return nil, err
-	}
-
-	return []Member(mCollection), nil
-}
-
-func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, error) {
-	urls, err := types.NewURLs([]string{peerURL})
-	if err != nil {
-		return nil, err
-	}
-
-	req := &membersAPIActionAdd{peerURLs: urls}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusCreated, http.StatusConflict); err != nil {
-		return nil, err
-	}
-
-	if resp.StatusCode != http.StatusCreated {
-		var merr membersError
-		if err := json.Unmarshal(body, &merr); err != nil {
-			return nil, err
-		}
-		return nil, merr
-	}
-
-	var memb Member
-	if err := json.Unmarshal(body, &memb); err != nil {
-		return nil, err
-	}
-
-	return &memb, nil
-}
-
-func (m *httpMembersAPI) Update(ctx context.Context, memberID string, peerURLs []string) error {
-	urls, err := types.NewURLs(peerURLs)
-	if err != nil {
-		return err
-	}
-
-	req := &membersAPIActionUpdate{peerURLs: urls, memberID: memberID}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusNotFound, http.StatusConflict); err != nil {
-		return err
-	}
-
-	if resp.StatusCode != http.StatusNoContent {
-		var merr membersError
-		if err := json.Unmarshal(body, &merr); err != nil {
-			return err
-		}
-		return merr
-	}
-
-	return nil
-}
-
-func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error {
-	req := &membersAPIActionRemove{memberID: memberID}
-	resp, _, err := m.client.Do(ctx, req)
-	if err != nil {
-		return err
-	}
-
-	return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone)
-}
-
-func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) {
-	req := &membersAPIActionLeader{}
-	resp, body, err := m.client.Do(ctx, req)
-	if err != nil {
-		return nil, err
-	}
-
-	if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil {
-		return nil, err
-	}
-
-	var leader Member
-	if err := json.Unmarshal(body, &leader); err != nil {
-		return nil, err
-	}
-
-	return &leader, nil
-}
-
-type membersAPIActionList struct{}
-
-func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-type membersAPIActionRemove struct {
-	memberID string
-}
-
-func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	u.Path = path.Join(u.Path, d.memberID)
-	req, _ := http.NewRequest("DELETE", u.String(), nil)
-	return req
-}
-
-type membersAPIActionAdd struct {
-	peerURLs types.URLs
-}
-
-func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
-	b, _ := json.Marshal(&m)
-	req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b))
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-type membersAPIActionUpdate struct {
-	memberID string
-	peerURLs types.URLs
-}
-
-func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
-	u.Path = path.Join(u.Path, a.memberID)
-	b, _ := json.Marshal(&m)
-	req, _ := http.NewRequest("PUT", u.String(), bytes.NewReader(b))
-	req.Header.Set("Content-Type", "application/json")
-	return req
-}
-
-func assertStatusCode(got int, want ...int) (err error) {
-	for _, w := range want {
-		if w == got {
-			return nil
-		}
-	}
-	return fmt.Errorf("unexpected status code %d", got)
-}
-
-type membersAPIActionLeader struct{}
-
-func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request {
-	u := v2MembersURL(ep)
-	u.Path = path.Join(u.Path, defaultLeaderSuffix)
-	req, _ := http.NewRequest("GET", u.String(), nil)
-	return req
-}
-
-// v2MembersURL add the necessary path to the provided endpoint
-// to route requests to the default v2 members API.
-func v2MembersURL(ep url.URL) *url.URL {
-	ep.Path = path.Join(ep.Path, defaultV2MembersPrefix)
-	return &ep
-}
-
-type membersError struct {
-	Message string `json:"message"`
-	Code    int    `json:"-"`
-}
-
-func (e membersError) Error() string {
-	return e.Message
-}
diff --git a/vendor/go.etcd.io/etcd/client/util.go b/vendor/go.etcd.io/etcd/client/util.go
deleted file mode 100644
index 15a8bab..0000000
--- a/vendor/go.etcd.io/etcd/client/util.go
+++ /dev/null
@@ -1,53 +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 client
-
-import (
-	"regexp"
-)
-
-var (
-	roleNotFoundRegExp *regexp.Regexp
-	userNotFoundRegExp *regexp.Regexp
-)
-
-func init() {
-	roleNotFoundRegExp = regexp.MustCompile("auth: Role .* does not exist.")
-	userNotFoundRegExp = regexp.MustCompile("auth: User .* does not exist.")
-}
-
-// IsKeyNotFound returns true if the error code is ErrorCodeKeyNotFound.
-func IsKeyNotFound(err error) bool {
-	if cErr, ok := err.(Error); ok {
-		return cErr.Code == ErrorCodeKeyNotFound
-	}
-	return false
-}
-
-// IsRoleNotFound returns true if the error means role not found of v2 API.
-func IsRoleNotFound(err error) bool {
-	if ae, ok := err.(authError); ok {
-		return roleNotFoundRegExp.MatchString(ae.Message)
-	}
-	return false
-}
-
-// IsUserNotFound returns true if the error means user not found of v2 API.
-func IsUserNotFound(err error) bool {
-	if ae, ok := err.(authError); ok {
-		return userNotFoundRegExp.MatchString(ae.Message)
-	}
-	return false
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/README.md b/vendor/go.etcd.io/etcd/clientv3/README.md
deleted file mode 100644
index 6c6fe7c..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/README.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# etcd/clientv3
-
-[![Docs](https://img.shields.io/badge/docs-latest-green.svg)](https://etcd.io/docs)
-[![Godoc](https://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/go.etcd.io/etcd/clientv3)
-
-`etcd/clientv3` is the official Go etcd client for v3.
-
-## Install
-
-```bash
-go get go.etcd.io/etcd/clientv3
-```
-
-## Get started
-
-Create client using `clientv3.New`:
-
-```go
-cli, err := clientv3.New(clientv3.Config{
-	Endpoints:   []string{"localhost:2379", "localhost:22379", "localhost:32379"},
-	DialTimeout: 5 * time.Second,
-})
-if err != nil {
-	// handle error!
-}
-defer cli.Close()
-```
-
-etcd v3 uses [`gRPC`](https://www.grpc.io) for remote procedure calls. And `clientv3` uses
-[`grpc-go`](https://github.com/grpc/grpc-go) to connect to etcd. Make sure to close the client after using it.
-If the client is not closed, the connection will have leaky goroutines. To specify client request timeout,
-pass `context.WithTimeout` to APIs:
-
-```go
-ctx, cancel := context.WithTimeout(context.Background(), timeout)
-resp, err := cli.Put(ctx, "sample_key", "sample_value")
-cancel()
-if err != nil {
-    // handle error!
-}
-// use the response
-```
-
-For full compatibility, it is recommended to vendor builds using etcd's vendored packages, using tools like `golang/dep`, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories).
-
-## Error Handling
-
-etcd client returns 2 types of errors:
-
-1. context error: canceled or deadline exceeded.
-2. gRPC error: see [api/v3rpc/rpctypes](https://godoc.org/go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes).
-
-Here is the example code to handle client errors:
-
-```go
-resp, err := cli.Put(ctx, "", "")
-if err != nil {
-	switch err {
-	case context.Canceled:
-		log.Fatalf("ctx is canceled by another routine: %v", err)
-	case context.DeadlineExceeded:
-		log.Fatalf("ctx is attached with a deadline is exceeded: %v", err)
-	case rpctypes.ErrEmptyKey:
-		log.Fatalf("client-side error: %v", err)
-	default:
-		log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err)
-	}
-}
-```
-
-## Metrics
-
-The etcd client optionally exposes RPC metrics through [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus). See the [examples](https://github.com/etcd-io/etcd/blob/master/clientv3/example_metrics_test.go).
-
-## Namespacing
-
-The [namespace](https://godoc.org/go.etcd.io/etcd/clientv3/namespace) package provides `clientv3` interface wrappers to transparently isolate client requests to a user-defined prefix.
-
-## Request size limit
-
-Client request size limit is configurable via `clientv3.Config.MaxCallSendMsgSize` and `MaxCallRecvMsgSize` in bytes. If none given, client request send limit defaults to 2 MiB including gRPC overhead bytes. And receive limit defaults to `math.MaxInt32`.
-
-## Examples
-
-More code examples can be found at [GoDoc](https://godoc.org/go.etcd.io/etcd/clientv3).
diff --git a/vendor/go.etcd.io/etcd/clientv3/auth.go b/vendor/go.etcd.io/etcd/clientv3/auth.go
index c954f1b..edccf1a 100644
--- a/vendor/go.etcd.io/etcd/clientv3/auth.go
+++ b/vendor/go.etcd.io/etcd/clientv3/auth.go
@@ -19,8 +19,9 @@
 	"fmt"
 	"strings"
 
-	"go.etcd.io/etcd/auth/authpb"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/auth/authpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+
 	"google.golang.org/grpc"
 )
 
@@ -52,8 +53,6 @@
 	PermReadWrite = authpb.READWRITE
 )
 
-type UserAddOptions authpb.UserAddOptions
-
 type Auth interface {
 	// AuthEnable enables auth of an etcd cluster.
 	AuthEnable(ctx context.Context) (*AuthEnableResponse, error)
@@ -64,9 +63,6 @@
 	// UserAdd adds a new user to an etcd cluster.
 	UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)
 
-	// UserAddWithOptions adds a new user to an etcd cluster with some options.
-	UserAddWithOptions(ctx context.Context, name string, password string, opt *UserAddOptions) (*AuthUserAddResponse, error)
-
 	// UserDelete deletes a user from an etcd cluster.
 	UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error)
 
@@ -104,75 +100,70 @@
 	RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error)
 }
 
-type authClient struct {
+type auth struct {
 	remote   pb.AuthClient
 	callOpts []grpc.CallOption
 }
 
 func NewAuth(c *Client) Auth {
-	api := &authClient{remote: RetryAuthClient(c)}
+	api := &auth{remote: RetryAuthClient(c)}
 	if c != nil {
 		api.callOpts = c.callOpts
 	}
 	return api
 }
 
-func (auth *authClient) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
+func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) {
 	resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}, auth.callOpts...)
 	return (*AuthEnableResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
+func (auth *auth) AuthDisable(ctx context.Context) (*AuthDisableResponse, error) {
 	resp, err := auth.remote.AuthDisable(ctx, &pb.AuthDisableRequest{}, auth.callOpts...)
 	return (*AuthDisableResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
-	resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: &authpb.UserAddOptions{NoPassword: false}}, auth.callOpts...)
+func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
+	resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}, auth.callOpts...)
 	return (*AuthUserAddResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserAddWithOptions(ctx context.Context, name string, password string, options *UserAddOptions) (*AuthUserAddResponse, error) {
-	resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: (*authpb.UserAddOptions)(options)}, auth.callOpts...)
-	return (*AuthUserAddResponse)(resp), toErr(ctx, err)
-}
-
-func (auth *authClient) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
+func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) {
 	resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}, auth.callOpts...)
 	return (*AuthUserDeleteResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
+func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) {
 	resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}, auth.callOpts...)
 	return (*AuthUserChangePasswordResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
+func (auth *auth) UserGrantRole(ctx context.Context, user string, role string) (*AuthUserGrantRoleResponse, error) {
 	resp, err := auth.remote.UserGrantRole(ctx, &pb.AuthUserGrantRoleRequest{User: user, Role: role}, auth.callOpts...)
 	return (*AuthUserGrantRoleResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
+func (auth *auth) UserGet(ctx context.Context, name string) (*AuthUserGetResponse, error) {
 	resp, err := auth.remote.UserGet(ctx, &pb.AuthUserGetRequest{Name: name}, auth.callOpts...)
 	return (*AuthUserGetResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserList(ctx context.Context) (*AuthUserListResponse, error) {
+func (auth *auth) UserList(ctx context.Context) (*AuthUserListResponse, error) {
 	resp, err := auth.remote.UserList(ctx, &pb.AuthUserListRequest{}, auth.callOpts...)
 	return (*AuthUserListResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
+func (auth *auth) UserRevokeRole(ctx context.Context, name string, role string) (*AuthUserRevokeRoleResponse, error) {
 	resp, err := auth.remote.UserRevokeRole(ctx, &pb.AuthUserRevokeRoleRequest{Name: name, Role: role}, auth.callOpts...)
 	return (*AuthUserRevokeRoleResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
+func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) {
 	resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}, auth.callOpts...)
 	return (*AuthRoleAddResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
+func (auth *auth) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType PermissionType) (*AuthRoleGrantPermissionResponse, error) {
 	perm := &authpb.Permission{
 		Key:      []byte(key),
 		RangeEnd: []byte(rangeEnd),
@@ -182,22 +173,22 @@
 	return (*AuthRoleGrantPermissionResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
+func (auth *auth) RoleGet(ctx context.Context, role string) (*AuthRoleGetResponse, error) {
 	resp, err := auth.remote.RoleGet(ctx, &pb.AuthRoleGetRequest{Role: role}, auth.callOpts...)
 	return (*AuthRoleGetResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
+func (auth *auth) RoleList(ctx context.Context) (*AuthRoleListResponse, error) {
 	resp, err := auth.remote.RoleList(ctx, &pb.AuthRoleListRequest{}, auth.callOpts...)
 	return (*AuthRoleListResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
-	resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: []byte(key), RangeEnd: []byte(rangeEnd)}, auth.callOpts...)
+func (auth *auth) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*AuthRoleRevokePermissionResponse, error) {
+	resp, err := auth.remote.RoleRevokePermission(ctx, &pb.AuthRoleRevokePermissionRequest{Role: role, Key: key, RangeEnd: rangeEnd}, auth.callOpts...)
 	return (*AuthRoleRevokePermissionResponse)(resp), toErr(ctx, err)
 }
 
-func (auth *authClient) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
+func (auth *auth) RoleDelete(ctx context.Context, role string) (*AuthRoleDeleteResponse, error) {
 	resp, err := auth.remote.RoleDelete(ctx, &pb.AuthRoleDeleteRequest{Role: role}, auth.callOpts...)
 	return (*AuthRoleDeleteResponse)(resp), toErr(ctx, err)
 }
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/balancer.go b/vendor/go.etcd.io/etcd/clientv3/balancer/balancer.go
deleted file mode 100644
index d02a7ee..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/balancer.go
+++ /dev/null
@@ -1,293 +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 balancer implements client balancer.
-package balancer
-
-import (
-	"strconv"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/clientv3/balancer/connectivity"
-	"go.etcd.io/etcd/clientv3/balancer/picker"
-
-	"go.uber.org/zap"
-	"google.golang.org/grpc/balancer"
-	grpcconnectivity "google.golang.org/grpc/connectivity"
-	"google.golang.org/grpc/resolver"
-	_ "google.golang.org/grpc/resolver/dns"         // register DNS resolver
-	_ "google.golang.org/grpc/resolver/passthrough" // register passthrough resolver
-)
-
-// Config defines balancer configurations.
-type Config struct {
-	// Policy configures balancer policy.
-	Policy picker.Policy
-
-	// Picker implements gRPC picker.
-	// Leave empty if "Policy" field is not custom.
-	// TODO: currently custom policy is not supported.
-	// Picker picker.Picker
-
-	// Name defines an additional name for balancer.
-	// Useful for balancer testing to avoid register conflicts.
-	// If empty, defaults to policy name.
-	Name string
-
-	// Logger configures balancer logging.
-	// If nil, logs are discarded.
-	Logger *zap.Logger
-}
-
-// RegisterBuilder creates and registers a builder. Since this function calls balancer.Register, it
-// must be invoked at initialization time.
-func RegisterBuilder(cfg Config) {
-	bb := &builder{cfg}
-	balancer.Register(bb)
-
-	bb.cfg.Logger.Debug(
-		"registered balancer",
-		zap.String("policy", bb.cfg.Policy.String()),
-		zap.String("name", bb.cfg.Name),
-	)
-}
-
-type builder struct {
-	cfg Config
-}
-
-// Build is called initially when creating "ccBalancerWrapper".
-// "grpc.Dial" is called to this client connection.
-// Then, resolved addresses will be handled via "HandleResolvedAddrs".
-func (b *builder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
-	bb := &baseBalancer{
-		id:     strconv.FormatInt(time.Now().UnixNano(), 36),
-		policy: b.cfg.Policy,
-		name:   b.cfg.Name,
-		lg:     b.cfg.Logger,
-
-		addrToSc: make(map[resolver.Address]balancer.SubConn),
-		scToAddr: make(map[balancer.SubConn]resolver.Address),
-		scToSt:   make(map[balancer.SubConn]grpcconnectivity.State),
-
-		currentConn:          nil,
-		connectivityRecorder: connectivity.New(b.cfg.Logger),
-
-		// initialize picker always returns "ErrNoSubConnAvailable"
-		picker: picker.NewErr(balancer.ErrNoSubConnAvailable),
-	}
-
-	// TODO: support multiple connections
-	bb.mu.Lock()
-	bb.currentConn = cc
-	bb.mu.Unlock()
-
-	bb.lg.Info(
-		"built balancer",
-		zap.String("balancer-id", bb.id),
-		zap.String("policy", bb.policy.String()),
-		zap.String("resolver-target", cc.Target()),
-	)
-	return bb
-}
-
-// Name implements "grpc/balancer.Builder" interface.
-func (b *builder) Name() string { return b.cfg.Name }
-
-// Balancer defines client balancer interface.
-type Balancer interface {
-	// Balancer is called on specified client connection. Client initiates gRPC
-	// connection with "grpc.Dial(addr, grpc.WithBalancerName)", and then those resolved
-	// addresses are passed to "grpc/balancer.Balancer.HandleResolvedAddrs".
-	// For each resolved address, balancer calls "balancer.ClientConn.NewSubConn".
-	// "grpc/balancer.Balancer.HandleSubConnStateChange" is called when connectivity state
-	// changes, thus requires failover logic in this method.
-	balancer.Balancer
-
-	// Picker calls "Pick" for every client request.
-	picker.Picker
-}
-
-type baseBalancer struct {
-	id     string
-	policy picker.Policy
-	name   string
-	lg     *zap.Logger
-
-	mu sync.RWMutex
-
-	addrToSc map[resolver.Address]balancer.SubConn
-	scToAddr map[balancer.SubConn]resolver.Address
-	scToSt   map[balancer.SubConn]grpcconnectivity.State
-
-	currentConn          balancer.ClientConn
-	connectivityRecorder connectivity.Recorder
-
-	picker picker.Picker
-}
-
-// HandleResolvedAddrs implements "grpc/balancer.Balancer" interface.
-// gRPC sends initial or updated resolved addresses from "Build".
-func (bb *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
-	if err != nil {
-		bb.lg.Warn("HandleResolvedAddrs called with error", zap.String("balancer-id", bb.id), zap.Error(err))
-		return
-	}
-	bb.lg.Info("resolved",
-		zap.String("picker", bb.picker.String()),
-		zap.String("balancer-id", bb.id),
-		zap.Strings("addresses", addrsToStrings(addrs)),
-	)
-
-	bb.mu.Lock()
-	defer bb.mu.Unlock()
-
-	resolved := make(map[resolver.Address]struct{})
-	for _, addr := range addrs {
-		resolved[addr] = struct{}{}
-		if _, ok := bb.addrToSc[addr]; !ok {
-			sc, err := bb.currentConn.NewSubConn([]resolver.Address{addr}, balancer.NewSubConnOptions{})
-			if err != nil {
-				bb.lg.Warn("NewSubConn failed", zap.String("picker", bb.picker.String()), zap.String("balancer-id", bb.id), zap.Error(err), zap.String("address", addr.Addr))
-				continue
-			}
-			bb.lg.Info("created subconn", zap.String("address", addr.Addr))
-			bb.addrToSc[addr] = sc
-			bb.scToAddr[sc] = addr
-			bb.scToSt[sc] = grpcconnectivity.Idle
-			sc.Connect()
-		}
-	}
-
-	for addr, sc := range bb.addrToSc {
-		if _, ok := resolved[addr]; !ok {
-			// was removed by resolver or failed to create subconn
-			bb.currentConn.RemoveSubConn(sc)
-			delete(bb.addrToSc, addr)
-
-			bb.lg.Info(
-				"removed subconn",
-				zap.String("picker", bb.picker.String()),
-				zap.String("balancer-id", bb.id),
-				zap.String("address", addr.Addr),
-				zap.String("subconn", scToString(sc)),
-			)
-
-			// Keep the state of this sc in bb.scToSt until sc's state becomes Shutdown.
-			// The entry will be deleted in HandleSubConnStateChange.
-			// (DO NOT) delete(bb.scToAddr, sc)
-			// (DO NOT) delete(bb.scToSt, sc)
-		}
-	}
-}
-
-// HandleSubConnStateChange implements "grpc/balancer.Balancer" interface.
-func (bb *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s grpcconnectivity.State) {
-	bb.mu.Lock()
-	defer bb.mu.Unlock()
-
-	old, ok := bb.scToSt[sc]
-	if !ok {
-		bb.lg.Warn(
-			"state change for an unknown subconn",
-			zap.String("picker", bb.picker.String()),
-			zap.String("balancer-id", bb.id),
-			zap.String("subconn", scToString(sc)),
-			zap.Int("subconn-size", len(bb.scToAddr)),
-			zap.String("state", s.String()),
-		)
-		return
-	}
-
-	bb.lg.Info(
-		"state changed",
-		zap.String("picker", bb.picker.String()),
-		zap.String("balancer-id", bb.id),
-		zap.Bool("connected", s == grpcconnectivity.Ready),
-		zap.String("subconn", scToString(sc)),
-		zap.Int("subconn-size", len(bb.scToAddr)),
-		zap.String("address", bb.scToAddr[sc].Addr),
-		zap.String("old-state", old.String()),
-		zap.String("new-state", s.String()),
-	)
-
-	bb.scToSt[sc] = s
-	switch s {
-	case grpcconnectivity.Idle:
-		sc.Connect()
-	case grpcconnectivity.Shutdown:
-		// When an address was removed by resolver, b called RemoveSubConn but
-		// kept the sc's state in scToSt. Remove state for this sc here.
-		delete(bb.scToAddr, sc)
-		delete(bb.scToSt, sc)
-	}
-
-	oldAggrState := bb.connectivityRecorder.GetCurrentState()
-	bb.connectivityRecorder.RecordTransition(old, s)
-
-	// Update balancer picker when one of the following happens:
-	//  - this sc became ready from not-ready
-	//  - this sc became not-ready from ready
-	//  - the aggregated state of balancer became TransientFailure from non-TransientFailure
-	//  - the aggregated state of balancer became non-TransientFailure from TransientFailure
-	if (s == grpcconnectivity.Ready) != (old == grpcconnectivity.Ready) ||
-		(bb.connectivityRecorder.GetCurrentState() == grpcconnectivity.TransientFailure) != (oldAggrState == grpcconnectivity.TransientFailure) {
-		bb.updatePicker()
-	}
-
-	bb.currentConn.UpdateBalancerState(bb.connectivityRecorder.GetCurrentState(), bb.picker)
-}
-
-func (bb *baseBalancer) updatePicker() {
-	if bb.connectivityRecorder.GetCurrentState() == grpcconnectivity.TransientFailure {
-		bb.picker = picker.NewErr(balancer.ErrTransientFailure)
-		bb.lg.Info(
-			"updated picker to transient error picker",
-			zap.String("picker", bb.picker.String()),
-			zap.String("balancer-id", bb.id),
-			zap.String("policy", bb.policy.String()),
-		)
-		return
-	}
-
-	// only pass ready subconns to picker
-	scToAddr := make(map[balancer.SubConn]resolver.Address)
-	for addr, sc := range bb.addrToSc {
-		if st, ok := bb.scToSt[sc]; ok && st == grpcconnectivity.Ready {
-			scToAddr[sc] = addr
-		}
-	}
-
-	bb.picker = picker.New(picker.Config{
-		Policy:                   bb.policy,
-		Logger:                   bb.lg,
-		SubConnToResolverAddress: scToAddr,
-	})
-	bb.lg.Info(
-		"updated picker",
-		zap.String("picker", bb.picker.String()),
-		zap.String("balancer-id", bb.id),
-		zap.String("policy", bb.policy.String()),
-		zap.Strings("subconn-ready", scsToStrings(scToAddr)),
-		zap.Int("subconn-size", len(scToAddr)),
-	)
-}
-
-// Close implements "grpc/balancer.Balancer" interface.
-// Close is a nop because base balancer doesn't have internal state to clean up,
-// and it doesn't need to call RemoveSubConn for the SubConns.
-func (bb *baseBalancer) Close() {
-	// TODO
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/connectivity/connectivity.go b/vendor/go.etcd.io/etcd/clientv3/balancer/connectivity/connectivity.go
deleted file mode 100644
index 4c4ad36..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/connectivity/connectivity.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 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 connectivity implements client connectivity operations.
-package connectivity
-
-import (
-	"sync"
-
-	"go.uber.org/zap"
-	"google.golang.org/grpc/connectivity"
-)
-
-// Recorder records gRPC connectivity.
-type Recorder interface {
-	GetCurrentState() connectivity.State
-	RecordTransition(oldState, newState connectivity.State)
-}
-
-// New returns a new Recorder.
-func New(lg *zap.Logger) Recorder {
-	return &recorder{lg: lg}
-}
-
-// recorder takes the connectivity states of multiple SubConns
-// and returns one aggregated connectivity state.
-// ref. https://github.com/grpc/grpc-go/blob/master/balancer/balancer.go
-type recorder struct {
-	lg *zap.Logger
-
-	mu sync.RWMutex
-
-	cur connectivity.State
-
-	numReady            uint64 // Number of addrConns in ready state.
-	numConnecting       uint64 // Number of addrConns in connecting state.
-	numTransientFailure uint64 // Number of addrConns in transientFailure.
-}
-
-func (rc *recorder) GetCurrentState() (state connectivity.State) {
-	rc.mu.RLock()
-	defer rc.mu.RUnlock()
-	return rc.cur
-}
-
-// RecordTransition records state change happening in subConn and based on that
-// it evaluates what aggregated state should be.
-//
-//  - If at least one SubConn in Ready, the aggregated state is Ready;
-//  - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
-//  - Else the aggregated state is TransientFailure.
-//
-// Idle and Shutdown are not considered.
-//
-// ref. https://github.com/grpc/grpc-go/blob/master/balancer/balancer.go
-func (rc *recorder) RecordTransition(oldState, newState connectivity.State) {
-	rc.mu.Lock()
-	defer rc.mu.Unlock()
-
-	for idx, state := range []connectivity.State{oldState, newState} {
-		updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
-		switch state {
-		case connectivity.Ready:
-			rc.numReady += updateVal
-		case connectivity.Connecting:
-			rc.numConnecting += updateVal
-		case connectivity.TransientFailure:
-			rc.numTransientFailure += updateVal
-		default:
-			rc.lg.Warn("connectivity recorder received unknown state", zap.String("connectivity-state", state.String()))
-		}
-	}
-
-	switch { // must be exclusive, no overlap
-	case rc.numReady > 0:
-		rc.cur = connectivity.Ready
-	case rc.numConnecting > 0:
-		rc.cur = connectivity.Connecting
-	default:
-		rc.cur = connectivity.TransientFailure
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/doc.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/doc.go
deleted file mode 100644
index 35dabf5..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/doc.go
+++ /dev/null
@@ -1,16 +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 picker defines/implements client balancer picker policy.
-package picker
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go
deleted file mode 100644
index 9e04378..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/err.go
+++ /dev/null
@@ -1,39 +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 picker
-
-import (
-	"context"
-
-	"google.golang.org/grpc/balancer"
-)
-
-// NewErr returns a picker that always returns err on "Pick".
-func NewErr(err error) Picker {
-	return &errPicker{p: Error, err: err}
-}
-
-type errPicker struct {
-	p   Policy
-	err error
-}
-
-func (ep *errPicker) String() string {
-	return ep.p.String()
-}
-
-func (ep *errPicker) Pick(context.Context, balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
-	return nil, nil, ep.err
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/picker.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/picker.go
deleted file mode 100644
index bd1a5d2..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/picker.go
+++ /dev/null
@@ -1,91 +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 picker
-
-import (
-	"fmt"
-
-	"go.uber.org/zap"
-	"google.golang.org/grpc/balancer"
-	"google.golang.org/grpc/resolver"
-)
-
-// Picker defines balancer Picker methods.
-type Picker interface {
-	balancer.Picker
-	String() string
-}
-
-// Config defines picker configuration.
-type Config struct {
-	// Policy specifies etcd clientv3's built in balancer policy.
-	Policy Policy
-
-	// Logger defines picker logging object.
-	Logger *zap.Logger
-
-	// SubConnToResolverAddress maps each gRPC sub-connection to an address.
-	// Basically, it is a list of addresses that the Picker can pick from.
-	SubConnToResolverAddress map[balancer.SubConn]resolver.Address
-}
-
-// Policy defines balancer picker policy.
-type Policy uint8
-
-const (
-	// Error is error picker policy.
-	Error Policy = iota
-
-	// RoundrobinBalanced balances loads over multiple endpoints
-	// and implements failover in roundrobin fashion.
-	RoundrobinBalanced
-
-	// Custom defines custom balancer picker.
-	// TODO: custom picker is not supported yet.
-	Custom
-)
-
-func (p Policy) String() string {
-	switch p {
-	case Error:
-		return "picker-error"
-
-	case RoundrobinBalanced:
-		return "picker-roundrobin-balanced"
-
-	case Custom:
-		panic("'custom' picker policy is not supported yet")
-
-	default:
-		panic(fmt.Errorf("invalid balancer picker policy (%d)", p))
-	}
-}
-
-// New creates a new Picker.
-func New(cfg Config) Picker {
-	switch cfg.Policy {
-	case Error:
-		panic("'error' picker policy is not supported here; use 'picker.NewErr'")
-
-	case RoundrobinBalanced:
-		return newRoundrobinBalanced(cfg)
-
-	case Custom:
-		panic("'custom' picker policy is not supported yet")
-
-	default:
-		panic(fmt.Errorf("invalid balancer picker policy (%d)", cfg.Policy))
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go b/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go
deleted file mode 100644
index 1b8b285..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/picker/roundrobin_balanced.go
+++ /dev/null
@@ -1,95 +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 picker
-
-import (
-	"context"
-	"sync"
-
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-	"google.golang.org/grpc/balancer"
-	"google.golang.org/grpc/resolver"
-)
-
-// newRoundrobinBalanced returns a new roundrobin balanced picker.
-func newRoundrobinBalanced(cfg Config) Picker {
-	scs := make([]balancer.SubConn, 0, len(cfg.SubConnToResolverAddress))
-	for sc := range cfg.SubConnToResolverAddress {
-		scs = append(scs, sc)
-	}
-	return &rrBalanced{
-		p:        RoundrobinBalanced,
-		lg:       cfg.Logger,
-		scs:      scs,
-		scToAddr: cfg.SubConnToResolverAddress,
-	}
-}
-
-type rrBalanced struct {
-	p Policy
-
-	lg *zap.Logger
-
-	mu       sync.RWMutex
-	next     int
-	scs      []balancer.SubConn
-	scToAddr map[balancer.SubConn]resolver.Address
-}
-
-func (rb *rrBalanced) String() string { return rb.p.String() }
-
-// Pick is called for every client request.
-func (rb *rrBalanced) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
-	rb.mu.RLock()
-	n := len(rb.scs)
-	rb.mu.RUnlock()
-	if n == 0 {
-		return nil, nil, balancer.ErrNoSubConnAvailable
-	}
-
-	rb.mu.Lock()
-	cur := rb.next
-	sc := rb.scs[cur]
-	picked := rb.scToAddr[sc].Addr
-	rb.next = (rb.next + 1) % len(rb.scs)
-	rb.mu.Unlock()
-
-	rb.lg.Debug(
-		"picked",
-		zap.String("picker", rb.p.String()),
-		zap.String("address", picked),
-		zap.Int("subconn-index", cur),
-		zap.Int("subconn-size", n),
-	)
-
-	doneFunc := func(info balancer.DoneInfo) {
-		// TODO: error handling?
-		fss := []zapcore.Field{
-			zap.Error(info.Err),
-			zap.String("picker", rb.p.String()),
-			zap.String("address", picked),
-			zap.Bool("success", info.Err == nil),
-			zap.Bool("bytes-sent", info.BytesSent),
-			zap.Bool("bytes-received", info.BytesReceived),
-		}
-		if info.Err == nil {
-			rb.lg.Debug("balancer done", fss...)
-		} else {
-			rb.lg.Warn("balancer failed", fss...)
-		}
-	}
-	return sc, doneFunc, nil
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go b/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go
deleted file mode 100644
index 1f32039..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/resolver/endpoint/endpoint.go
+++ /dev/null
@@ -1,240 +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 endpoint resolves etcd entpoints using grpc targets of the form 'endpoint://<id>/<endpoint>'.
-package endpoint
-
-import (
-	"fmt"
-	"net/url"
-	"strings"
-	"sync"
-
-	"google.golang.org/grpc/resolver"
-)
-
-const scheme = "endpoint"
-
-var (
-	targetPrefix = fmt.Sprintf("%s://", scheme)
-
-	bldr *builder
-)
-
-func init() {
-	bldr = &builder{
-		resolverGroups: make(map[string]*ResolverGroup),
-	}
-	resolver.Register(bldr)
-}
-
-type builder struct {
-	mu             sync.RWMutex
-	resolverGroups map[string]*ResolverGroup
-}
-
-// NewResolverGroup creates a new ResolverGroup with the given id.
-func NewResolverGroup(id string) (*ResolverGroup, error) {
-	return bldr.newResolverGroup(id)
-}
-
-// ResolverGroup keeps all endpoints of resolvers using a common endpoint://<id>/ target
-// up-to-date.
-type ResolverGroup struct {
-	mu        sync.RWMutex
-	id        string
-	endpoints []string
-	resolvers []*Resolver
-}
-
-func (e *ResolverGroup) addResolver(r *Resolver) {
-	e.mu.Lock()
-	addrs := epsToAddrs(e.endpoints...)
-	e.resolvers = append(e.resolvers, r)
-	e.mu.Unlock()
-	r.cc.NewAddress(addrs)
-}
-
-func (e *ResolverGroup) removeResolver(r *Resolver) {
-	e.mu.Lock()
-	for i, er := range e.resolvers {
-		if er == r {
-			e.resolvers = append(e.resolvers[:i], e.resolvers[i+1:]...)
-			break
-		}
-	}
-	e.mu.Unlock()
-}
-
-// SetEndpoints updates the endpoints for ResolverGroup. All registered resolver are updated
-// immediately with the new endpoints.
-func (e *ResolverGroup) SetEndpoints(endpoints []string) {
-	addrs := epsToAddrs(endpoints...)
-	e.mu.Lock()
-	e.endpoints = endpoints
-	for _, r := range e.resolvers {
-		r.cc.NewAddress(addrs)
-	}
-	e.mu.Unlock()
-}
-
-// Target constructs a endpoint target using the endpoint id of the ResolverGroup.
-func (e *ResolverGroup) Target(endpoint string) string {
-	return Target(e.id, endpoint)
-}
-
-// Target constructs a endpoint resolver target.
-func Target(id, endpoint string) string {
-	return fmt.Sprintf("%s://%s/%s", scheme, id, endpoint)
-}
-
-// IsTarget checks if a given target string in an endpoint resolver target.
-func IsTarget(target string) bool {
-	return strings.HasPrefix(target, "endpoint://")
-}
-
-func (e *ResolverGroup) Close() {
-	bldr.close(e.id)
-}
-
-// Build creates or reuses an etcd resolver for the etcd cluster name identified by the authority part of the target.
-func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
-	if len(target.Authority) < 1 {
-		return nil, fmt.Errorf("'etcd' target scheme requires non-empty authority identifying etcd cluster being routed to")
-	}
-	id := target.Authority
-	es, err := b.getResolverGroup(id)
-	if err != nil {
-		return nil, fmt.Errorf("failed to build resolver: %v", err)
-	}
-	r := &Resolver{
-		endpointID: id,
-		cc:         cc,
-	}
-	es.addResolver(r)
-	return r, nil
-}
-
-func (b *builder) newResolverGroup(id string) (*ResolverGroup, error) {
-	b.mu.RLock()
-	_, ok := b.resolverGroups[id]
-	b.mu.RUnlock()
-	if ok {
-		return nil, fmt.Errorf("Endpoint already exists for id: %s", id)
-	}
-
-	es := &ResolverGroup{id: id}
-	b.mu.Lock()
-	b.resolverGroups[id] = es
-	b.mu.Unlock()
-	return es, nil
-}
-
-func (b *builder) getResolverGroup(id string) (*ResolverGroup, error) {
-	b.mu.RLock()
-	es, ok := b.resolverGroups[id]
-	b.mu.RUnlock()
-	if !ok {
-		return nil, fmt.Errorf("ResolverGroup not found for id: %s", id)
-	}
-	return es, nil
-}
-
-func (b *builder) close(id string) {
-	b.mu.Lock()
-	delete(b.resolverGroups, id)
-	b.mu.Unlock()
-}
-
-func (b *builder) Scheme() string {
-	return scheme
-}
-
-// Resolver provides a resolver for a single etcd cluster, identified by name.
-type Resolver struct {
-	endpointID string
-	cc         resolver.ClientConn
-	sync.RWMutex
-}
-
-// TODO: use balancer.epsToAddrs
-func epsToAddrs(eps ...string) (addrs []resolver.Address) {
-	addrs = make([]resolver.Address, 0, len(eps))
-	for _, ep := range eps {
-		addrs = append(addrs, resolver.Address{Addr: ep})
-	}
-	return addrs
-}
-
-func (*Resolver) ResolveNow(o resolver.ResolveNowOption) {}
-
-func (r *Resolver) Close() {
-	es, err := bldr.getResolverGroup(r.endpointID)
-	if err != nil {
-		return
-	}
-	es.removeResolver(r)
-}
-
-// ParseEndpoint endpoint parses an endpoint of the form
-// (http|https)://<host>*|(unix|unixs)://<path>)
-// and returns a protocol ('tcp' or 'unix'),
-// host (or filepath if a unix socket),
-// scheme (http, https, unix, unixs).
-func ParseEndpoint(endpoint string) (proto string, host string, scheme string) {
-	proto = "tcp"
-	host = endpoint
-	url, uerr := url.Parse(endpoint)
-	if uerr != nil || !strings.Contains(endpoint, "://") {
-		return proto, host, scheme
-	}
-	scheme = url.Scheme
-
-	// strip scheme:// prefix since grpc dials by host
-	host = url.Host
-	switch url.Scheme {
-	case "http", "https":
-	case "unix", "unixs":
-		proto = "unix"
-		host = url.Host + url.Path
-	default:
-		proto, host = "", ""
-	}
-	return proto, host, scheme
-}
-
-// ParseTarget parses a endpoint://<id>/<endpoint> string and returns the parsed id and endpoint.
-// If the target is malformed, an error is returned.
-func ParseTarget(target string) (string, string, error) {
-	noPrefix := strings.TrimPrefix(target, targetPrefix)
-	if noPrefix == target {
-		return "", "", fmt.Errorf("malformed target, %s prefix is required: %s", targetPrefix, target)
-	}
-	parts := strings.SplitN(noPrefix, "/", 2)
-	if len(parts) != 2 {
-		return "", "", fmt.Errorf("malformed target, expected %s://<id>/<endpoint>, but got %s", scheme, target)
-	}
-	return parts[0], parts[1], nil
-}
-
-// ParseHostPort splits a "<host>:<port>" string into the host and port parts.
-// The port part is optional.
-func ParseHostPort(hostPort string) (host string, port string) {
-	parts := strings.SplitN(hostPort, ":", 2)
-	host = parts[0]
-	if len(parts) > 1 {
-		port = parts[1]
-	}
-	return host, port
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/balancer/utils.go b/vendor/go.etcd.io/etcd/clientv3/balancer/utils.go
deleted file mode 100644
index 48eb875..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/balancer/utils.go
+++ /dev/null
@@ -1,68 +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 balancer
-
-import (
-	"fmt"
-	"net/url"
-	"sort"
-	"sync/atomic"
-	"time"
-
-	"google.golang.org/grpc/balancer"
-	"google.golang.org/grpc/resolver"
-)
-
-func scToString(sc balancer.SubConn) string {
-	return fmt.Sprintf("%p", sc)
-}
-
-func scsToStrings(scs map[balancer.SubConn]resolver.Address) (ss []string) {
-	ss = make([]string, 0, len(scs))
-	for sc, a := range scs {
-		ss = append(ss, fmt.Sprintf("%s (%s)", a.Addr, scToString(sc)))
-	}
-	sort.Strings(ss)
-	return ss
-}
-
-func addrsToStrings(addrs []resolver.Address) (ss []string) {
-	ss = make([]string, len(addrs))
-	for i := range addrs {
-		ss[i] = addrs[i].Addr
-	}
-	sort.Strings(ss)
-	return ss
-}
-
-func epsToAddrs(eps ...string) (addrs []resolver.Address) {
-	addrs = make([]resolver.Address, 0, len(eps))
-	for _, ep := range eps {
-		u, err := url.Parse(ep)
-		if err != nil {
-			addrs = append(addrs, resolver.Address{Addr: ep, Type: resolver.Backend})
-			continue
-		}
-		addrs = append(addrs, resolver.Address{Addr: u.Host, Type: resolver.Backend})
-	}
-	return addrs
-}
-
-var genN = new(uint32)
-
-func genName() string {
-	now := time.Now().UnixNano()
-	return fmt.Sprintf("%X%X", now, atomic.AddUint32(genN, 1))
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/client.go b/vendor/go.etcd.io/etcd/clientv3/client.go
index d6000a8..c49e4ba 100644
--- a/vendor/go.etcd.io/etcd/clientv3/client.go
+++ b/vendor/go.etcd.io/etcd/clientv3/client.go
@@ -25,19 +25,19 @@
 	"sync"
 	"time"
 
+	"github.com/coreos/etcd/clientv3/balancer"
+	"github.com/coreos/etcd/clientv3/balancer/picker"
+	"github.com/coreos/etcd/clientv3/balancer/resolver/endpoint"
+	"github.com/coreos/etcd/clientv3/credentials"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+	"github.com/coreos/etcd/pkg/logutil"
+	"github.com/coreos/pkg/capnslog"
 	"github.com/google/uuid"
-	"go.etcd.io/etcd/clientv3/balancer"
-	"go.etcd.io/etcd/clientv3/balancer/picker"
-	"go.etcd.io/etcd/clientv3/balancer/resolver/endpoint"
-	"go.etcd.io/etcd/clientv3/credentials"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	"go.etcd.io/etcd/pkg/logutil"
 	"go.uber.org/zap"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	grpccredentials "google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/keepalive"
-	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
 )
 
@@ -48,6 +48,10 @@
 	roundRobinBalancerName = fmt.Sprintf("etcd-%s", picker.RoundrobinBalanced.String())
 )
 
+var (
+	plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "clientv3")
+)
+
 func init() {
 	lg := zap.NewNop()
 	if os.Getenv("ETCD_CLIENT_DEBUG") != "" {
@@ -129,12 +133,8 @@
 // Close shuts down the client's etcd connections.
 func (c *Client) Close() error {
 	c.cancel()
-	if c.Watcher != nil {
-		c.Watcher.Close()
-	}
-	if c.Lease != nil {
-		c.Lease.Close()
-	}
+	c.Watcher.Close()
+	c.Lease.Close()
 	if c.resolverGroup != nil {
 		c.resolverGroup.Close()
 	}
@@ -230,24 +230,17 @@
 	}
 	opts = append(opts, dopts...)
 
-	// Provide a net dialer that supports cancelation and timeout.
-	f := func(dialEp string, t time.Duration) (net.Conn, error) {
-		proto, host, _ := endpoint.ParseEndpoint(dialEp)
-		select {
-		case <-c.ctx.Done():
-			return nil, c.ctx.Err()
-		default:
-		}
-		dialer := &net.Dialer{Timeout: t}
-		return dialer.DialContext(c.ctx, proto, host)
-	}
-	opts = append(opts, grpc.WithDialer(f))
-
+	dialer := endpoint.Dialer
 	if creds != nil {
 		opts = append(opts, grpc.WithTransportCredentials(creds))
+		// gRPC load balancer workaround. See credentials.transportCredential for details.
+		if credsDialer, ok := creds.(TransportCredentialsWithDialer); ok {
+			dialer = credsDialer.Dialer
+		}
 	} else {
 		opts = append(opts, grpc.WithInsecure())
 	}
+	opts = append(opts, grpc.WithContextDialer(dialer))
 
 	// Interceptor retry and backoff.
 	// TODO: Replace all of clientv3/retry.go with interceptor based retry, or with
@@ -266,7 +259,10 @@
 
 // Dial connects to a single endpoint using the client's config.
 func (c *Client) Dial(ep string) (*grpc.ClientConn, error) {
-	creds := c.directDialCreds(ep)
+	creds, err := c.directDialCreds(ep)
+	if err != nil {
+		return nil, err
+	}
 	// Use the grpc passthrough resolver to directly dial a single endpoint.
 	// This resolver passes through the 'unix' and 'unixs' endpoints schemes used
 	// by etcd without modification, allowing us to directly dial endpoints and
@@ -369,8 +365,8 @@
 	return conn, nil
 }
 
-func (c *Client) directDialCreds(ep string) grpccredentials.TransportCredentials {
-	_, hostPort, scheme := endpoint.ParseEndpoint(ep)
+func (c *Client) directDialCreds(ep string) (grpccredentials.TransportCredentials, error) {
+	_, host, scheme := endpoint.ParseEndpoint(ep)
 	creds := c.creds
 	if len(scheme) != 0 {
 		creds = c.processCreds(scheme)
@@ -379,12 +375,17 @@
 			// Set the server name must to the endpoint hostname without port since grpc
 			// otherwise attempts to check if x509 cert is valid for the full endpoint
 			// including the scheme and port, which fails.
-			host, _ := endpoint.ParseHostPort(hostPort)
-			clone.OverrideServerName(host)
+			overrideServerName, _, err := net.SplitHostPort(host)
+			if err != nil {
+				// Either the host didn't have a port or the host could not be parsed. Either way, continue with the
+				// original host string.
+				overrideServerName = host
+			}
+			clone.OverrideServerName(overrideServerName)
 			creds = clone
 		}
 	}
-	return creds
+	return creds, nil
 }
 
 func (c *Client) dialWithBalancerCreds(ep string) grpccredentials.TransportCredentials {
@@ -396,13 +397,6 @@
 	return creds
 }
 
-// WithRequireLeader requires client requests to only succeed
-// when the cluster has a leader.
-func WithRequireLeader(ctx context.Context) context.Context {
-	md := metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
-	return metadata.NewOutgoingContext(ctx, md)
-}
-
 func newClient(cfg *Config) (*Client, error) {
 	if cfg == nil {
 		cfg = &Config{}
@@ -663,3 +657,9 @@
 	// <= gRPC v1.7.x returns 'errors.New("grpc: the client connection is closing")'
 	return strings.Contains(err.Error(), "grpc: the client connection is closing")
 }
+
+// TransportCredentialsWithDialer is for a gRPC load balancer workaround. See credentials.transportCredential for details.
+type TransportCredentialsWithDialer interface {
+	grpccredentials.TransportCredentials
+	Dialer(ctx context.Context, dialEp string) (net.Conn, error)
+}
diff --git a/vendor/go.etcd.io/etcd/clientv3/cluster.go b/vendor/go.etcd.io/etcd/clientv3/cluster.go
index ce97e5c..785672b 100644
--- a/vendor/go.etcd.io/etcd/clientv3/cluster.go
+++ b/vendor/go.etcd.io/etcd/clientv3/cluster.go
@@ -17,19 +17,18 @@
 import (
 	"context"
 
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/pkg/types"
 
 	"google.golang.org/grpc"
 )
 
 type (
-	Member                pb.Member
-	MemberListResponse    pb.MemberListResponse
-	MemberAddResponse     pb.MemberAddResponse
-	MemberRemoveResponse  pb.MemberRemoveResponse
-	MemberUpdateResponse  pb.MemberUpdateResponse
-	MemberPromoteResponse pb.MemberPromoteResponse
+	Member               pb.Member
+	MemberListResponse   pb.MemberListResponse
+	MemberAddResponse    pb.MemberAddResponse
+	MemberRemoveResponse pb.MemberRemoveResponse
+	MemberUpdateResponse pb.MemberUpdateResponse
 )
 
 type Cluster interface {
@@ -39,17 +38,11 @@
 	// MemberAdd adds a new member into the cluster.
 	MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error)
 
-	// MemberAddAsLearner adds a new learner member into the cluster.
-	MemberAddAsLearner(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error)
-
 	// MemberRemove removes an existing member from the cluster.
 	MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error)
 
 	// MemberUpdate updates the peer addresses of the member.
 	MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error)
-
-	// MemberPromote promotes a member from raft learner (non-voting) to raft voting member.
-	MemberPromote(ctx context.Context, id uint64) (*MemberPromoteResponse, error)
 }
 
 type cluster struct {
@@ -74,23 +67,12 @@
 }
 
 func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
-	return c.memberAdd(ctx, peerAddrs, false)
-}
-
-func (c *cluster) MemberAddAsLearner(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
-	return c.memberAdd(ctx, peerAddrs, true)
-}
-
-func (c *cluster) memberAdd(ctx context.Context, peerAddrs []string, isLearner bool) (*MemberAddResponse, error) {
 	// fail-fast before panic in rafthttp
 	if _, err := types.NewURLs(peerAddrs); err != nil {
 		return nil, err
 	}
 
-	r := &pb.MemberAddRequest{
-		PeerURLs:  peerAddrs,
-		IsLearner: isLearner,
-	}
+	r := &pb.MemberAddRequest{PeerURLs: peerAddrs}
 	resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...)
 	if err != nil {
 		return nil, toErr(ctx, err)
@@ -130,12 +112,3 @@
 	}
 	return nil, toErr(ctx, err)
 }
-
-func (c *cluster) MemberPromote(ctx context.Context, id uint64) (*MemberPromoteResponse, error) {
-	r := &pb.MemberPromoteRequest{ID: id}
-	resp, err := c.remote.MemberPromote(ctx, r, c.callOpts...)
-	if err != nil {
-		return nil, toErr(ctx, err)
-	}
-	return (*MemberPromoteResponse)(resp), nil
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/compact_op.go b/vendor/go.etcd.io/etcd/clientv3/compact_op.go
index 5779713..41e80c1 100644
--- a/vendor/go.etcd.io/etcd/clientv3/compact_op.go
+++ b/vendor/go.etcd.io/etcd/clientv3/compact_op.go
@@ -15,7 +15,7 @@
 package clientv3
 
 import (
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 )
 
 // CompactOp represents a compact operation.
diff --git a/vendor/go.etcd.io/etcd/clientv3/compare.go b/vendor/go.etcd.io/etcd/clientv3/compare.go
index 01ed68e..b5f0a25 100644
--- a/vendor/go.etcd.io/etcd/clientv3/compare.go
+++ b/vendor/go.etcd.io/etcd/clientv3/compare.go
@@ -15,7 +15,7 @@
 package clientv3
 
 import (
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 )
 
 type CompareTarget int
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/doc.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/doc.go
deleted file mode 100644
index dcdbf51..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/doc.go
+++ /dev/null
@@ -1,17 +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 concurrency implements concurrency operations on top of
-// etcd such as distributed locks, barriers, and elections.
-package concurrency
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/election.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/election.go
deleted file mode 100644
index 2521db6..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/election.go
+++ /dev/null
@@ -1,254 +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 concurrency
-
-import (
-	"context"
-	"errors"
-	"fmt"
-
-	v3 "go.etcd.io/etcd/clientv3"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-var (
-	ErrElectionNotLeader = errors.New("election: not leader")
-	ErrElectionNoLeader  = errors.New("election: no leader")
-)
-
-type Election struct {
-	session *Session
-
-	keyPrefix string
-
-	leaderKey     string
-	leaderRev     int64
-	leaderSession *Session
-	hdr           *pb.ResponseHeader
-}
-
-// NewElection returns a new election on a given key prefix.
-func NewElection(s *Session, pfx string) *Election {
-	return &Election{session: s, keyPrefix: pfx + "/"}
-}
-
-// ResumeElection initializes an election with a known leader.
-func ResumeElection(s *Session, pfx string, leaderKey string, leaderRev int64) *Election {
-	return &Election{
-		keyPrefix:     pfx,
-		session:       s,
-		leaderKey:     leaderKey,
-		leaderRev:     leaderRev,
-		leaderSession: s,
-	}
-}
-
-// Campaign puts a value as eligible for the election on the prefix
-// key.
-// Multiple sessions can participate in the election for the
-// same prefix, but only one can be the leader at a time.
-//
-// If the context is 'context.TODO()/context.Background()', the Campaign
-// will continue to be blocked for other keys to be deleted, unless server
-// returns a non-recoverable error (e.g. ErrCompacted).
-// Otherwise, until the context is not cancelled or timed-out, Campaign will
-// continue to be blocked until it becomes the leader.
-func (e *Election) Campaign(ctx context.Context, val string) error {
-	s := e.session
-	client := e.session.Client()
-
-	k := fmt.Sprintf("%s%x", e.keyPrefix, s.Lease())
-	txn := client.Txn(ctx).If(v3.Compare(v3.CreateRevision(k), "=", 0))
-	txn = txn.Then(v3.OpPut(k, val, v3.WithLease(s.Lease())))
-	txn = txn.Else(v3.OpGet(k))
-	resp, err := txn.Commit()
-	if err != nil {
-		return err
-	}
-	e.leaderKey, e.leaderRev, e.leaderSession = k, resp.Header.Revision, s
-	if !resp.Succeeded {
-		kv := resp.Responses[0].GetResponseRange().Kvs[0]
-		e.leaderRev = kv.CreateRevision
-		if string(kv.Value) != val {
-			if err = e.Proclaim(ctx, val); err != nil {
-				e.Resign(ctx)
-				return err
-			}
-		}
-	}
-
-	_, err = waitDeletes(ctx, client, e.keyPrefix, e.leaderRev-1)
-	if err != nil {
-		// clean up in case of context cancel
-		select {
-		case <-ctx.Done():
-			e.Resign(client.Ctx())
-		default:
-			e.leaderSession = nil
-		}
-		return err
-	}
-	e.hdr = resp.Header
-
-	return nil
-}
-
-// Proclaim lets the leader announce a new value without another election.
-func (e *Election) Proclaim(ctx context.Context, val string) error {
-	if e.leaderSession == nil {
-		return ErrElectionNotLeader
-	}
-	client := e.session.Client()
-	cmp := v3.Compare(v3.CreateRevision(e.leaderKey), "=", e.leaderRev)
-	txn := client.Txn(ctx).If(cmp)
-	txn = txn.Then(v3.OpPut(e.leaderKey, val, v3.WithLease(e.leaderSession.Lease())))
-	tresp, terr := txn.Commit()
-	if terr != nil {
-		return terr
-	}
-	if !tresp.Succeeded {
-		e.leaderKey = ""
-		return ErrElectionNotLeader
-	}
-
-	e.hdr = tresp.Header
-	return nil
-}
-
-// Resign lets a leader start a new election.
-func (e *Election) Resign(ctx context.Context) (err error) {
-	if e.leaderSession == nil {
-		return nil
-	}
-	client := e.session.Client()
-	cmp := v3.Compare(v3.CreateRevision(e.leaderKey), "=", e.leaderRev)
-	resp, err := client.Txn(ctx).If(cmp).Then(v3.OpDelete(e.leaderKey)).Commit()
-	if err == nil {
-		e.hdr = resp.Header
-	}
-	e.leaderKey = ""
-	e.leaderSession = nil
-	return err
-}
-
-// Leader returns the leader value for the current election.
-func (e *Election) Leader(ctx context.Context) (*v3.GetResponse, error) {
-	client := e.session.Client()
-	resp, err := client.Get(ctx, e.keyPrefix, v3.WithFirstCreate()...)
-	if err != nil {
-		return nil, err
-	} else if len(resp.Kvs) == 0 {
-		// no leader currently elected
-		return nil, ErrElectionNoLeader
-	}
-	return resp, nil
-}
-
-// Observe returns a channel that reliably observes ordered leader proposals
-// as GetResponse values on every current elected leader key. It will not
-// necessarily fetch all historical leader updates, but will always post the
-// most recent leader value.
-//
-// The channel closes when the context is canceled or the underlying watcher
-// is otherwise disrupted.
-func (e *Election) Observe(ctx context.Context) <-chan v3.GetResponse {
-	retc := make(chan v3.GetResponse)
-	go e.observe(ctx, retc)
-	return retc
-}
-
-func (e *Election) observe(ctx context.Context, ch chan<- v3.GetResponse) {
-	client := e.session.Client()
-
-	defer close(ch)
-	for {
-		resp, err := client.Get(ctx, e.keyPrefix, v3.WithFirstCreate()...)
-		if err != nil {
-			return
-		}
-
-		var kv *mvccpb.KeyValue
-		var hdr *pb.ResponseHeader
-
-		if len(resp.Kvs) == 0 {
-			cctx, cancel := context.WithCancel(ctx)
-			// wait for first key put on prefix
-			opts := []v3.OpOption{v3.WithRev(resp.Header.Revision), v3.WithPrefix()}
-			wch := client.Watch(cctx, e.keyPrefix, opts...)
-			for kv == nil {
-				wr, ok := <-wch
-				if !ok || wr.Err() != nil {
-					cancel()
-					return
-				}
-				// only accept puts; a delete will make observe() spin
-				for _, ev := range wr.Events {
-					if ev.Type == mvccpb.PUT {
-						hdr, kv = &wr.Header, ev.Kv
-						// may have multiple revs; hdr.rev = the last rev
-						// set to kv's rev in case batch has multiple Puts
-						hdr.Revision = kv.ModRevision
-						break
-					}
-				}
-			}
-			cancel()
-		} else {
-			hdr, kv = resp.Header, resp.Kvs[0]
-		}
-
-		select {
-		case ch <- v3.GetResponse{Header: hdr, Kvs: []*mvccpb.KeyValue{kv}}:
-		case <-ctx.Done():
-			return
-		}
-
-		cctx, cancel := context.WithCancel(ctx)
-		wch := client.Watch(cctx, string(kv.Key), v3.WithRev(hdr.Revision+1))
-		keyDeleted := false
-		for !keyDeleted {
-			wr, ok := <-wch
-			if !ok {
-				cancel()
-				return
-			}
-			for _, ev := range wr.Events {
-				if ev.Type == mvccpb.DELETE {
-					keyDeleted = true
-					break
-				}
-				resp.Header = &wr.Header
-				resp.Kvs = []*mvccpb.KeyValue{ev.Kv}
-				select {
-				case ch <- *resp:
-				case <-cctx.Done():
-					cancel()
-					return
-				}
-			}
-		}
-		cancel()
-	}
-}
-
-// Key returns the leader key if elected, empty string otherwise.
-func (e *Election) Key() string { return e.leaderKey }
-
-// Rev returns the leader key's creation revision, if elected.
-func (e *Election) Rev() int64 { return e.leaderRev }
-
-// Header is the response header from the last successful election proposal.
-func (e *Election) Header() *pb.ResponseHeader { return e.hdr }
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/key.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/key.go
deleted file mode 100644
index e4cf775..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/key.go
+++ /dev/null
@@ -1,65 +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 concurrency
-
-import (
-	"context"
-	"fmt"
-
-	v3 "go.etcd.io/etcd/clientv3"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-func waitDelete(ctx context.Context, client *v3.Client, key string, rev int64) error {
-	cctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	var wr v3.WatchResponse
-	wch := client.Watch(cctx, key, v3.WithRev(rev))
-	for wr = range wch {
-		for _, ev := range wr.Events {
-			if ev.Type == mvccpb.DELETE {
-				return nil
-			}
-		}
-	}
-	if err := wr.Err(); err != nil {
-		return err
-	}
-	if err := ctx.Err(); err != nil {
-		return err
-	}
-	return fmt.Errorf("lost watcher waiting for delete")
-}
-
-// waitDeletes efficiently waits until all keys matching the prefix and no greater
-// than the create revision.
-func waitDeletes(ctx context.Context, client *v3.Client, pfx string, maxCreateRev int64) (*pb.ResponseHeader, error) {
-	getOpts := append(v3.WithLastCreate(), v3.WithMaxCreateRev(maxCreateRev))
-	for {
-		resp, err := client.Get(ctx, pfx, getOpts...)
-		if err != nil {
-			return nil, err
-		}
-		if len(resp.Kvs) == 0 {
-			return resp.Header, nil
-		}
-		lastKey := string(resp.Kvs[0].Key)
-		if err = waitDelete(ctx, client, lastKey, resp.Header.Revision); err != nil {
-			return nil, err
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/mutex.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/mutex.go
deleted file mode 100644
index 306470b..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/mutex.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 concurrency
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"sync"
-
-	v3 "go.etcd.io/etcd/clientv3"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-)
-
-// ErrLocked is returned by TryLock when Mutex is already locked by another session.
-var ErrLocked = errors.New("mutex: Locked by another session")
-
-// Mutex implements the sync Locker interface with etcd
-type Mutex struct {
-	s *Session
-
-	pfx   string
-	myKey string
-	myRev int64
-	hdr   *pb.ResponseHeader
-}
-
-func NewMutex(s *Session, pfx string) *Mutex {
-	return &Mutex{s, pfx + "/", "", -1, nil}
-}
-
-// TryLock locks the mutex if not already locked by another session.
-// If lock is held by another session, return immediately after attempting necessary cleanup
-// The ctx argument is used for the sending/receiving Txn RPC.
-func (m *Mutex) TryLock(ctx context.Context) error {
-	resp, err := m.tryAcquire(ctx)
-	if err != nil {
-		return err
-	}
-	// if no key on prefix / the minimum rev is key, already hold the lock
-	ownerKey := resp.Responses[1].GetResponseRange().Kvs
-	if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev {
-		m.hdr = resp.Header
-		return nil
-	}
-	client := m.s.Client()
-	// Cannot lock, so delete the key
-	if _, err := client.Delete(ctx, m.myKey); err != nil {
-		return err
-	}
-	m.myKey = "\x00"
-	m.myRev = -1
-	return ErrLocked
-}
-
-// Lock locks the mutex with a cancelable context. If the context is canceled
-// while trying to acquire the lock, the mutex tries to clean its stale lock entry.
-func (m *Mutex) Lock(ctx context.Context) error {
-	resp, err := m.tryAcquire(ctx)
-	if err != nil {
-		return err
-	}
-	// if no key on prefix / the minimum rev is key, already hold the lock
-	ownerKey := resp.Responses[1].GetResponseRange().Kvs
-	if len(ownerKey) == 0 || ownerKey[0].CreateRevision == m.myRev {
-		m.hdr = resp.Header
-		return nil
-	}
-	client := m.s.Client()
-	// wait for deletion revisions prior to myKey
-	hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1)
-	// release lock key if wait failed
-	if werr != nil {
-		m.Unlock(client.Ctx())
-	} else {
-		m.hdr = hdr
-	}
-	return werr
-}
-
-func (m *Mutex) tryAcquire(ctx context.Context) (*v3.TxnResponse, error) {
-	s := m.s
-	client := m.s.Client()
-
-	m.myKey = fmt.Sprintf("%s%x", m.pfx, s.Lease())
-	cmp := v3.Compare(v3.CreateRevision(m.myKey), "=", 0)
-	// put self in lock waiters via myKey; oldest waiter holds lock
-	put := v3.OpPut(m.myKey, "", v3.WithLease(s.Lease()))
-	// reuse key in case this session already holds the lock
-	get := v3.OpGet(m.myKey)
-	// fetch current holder to complete uncontended path with only one RPC
-	getOwner := v3.OpGet(m.pfx, v3.WithFirstCreate()...)
-	resp, err := client.Txn(ctx).If(cmp).Then(put, getOwner).Else(get, getOwner).Commit()
-	if err != nil {
-		return nil, err
-	}
-	m.myRev = resp.Header.Revision
-	if !resp.Succeeded {
-		m.myRev = resp.Responses[0].GetResponseRange().Kvs[0].CreateRevision
-	}
-	return resp, nil
-}
-
-func (m *Mutex) Unlock(ctx context.Context) error {
-	client := m.s.Client()
-	if _, err := client.Delete(ctx, m.myKey); err != nil {
-		return err
-	}
-	m.myKey = "\x00"
-	m.myRev = -1
-	return nil
-}
-
-func (m *Mutex) IsOwner() v3.Cmp {
-	return v3.Compare(v3.CreateRevision(m.myKey), "=", m.myRev)
-}
-
-func (m *Mutex) Key() string { return m.myKey }
-
-// Header is the response header received from etcd on acquiring the lock.
-func (m *Mutex) Header() *pb.ResponseHeader { return m.hdr }
-
-type lockerMutex struct{ *Mutex }
-
-func (lm *lockerMutex) Lock() {
-	client := lm.s.Client()
-	if err := lm.Mutex.Lock(client.Ctx()); err != nil {
-		panic(err)
-	}
-}
-func (lm *lockerMutex) Unlock() {
-	client := lm.s.Client()
-	if err := lm.Mutex.Unlock(client.Ctx()); err != nil {
-		panic(err)
-	}
-}
-
-// NewLocker creates a sync.Locker backed by an etcd mutex.
-func NewLocker(s *Session, pfx string) sync.Locker {
-	return &lockerMutex{NewMutex(s, pfx)}
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/session.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/session.go
deleted file mode 100644
index 97eb763..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/session.go
+++ /dev/null
@@ -1,141 +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 concurrency
-
-import (
-	"context"
-	"time"
-
-	v3 "go.etcd.io/etcd/clientv3"
-)
-
-const defaultSessionTTL = 60
-
-// Session represents a lease kept alive for the lifetime of a client.
-// Fault-tolerant applications may use sessions to reason about liveness.
-type Session struct {
-	client *v3.Client
-	opts   *sessionOptions
-	id     v3.LeaseID
-
-	cancel context.CancelFunc
-	donec  <-chan struct{}
-}
-
-// NewSession gets the leased session for a client.
-func NewSession(client *v3.Client, opts ...SessionOption) (*Session, error) {
-	ops := &sessionOptions{ttl: defaultSessionTTL, ctx: client.Ctx()}
-	for _, opt := range opts {
-		opt(ops)
-	}
-
-	id := ops.leaseID
-	if id == v3.NoLease {
-		resp, err := client.Grant(ops.ctx, int64(ops.ttl))
-		if err != nil {
-			return nil, err
-		}
-		id = resp.ID
-	}
-
-	ctx, cancel := context.WithCancel(ops.ctx)
-	keepAlive, err := client.KeepAlive(ctx, id)
-	if err != nil || keepAlive == nil {
-		cancel()
-		return nil, err
-	}
-
-	donec := make(chan struct{})
-	s := &Session{client: client, opts: ops, id: id, cancel: cancel, donec: donec}
-
-	// keep the lease alive until client error or cancelled context
-	go func() {
-		defer close(donec)
-		for range keepAlive {
-			// eat messages until keep alive channel closes
-		}
-	}()
-
-	return s, nil
-}
-
-// Client is the etcd client that is attached to the session.
-func (s *Session) Client() *v3.Client {
-	return s.client
-}
-
-// Lease is the lease ID for keys bound to the session.
-func (s *Session) Lease() v3.LeaseID { return s.id }
-
-// Done returns a channel that closes when the lease is orphaned, expires, or
-// is otherwise no longer being refreshed.
-func (s *Session) Done() <-chan struct{} { return s.donec }
-
-// Orphan ends the refresh for the session lease. This is useful
-// in case the state of the client connection is indeterminate (revoke
-// would fail) or when transferring lease ownership.
-func (s *Session) Orphan() {
-	s.cancel()
-	<-s.donec
-}
-
-// Close orphans the session and revokes the session lease.
-func (s *Session) Close() error {
-	s.Orphan()
-	// if revoke takes longer than the ttl, lease is expired anyway
-	ctx, cancel := context.WithTimeout(s.opts.ctx, time.Duration(s.opts.ttl)*time.Second)
-	_, err := s.client.Revoke(ctx, s.id)
-	cancel()
-	return err
-}
-
-type sessionOptions struct {
-	ttl     int
-	leaseID v3.LeaseID
-	ctx     context.Context
-}
-
-// SessionOption configures Session.
-type SessionOption func(*sessionOptions)
-
-// WithTTL configures the session's TTL in seconds.
-// If TTL is <= 0, the default 60 seconds TTL will be used.
-func WithTTL(ttl int) SessionOption {
-	return func(so *sessionOptions) {
-		if ttl > 0 {
-			so.ttl = ttl
-		}
-	}
-}
-
-// WithLease specifies the existing leaseID to be used for the session.
-// This is useful in process restart scenario, for example, to reclaim
-// leadership from an election prior to restart.
-func WithLease(leaseID v3.LeaseID) SessionOption {
-	return func(so *sessionOptions) {
-		so.leaseID = leaseID
-	}
-}
-
-// WithContext assigns a context to the session instead of defaulting to
-// using the client context. This is useful for canceling NewSession and
-// Close operations immediately without having to close the client. If the
-// context is canceled before Close() completes, the session's lease will be
-// abandoned and left to expire instead of being revoked.
-func WithContext(ctx context.Context) SessionOption {
-	return func(so *sessionOptions) {
-		so.ctx = ctx
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/concurrency/stm.go b/vendor/go.etcd.io/etcd/clientv3/concurrency/stm.go
deleted file mode 100644
index ee11510..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/concurrency/stm.go
+++ /dev/null
@@ -1,387 +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 concurrency
-
-import (
-	"context"
-	"math"
-
-	v3 "go.etcd.io/etcd/clientv3"
-)
-
-// STM is an interface for software transactional memory.
-type STM interface {
-	// Get returns the value for a key and inserts the key in the txn's read set.
-	// If Get fails, it aborts the transaction with an error, never returning.
-	Get(key ...string) string
-	// Put adds a value for a key to the write set.
-	Put(key, val string, opts ...v3.OpOption)
-	// Rev returns the revision of a key in the read set.
-	Rev(key string) int64
-	// Del deletes a key.
-	Del(key string)
-
-	// commit attempts to apply the txn's changes to the server.
-	commit() *v3.TxnResponse
-	reset()
-}
-
-// Isolation is an enumeration of transactional isolation levels which
-// describes how transactions should interfere and conflict.
-type Isolation int
-
-const (
-	// SerializableSnapshot provides serializable isolation and also checks
-	// for write conflicts.
-	SerializableSnapshot Isolation = iota
-	// Serializable reads within the same transaction attempt return data
-	// from the at the revision of the first read.
-	Serializable
-	// RepeatableReads reads within the same transaction attempt always
-	// return the same data.
-	RepeatableReads
-	// ReadCommitted reads keys from any committed revision.
-	ReadCommitted
-)
-
-// stmError safely passes STM errors through panic to the STM error channel.
-type stmError struct{ err error }
-
-type stmOptions struct {
-	iso      Isolation
-	ctx      context.Context
-	prefetch []string
-}
-
-type stmOption func(*stmOptions)
-
-// WithIsolation specifies the transaction isolation level.
-func WithIsolation(lvl Isolation) stmOption {
-	return func(so *stmOptions) { so.iso = lvl }
-}
-
-// WithAbortContext specifies the context for permanently aborting the transaction.
-func WithAbortContext(ctx context.Context) stmOption {
-	return func(so *stmOptions) { so.ctx = ctx }
-}
-
-// WithPrefetch is a hint to prefetch a list of keys before trying to apply.
-// If an STM transaction will unconditionally fetch a set of keys, prefetching
-// those keys will save the round-trip cost from requesting each key one by one
-// with Get().
-func WithPrefetch(keys ...string) stmOption {
-	return func(so *stmOptions) { so.prefetch = append(so.prefetch, keys...) }
-}
-
-// NewSTM initiates a new STM instance, using serializable snapshot isolation by default.
-func NewSTM(c *v3.Client, apply func(STM) error, so ...stmOption) (*v3.TxnResponse, error) {
-	opts := &stmOptions{ctx: c.Ctx()}
-	for _, f := range so {
-		f(opts)
-	}
-	if len(opts.prefetch) != 0 {
-		f := apply
-		apply = func(s STM) error {
-			s.Get(opts.prefetch...)
-			return f(s)
-		}
-	}
-	return runSTM(mkSTM(c, opts), apply)
-}
-
-func mkSTM(c *v3.Client, opts *stmOptions) STM {
-	switch opts.iso {
-	case SerializableSnapshot:
-		s := &stmSerializable{
-			stm:      stm{client: c, ctx: opts.ctx},
-			prefetch: make(map[string]*v3.GetResponse),
-		}
-		s.conflicts = func() []v3.Cmp {
-			return append(s.rset.cmps(), s.wset.cmps(s.rset.first()+1)...)
-		}
-		return s
-	case Serializable:
-		s := &stmSerializable{
-			stm:      stm{client: c, ctx: opts.ctx},
-			prefetch: make(map[string]*v3.GetResponse),
-		}
-		s.conflicts = func() []v3.Cmp { return s.rset.cmps() }
-		return s
-	case RepeatableReads:
-		s := &stm{client: c, ctx: opts.ctx, getOpts: []v3.OpOption{v3.WithSerializable()}}
-		s.conflicts = func() []v3.Cmp { return s.rset.cmps() }
-		return s
-	case ReadCommitted:
-		s := &stm{client: c, ctx: opts.ctx, getOpts: []v3.OpOption{v3.WithSerializable()}}
-		s.conflicts = func() []v3.Cmp { return nil }
-		return s
-	default:
-		panic("unsupported stm")
-	}
-}
-
-type stmResponse struct {
-	resp *v3.TxnResponse
-	err  error
-}
-
-func runSTM(s STM, apply func(STM) error) (*v3.TxnResponse, error) {
-	outc := make(chan stmResponse, 1)
-	go func() {
-		defer func() {
-			if r := recover(); r != nil {
-				e, ok := r.(stmError)
-				if !ok {
-					// client apply panicked
-					panic(r)
-				}
-				outc <- stmResponse{nil, e.err}
-			}
-		}()
-		var out stmResponse
-		for {
-			s.reset()
-			if out.err = apply(s); out.err != nil {
-				break
-			}
-			if out.resp = s.commit(); out.resp != nil {
-				break
-			}
-		}
-		outc <- out
-	}()
-	r := <-outc
-	return r.resp, r.err
-}
-
-// stm implements repeatable-read software transactional memory over etcd
-type stm struct {
-	client *v3.Client
-	ctx    context.Context
-	// rset holds read key values and revisions
-	rset readSet
-	// wset holds overwritten keys and their values
-	wset writeSet
-	// getOpts are the opts used for gets
-	getOpts []v3.OpOption
-	// conflicts computes the current conflicts on the txn
-	conflicts func() []v3.Cmp
-}
-
-type stmPut struct {
-	val string
-	op  v3.Op
-}
-
-type readSet map[string]*v3.GetResponse
-
-func (rs readSet) add(keys []string, txnresp *v3.TxnResponse) {
-	for i, resp := range txnresp.Responses {
-		rs[keys[i]] = (*v3.GetResponse)(resp.GetResponseRange())
-	}
-}
-
-// first returns the store revision from the first fetch
-func (rs readSet) first() int64 {
-	ret := int64(math.MaxInt64 - 1)
-	for _, resp := range rs {
-		if rev := resp.Header.Revision; rev < ret {
-			ret = rev
-		}
-	}
-	return ret
-}
-
-// cmps guards the txn from updates to read set
-func (rs readSet) cmps() []v3.Cmp {
-	cmps := make([]v3.Cmp, 0, len(rs))
-	for k, rk := range rs {
-		cmps = append(cmps, isKeyCurrent(k, rk))
-	}
-	return cmps
-}
-
-type writeSet map[string]stmPut
-
-func (ws writeSet) get(keys ...string) *stmPut {
-	for _, key := range keys {
-		if wv, ok := ws[key]; ok {
-			return &wv
-		}
-	}
-	return nil
-}
-
-// cmps returns a cmp list testing no writes have happened past rev
-func (ws writeSet) cmps(rev int64) []v3.Cmp {
-	cmps := make([]v3.Cmp, 0, len(ws))
-	for key := range ws {
-		cmps = append(cmps, v3.Compare(v3.ModRevision(key), "<", rev))
-	}
-	return cmps
-}
-
-// puts is the list of ops for all pending writes
-func (ws writeSet) puts() []v3.Op {
-	puts := make([]v3.Op, 0, len(ws))
-	for _, v := range ws {
-		puts = append(puts, v.op)
-	}
-	return puts
-}
-
-func (s *stm) Get(keys ...string) string {
-	if wv := s.wset.get(keys...); wv != nil {
-		return wv.val
-	}
-	return respToValue(s.fetch(keys...))
-}
-
-func (s *stm) Put(key, val string, opts ...v3.OpOption) {
-	s.wset[key] = stmPut{val, v3.OpPut(key, val, opts...)}
-}
-
-func (s *stm) Del(key string) { s.wset[key] = stmPut{"", v3.OpDelete(key)} }
-
-func (s *stm) Rev(key string) int64 {
-	if resp := s.fetch(key); resp != nil && len(resp.Kvs) != 0 {
-		return resp.Kvs[0].ModRevision
-	}
-	return 0
-}
-
-func (s *stm) commit() *v3.TxnResponse {
-	txnresp, err := s.client.Txn(s.ctx).If(s.conflicts()...).Then(s.wset.puts()...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	if txnresp.Succeeded {
-		return txnresp
-	}
-	return nil
-}
-
-func (s *stm) fetch(keys ...string) *v3.GetResponse {
-	if len(keys) == 0 {
-		return nil
-	}
-	ops := make([]v3.Op, len(keys))
-	for i, key := range keys {
-		if resp, ok := s.rset[key]; ok {
-			return resp
-		}
-		ops[i] = v3.OpGet(key, s.getOpts...)
-	}
-	txnresp, err := s.client.Txn(s.ctx).Then(ops...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	s.rset.add(keys, txnresp)
-	return (*v3.GetResponse)(txnresp.Responses[0].GetResponseRange())
-}
-
-func (s *stm) reset() {
-	s.rset = make(map[string]*v3.GetResponse)
-	s.wset = make(map[string]stmPut)
-}
-
-type stmSerializable struct {
-	stm
-	prefetch map[string]*v3.GetResponse
-}
-
-func (s *stmSerializable) Get(keys ...string) string {
-	if wv := s.wset.get(keys...); wv != nil {
-		return wv.val
-	}
-	firstRead := len(s.rset) == 0
-	for _, key := range keys {
-		if resp, ok := s.prefetch[key]; ok {
-			delete(s.prefetch, key)
-			s.rset[key] = resp
-		}
-	}
-	resp := s.stm.fetch(keys...)
-	if firstRead {
-		// txn's base revision is defined by the first read
-		s.getOpts = []v3.OpOption{
-			v3.WithRev(resp.Header.Revision),
-			v3.WithSerializable(),
-		}
-	}
-	return respToValue(resp)
-}
-
-func (s *stmSerializable) Rev(key string) int64 {
-	s.Get(key)
-	return s.stm.Rev(key)
-}
-
-func (s *stmSerializable) gets() ([]string, []v3.Op) {
-	keys := make([]string, 0, len(s.rset))
-	ops := make([]v3.Op, 0, len(s.rset))
-	for k := range s.rset {
-		keys = append(keys, k)
-		ops = append(ops, v3.OpGet(k))
-	}
-	return keys, ops
-}
-
-func (s *stmSerializable) commit() *v3.TxnResponse {
-	keys, getops := s.gets()
-	txn := s.client.Txn(s.ctx).If(s.conflicts()...).Then(s.wset.puts()...)
-	// use Else to prefetch keys in case of conflict to save a round trip
-	txnresp, err := txn.Else(getops...).Commit()
-	if err != nil {
-		panic(stmError{err})
-	}
-	if txnresp.Succeeded {
-		return txnresp
-	}
-	// load prefetch with Else data
-	s.rset.add(keys, txnresp)
-	s.prefetch = s.rset
-	s.getOpts = nil
-	return nil
-}
-
-func isKeyCurrent(k string, r *v3.GetResponse) v3.Cmp {
-	if len(r.Kvs) != 0 {
-		return v3.Compare(v3.ModRevision(k), "=", r.Kvs[0].ModRevision)
-	}
-	return v3.Compare(v3.ModRevision(k), "=", 0)
-}
-
-func respToValue(resp *v3.GetResponse) string {
-	if resp == nil || len(resp.Kvs) == 0 {
-		return ""
-	}
-	return string(resp.Kvs[0].Value)
-}
-
-// NewSTMRepeatable is deprecated.
-func NewSTMRepeatable(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(RepeatableReads))
-}
-
-// NewSTMSerializable is deprecated.
-func NewSTMSerializable(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(Serializable))
-}
-
-// NewSTMReadCommitted is deprecated.
-func NewSTMReadCommitted(ctx context.Context, c *v3.Client, apply func(STM) error) (*v3.TxnResponse, error) {
-	return NewSTM(c, apply, WithAbortContext(ctx), WithIsolation(ReadCommitted))
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/config.go b/vendor/go.etcd.io/etcd/clientv3/config.go
index 11d447d..9c17fc2 100644
--- a/vendor/go.etcd.io/etcd/clientv3/config.go
+++ b/vendor/go.etcd.io/etcd/clientv3/config.go
@@ -72,17 +72,15 @@
 	// Without this, Dial returns immediately and connecting the server happens in background.
 	DialOptions []grpc.DialOption
 
-	// Context is the default client context; it can be used to cancel grpc dial out and
-	// other operations that do not have an explicit context.
-	Context context.Context
-
 	// LogConfig configures client-side logger.
 	// If nil, use the default logger.
 	// TODO: configure gRPC logger
 	LogConfig *zap.Config
 
+	// Context is the default client context; it can be used to cancel grpc dial out and
+	// other operations that do not have an explicit context.
+	Context context.Context
+
 	// PermitWithoutStream when set will allow client to send keepalive pings to server without any active streams(RPCs).
 	PermitWithoutStream bool `json:"permit-without-stream"`
-
-	// TODO: support custom balancer picker
 }
diff --git a/vendor/go.etcd.io/etcd/clientv3/credentials/credentials.go b/vendor/go.etcd.io/etcd/clientv3/credentials/credentials.go
deleted file mode 100644
index e6fd75c..0000000
--- a/vendor/go.etcd.io/etcd/clientv3/credentials/credentials.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2019 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 credentials implements gRPC credential interface with etcd specific logic.
-// e.g., client handshake with custom authority parameter
-package credentials
-
-import (
-	"context"
-	"crypto/tls"
-	"net"
-	"sync"
-
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	grpccredentials "google.golang.org/grpc/credentials"
-)
-
-// Config defines gRPC credential configuration.
-type Config struct {
-	TLSConfig *tls.Config
-}
-
-// Bundle defines gRPC credential interface.
-type Bundle interface {
-	grpccredentials.Bundle
-	UpdateAuthToken(token string)
-}
-
-// NewBundle constructs a new gRPC credential bundle.
-func NewBundle(cfg Config) Bundle {
-	return &bundle{
-		tc: newTransportCredential(cfg.TLSConfig),
-		rc: newPerRPCCredential(),
-	}
-}
-
-// bundle implements "grpccredentials.Bundle" interface.
-type bundle struct {
-	tc *transportCredential
-	rc *perRPCCredential
-}
-
-func (b *bundle) TransportCredentials() grpccredentials.TransportCredentials {
-	return b.tc
-}
-
-func (b *bundle) PerRPCCredentials() grpccredentials.PerRPCCredentials {
-	return b.rc
-}
-
-func (b *bundle) NewWithMode(mode string) (grpccredentials.Bundle, error) {
-	// no-op
-	return nil, nil
-}
-
-// transportCredential implements "grpccredentials.TransportCredentials" interface.
-type transportCredential struct {
-	gtc grpccredentials.TransportCredentials
-}
-
-func newTransportCredential(cfg *tls.Config) *transportCredential {
-	return &transportCredential{
-		gtc: grpccredentials.NewTLS(cfg),
-	}
-}
-
-func (tc *transportCredential) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, grpccredentials.AuthInfo, error) {
-	// Only overwrite when authority is an IP address!
-	// Let's say, a server runs SRV records on "etcd.local" that resolves
-	// to "m1.etcd.local", and its SAN field also includes "m1.etcd.local".
-	// But what if SAN does not include its resolved IP address (e.g. 127.0.0.1)?
-	// Then, the server should only authenticate using its DNS hostname "m1.etcd.local",
-	// instead of overwriting it with its IP address.
-	// And we do not overwrite "localhost" either. Only overwrite IP addresses!
-	if isIP(authority) {
-		target := rawConn.RemoteAddr().String()
-		if authority != target {
-			// When user dials with "grpc.WithDialer", "grpc.DialContext" "cc.parsedTarget"
-			// update only happens once. This is problematic, because when TLS is enabled,
-			// retries happen through "grpc.WithDialer" with static "cc.parsedTarget" from
-			// the initial dial call.
-			// If the server authenticates by IP addresses, we want to set a new endpoint as
-			// a new authority. Otherwise
-			// "transport: authentication handshake failed: x509: certificate is valid for 127.0.0.1, 192.168.121.180, not 192.168.223.156"
-			// when the new dial target is "192.168.121.180" whose certificate host name is also "192.168.121.180"
-			// but client tries to authenticate with previously set "cc.parsedTarget" field "192.168.223.156"
-			authority = target
-		}
-	}
-	return tc.gtc.ClientHandshake(ctx, authority, rawConn)
-}
-
-// return true if given string is an IP.
-func isIP(ep string) bool {
-	return net.ParseIP(ep) != nil
-}
-
-func (tc *transportCredential) ServerHandshake(rawConn net.Conn) (net.Conn, grpccredentials.AuthInfo, error) {
-	return tc.gtc.ServerHandshake(rawConn)
-}
-
-func (tc *transportCredential) Info() grpccredentials.ProtocolInfo {
-	return tc.gtc.Info()
-}
-
-func (tc *transportCredential) Clone() grpccredentials.TransportCredentials {
-	return &transportCredential{
-		gtc: tc.gtc.Clone(),
-	}
-}
-
-func (tc *transportCredential) OverrideServerName(serverNameOverride string) error {
-	return tc.gtc.OverrideServerName(serverNameOverride)
-}
-
-// perRPCCredential implements "grpccredentials.PerRPCCredentials" interface.
-type perRPCCredential struct {
-	authToken   string
-	authTokenMu sync.RWMutex
-}
-
-func newPerRPCCredential() *perRPCCredential { return &perRPCCredential{} }
-
-func (rc *perRPCCredential) RequireTransportSecurity() bool { return false }
-
-func (rc *perRPCCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
-	rc.authTokenMu.RLock()
-	authToken := rc.authToken
-	rc.authTokenMu.RUnlock()
-	return map[string]string{rpctypes.TokenFieldNameGRPC: authToken}, nil
-}
-
-func (b *bundle) UpdateAuthToken(token string) {
-	if b.rc == nil {
-		return
-	}
-	b.rc.UpdateAuthToken(token)
-}
-
-func (rc *perRPCCredential) UpdateAuthToken(token string) {
-	rc.authTokenMu.Lock()
-	rc.authToken = token
-	rc.authTokenMu.Unlock()
-}
diff --git a/vendor/go.etcd.io/etcd/clientv3/ctx.go b/vendor/go.etcd.io/etcd/clientv3/ctx.go
new file mode 100644
index 0000000..da8297b
--- /dev/null
+++ b/vendor/go.etcd.io/etcd/clientv3/ctx.go
@@ -0,0 +1,64 @@
+// Copyright 2020 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 clientv3
+
+import (
+	"context"
+	"strings"
+
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+	"github.com/coreos/etcd/version"
+	"google.golang.org/grpc/metadata"
+)
+
+// WithRequireLeader requires client requests to only succeed
+// when the cluster has a leader.
+func WithRequireLeader(ctx context.Context) context.Context {
+	md, ok := metadata.FromOutgoingContext(ctx)
+	if !ok { // no outgoing metadata ctx key, create one
+		md = metadata.Pairs(rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
+		return metadata.NewOutgoingContext(ctx, md)
+	}
+	copied := md.Copy() // avoid racey updates
+	// overwrite/add 'hasleader' key/value
+	metadataSet(copied, rpctypes.MetadataRequireLeaderKey, rpctypes.MetadataHasLeader)
+	return metadata.NewOutgoingContext(ctx, copied)
+}
+
+// embeds client version
+func withVersion(ctx context.Context) context.Context {
+	md, ok := metadata.FromOutgoingContext(ctx)
+	if !ok { // no outgoing metadata ctx key, create one
+		md = metadata.Pairs(rpctypes.MetadataClientAPIVersionKey, version.APIVersion)
+		return metadata.NewOutgoingContext(ctx, md)
+	}
+	copied := md.Copy() // avoid racey updates
+	// overwrite/add version key/value
+	metadataSet(copied, rpctypes.MetadataClientAPIVersionKey, version.APIVersion)
+	return metadata.NewOutgoingContext(ctx, copied)
+}
+
+func metadataGet(md metadata.MD, k string) []string {
+	k = strings.ToLower(k)
+	return md[k]
+}
+
+func metadataSet(md metadata.MD, k string, vals ...string) {
+	if len(vals) == 0 {
+		return
+	}
+	k = strings.ToLower(k)
+	md[k] = vals
+}
diff --git a/vendor/go.etcd.io/etcd/clientv3/doc.go b/vendor/go.etcd.io/etcd/clientv3/doc.go
index 913cd28..717fbe4 100644
--- a/vendor/go.etcd.io/etcd/clientv3/doc.go
+++ b/vendor/go.etcd.io/etcd/clientv3/doc.go
@@ -19,7 +19,7 @@
 //	// expect dial time-out on ipv4 blackhole
 //	_, err := clientv3.New(clientv3.Config{
 //		Endpoints:   []string{"http://254.0.0.1:12345"},
-//		DialTimeout: 2 * time.Second,
+//		DialTimeout: 2 * time.Second
 //	})
 //
 //	// etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3
@@ -61,7 +61,7 @@
 //
 //  1. context error: canceled or deadline exceeded.
 //  2. gRPC status error: e.g. when clock drifts in server-side before client's context deadline exceeded.
-//  3. gRPC error: see https://github.com/etcd-io/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go
+//  3. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go
 //
 // Here is the example code to handle client errors:
 //
@@ -71,14 +71,14 @@
 //			// ctx is canceled by another routine
 //		} else if err == context.DeadlineExceeded {
 //			// ctx is attached with a deadline and it exceeded
-//		} else if err == rpctypes.ErrEmptyKey {
-//			// client-side error: key is not provided
 //		} else if ev, ok := status.FromError(err); ok {
 //			code := ev.Code()
 //			if code == codes.DeadlineExceeded {
 //				// server-side context might have timed-out first (due to clock skew)
 //				// while original client-side context is not timed-out yet
 //			}
+//		} else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok {
+//			// process (verr.Errors)
 //		} else {
 //			// bad cluster endpoints, which are not etcd servers
 //		}
@@ -87,20 +87,11 @@
 //	go func() { cli.Close() }()
 //	_, err := kvc.Get(ctx, "a")
 //	if err != nil {
-//		// with etcd clientv3 <= v3.3
 //		if err == context.Canceled {
 //			// grpc balancer calls 'Get' with an inflight client.Close
-//		} else if err == grpc.ErrClientConnClosing { // <= gRCP v1.7.x
+//		} else if err == grpc.ErrClientConnClosing {
 //			// grpc balancer calls 'Get' after client.Close.
 //		}
-//		// with etcd clientv3 >= v3.4
-//		if clientv3.IsConnCanceled(err) {
-//			// gRPC client connection is closed
-//		}
 //	}
 //
-// The grpc load balancer is registered statically and is shared across etcd clients.
-// To enable detailed load balancer logging, set the ETCD_CLIENT_DEBUG environment
-// variable.  E.g. "ETCD_CLIENT_DEBUG=1".
-//
 package clientv3
diff --git a/vendor/go.etcd.io/etcd/clientv3/kv.go b/vendor/go.etcd.io/etcd/clientv3/kv.go
index 2b7864a..5a7469b 100644
--- a/vendor/go.etcd.io/etcd/clientv3/kv.go
+++ b/vendor/go.etcd.io/etcd/clientv3/kv.go
@@ -17,7 +17,7 @@
 import (
 	"context"
 
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
 	"google.golang.org/grpc"
 )
diff --git a/vendor/go.etcd.io/etcd/clientv3/lease.go b/vendor/go.etcd.io/etcd/clientv3/lease.go
index c2796fc..3729cf3 100644
--- a/vendor/go.etcd.io/etcd/clientv3/lease.go
+++ b/vendor/go.etcd.io/etcd/clientv3/lease.go
@@ -19,10 +19,9 @@
 	"sync"
 	"time"
 
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
-	"go.uber.org/zap"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/metadata"
 )
@@ -118,21 +117,22 @@
 	// Leases retrieves all leases.
 	Leases(ctx context.Context) (*LeaseLeasesResponse, error)
 
-	// KeepAlive attempts to keep the given lease alive forever. If the keepalive responses posted
-	// to the channel are not consumed promptly the channel may become full. When full, the lease
-	// client will continue sending keep alive requests to the etcd server, but will drop responses
-	// until there is capacity on the channel to send more responses.
-	//
-	// If client keep alive loop halts with an unexpected error (e.g. "etcdserver: no leader") or
-	// canceled by the caller (e.g. context.Canceled), KeepAlive returns a ErrKeepAliveHalted error
-	// containing the error reason.
+	// KeepAlive keeps the given lease alive forever. If the keepalive response
+	// posted to the channel is not consumed immediately, the lease client will
+	// continue sending keep alive requests to the etcd server at least every
+	// second until latest response is consumed.
 	//
 	// The returned "LeaseKeepAliveResponse" channel closes if underlying keep
 	// alive stream is interrupted in some way the client cannot handle itself;
-	// given context "ctx" is canceled or timed out.
+	// given context "ctx" is canceled or timed out. "LeaseKeepAliveResponse"
+	// from this closed channel is nil.
+	//
+	// If client keep alive loop halts with an unexpected error (e.g. "etcdserver:
+	// no leader") or canceled by the caller (e.g. context.Canceled), the error
+	// is returned. Otherwise, it retries.
 	//
 	// TODO(v4.0): post errors to last keep alive message before closing
-	// (see https://github.com/etcd-io/etcd/pull/7866)
+	// (see https://github.com/coreos/etcd/pull/7866)
 	KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error)
 
 	// KeepAliveOnce renews the lease once. The response corresponds to the
@@ -172,8 +172,6 @@
 	firstKeepAliveOnce sync.Once
 
 	callOpts []grpc.CallOption
-
-	lg *zap.Logger
 }
 
 // keepAlive multiplexes a keepalive for a lease over multiple channels
@@ -198,7 +196,6 @@
 		keepAlives:            make(map[LeaseID]*keepAlive),
 		remote:                remote,
 		firstKeepAliveTimeout: keepAliveTimeout,
-		lg:                    c.lg,
 	}
 	if l.firstKeepAliveTimeout == time.Second {
 		l.firstKeepAliveTimeout = defaultTTL
@@ -294,7 +291,7 @@
 	}
 	l.mu.Unlock()
 
-	go l.keepAliveCtxCloser(ctx, id, ka.donec)
+	go l.keepAliveCtxCloser(id, ctx, ka.donec)
 	l.firstKeepAliveOnce.Do(func() {
 		go l.recvKeepAliveLoop()
 		go l.deadlineLoop()
@@ -326,7 +323,7 @@
 	return nil
 }
 
-func (l *lessor) keepAliveCtxCloser(ctx context.Context, id LeaseID, donec <-chan struct{}) {
+func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, donec <-chan struct{}) {
 	select {
 	case <-donec:
 		return
@@ -462,6 +459,7 @@
 
 		select {
 		case <-time.After(retryConnWait):
+			continue
 		case <-l.stopCtx.Done():
 			return l.stopCtx.Err()
 		}
@@ -471,7 +469,7 @@
 // resetRecv opens a new lease stream and starts sending keep alive requests.
 func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) {
 	sctx, cancel := context.WithCancel(l.stopCtx)
-	stream, err := l.remote.LeaseKeepAlive(sctx, append(l.callOpts, withMax(0))...)
+	stream, err := l.remote.LeaseKeepAlive(sctx, l.callOpts...)
 	if err != nil {
 		cancel()
 		return nil, err
@@ -520,12 +518,6 @@
 		select {
 		case ch <- karesp:
 		default:
-			if l.lg != nil {
-				l.lg.Warn("lease keepalive response queue is full; dropping response send",
-					zap.Int("queue-size", len(ch)),
-					zap.Int("queue-capacity", cap(ch)),
-				)
-			}
 		}
 		// still advance in order to rate-limit keep-alive sends
 		ka.nextKeepAlive = nextKeepAlive
@@ -577,7 +569,7 @@
 		}
 
 		select {
-		case <-time.After(retryConnWait):
+		case <-time.After(500 * time.Millisecond):
 		case <-stream.Context().Done():
 			return
 		case <-l.donec:
diff --git a/vendor/go.etcd.io/etcd/clientv3/logger.go b/vendor/go.etcd.io/etcd/clientv3/logger.go
index f5ae010..3276372 100644
--- a/vendor/go.etcd.io/etcd/clientv3/logger.go
+++ b/vendor/go.etcd.io/etcd/clientv3/logger.go
@@ -18,7 +18,7 @@
 	"io/ioutil"
 	"sync"
 
-	"go.etcd.io/etcd/pkg/logutil"
+	"github.com/coreos/etcd/pkg/logutil"
 
 	"google.golang.org/grpc/grpclog"
 )
diff --git a/vendor/go.etcd.io/etcd/clientv3/maintenance.go b/vendor/go.etcd.io/etcd/clientv3/maintenance.go
index 744455a..5e87cf8 100644
--- a/vendor/go.etcd.io/etcd/clientv3/maintenance.go
+++ b/vendor/go.etcd.io/etcd/clientv3/maintenance.go
@@ -19,7 +19,7 @@
 	"fmt"
 	"io"
 
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
 	"google.golang.org/grpc"
 )
@@ -193,23 +193,32 @@
 		return nil, toErr(ctx, err)
 	}
 
+	plog.Info("opened snapshot stream; downloading")
 	pr, pw := io.Pipe()
 	go func() {
 		for {
 			resp, err := ss.Recv()
 			if err != nil {
+				switch err {
+				case io.EOF:
+					plog.Info("completed snapshot read; closing")
+				default:
+					plog.Warningf("failed to receive from snapshot stream; closing (%v)", err)
+				}
 				pw.CloseWithError(err)
 				return
 			}
-			if resp == nil && err == nil {
-				break
-			}
+
+			// can "resp == nil && err == nil"
+			// before we receive snapshot SHA digest?
+			// No, server sends EOF with an empty response
+			// after it sends SHA digest at the end
+
 			if _, werr := pw.Write(resp.Blob); werr != nil {
 				pw.CloseWithError(werr)
 				return
 			}
 		}
-		pw.Close()
 	}()
 	return &snapshotReadCloser{ctx: ctx, ReadCloser: pr}, nil
 }
diff --git a/vendor/go.etcd.io/etcd/clientv3/op.go b/vendor/go.etcd.io/etcd/clientv3/op.go
index 81ae31f..3dca41b 100644
--- a/vendor/go.etcd.io/etcd/clientv3/op.go
+++ b/vendor/go.etcd.io/etcd/clientv3/op.go
@@ -14,7 +14,7 @@
 
 package clientv3
 
-import pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+import pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
 type opType int
 
@@ -26,7 +26,9 @@
 	tTxn
 )
 
-var noPrefixEnd = []byte{0}
+var (
+	noPrefixEnd = []byte{0}
+)
 
 // Op represents an Operation that kv can execute.
 type Op struct {
@@ -81,15 +83,8 @@
 
 // accessors / mutators
 
-// IsTxn returns true if the "Op" type is transaction.
-func (op Op) IsTxn() bool {
-	return op.t == tTxn
-}
-
-// Txn returns the comparison(if) operations, "then" operations, and "else" operations.
-func (op Op) Txn() ([]Cmp, []Op, []Op) {
-	return op.cmps, op.thenOps, op.elseOps
-}
+func (op Op) IsTxn() bool              { return op.t == tTxn }
+func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps }
 
 // KeyBytes returns the byte slice holding the Op's key.
 func (op Op) KeyBytes() []byte { return op.key }
@@ -113,13 +108,13 @@
 func (op Op) IsDelete() bool { return op.t == tDeleteRange }
 
 // IsSerializable returns true if the serializable field is true.
-func (op Op) IsSerializable() bool { return op.serializable }
+func (op Op) IsSerializable() bool { return op.serializable == true }
 
 // IsKeysOnly returns whether keysOnly is set.
-func (op Op) IsKeysOnly() bool { return op.keysOnly }
+func (op Op) IsKeysOnly() bool { return op.keysOnly == true }
 
 // IsCountOnly returns whether countOnly is set.
-func (op Op) IsCountOnly() bool { return op.countOnly }
+func (op Op) IsCountOnly() bool { return op.countOnly == true }
 
 // MinModRev returns the operation's minimum modify revision.
 func (op Op) MinModRev() int64 { return op.minModRev }
@@ -216,23 +211,13 @@
 	return op.t != tRange
 }
 
-// OpGet returns "get" operation based on given key and operation options.
 func OpGet(key string, opts ...OpOption) Op {
-	// WithPrefix and WithFromKey are not supported together
-	if isWithPrefix(opts) && isWithFromKey(opts) {
-		panic("`WithPrefix` and `WithFromKey` cannot be set at the same time, choose one")
-	}
 	ret := Op{t: tRange, key: []byte(key)}
 	ret.applyOpts(opts)
 	return ret
 }
 
-// OpDelete returns "delete" operation based on given key and operation options.
 func OpDelete(key string, opts ...OpOption) Op {
-	// WithPrefix and WithFromKey are not supported together
-	if isWithPrefix(opts) && isWithFromKey(opts) {
-		panic("`WithPrefix` and `WithFromKey` cannot be set at the same time, choose one")
-	}
 	ret := Op{t: tDeleteRange, key: []byte(key)}
 	ret.applyOpts(opts)
 	switch {
@@ -260,7 +245,6 @@
 	return ret
 }
 
-// OpPut returns "put" operation based on given key-value and operation options.
 func OpPut(key, val string, opts ...OpOption) Op {
 	ret := Op{t: tPut, key: []byte(key), val: []byte(val)}
 	ret.applyOpts(opts)
@@ -289,7 +273,6 @@
 	return ret
 }
 
-// OpTxn returns "txn" operation based on given transaction conditions.
 func OpTxn(cmps []Cmp, thenOps []Op, elseOps []Op) Op {
 	return Op{t: tTxn, cmps: cmps, thenOps: thenOps, elseOps: elseOps}
 }
@@ -400,14 +383,7 @@
 
 // WithFromKey specifies the range of 'Get', 'Delete', 'Watch' requests
 // to be equal or greater than the key in the argument.
-func WithFromKey() OpOption {
-	return func(op *Op) {
-		if len(op.key) == 0 {
-			op.key = []byte{0}
-		}
-		op.end = []byte("\x00")
-	}
-}
+func WithFromKey() OpOption { return WithRange("\x00") }
 
 // WithSerializable makes 'Get' request serializable. By default,
 // it's linearizable. Serializable requests are better for lower latency
@@ -496,17 +472,6 @@
 	}
 }
 
-// WithFragment to receive raw watch response with fragmentation.
-// Fragmentation is disabled by default. If fragmentation is enabled,
-// etcd watch server will split watch response before sending to clients
-// when the total size of watch events exceed server-side request limit.
-// The default server-side request limit is 1.5 MiB, which can be configured
-// as "--max-request-bytes" flag value + gRPC-overhead 512 bytes.
-// See "etcdserver/api/v3rpc/watch.go" for more details.
-func WithFragment() OpOption {
-	return func(op *Op) { op.fragment = true }
-}
-
 // WithIgnoreValue updates the key using its current value.
 // This option can not be combined with non-empty values.
 // Returns an error if the key does not exist.
@@ -553,8 +518,13 @@
 	return &pb.LeaseTimeToLiveRequest{ID: int64(id), Keys: ret.attachedKeys}
 }
 
-// isWithPrefix returns true if WithPrefix is being called in the op
-func isWithPrefix(opts []OpOption) bool { return isOpFuncCalled("WithPrefix", opts) }
-
-// isWithFromKey returns true if WithFromKey is being called in the op
-func isWithFromKey(opts []OpOption) bool { return isOpFuncCalled("WithFromKey", opts) }
+// WithFragment to receive raw watch response with fragmentation.
+// Fragmentation is disabled by default. If fragmentation is enabled,
+// etcd watch server will split watch response before sending to clients
+// when the total size of watch events exceed server-side request limit.
+// The default server-side request limit is 1.5 MiB, which can be configured
+// as "--max-request-bytes" flag value + gRPC-overhead 512 bytes.
+// See "etcdserver/api/v3rpc/watch.go" for more details.
+func WithFragment() OpOption {
+	return func(op *Op) { op.fragment = true }
+}
diff --git a/vendor/go.etcd.io/etcd/clientv3/retry.go b/vendor/go.etcd.io/etcd/clientv3/retry.go
index 7e855de..6baa52e 100644
--- a/vendor/go.etcd.io/etcd/clientv3/retry.go
+++ b/vendor/go.etcd.io/etcd/clientv3/retry.go
@@ -17,8 +17,8 @@
 import (
 	"context"
 
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -179,10 +179,6 @@
 	return rcc.cc.MemberUpdate(ctx, in, opts...)
 }
 
-func (rcc *retryClusterClient) MemberPromote(ctx context.Context, in *pb.MemberPromoteRequest, opts ...grpc.CallOption) (resp *pb.MemberPromoteResponse, err error) {
-	return rcc.cc.MemberPromote(ctx, in, opts...)
-}
-
 type retryMaintenanceClient struct {
 	mc pb.MaintenanceClient
 }
diff --git a/vendor/go.etcd.io/etcd/clientv3/retry_interceptor.go b/vendor/go.etcd.io/etcd/clientv3/retry_interceptor.go
index 080490a..f3c5057 100644
--- a/vendor/go.etcd.io/etcd/clientv3/retry_interceptor.go
+++ b/vendor/go.etcd.io/etcd/clientv3/retry_interceptor.go
@@ -23,7 +23,7 @@
 	"sync"
 	"time"
 
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
 	"go.uber.org/zap"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -38,6 +38,7 @@
 func (c *Client) unaryClientInterceptor(logger *zap.Logger, optFuncs ...retryOption) grpc.UnaryClientInterceptor {
 	intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)
 	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
+		ctx = withVersion(ctx)
 		grpcOpts, retryOpts := filterCallOptions(opts)
 		callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)
 		// short circuit for simplicity, and avoiding allocations.
@@ -103,6 +104,7 @@
 func (c *Client) streamClientInterceptor(logger *zap.Logger, optFuncs ...retryOption) grpc.StreamClientInterceptor {
 	intOpts := reuseOrNewWithCallOptions(defaultOptions, optFuncs)
 	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
+		ctx = withVersion(ctx)
 		grpcOpts, retryOpts := filterCallOptions(opts)
 		callOpts := reuseOrNewWithCallOptions(intOpts, retryOpts)
 		// short circuit for simplicity, and avoiding allocations.
@@ -113,10 +115,9 @@
 			return nil, status.Errorf(codes.Unimplemented, "clientv3/retry_interceptor: cannot retry on ClientStreams, set Disable()")
 		}
 		newStreamer, err := streamer(ctx, desc, cc, method, grpcOpts...)
-		logger.Warn("retry stream intercept", zap.Error(err))
 		if err != nil {
-			// TODO(mwitkow): Maybe dial and transport errors should be retriable?
-			return nil, err
+			logger.Error("streamer failed to create ClientStream", zap.Error(err))
+			return nil, err // TODO(mwitkow): Maybe dial and transport errors should be retriable?
 		}
 		retryingStreamer := &serverStreamingRetryingStream{
 			client:       c,
@@ -185,6 +186,7 @@
 	if !attemptRetry {
 		return lastErr // success or hard failure
 	}
+
 	// We start off from attempt 1, because zeroth was already made on normal SendMsg().
 	for attempt := uint(1); attempt < s.callOpts.max; attempt++ {
 		if err := waitRetryBackoff(s.ctx, attempt, s.callOpts); err != nil {
@@ -192,12 +194,13 @@
 		}
 		newStream, err := s.reestablishStreamAndResendBuffer(s.ctx)
 		if err != nil {
-			// TODO(mwitkow): Maybe dial and transport errors should be retriable?
-			return err
+			s.client.lg.Error("failed reestablishStreamAndResendBuffer", zap.Error(err))
+			return err // TODO(mwitkow): Maybe dial and transport errors should be retriable?
 		}
 		s.setStream(newStream)
+
+		s.client.lg.Warn("retrying RecvMsg", zap.Error(lastErr))
 		attemptRetry, lastErr = s.receiveMsgAndIndicateRetry(m)
-		//fmt.Printf("Received message and indicate: %v  %v\n", attemptRetry, lastErr)
 		if !attemptRetry {
 			return lastErr
 		}
diff --git a/vendor/go.etcd.io/etcd/clientv3/txn.go b/vendor/go.etcd.io/etcd/clientv3/txn.go
index c19715d..c3c2d24 100644
--- a/vendor/go.etcd.io/etcd/clientv3/txn.go
+++ b/vendor/go.etcd.io/etcd/clientv3/txn.go
@@ -18,7 +18,7 @@
 	"context"
 	"sync"
 
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
 
 	"google.golang.org/grpc"
 )
diff --git a/vendor/go.etcd.io/etcd/clientv3/watch.go b/vendor/go.etcd.io/etcd/clientv3/watch.go
index 87d222d..4a3b8cc 100644
--- a/vendor/go.etcd.io/etcd/clientv3/watch.go
+++ b/vendor/go.etcd.io/etcd/clientv3/watch.go
@@ -21,9 +21,9 @@
 	"sync"
 	"time"
 
-	v3rpc "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	mvccpb "go.etcd.io/etcd/mvcc/mvccpb"
+	v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+	mvccpb "github.com/coreos/etcd/mvcc/mvccpb"
 
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
diff --git a/vendor/go.etcd.io/etcd/embed/config.go b/vendor/go.etcd.io/etcd/embed/config.go
index 2f64d92..473e757 100644
--- a/vendor/go.etcd.io/etcd/embed/config.go
+++ b/vendor/go.etcd.io/etcd/embed/config.go
@@ -24,24 +24,20 @@
 	"os"
 	"path/filepath"
 	"strings"
-	"sync"
 	"time"
 
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3compactor"
-	"go.etcd.io/etcd/pkg/flags"
-	"go.etcd.io/etcd/pkg/logutil"
-	"go.etcd.io/etcd/pkg/netutil"
-	"go.etcd.io/etcd/pkg/srv"
-	"go.etcd.io/etcd/pkg/tlsutil"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
+	"github.com/coreos/etcd/compactor"
+	"github.com/coreos/etcd/etcdserver"
+	"github.com/coreos/etcd/pkg/cors"
+	"github.com/coreos/etcd/pkg/netutil"
+	"github.com/coreos/etcd/pkg/srv"
+	"github.com/coreos/etcd/pkg/tlsutil"
+	"github.com/coreos/etcd/pkg/transport"
+	"github.com/coreos/etcd/pkg/types"
 
-	bolt "go.etcd.io/bbolt"
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-	"golang.org/x/crypto/bcrypt"
+	"github.com/coreos/pkg/capnslog"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/grpclog"
 	"sigs.k8s.io/yaml"
 )
 
@@ -62,22 +58,18 @@
 	DefaultListenClientURLs = "http://localhost:2379"
 
 	DefaultLogOutput = "default"
-	JournalLogOutput = "systemd/journal"
-	StdErrLogOutput  = "stderr"
-	StdOutLogOutput  = "stdout"
 
 	// DefaultStrictReconfigCheck is the default value for "--strict-reconfig-check" flag.
 	// It's enabled by default.
 	DefaultStrictReconfigCheck = true
 	// DefaultEnableV2 is the default value for "--enable-v2" flag.
-	// v2 API is disabled by default.
-	DefaultEnableV2 = false
+	// v2 is enabled by default.
+	// TODO: disable v2 when deprecated.
+	DefaultEnableV2 = true
 
 	// maxElectionMs specifies the maximum value of election timeout.
 	// More details are listed in ../Documentation/tuning.md#time-parameters.
 	maxElectionMs = 50000
-	// backend freelist map type
-	freelistMapType = "map"
 )
 
 var (
@@ -92,46 +84,30 @@
 	defaultHostStatus error
 )
 
-var (
-	// CompactorModePeriodic is periodic compaction mode
-	// for "Config.AutoCompactionMode" field.
-	// If "AutoCompactionMode" is CompactorModePeriodic and
-	// "AutoCompactionRetention" is "1h", it automatically compacts
-	// compacts storage every hour.
-	CompactorModePeriodic = v3compactor.ModePeriodic
-
-	// CompactorModeRevision is revision-based compaction mode
-	// for "Config.AutoCompactionMode" field.
-	// If "AutoCompactionMode" is CompactorModeRevision and
-	// "AutoCompactionRetention" is "1000", it compacts log on
-	// revision 5000 when the current revision is 6000.
-	// This runs every 5-minute if enough of logs have proceeded.
-	CompactorModeRevision = v3compactor.ModeRevision
-)
-
 func init() {
 	defaultHostname, defaultHostStatus = netutil.GetDefaultHost()
 }
 
 // Config holds the arguments for configuring an etcd server.
 type Config struct {
-	Name   string `json:"name"`
-	Dir    string `json:"data-dir"`
-	WalDir string `json:"wal-dir"`
+	// member
 
-	SnapshotCount uint64 `json:"snapshot-count"`
+	CorsInfo       *cors.CORSInfo
+	LPUrls, LCUrls []url.URL
+	Dir            string `json:"data-dir"`
+	WalDir         string `json:"wal-dir"`
+	MaxSnapFiles   uint   `json:"max-snapshots"`
+	MaxWalFiles    uint   `json:"max-wals"`
+	Name           string `json:"name"`
+	SnapCount      uint64 `json:"snapshot-count"`
 
-	// SnapshotCatchUpEntries is the number of entries for a slow follower
-	// to catch-up after compacting the raft storage entries.
-	// We expect the follower has a millisecond level latency with the leader.
-	// The max throughput is around 10K. Keep a 5K entries is enough for helping
-	// follower to catch up.
-	// WARNING: only change this for tests.
-	// Always use "DefaultSnapshotCatchUpEntries"
-	SnapshotCatchUpEntries uint64
-
-	MaxSnapFiles uint `json:"max-snapshots"`
-	MaxWalFiles  uint `json:"max-wals"`
+	// AutoCompactionMode is either 'periodic' or 'revision'.
+	AutoCompactionMode string `json:"auto-compaction-mode"`
+	// AutoCompactionRetention is either duration string with time unit
+	// (e.g. '5m' for 5-minute), or revision unit (e.g. '5000').
+	// If no time unit is provided and compaction mode is 'periodic',
+	// the unit defaults to hour. For example, '5' translates into 5-hour.
+	AutoCompactionRetention string `json:"auto-compaction-retention"`
 
 	// TickMs is the number of milliseconds between heartbeat ticks.
 	// TODO: decouple tickMs and heartbeat tick (current heartbeat tick = 1).
@@ -165,46 +141,14 @@
 	//
 	// If single-node, it advances ticks regardless.
 	//
-	// See https://github.com/etcd-io/etcd/issues/9333 for more detail.
+	// See https://github.com/coreos/etcd/issues/9333 for more detail.
 	InitialElectionTickAdvance bool `json:"initial-election-tick-advance"`
 
-	// BackendBatchInterval is the maximum time before commit the backend transaction.
-	BackendBatchInterval time.Duration `json:"backend-batch-interval"`
-	// BackendBatchLimit is the maximum operations before commit the backend transaction.
-	BackendBatchLimit int   `json:"backend-batch-limit"`
 	QuotaBackendBytes int64 `json:"quota-backend-bytes"`
 	MaxTxnOps         uint  `json:"max-txn-ops"`
 	MaxRequestBytes   uint  `json:"max-request-bytes"`
 
-	LPUrls, LCUrls []url.URL
-	APUrls, ACUrls []url.URL
-	ClientTLSInfo  transport.TLSInfo
-	ClientAutoTLS  bool
-	PeerTLSInfo    transport.TLSInfo
-	PeerAutoTLS    bool
-
-	// CipherSuites is a list of supported TLS cipher suites between
-	// client/server and peers. If empty, Go auto-populates the list.
-	// Note that cipher suites are prioritized in the given order.
-	CipherSuites []string `json:"cipher-suites"`
-
-	ClusterState          string `json:"initial-cluster-state"`
-	DNSCluster            string `json:"discovery-srv"`
-	DNSClusterServiceName string `json:"discovery-srv-name"`
-	Dproxy                string `json:"discovery-proxy"`
-	Durl                  string `json:"discovery"`
-	InitialCluster        string `json:"initial-cluster"`
-	InitialClusterToken   string `json:"initial-cluster-token"`
-	StrictReconfigCheck   bool   `json:"strict-reconfig-check"`
-	EnableV2              bool   `json:"enable-v2"`
-
-	// AutoCompactionMode is either 'periodic' or 'revision'.
-	AutoCompactionMode string `json:"auto-compaction-mode"`
-	// AutoCompactionRetention is either duration string with time unit
-	// (e.g. '5m' for 5-minute), or revision unit (e.g. '5000').
-	// If no time unit is provided and compaction mode is 'periodic',
-	// the unit defaults to hour. For example, '5' translates into 5-hour.
-	AutoCompactionRetention string `json:"auto-compaction-retention"`
+	// gRPC server options
 
 	// GRPCKeepAliveMinTime is the minimum interval that a client should
 	// wait before pinging server. When client pings "too fast", server
@@ -221,40 +165,42 @@
 	// before closing a non-responsive connection. 0 to disable.
 	GRPCKeepAliveTimeout time.Duration `json:"grpc-keepalive-timeout"`
 
-	// PreVote is true to enable Raft Pre-Vote.
-	// If enabled, Raft runs an additional election phase
-	// to check whether it would get enough votes to win
-	// an election, thus minimizing disruptions.
-	// TODO: enable by default in 3.5.
-	PreVote bool `json:"pre-vote"`
+	// clustering
 
-	CORS map[string]struct{}
+	APUrls, ACUrls      []url.URL
+	ClusterState        string `json:"initial-cluster-state"`
+	DNSCluster          string `json:"discovery-srv"`
+	Dproxy              string `json:"discovery-proxy"`
+	Durl                string `json:"discovery"`
+	InitialCluster      string `json:"initial-cluster"`
+	InitialClusterToken string `json:"initial-cluster-token"`
+	StrictReconfigCheck bool   `json:"strict-reconfig-check"`
+	EnableV2            bool   `json:"enable-v2"`
 
-	// HostWhitelist lists acceptable hostnames from HTTP client requests.
-	// Client origin policy protects against "DNS Rebinding" attacks
-	// to insecure etcd servers. That is, any website can simply create
-	// an authorized DNS name, and direct DNS to "localhost" (or any
-	// other address). Then, all HTTP endpoints of etcd server listening
-	// on "localhost" becomes accessible, thus vulnerable to DNS rebinding
-	// attacks. See "CVE-2018-5702" for more detail.
-	//
-	// 1. If client connection is secure via HTTPS, allow any hostnames.
-	// 2. If client connection is not secure and "HostWhitelist" is not empty,
-	//    only allow HTTP requests whose Host field is listed in whitelist.
-	//
-	// Note that the client origin policy is enforced whether authentication
-	// is enabled or not, for tighter controls.
-	//
-	// By default, "HostWhitelist" is "*", which allows any hostnames.
-	// Note that when specifying hostnames, loopback addresses are not added
-	// automatically. To allow loopback interfaces, leave it empty or set it "*",
-	// or add them to whitelist manually (e.g. "localhost", "127.0.0.1", etc.).
-	//
-	// CVE-2018-5702 reference:
-	// - https://bugs.chromium.org/p/project-zero/issues/detail?id=1447#c2
-	// - https://github.com/transmission/transmission/pull/468
-	// - https://github.com/etcd-io/etcd/issues/9353
-	HostWhitelist map[string]struct{}
+	// security
+
+	ClientTLSInfo transport.TLSInfo
+	ClientAutoTLS bool
+	PeerTLSInfo   transport.TLSInfo
+	PeerAutoTLS   bool
+
+	// CipherSuites is a list of supported TLS cipher suites between
+	// client/server and peers. If empty, Go auto-populates the list.
+	// Note that cipher suites are prioritized in the given order.
+	CipherSuites []string `json:"cipher-suites"`
+
+	// debug
+
+	Debug                 bool   `json:"debug"`
+	LogPkgLevels          string `json:"log-package-levels"`
+	LogOutput             string `json:"log-output"`
+	EnablePprof           bool   `json:"enable-pprof"`
+	Metrics               string `json:"metrics"`
+	ListenMetricsUrls     []url.URL
+	ListenMetricsUrlsJSON string `json:"listen-metrics-urls"`
+
+	// ForceNewCluster starts a new cluster even if previously started; unsafe.
+	ForceNewCluster bool `json:"force-new-cluster"`
 
 	// UserHandlers is for registering users handlers and only used for
 	// embedding etcd into other applications.
@@ -270,71 +216,18 @@
 	//	embed.StartEtcd(cfg)
 	ServiceRegister func(*grpc.Server) `json:"-"`
 
-	AuthToken  string `json:"auth-token"`
-	BcryptCost uint   `json:"bcrypt-cost"`
+	// auth
+
+	AuthToken string `json:"auth-token"`
+
+	// Experimental flags
+
+	//The AuthTokenTTL in seconds of the simple token
+	AuthTokenTTL uint `json:"auth-token-ttl"`
 
 	ExperimentalInitialCorruptCheck bool          `json:"experimental-initial-corrupt-check"`
 	ExperimentalCorruptCheckTime    time.Duration `json:"experimental-corrupt-check-time"`
 	ExperimentalEnableV2V3          string        `json:"experimental-enable-v2v3"`
-	// ExperimentalBackendFreelistType specifies the type of freelist that boltdb backend uses (array and map are supported types).
-	ExperimentalBackendFreelistType string `json:"experimental-backend-bbolt-freelist-type"`
-	// ExperimentalEnableLeaseCheckpoint enables primary lessor to persist lease remainingTTL to prevent indefinite auto-renewal of long lived leases.
-	ExperimentalEnableLeaseCheckpoint bool `json:"experimental-enable-lease-checkpoint"`
-	ExperimentalCompactionBatchLimit  int  `json:"experimental-compaction-batch-limit"`
-
-	// ForceNewCluster starts a new cluster even if previously started; unsafe.
-	ForceNewCluster bool `json:"force-new-cluster"`
-
-	EnablePprof           bool   `json:"enable-pprof"`
-	Metrics               string `json:"metrics"`
-	ListenMetricsUrls     []url.URL
-	ListenMetricsUrlsJSON string `json:"listen-metrics-urls"`
-
-	// Logger is logger options: "zap", "capnslog".
-	// WARN: "capnslog" is being deprecated in v3.5.
-	Logger string `json:"logger"`
-	// LogLevel configures log level. Only supports debug, info, warn, error, panic, or fatal. Default 'info'.
-	LogLevel string `json:"log-level"`
-	// LogOutputs is either:
-	//  - "default" as os.Stderr,
-	//  - "stderr" as os.Stderr,
-	//  - "stdout" as os.Stdout,
-	//  - file path to append server logs to.
-	// It can be multiple when "Logger" is zap.
-	LogOutputs []string `json:"log-outputs"`
-
-	// ZapLoggerBuilder is used to build the zap logger.
-	ZapLoggerBuilder func(*Config) error
-
-	// logger logs server-side operations. The default is nil,
-	// and "setupLogging" must be called before starting server.
-	// Do not set logger directly.
-	loggerMu *sync.RWMutex
-	logger   *zap.Logger
-
-	// loggerConfig is server logger configuration for Raft logger.
-	// Must be either: "loggerConfig != nil" or "loggerCore != nil && loggerWriteSyncer != nil".
-	loggerConfig *zap.Config
-	// loggerCore is "zapcore.Core" for raft logger.
-	// Must be either: "loggerConfig != nil" or "loggerCore != nil && loggerWriteSyncer != nil".
-	loggerCore        zapcore.Core
-	loggerWriteSyncer zapcore.WriteSyncer
-
-	// EnableGRPCGateway is false to disable grpc gateway.
-	EnableGRPCGateway bool `json:"enable-grpc-gateway"`
-
-	// TO BE DEPRECATED
-
-	// DeprecatedLogOutput is to be deprecated in v3.5.
-	// Just here for safe migration in v3.4.
-	DeprecatedLogOutput []string `json:"log-output"`
-	// Debug is true, to enable debug level logging.
-	// WARNING: to be deprecated in 3.5. Use "--log-level=debug" instead.
-	Debug bool `json:"debug"`
-	// LogPkgLevels is being deprecated in v3.5.
-	// Only valid if "logger" option is "capnslog".
-	// WARN: DO NOT USE THIS!
-	LogPkgLevels string `json:"log-package-levels"`
 }
 
 // configYAML holds the config suitable for yaml parsing
@@ -345,19 +238,17 @@
 
 // configJSON has file options that are translated into Config options
 type configJSON struct {
-	LPUrlsJSON string `json:"listen-peer-urls"`
-	LCUrlsJSON string `json:"listen-client-urls"`
-	APUrlsJSON string `json:"initial-advertise-peer-urls"`
-	ACUrlsJSON string `json:"advertise-client-urls"`
-
-	CORSJSON          string `json:"cors"`
-	HostWhitelistJSON string `json:"host-whitelist"`
-
+	LPUrlsJSON         string         `json:"listen-peer-urls"`
+	LCUrlsJSON         string         `json:"listen-client-urls"`
+	CorsJSON           string         `json:"cors"`
+	APUrlsJSON         string         `json:"initial-advertise-peer-urls"`
+	ACUrlsJSON         string         `json:"advertise-client-urls"`
 	ClientSecurityJSON securityConfig `json:"client-transport-security"`
 	PeerSecurityJSON   securityConfig `json:"peer-transport-security"`
 }
 
 type securityConfig struct {
+	CAFile        string `json:"ca-file"`
 	CertFile      string `json:"cert-file"`
 	KeyFile       string `json:"key-file"`
 	CertAuth      bool   `json:"client-cert-auth"`
@@ -372,53 +263,31 @@
 	lcurl, _ := url.Parse(DefaultListenClientURLs)
 	acurl, _ := url.Parse(DefaultAdvertiseClientURLs)
 	cfg := &Config{
-		MaxSnapFiles: DefaultMaxSnapshots,
-		MaxWalFiles:  DefaultMaxWALs,
-
-		Name: DefaultName,
-
-		SnapshotCount:          etcdserver.DefaultSnapshotCount,
-		SnapshotCatchUpEntries: etcdserver.DefaultSnapshotCatchUpEntries,
-
-		MaxTxnOps:       DefaultMaxTxnOps,
-		MaxRequestBytes: DefaultMaxRequestBytes,
-
-		GRPCKeepAliveMinTime:  DefaultGRPCKeepAliveMinTime,
-		GRPCKeepAliveInterval: DefaultGRPCKeepAliveInterval,
-		GRPCKeepAliveTimeout:  DefaultGRPCKeepAliveTimeout,
-
+		CorsInfo:                   &cors.CORSInfo{},
+		MaxSnapFiles:               DefaultMaxSnapshots,
+		MaxWalFiles:                DefaultMaxWALs,
+		Name:                       DefaultName,
+		SnapCount:                  etcdserver.DefaultSnapCount,
+		MaxTxnOps:                  DefaultMaxTxnOps,
+		MaxRequestBytes:            DefaultMaxRequestBytes,
+		GRPCKeepAliveMinTime:       DefaultGRPCKeepAliveMinTime,
+		GRPCKeepAliveInterval:      DefaultGRPCKeepAliveInterval,
+		GRPCKeepAliveTimeout:       DefaultGRPCKeepAliveTimeout,
 		TickMs:                     100,
 		ElectionMs:                 1000,
 		InitialElectionTickAdvance: true,
-
-		LPUrls: []url.URL{*lpurl},
-		LCUrls: []url.URL{*lcurl},
-		APUrls: []url.URL{*apurl},
-		ACUrls: []url.URL{*acurl},
-
-		ClusterState:        ClusterStateFlagNew,
-		InitialClusterToken: "etcd-cluster",
-
-		StrictReconfigCheck: DefaultStrictReconfigCheck,
-		Metrics:             "basic",
-		EnableV2:            DefaultEnableV2,
-
-		CORS:          map[string]struct{}{"*": {}},
-		HostWhitelist: map[string]struct{}{"*": {}},
-
-		AuthToken:  "simple",
-		BcryptCost: uint(bcrypt.DefaultCost),
-
-		PreVote: false, // TODO: enable by default in v3.5
-
-		loggerMu:            new(sync.RWMutex),
-		logger:              nil,
-		Logger:              "capnslog",
-		DeprecatedLogOutput: []string{DefaultLogOutput},
-		LogOutputs:          []string{DefaultLogOutput},
-		Debug:               false,
-		LogLevel:            logutil.DefaultLogLevel,
-		LogPkgLevels:        "",
+		LPUrls:                     []url.URL{*lpurl},
+		LCUrls:                     []url.URL{*lcurl},
+		APUrls:                     []url.URL{*apurl},
+		ACUrls:                     []url.URL{*acurl},
+		ClusterState:               ClusterStateFlagNew,
+		InitialClusterToken:        "etcd-cluster",
+		StrictReconfigCheck:        DefaultStrictReconfigCheck,
+		LogOutput:                  DefaultLogOutput,
+		Metrics:                    "basic",
+		EnableV2:                   DefaultEnableV2,
+		AuthToken:                  "simple",
+		AuthTokenTTL: 300,
 	}
 	cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
 	return cfg
@@ -437,6 +306,46 @@
 	}
 }
 
+// SetupLogging initializes etcd logging.
+// Must be called after flag parsing.
+func (cfg *Config) SetupLogging() {
+	cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure
+	cfg.PeerTLSInfo.HandshakeFailure = logTLSHandshakeFailure
+
+	capnslog.SetGlobalLogLevel(capnslog.INFO)
+	if cfg.Debug {
+		capnslog.SetGlobalLogLevel(capnslog.DEBUG)
+		grpc.EnableTracing = true
+		// enable info, warning, error
+		grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
+	} else {
+		// only discard info
+		grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr))
+	}
+	if cfg.LogPkgLevels != "" {
+		repoLog := capnslog.MustRepoLogger("github.com/coreos/etcd")
+		settings, err := repoLog.ParseLogLevelConfig(cfg.LogPkgLevels)
+		if err != nil {
+			plog.Warningf("couldn't parse log level string: %s, continuing with default levels", err.Error())
+			return
+		}
+		repoLog.SetLogLevel(settings)
+	}
+
+	// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
+	// where NewDefaultFormatter returns NewJournaldFormatter when syscall.Getppid() == 1
+	// specify 'stdout' or 'stderr' to skip journald logging even when running under systemd
+	switch cfg.LogOutput {
+	case "stdout":
+		capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, cfg.Debug))
+	case "stderr":
+		capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stderr, cfg.Debug))
+	case DefaultLogOutput:
+	default:
+		plog.Panicf(`unknown log-output %q (only supports %q, "stdout", "stderr")`, cfg.LogOutput, DefaultLogOutput)
+	}
+}
+
 func ConfigFromFile(path string) (*Config, error) {
 	cfg := &configYAML{Config: *NewConfig()}
 	if err := cfg.configFromFile(path); err != nil {
@@ -461,8 +370,7 @@
 	if cfg.LPUrlsJSON != "" {
 		u, err := types.NewURLs(strings.Split(cfg.LPUrlsJSON, ","))
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "unexpected error setting up listen-peer-urls: %v\n", err)
-			os.Exit(1)
+			plog.Fatalf("unexpected error setting up listen-peer-urls: %v", err)
 		}
 		cfg.LPUrls = []url.URL(u)
 	}
@@ -470,17 +378,21 @@
 	if cfg.LCUrlsJSON != "" {
 		u, err := types.NewURLs(strings.Split(cfg.LCUrlsJSON, ","))
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "unexpected error setting up listen-client-urls: %v\n", err)
-			os.Exit(1)
+			plog.Fatalf("unexpected error setting up listen-client-urls: %v", err)
 		}
 		cfg.LCUrls = []url.URL(u)
 	}
 
+	if cfg.CorsJSON != "" {
+		if err := cfg.CorsInfo.Set(cfg.CorsJSON); err != nil {
+			plog.Panicf("unexpected error setting up cors: %v", err)
+		}
+	}
+
 	if cfg.APUrlsJSON != "" {
 		u, err := types.NewURLs(strings.Split(cfg.APUrlsJSON, ","))
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "unexpected error setting up initial-advertise-peer-urls: %v\n", err)
-			os.Exit(1)
+			plog.Fatalf("unexpected error setting up initial-advertise-peer-urls: %v", err)
 		}
 		cfg.APUrls = []url.URL(u)
 	}
@@ -488,8 +400,7 @@
 	if cfg.ACUrlsJSON != "" {
 		u, err := types.NewURLs(strings.Split(cfg.ACUrlsJSON, ","))
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "unexpected error setting up advertise-peer-urls: %v\n", err)
-			os.Exit(1)
+			plog.Fatalf("unexpected error setting up advertise-peer-urls: %v", err)
 		}
 		cfg.ACUrls = []url.URL(u)
 	}
@@ -497,22 +408,11 @@
 	if cfg.ListenMetricsUrlsJSON != "" {
 		u, err := types.NewURLs(strings.Split(cfg.ListenMetricsUrlsJSON, ","))
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "unexpected error setting up listen-metrics-urls: %v\n", err)
-			os.Exit(1)
+			plog.Fatalf("unexpected error setting up listen-metrics-urls: %v", err)
 		}
 		cfg.ListenMetricsUrls = []url.URL(u)
 	}
 
-	if cfg.CORSJSON != "" {
-		uv := flags.NewUniqueURLsWithExceptions(cfg.CORSJSON, "*")
-		cfg.CORS = uv.Values
-	}
-
-	if cfg.HostWhitelistJSON != "" {
-		uv := flags.NewUniqueStringsValue(cfg.HostWhitelistJSON)
-		cfg.HostWhitelist = uv.Values
-	}
-
 	// If a discovery flag is set, clear default initial cluster set by InitialClusterFromName
 	if (cfg.Durl != "" || cfg.DNSCluster != "") && cfg.InitialCluster == defaultInitialCluster {
 		cfg.InitialCluster = ""
@@ -522,6 +422,7 @@
 	}
 
 	copySecurityDetails := func(tls *transport.TLSInfo, ysc *securityConfig) {
+		tls.CAFile = ysc.CAFile
 		tls.CertFile = ysc.CertFile
 		tls.KeyFile = ysc.KeyFile
 		tls.ClientCertAuth = ysc.CertAuth
@@ -555,9 +456,6 @@
 
 // Validate ensures that '*embed.Config' fields are properly configured.
 func (cfg *Config) Validate() error {
-	if err := cfg.setupLogging(); err != nil {
-		return err
-	}
 	if err := checkBindURLs(cfg.LPUrls); err != nil {
 		return err
 	}
@@ -568,13 +466,22 @@
 		return err
 	}
 	if err := checkHostURLs(cfg.APUrls); err != nil {
-		addrs := cfg.getAPURLs()
-		return fmt.Errorf(`--initial-advertise-peer-urls %q must be "host:port" (%v)`, strings.Join(addrs, ","), err)
+		// TODO: return err in v3.4
+		addrs := make([]string, len(cfg.APUrls))
+		for i := range cfg.APUrls {
+			addrs[i] = cfg.APUrls[i].String()
+		}
+		plog.Warningf("advertise-peer-urls %q is deprecated (%v)", strings.Join(addrs, ","), err)
 	}
 	if err := checkHostURLs(cfg.ACUrls); err != nil {
-		addrs := cfg.getACURLs()
-		return fmt.Errorf(`--advertise-client-urls %q must be "host:port" (%v)`, strings.Join(addrs, ","), err)
+		// TODO: return err in v3.4
+		addrs := make([]string, len(cfg.ACUrls))
+		for i := range cfg.ACUrls {
+			addrs[i] = cfg.ACUrls[i].String()
+		}
+		plog.Warningf("advertise-client-urls %q is deprecated (%v)", strings.Join(addrs, ","), err)
 	}
+
 	// Check if conflicting flags are passed.
 	nSet := 0
 	for _, v := range []bool{cfg.Durl != "", cfg.InitialCluster != "", cfg.DNSCluster != ""} {
@@ -611,7 +518,7 @@
 
 	switch cfg.AutoCompactionMode {
 	case "":
-	case CompactorModeRevision, CompactorModePeriodic:
+	case compactor.ModeRevision, compactor.ModePeriodic:
 	default:
 		return fmt.Errorf("unknown auto-compaction-mode %q", cfg.AutoCompactionMode)
 	}
@@ -629,27 +536,17 @@
 		// self's advertised peer URLs
 		urlsmap[cfg.Name] = cfg.APUrls
 		token = cfg.Durl
-
 	case cfg.DNSCluster != "":
-		clusterStrs, cerr := cfg.GetDNSClusterNames()
-		lg := cfg.logger
+		clusterStrs, cerr := srv.GetCluster("etcd-server", cfg.Name, cfg.DNSCluster, cfg.APUrls)
 		if cerr != nil {
-			if lg != nil {
-				lg.Warn("failed to resolve during SRV discovery", zap.Error(cerr))
-			} else {
-				plog.Errorf("couldn't resolve during SRV discovery (%v)", cerr)
-			}
+			plog.Errorf("couldn't resolve during SRV discovery (%v)", cerr)
 			return nil, "", cerr
 		}
 		for _, s := range clusterStrs {
-			if lg != nil {
-				lg.Info("got bootstrap from DNS for etcd-server", zap.String("node", s))
-			} else {
-				plog.Noticef("got bootstrap from DNS for etcd-server at %s", s)
-			}
+			plog.Noticef("got bootstrap from DNS for etcd-server at %s", s)
 		}
 		clusterStr := strings.Join(clusterStrs, ",")
-		if strings.Contains(clusterStr, "https://") && cfg.PeerTLSInfo.TrustedCAFile == "" {
+		if strings.Contains(clusterStr, "https://") && cfg.PeerTLSInfo.CAFile == "" {
 			cfg.PeerTLSInfo.ServerName = cfg.DNSCluster
 		}
 		urlsmap, err = types.NewURLsMap(clusterStr)
@@ -660,7 +557,6 @@
 				return nil, "", fmt.Errorf("cannot find local etcd member %q in SRV records", cfg.Name)
 			}
 		}
-
 	default:
 		// We're statically configured, and cluster has appropriately been set.
 		urlsmap, err = types.NewURLsMap(cfg.InitialCluster)
@@ -668,58 +564,6 @@
 	return urlsmap, token, err
 }
 
-// GetDNSClusterNames uses DNS SRV records to get a list of initial nodes for cluster bootstrapping.
-func (cfg *Config) GetDNSClusterNames() ([]string, error) {
-	var (
-		clusterStrs       []string
-		cerr              error
-		serviceNameSuffix string
-	)
-	if cfg.DNSClusterServiceName != "" {
-		serviceNameSuffix = "-" + cfg.DNSClusterServiceName
-	}
-
-	lg := cfg.GetLogger()
-
-	// Use both etcd-server-ssl and etcd-server for discovery.
-	// Combine the results if both are available.
-	clusterStrs, cerr = srv.GetCluster("https", "etcd-server-ssl"+serviceNameSuffix, cfg.Name, cfg.DNSCluster, cfg.APUrls)
-	if cerr != nil {
-		clusterStrs = make([]string, 0)
-	}
-	if lg != nil {
-		lg.Info(
-			"get cluster for etcd-server-ssl SRV",
-			zap.String("service-scheme", "https"),
-			zap.String("service-name", "etcd-server-ssl"+serviceNameSuffix),
-			zap.String("server-name", cfg.Name),
-			zap.String("discovery-srv", cfg.DNSCluster),
-			zap.Strings("advertise-peer-urls", cfg.getAPURLs()),
-			zap.Strings("found-cluster", clusterStrs),
-			zap.Error(cerr),
-		)
-	}
-
-	defaultHTTPClusterStrs, httpCerr := srv.GetCluster("http", "etcd-server"+serviceNameSuffix, cfg.Name, cfg.DNSCluster, cfg.APUrls)
-	if httpCerr != nil {
-		clusterStrs = append(clusterStrs, defaultHTTPClusterStrs...)
-	}
-	if lg != nil {
-		lg.Info(
-			"get cluster for etcd-server SRV",
-			zap.String("service-scheme", "http"),
-			zap.String("service-name", "etcd-server"+serviceNameSuffix),
-			zap.String("server-name", cfg.Name),
-			zap.String("discovery-srv", cfg.DNSCluster),
-			zap.Strings("advertise-peer-urls", cfg.getAPURLs()),
-			zap.Strings("found-cluster", clusterStrs),
-			zap.Error(httpCerr),
-		)
-	}
-
-	return clusterStrs, cerr
-}
-
 func (cfg Config) InitialClusterFromName(name string) (ret string) {
 	if len(cfg.APUrls) == 0 {
 		return ""
@@ -750,18 +594,14 @@
 		return nil
 	}
 	if !cfg.ClientTLSInfo.Empty() {
-		if cfg.logger != nil {
-			cfg.logger.Warn("ignoring client auto TLS since certs given")
-		} else {
-			plog.Warningf("ignoring client auto TLS since certs given")
-		}
+		plog.Warningf("ignoring client auto TLS since certs given")
 		return nil
 	}
 	chosts := make([]string, len(cfg.LCUrls))
 	for i, u := range cfg.LCUrls {
 		chosts[i] = u.Host
 	}
-	cfg.ClientTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
+	cfg.ClientTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "client"), chosts)
 	if err != nil {
 		return err
 	}
@@ -773,18 +613,14 @@
 		return nil
 	}
 	if !cfg.PeerTLSInfo.Empty() {
-		if cfg.logger != nil {
-			cfg.logger.Warn("ignoring peer auto TLS since certs given")
-		} else {
-			plog.Warningf("ignoring peer auto TLS since certs given")
-		}
+		plog.Warningf("ignoring peer auto TLS since certs given")
 		return nil
 	}
 	phosts := make([]string, len(cfg.LPUrls))
 	for i, u := range cfg.LPUrls {
 		phosts[i] = u.Host
 	}
-	cfg.PeerTLSInfo, err = transport.SelfCert(cfg.logger, filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
+	cfg.PeerTLSInfo, err = transport.SelfCert(filepath.Join(cfg.Dir, "fixtures", "peer"), phosts)
 	if err != nil {
 		return err
 	}
@@ -865,51 +701,3 @@
 	}
 	return nil
 }
-
-func (cfg *Config) getAPURLs() (ss []string) {
-	ss = make([]string, len(cfg.APUrls))
-	for i := range cfg.APUrls {
-		ss[i] = cfg.APUrls[i].String()
-	}
-	return ss
-}
-
-func (cfg *Config) getLPURLs() (ss []string) {
-	ss = make([]string, len(cfg.LPUrls))
-	for i := range cfg.LPUrls {
-		ss[i] = cfg.LPUrls[i].String()
-	}
-	return ss
-}
-
-func (cfg *Config) getACURLs() (ss []string) {
-	ss = make([]string, len(cfg.ACUrls))
-	for i := range cfg.ACUrls {
-		ss[i] = cfg.ACUrls[i].String()
-	}
-	return ss
-}
-
-func (cfg *Config) getLCURLs() (ss []string) {
-	ss = make([]string, len(cfg.LCUrls))
-	for i := range cfg.LCUrls {
-		ss[i] = cfg.LCUrls[i].String()
-	}
-	return ss
-}
-
-func (cfg *Config) getMetricsURLs() (ss []string) {
-	ss = make([]string, len(cfg.ListenMetricsUrls))
-	for i := range cfg.ListenMetricsUrls {
-		ss[i] = cfg.ListenMetricsUrls[i].String()
-	}
-	return ss
-}
-
-func parseBackendFreelistType(freelistType string) bolt.FreelistType {
-	if freelistType == freelistMapType {
-		return bolt.FreelistMapType
-	}
-
-	return bolt.FreelistArrayType
-}
diff --git a/vendor/go.etcd.io/etcd/embed/config_logging.go b/vendor/go.etcd.io/etcd/embed/config_logging.go
deleted file mode 100644
index e42103c..0000000
--- a/vendor/go.etcd.io/etcd/embed/config_logging.go
+++ /dev/null
@@ -1,312 +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 embed
-
-import (
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"sync"
-
-	"go.etcd.io/etcd/pkg/logutil"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/grpclog"
-)
-
-// GetLogger returns the logger.
-func (cfg Config) GetLogger() *zap.Logger {
-	cfg.loggerMu.RLock()
-	l := cfg.logger
-	cfg.loggerMu.RUnlock()
-	return l
-}
-
-// for testing
-var grpcLogOnce = new(sync.Once)
-
-// setupLogging initializes etcd logging.
-// Must be called after flag parsing or finishing configuring embed.Config.
-func (cfg *Config) setupLogging() error {
-	// handle "DeprecatedLogOutput" in v3.4
-	// TODO: remove "DeprecatedLogOutput" in v3.5
-	len1 := len(cfg.DeprecatedLogOutput)
-	len2 := len(cfg.LogOutputs)
-	if len1 != len2 {
-		switch {
-		case len1 > len2: // deprecate "log-output" flag is used
-			fmt.Fprintln(os.Stderr, "'--log-output' flag has been deprecated! Please use '--log-outputs'!")
-			cfg.LogOutputs = cfg.DeprecatedLogOutput
-		case len1 < len2: // "--log-outputs" flag has been set with multiple writers
-			cfg.DeprecatedLogOutput = []string{}
-		}
-	} else {
-		if len1 > 1 {
-			return errors.New("both '--log-output' and '--log-outputs' are set; only set '--log-outputs'")
-		}
-		if len1 < 1 {
-			return errors.New("either '--log-output' or '--log-outputs' flag must be set")
-		}
-		if reflect.DeepEqual(cfg.DeprecatedLogOutput, cfg.LogOutputs) && cfg.DeprecatedLogOutput[0] != DefaultLogOutput {
-			return fmt.Errorf("'--log-output=%q' and '--log-outputs=%q' are incompatible; only set --log-outputs", cfg.DeprecatedLogOutput, cfg.LogOutputs)
-		}
-		if !reflect.DeepEqual(cfg.DeprecatedLogOutput, []string{DefaultLogOutput}) {
-			fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--log-output' flag is set to %q\n", cfg.DeprecatedLogOutput)
-			fmt.Fprintln(os.Stderr, "Please use '--log-outputs' flag")
-		}
-	}
-
-	// TODO: remove after deprecating log related flags in v3.5
-	if cfg.Debug {
-		fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--debug' flag is set to %v (use '--log-level=debug' instead\n", cfg.Debug)
-	}
-	if cfg.Debug && cfg.LogLevel != "debug" {
-		fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--debug' flag is set to %v with inconsistent '--log-level=%s' flag\n", cfg.Debug, cfg.LogLevel)
-	}
-	if cfg.Logger == "capnslog" {
-		fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--logger=%s' flag is set; use '--logger=zap' flag instead\n", cfg.Logger)
-	}
-	if cfg.LogPkgLevels != "" {
-		fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--log-package-levels=%s' flag is set; use '--logger=zap' flag instead\n", cfg.LogPkgLevels)
-	}
-
-	switch cfg.Logger {
-	case "capnslog": // TODO: deprecate this in v3.5
-		cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-		cfg.PeerTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-
-		if cfg.Debug {
-			capnslog.SetGlobalLogLevel(capnslog.DEBUG)
-			grpc.EnableTracing = true
-			// enable info, warning, error
-			grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
-		} else {
-			capnslog.SetGlobalLogLevel(logutil.ConvertToCapnslogLogLevel(cfg.LogLevel))
-			// only discard info
-			grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr))
-		}
-
-		// TODO: deprecate with "capnslog"
-		if cfg.LogPkgLevels != "" {
-			repoLog := capnslog.MustRepoLogger("go.etcd.io/etcd")
-			settings, err := repoLog.ParseLogLevelConfig(cfg.LogPkgLevels)
-			if err != nil {
-				plog.Warningf("couldn't parse log level string: %s, continuing with default levels", err.Error())
-				return nil
-			}
-			repoLog.SetLogLevel(settings)
-		}
-
-		if len(cfg.LogOutputs) != 1 {
-			return fmt.Errorf("--logger=capnslog supports only 1 value in '--log-outputs', got %q", cfg.LogOutputs)
-		}
-		// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
-		// where NewDefaultFormatter returns NewJournaldFormatter when syscall.Getppid() == 1
-		// specify 'stdout' or 'stderr' to skip journald logging even when running under systemd
-		output := cfg.LogOutputs[0]
-		switch output {
-		case StdErrLogOutput:
-			capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stderr, cfg.Debug))
-		case StdOutLogOutput:
-			capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, cfg.Debug))
-		case DefaultLogOutput:
-		default:
-			return fmt.Errorf("unknown log-output %q (only supports %q, %q, %q)", output, DefaultLogOutput, StdErrLogOutput, StdOutLogOutput)
-		}
-
-	case "zap":
-		if len(cfg.LogOutputs) == 0 {
-			cfg.LogOutputs = []string{DefaultLogOutput}
-		}
-		if len(cfg.LogOutputs) > 1 {
-			for _, v := range cfg.LogOutputs {
-				if v == DefaultLogOutput {
-					return fmt.Errorf("multi logoutput for %q is not supported yet", DefaultLogOutput)
-				}
-			}
-		}
-
-		outputPaths, errOutputPaths := make([]string, 0), make([]string, 0)
-		isJournal := false
-		for _, v := range cfg.LogOutputs {
-			switch v {
-			case DefaultLogOutput:
-				outputPaths = append(outputPaths, StdErrLogOutput)
-				errOutputPaths = append(errOutputPaths, StdErrLogOutput)
-
-			case JournalLogOutput:
-				isJournal = true
-
-			case StdErrLogOutput:
-				outputPaths = append(outputPaths, StdErrLogOutput)
-				errOutputPaths = append(errOutputPaths, StdErrLogOutput)
-
-			case StdOutLogOutput:
-				outputPaths = append(outputPaths, StdOutLogOutput)
-				errOutputPaths = append(errOutputPaths, StdOutLogOutput)
-
-			default:
-				outputPaths = append(outputPaths, v)
-				errOutputPaths = append(errOutputPaths, v)
-			}
-		}
-
-		if !isJournal {
-			copied := logutil.DefaultZapLoggerConfig
-			copied.OutputPaths = outputPaths
-			copied.ErrorOutputPaths = errOutputPaths
-			copied = logutil.MergeOutputPaths(copied)
-			copied.Level = zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
-			if cfg.Debug || cfg.LogLevel == "debug" {
-				// enable tracing even when "--debug --log-level info"
-				// in order to keep backward compatibility with <= v3.3
-				// TODO: remove "Debug" check in v3.5
-				grpc.EnableTracing = true
-			}
-			if cfg.ZapLoggerBuilder == nil {
-				cfg.ZapLoggerBuilder = func(c *Config) error {
-					var err error
-					c.logger, err = copied.Build()
-					if err != nil {
-						return err
-					}
-					c.loggerMu.Lock()
-					defer c.loggerMu.Unlock()
-					c.loggerConfig = &copied
-					c.loggerCore = nil
-					c.loggerWriteSyncer = nil
-					grpcLogOnce.Do(func() {
-						// debug true, enable info, warning, error
-						// debug false, only discard info
-						var gl grpclog.LoggerV2
-						gl, err = logutil.NewGRPCLoggerV2(copied)
-						if err == nil {
-							grpclog.SetLoggerV2(gl)
-						}
-					})
-					return nil
-				}
-			}
-		} else {
-			if len(cfg.LogOutputs) > 1 {
-				for _, v := range cfg.LogOutputs {
-					if v != DefaultLogOutput {
-						return fmt.Errorf("running with systemd/journal but other '--log-outputs' values (%q) are configured with 'default'; override 'default' value with something else", cfg.LogOutputs)
-					}
-				}
-			}
-
-			// use stderr as fallback
-			syncer, lerr := getJournalWriteSyncer()
-			if lerr != nil {
-				return lerr
-			}
-
-			lvl := zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
-			if cfg.Debug || cfg.LogLevel == "debug" {
-				// enable tracing even when "--debug --log-level info"
-				// in order to keep backward compatibility with <= v3.3
-				// TODO: remove "Debug" check in v3.5
-				grpc.EnableTracing = true
-			}
-
-			// WARN: do not change field names in encoder config
-			// journald logging writer assumes field names of "level" and "caller"
-			cr := zapcore.NewCore(
-				zapcore.NewJSONEncoder(logutil.DefaultZapLoggerConfig.EncoderConfig),
-				syncer,
-				lvl,
-			)
-			if cfg.ZapLoggerBuilder == nil {
-				cfg.ZapLoggerBuilder = func(c *Config) error {
-					c.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer))
-					c.loggerMu.Lock()
-					defer c.loggerMu.Unlock()
-					c.loggerConfig = nil
-					c.loggerCore = cr
-					c.loggerWriteSyncer = syncer
-
-					grpcLogOnce.Do(func() {
-						grpclog.SetLoggerV2(logutil.NewGRPCLoggerV2FromZapCore(cr, syncer))
-					})
-					return nil
-				}
-			}
-		}
-
-		err := cfg.ZapLoggerBuilder(cfg)
-		if err != nil {
-			return err
-		}
-
-		logTLSHandshakeFailure := func(conn *tls.Conn, err error) {
-			state := conn.ConnectionState()
-			remoteAddr := conn.RemoteAddr().String()
-			serverName := state.ServerName
-			if len(state.PeerCertificates) > 0 {
-				cert := state.PeerCertificates[0]
-				ips := make([]string, len(cert.IPAddresses))
-				for i := range cert.IPAddresses {
-					ips[i] = cert.IPAddresses[i].String()
-				}
-				cfg.logger.Warn(
-					"rejected connection",
-					zap.String("remote-addr", remoteAddr),
-					zap.String("server-name", serverName),
-					zap.Strings("ip-addresses", ips),
-					zap.Strings("dns-names", cert.DNSNames),
-					zap.Error(err),
-				)
-			} else {
-				cfg.logger.Warn(
-					"rejected connection",
-					zap.String("remote-addr", remoteAddr),
-					zap.String("server-name", serverName),
-					zap.Error(err),
-				)
-			}
-		}
-		cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-		cfg.PeerTLSInfo.HandshakeFailure = logTLSHandshakeFailure
-
-	default:
-		return fmt.Errorf("unknown logger option %q", cfg.Logger)
-	}
-
-	return nil
-}
-
-// NewZapCoreLoggerBuilder generates a zap core logger builder.
-func NewZapCoreLoggerBuilder(lg *zap.Logger, cr zapcore.Core, syncer zapcore.WriteSyncer) func(*Config) error {
-	return func(cfg *Config) error {
-		cfg.loggerMu.Lock()
-		defer cfg.loggerMu.Unlock()
-		cfg.logger = lg
-		cfg.loggerConfig = nil
-		cfg.loggerCore = cr
-		cfg.loggerWriteSyncer = syncer
-
-		grpcLogOnce.Do(func() {
-			grpclog.SetLoggerV2(logutil.NewGRPCLoggerV2FromZapCore(cr, syncer))
-		})
-		return nil
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/embed/config_logging_journal_unix.go b/vendor/go.etcd.io/etcd/embed/config_logging_journal_unix.go
deleted file mode 100644
index 44a51d6..0000000
--- a/vendor/go.etcd.io/etcd/embed/config_logging_journal_unix.go
+++ /dev/null
@@ -1,35 +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.
-
-// +build !windows
-
-package embed
-
-import (
-	"fmt"
-	"os"
-
-	"go.etcd.io/etcd/pkg/logutil"
-
-	"go.uber.org/zap/zapcore"
-)
-
-// use stderr as fallback
-func getJournalWriteSyncer() (zapcore.WriteSyncer, error) {
-	jw, err := logutil.NewJournalWriter(os.Stderr)
-	if err != nil {
-		return nil, fmt.Errorf("can't find journal (%v)", err)
-	}
-	return zapcore.AddSync(jw), nil
-}
diff --git a/vendor/go.etcd.io/etcd/embed/config_logging_journal_windows.go b/vendor/go.etcd.io/etcd/embed/config_logging_journal_windows.go
deleted file mode 100644
index 5b76256..0000000
--- a/vendor/go.etcd.io/etcd/embed/config_logging_journal_windows.go
+++ /dev/null
@@ -1,27 +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.
-
-// +build windows
-
-package embed
-
-import (
-	"os"
-
-	"go.uber.org/zap/zapcore"
-)
-
-func getJournalWriteSyncer() (zapcore.WriteSyncer, error) {
-	return zapcore.AddSync(os.Stderr), nil
-}
diff --git a/vendor/go.etcd.io/etcd/embed/doc.go b/vendor/go.etcd.io/etcd/embed/doc.go
index 4811bb6..c555aa5 100644
--- a/vendor/go.etcd.io/etcd/embed/doc.go
+++ b/vendor/go.etcd.io/etcd/embed/doc.go
@@ -21,7 +21,7 @@
 		"log"
 		"time"
 
-		"go.etcd.io/etcd/embed"
+		"github.com/coreos/etcd/embed"
 	)
 
 	func main() {
diff --git a/vendor/go.etcd.io/etcd/embed/etcd.go b/vendor/go.etcd.io/etcd/embed/etcd.go
index ac7dbc9..d656e17 100644
--- a/vendor/go.etcd.io/etcd/embed/etcd.go
+++ b/vendor/go.etcd.io/etcd/embed/etcd.go
@@ -23,34 +23,32 @@
 	"net"
 	"net/http"
 	"net/url"
-	"runtime"
-	"sort"
 	"strconv"
 	"sync"
 	"time"
 
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/etcdhttp"
-	"go.etcd.io/etcd/etcdserver/api/rafthttp"
-	"go.etcd.io/etcd/etcdserver/api/v2http"
-	"go.etcd.io/etcd/etcdserver/api/v2v3"
-	"go.etcd.io/etcd/etcdserver/api/v3client"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc"
-	"go.etcd.io/etcd/pkg/debugutil"
-	runtimeutil "go.etcd.io/etcd/pkg/runtime"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/version"
+	"github.com/coreos/etcd/compactor"
+	"github.com/coreos/etcd/etcdserver"
+	"github.com/coreos/etcd/etcdserver/api/etcdhttp"
+	"github.com/coreos/etcd/etcdserver/api/v2http"
+	"github.com/coreos/etcd/etcdserver/api/v2v3"
+	"github.com/coreos/etcd/etcdserver/api/v3client"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc"
+	"github.com/coreos/etcd/pkg/cors"
+	"github.com/coreos/etcd/pkg/debugutil"
+	runtimeutil "github.com/coreos/etcd/pkg/runtime"
+	"github.com/coreos/etcd/pkg/transport"
+	"github.com/coreos/etcd/pkg/types"
+	"github.com/coreos/etcd/rafthttp"
 
 	"github.com/coreos/pkg/capnslog"
 	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/soheilhy/cmux"
-	"go.uber.org/zap"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/keepalive"
 )
 
-var plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "embed")
+var plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "embed")
 
 const (
 	// internal fd usage includes disk usage and transport usage.
@@ -113,26 +111,12 @@
 		e = nil
 	}()
 
-	if e.cfg.logger != nil {
-		e.cfg.logger.Info(
-			"configuring peer listeners",
-			zap.Strings("listen-peer-urls", e.cfg.getLPURLs()),
-		)
-	}
-	if e.Peers, err = configurePeerListeners(cfg); err != nil {
+	if e.Peers, err = startPeerListeners(cfg); err != nil {
 		return e, err
 	}
-
-	if e.cfg.logger != nil {
-		e.cfg.logger.Info(
-			"configuring client listeners",
-			zap.Strings("listen-client-urls", e.cfg.getLCURLs()),
-		)
-	}
-	if e.sctxs, err = configureClientListeners(cfg); err != nil {
+	if e.sctxs, err = startClientListeners(cfg); err != nil {
 		return e, err
 	}
-
 	for _, sctx := range e.sctxs {
 		e.Clients = append(e.Clients, sctx.l)
 	}
@@ -141,6 +125,7 @@
 		urlsmap types.URLsMap
 		token   string
 	)
+
 	memberInitialized := true
 	if !isMemberInitialized(cfg) {
 		memberInitialized = false
@@ -159,16 +144,13 @@
 		return e, err
 	}
 
-	backendFreelistType := parseBackendFreelistType(cfg.ExperimentalBackendFreelistType)
-
 	srvcfg := etcdserver.ServerConfig{
 		Name:                       cfg.Name,
 		ClientURLs:                 cfg.ACUrls,
 		PeerURLs:                   cfg.APUrls,
 		DataDir:                    cfg.Dir,
 		DedicatedWALDir:            cfg.WalDir,
-		SnapshotCount:              cfg.SnapshotCount,
-		SnapshotCatchUpEntries:     cfg.SnapshotCatchUpEntries,
+		SnapCount:                  cfg.SnapCount,
 		MaxSnapFiles:               cfg.MaxSnapFiles,
 		MaxWALFiles:                cfg.MaxWalFiles,
 		InitialPeerURLsMap:         urlsmap,
@@ -176,6 +158,7 @@
 		DiscoveryURL:               cfg.Durl,
 		DiscoveryProxy:             cfg.Dproxy,
 		NewCluster:                 cfg.IsNewCluster(),
+		ForceNewCluster:            cfg.ForceNewCluster,
 		PeerTLSInfo:                cfg.PeerTLSInfo,
 		TickMs:                     cfg.TickMs,
 		ElectionTicks:              cfg.ElectionTicks(),
@@ -183,31 +166,17 @@
 		AutoCompactionRetention:    autoCompactionRetention,
 		AutoCompactionMode:         cfg.AutoCompactionMode,
 		QuotaBackendBytes:          cfg.QuotaBackendBytes,
-		BackendBatchLimit:          cfg.BackendBatchLimit,
-		BackendFreelistType:        backendFreelistType,
-		BackendBatchInterval:       cfg.BackendBatchInterval,
 		MaxTxnOps:                  cfg.MaxTxnOps,
 		MaxRequestBytes:            cfg.MaxRequestBytes,
 		StrictReconfigCheck:        cfg.StrictReconfigCheck,
 		ClientCertAuthEnabled:      cfg.ClientTLSInfo.ClientCertAuth,
 		AuthToken:                  cfg.AuthToken,
-		BcryptCost:                 cfg.BcryptCost,
-		CORS:                       cfg.CORS,
-		HostWhitelist:              cfg.HostWhitelist,
+		TokenTTL:                   cfg.AuthTokenTTL,
 		InitialCorruptCheck:        cfg.ExperimentalInitialCorruptCheck,
 		CorruptCheckTime:           cfg.ExperimentalCorruptCheckTime,
-		PreVote:                    cfg.PreVote,
-		Logger:                     cfg.logger,
-		LoggerConfig:               cfg.loggerConfig,
-		LoggerCore:                 cfg.loggerCore,
-		LoggerWriteSyncer:          cfg.loggerWriteSyncer,
 		Debug:                      cfg.Debug,
-		ForceNewCluster:            cfg.ForceNewCluster,
-		EnableGRPCGateway:          cfg.EnableGRPCGateway,
-		EnableLeaseCheckpoint:      cfg.ExperimentalEnableLeaseCheckpoint,
-		CompactionBatchLimit:       cfg.ExperimentalCompactionBatchLimit,
 	}
-	print(e.cfg.logger, *cfg, srvcfg, memberInitialized)
+
 	if e.Server, err = etcdserver.NewServer(srvcfg); err != nil {
 		return e, err
 	}
@@ -237,109 +206,10 @@
 		return e, err
 	}
 
-	if e.cfg.logger != nil {
-		e.cfg.logger.Info(
-			"now serving peer/client/metrics",
-			zap.String("local-member-id", e.Server.ID().String()),
-			zap.Strings("initial-advertise-peer-urls", e.cfg.getAPURLs()),
-			zap.Strings("listen-peer-urls", e.cfg.getLPURLs()),
-			zap.Strings("advertise-client-urls", e.cfg.getACURLs()),
-			zap.Strings("listen-client-urls", e.cfg.getLCURLs()),
-			zap.Strings("listen-metrics-urls", e.cfg.getMetricsURLs()),
-		)
-	}
 	serving = true
 	return e, nil
 }
 
-func print(lg *zap.Logger, ec Config, sc etcdserver.ServerConfig, memberInitialized bool) {
-	// TODO: remove this after dropping "capnslog"
-	if lg == nil {
-		plog.Infof("name = %s", ec.Name)
-		if sc.ForceNewCluster {
-			plog.Infof("force new cluster")
-		}
-		plog.Infof("data dir = %s", sc.DataDir)
-		plog.Infof("member dir = %s", sc.MemberDir())
-		if sc.DedicatedWALDir != "" {
-			plog.Infof("dedicated WAL dir = %s", sc.DedicatedWALDir)
-		}
-		plog.Infof("heartbeat = %dms", sc.TickMs)
-		plog.Infof("election = %dms", sc.ElectionTicks*int(sc.TickMs))
-		plog.Infof("snapshot count = %d", sc.SnapshotCount)
-		if len(sc.DiscoveryURL) != 0 {
-			plog.Infof("discovery URL= %s", sc.DiscoveryURL)
-			if len(sc.DiscoveryProxy) != 0 {
-				plog.Infof("discovery proxy = %s", sc.DiscoveryProxy)
-			}
-		}
-		plog.Infof("advertise client URLs = %s", sc.ClientURLs)
-		if memberInitialized {
-			plog.Infof("initial advertise peer URLs = %s", sc.PeerURLs)
-			plog.Infof("initial cluster = %s", sc.InitialPeerURLsMap)
-		}
-	} else {
-		cors := make([]string, 0, len(ec.CORS))
-		for v := range ec.CORS {
-			cors = append(cors, v)
-		}
-		sort.Strings(cors)
-
-		hss := make([]string, 0, len(ec.HostWhitelist))
-		for v := range ec.HostWhitelist {
-			hss = append(hss, v)
-		}
-		sort.Strings(hss)
-
-		quota := ec.QuotaBackendBytes
-		if quota == 0 {
-			quota = etcdserver.DefaultQuotaBytes
-		}
-
-		lg.Info(
-			"starting an etcd server",
-			zap.String("etcd-version", version.Version),
-			zap.String("git-sha", version.GitSHA),
-			zap.String("go-version", runtime.Version()),
-			zap.String("go-os", runtime.GOOS),
-			zap.String("go-arch", runtime.GOARCH),
-			zap.Int("max-cpu-set", runtime.GOMAXPROCS(0)),
-			zap.Int("max-cpu-available", runtime.NumCPU()),
-			zap.Bool("member-initialized", memberInitialized),
-			zap.String("name", sc.Name),
-			zap.String("data-dir", sc.DataDir),
-			zap.String("wal-dir", ec.WalDir),
-			zap.String("wal-dir-dedicated", sc.DedicatedWALDir),
-			zap.String("member-dir", sc.MemberDir()),
-			zap.Bool("force-new-cluster", sc.ForceNewCluster),
-			zap.String("heartbeat-interval", fmt.Sprintf("%v", time.Duration(sc.TickMs)*time.Millisecond)),
-			zap.String("election-timeout", fmt.Sprintf("%v", time.Duration(sc.ElectionTicks*int(sc.TickMs))*time.Millisecond)),
-			zap.Bool("initial-election-tick-advance", sc.InitialElectionTickAdvance),
-			zap.Uint64("snapshot-count", sc.SnapshotCount),
-			zap.Uint64("snapshot-catchup-entries", sc.SnapshotCatchUpEntries),
-			zap.Strings("initial-advertise-peer-urls", ec.getAPURLs()),
-			zap.Strings("listen-peer-urls", ec.getLPURLs()),
-			zap.Strings("advertise-client-urls", ec.getACURLs()),
-			zap.Strings("listen-client-urls", ec.getLCURLs()),
-			zap.Strings("listen-metrics-urls", ec.getMetricsURLs()),
-			zap.Strings("cors", cors),
-			zap.Strings("host-whitelist", hss),
-			zap.String("initial-cluster", sc.InitialPeerURLsMap.String()),
-			zap.String("initial-cluster-state", ec.ClusterState),
-			zap.String("initial-cluster-token", sc.InitialClusterToken),
-			zap.Int64("quota-size-bytes", quota),
-			zap.Bool("pre-vote", sc.PreVote),
-			zap.Bool("initial-corrupt-check", sc.InitialCorruptCheck),
-			zap.String("corrupt-check-time-interval", sc.CorruptCheckTime.String()),
-			zap.String("auto-compaction-mode", sc.AutoCompactionMode),
-			zap.Duration("auto-compaction-retention", sc.AutoCompactionRetention),
-			zap.String("auto-compaction-interval", sc.AutoCompactionRetention.String()),
-			zap.String("discovery-url", sc.DiscoveryURL),
-			zap.String("discovery-proxy", sc.DiscoveryProxy),
-		)
-	}
-}
-
 // Config returns the current configuration.
 func (e *Etcd) Config() Config {
 	return e.cfg
@@ -349,23 +219,6 @@
 // Client requests will be terminated with request timeout.
 // After timeout, enforce remaning requests be closed immediately.
 func (e *Etcd) Close() {
-	fields := []zap.Field{
-		zap.String("name", e.cfg.Name),
-		zap.String("data-dir", e.cfg.Dir),
-		zap.Strings("advertise-peer-urls", e.cfg.getAPURLs()),
-		zap.Strings("advertise-client-urls", e.cfg.getACURLs()),
-	}
-	lg := e.GetLogger()
-	if lg != nil {
-		lg.Info("closing etcd server", fields...)
-	}
-	defer func() {
-		if lg != nil {
-			lg.Info("closed etcd server", fields...)
-			lg.Sync()
-		}
-	}()
-
 	e.closeOnce.Do(func() { close(e.stopc) })
 
 	// close client requests with request timeout
@@ -420,7 +273,7 @@
 
 	// do not grpc.Server.GracefulStop with TLS enabled etcd server
 	// See https://github.com/grpc/grpc-go/issues/1384#issuecomment-317124531
-	// and https://github.com/etcd-io/etcd/issues/8916
+	// and https://github.com/coreos/etcd/issues/8916
 	if ss.secure {
 		shutdownNow()
 		return
@@ -449,27 +302,15 @@
 
 func (e *Etcd) Err() <-chan error { return e.errc }
 
-func configurePeerListeners(cfg *Config) (peers []*peerListener, err error) {
+func startPeerListeners(cfg *Config) (peers []*peerListener, err error) {
 	if err = updateCipherSuites(&cfg.PeerTLSInfo, cfg.CipherSuites); err != nil {
 		return nil, err
 	}
 	if err = cfg.PeerSelfCert(); err != nil {
-		if cfg.logger != nil {
-			cfg.logger.Fatal("failed to get peer self-signed certs", zap.Error(err))
-		} else {
-			plog.Fatalf("could not get certs (%v)", err)
-		}
+		plog.Fatalf("could not get certs (%v)", err)
 	}
 	if !cfg.PeerTLSInfo.Empty() {
-		if cfg.logger != nil {
-			cfg.logger.Info(
-				"starting with peer TLS",
-				zap.String("tls-info", fmt.Sprintf("%+v", cfg.PeerTLSInfo)),
-				zap.Strings("cipher-suites", cfg.CipherSuites),
-			)
-		} else {
-			plog.Infof("peerTLS: %s", cfg.PeerTLSInfo)
-		}
+		plog.Infof("peerTLS: %s", cfg.PeerTLSInfo)
 	}
 
 	peers = make([]*peerListener, len(cfg.LPUrls))
@@ -479,15 +320,7 @@
 		}
 		for i := range peers {
 			if peers[i] != nil && peers[i].close != nil {
-				if cfg.logger != nil {
-					cfg.logger.Warn(
-						"closing peer listener",
-						zap.String("address", cfg.LPUrls[i].String()),
-						zap.Error(err),
-					)
-				} else {
-					plog.Info("stopping listening for peers on ", cfg.LPUrls[i].String())
-				}
+				plog.Info("stopping listening for peers on ", cfg.LPUrls[i].String())
 				ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 				peers[i].close(ctx)
 				cancel()
@@ -498,18 +331,10 @@
 	for i, u := range cfg.LPUrls {
 		if u.Scheme == "http" {
 			if !cfg.PeerTLSInfo.Empty() {
-				if cfg.logger != nil {
-					cfg.logger.Warn("scheme is HTTP while key and cert files are present; ignoring key and cert files", zap.String("peer-url", u.String()))
-				} else {
-					plog.Warningf("The scheme of peer url %s is HTTP while peer key/cert files are presented. Ignored peer key/cert files.", u.String())
-				}
+				plog.Warningf("The scheme of peer url %s is HTTP while peer key/cert files are presented. Ignored peer key/cert files.", u.String())
 			}
 			if cfg.PeerTLSInfo.ClientCertAuth {
-				if cfg.logger != nil {
-					cfg.logger.Warn("scheme is HTTP while --peer-client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("peer-url", u.String()))
-				} else {
-					plog.Warningf("The scheme of peer url %s is HTTP while client cert auth (--peer-client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
-				}
+				plog.Warningf("The scheme of peer url %s is HTTP while client cert auth (--peer-client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
 			}
 		}
 		peers[i] = &peerListener{close: func(context.Context) error { return nil }}
@@ -521,13 +346,14 @@
 		peers[i].close = func(context.Context) error {
 			return peers[i].Listener.Close()
 		}
+		plog.Info("listening for peers on ", u.String())
 	}
 	return peers, nil
 }
 
 // configure peer handlers after rafthttp.Transport started
 func (e *Etcd) servePeers() (err error) {
-	ph := etcdhttp.NewPeerHandler(e.GetLogger(), e.Server)
+	ph := etcdhttp.NewPeerHandler(e.Server)
 	var peerTLScfg *tls.Config
 	if !e.cfg.PeerTLSInfo.Empty() {
 		if peerTLScfg, err = e.cfg.PeerTLSInfo.ServerConfig(); err != nil {
@@ -536,7 +362,6 @@
 	}
 
 	for _, p := range e.Peers {
-		u := p.Listener.Addr().String()
 		gs := v3rpc.Server(e.Server, peerTLScfg)
 		m := cmux.New(p.Listener)
 		go gs.Serve(m.Match(cmux.HTTP2()))
@@ -551,19 +376,7 @@
 			// gracefully shutdown http.Server
 			// close open listeners, idle connections
 			// until context cancel or time-out
-			if e.cfg.logger != nil {
-				e.cfg.logger.Info(
-					"stopping serving peer traffic",
-					zap.String("address", u),
-				)
-			}
 			stopServers(ctx, &servers{secure: peerTLScfg != nil, grpc: gs, http: srv})
-			if e.cfg.logger != nil {
-				e.cfg.logger.Info(
-					"stopped serving peer traffic",
-					zap.String("address", u),
-				)
-			}
 			return nil
 		}
 	}
@@ -571,70 +384,45 @@
 	// start peer servers in a goroutine
 	for _, pl := range e.Peers {
 		go func(l *peerListener) {
-			u := l.Addr().String()
-			if e.cfg.logger != nil {
-				e.cfg.logger.Info(
-					"serving peer traffic",
-					zap.String("address", u),
-				)
-			} else {
-				plog.Info("listening for peers on ", u)
-			}
 			e.errHandler(l.serve())
 		}(pl)
 	}
 	return nil
 }
 
-func configureClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
+func startClientListeners(cfg *Config) (sctxs map[string]*serveCtx, err error) {
 	if err = updateCipherSuites(&cfg.ClientTLSInfo, cfg.CipherSuites); err != nil {
 		return nil, err
 	}
 	if err = cfg.ClientSelfCert(); err != nil {
-		if cfg.logger != nil {
-			cfg.logger.Fatal("failed to get client self-signed certs", zap.Error(err))
-		} else {
-			plog.Fatalf("could not get certs (%v)", err)
-		}
+		plog.Fatalf("could not get certs (%v)", err)
 	}
 	if cfg.EnablePprof {
-		if cfg.logger != nil {
-			cfg.logger.Info("pprof is enabled", zap.String("path", debugutil.HTTPPrefixPProf))
-		} else {
-			plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
-		}
+		plog.Infof("pprof is enabled under %s", debugutil.HTTPPrefixPProf)
 	}
 
 	sctxs = make(map[string]*serveCtx)
 	for _, u := range cfg.LCUrls {
-		sctx := newServeCtx(cfg.logger)
+		sctx := newServeCtx()
+
 		if u.Scheme == "http" || u.Scheme == "unix" {
 			if !cfg.ClientTLSInfo.Empty() {
-				if cfg.logger != nil {
-					cfg.logger.Warn("scheme is HTTP while key and cert files are present; ignoring key and cert files", zap.String("client-url", u.String()))
-				} else {
-					plog.Warningf("The scheme of client url %s is HTTP while peer key/cert files are presented. Ignored key/cert files.", u.String())
-				}
+				plog.Warningf("The scheme of client url %s is HTTP while peer key/cert files are presented. Ignored key/cert files.", u.String())
 			}
 			if cfg.ClientTLSInfo.ClientCertAuth {
-				if cfg.logger != nil {
-					cfg.logger.Warn("scheme is HTTP while --client-cert-auth is enabled; ignoring client cert auth for this URL", zap.String("client-url", u.String()))
-				} else {
-					plog.Warningf("The scheme of client url %s is HTTP while client cert auth (--client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
-				}
+				plog.Warningf("The scheme of client url %s is HTTP while client cert auth (--client-cert-auth) is enabled. Ignored client cert auth for this url.", u.String())
 			}
 		}
 		if (u.Scheme == "https" || u.Scheme == "unixs") && cfg.ClientTLSInfo.Empty() {
-			return nil, fmt.Errorf("TLS key/cert (--cert-file, --key-file) must be provided for client url %s with HTTPS scheme", u.String())
+			return nil, fmt.Errorf("TLS key/cert (--cert-file, --key-file) must be provided for client url %s with HTTPs scheme", u.String())
 		}
 
-		network := "tcp"
+		proto := "tcp"
 		addr := u.Host
 		if u.Scheme == "unix" || u.Scheme == "unixs" {
-			network = "unix"
+			proto = "unix"
 			addr = u.Host + u.Path
 		}
-		sctx.network = network
 
 		sctx.secure = u.Scheme == "https" || u.Scheme == "unixs"
 		sctx.insecure = !sctx.secure
@@ -644,7 +432,7 @@
 			continue
 		}
 
-		if sctx.l, err = net.Listen(network, addr); err != nil {
+		if sctx.l, err = net.Listen(proto, addr); err != nil {
 			return nil, err
 		}
 		// net.Listener will rewrite ipv4 0.0.0.0 to ipv6 [::], breaking
@@ -653,37 +441,21 @@
 
 		if fdLimit, fderr := runtimeutil.FDLimit(); fderr == nil {
 			if fdLimit <= reservedInternalFDNum {
-				if cfg.logger != nil {
-					cfg.logger.Fatal(
-						"file descriptor limit of etcd process is too low; please set higher",
-						zap.Uint64("limit", fdLimit),
-						zap.Int("recommended-limit", reservedInternalFDNum),
-					)
-				} else {
-					plog.Fatalf("file descriptor limit[%d] of etcd process is too low, and should be set higher than %d to ensure internal usage", fdLimit, reservedInternalFDNum)
-				}
+				plog.Fatalf("file descriptor limit[%d] of etcd process is too low, and should be set higher than %d to ensure internal usage", fdLimit, reservedInternalFDNum)
 			}
 			sctx.l = transport.LimitListener(sctx.l, int(fdLimit-reservedInternalFDNum))
 		}
 
-		if network == "tcp" {
-			if sctx.l, err = transport.NewKeepAliveListener(sctx.l, network, nil); err != nil {
+		if proto == "tcp" {
+			if sctx.l, err = transport.NewKeepAliveListener(sctx.l, "tcp", nil); err != nil {
 				return nil, err
 			}
 		}
 
+		plog.Info("listening for client requests on ", u.Host)
 		defer func() {
-			if err == nil {
-				return
-			}
-			sctx.l.Close()
-			if cfg.logger != nil {
-				cfg.logger.Warn(
-					"closing peer listener",
-					zap.String("address", u.Host),
-					zap.Error(err),
-				)
-			} else {
+			if err != nil {
+				sctx.l.Close()
 				plog.Info("stopping listening for client requests on ", u.Host)
 			}
 		}()
@@ -704,31 +476,28 @@
 
 func (e *Etcd) serveClients() (err error) {
 	if !e.cfg.ClientTLSInfo.Empty() {
-		if e.cfg.logger != nil {
-			e.cfg.logger.Info(
-				"starting with client TLS",
-				zap.String("tls-info", fmt.Sprintf("%+v", e.cfg.ClientTLSInfo)),
-				zap.Strings("cipher-suites", e.cfg.CipherSuites),
-			)
-		} else {
-			plog.Infof("ClientTLS: %s", e.cfg.ClientTLSInfo)
-		}
+		plog.Infof("ClientTLS: %s", e.cfg.ClientTLSInfo)
+	}
+
+	if e.cfg.CorsInfo.String() != "" {
+		plog.Infof("cors = %s", e.cfg.CorsInfo)
 	}
 
 	// Start a client server goroutine for each listen address
 	var h http.Handler
 	if e.Config().EnableV2 {
 		if len(e.Config().ExperimentalEnableV2V3) > 0 {
-			srv := v2v3.NewServer(e.cfg.logger, v3client.New(e.Server), e.cfg.ExperimentalEnableV2V3)
-			h = v2http.NewClientHandler(e.GetLogger(), srv, e.Server.Cfg.ReqTimeout())
+			srv := v2v3.NewServer(v3client.New(e.Server), e.cfg.ExperimentalEnableV2V3)
+			h = v2http.NewClientHandler(srv, e.Server.Cfg.ReqTimeout())
 		} else {
-			h = v2http.NewClientHandler(e.GetLogger(), e.Server, e.Server.Cfg.ReqTimeout())
+			h = v2http.NewClientHandler(e.Server, e.Server.Cfg.ReqTimeout())
 		}
 	} else {
 		mux := http.NewServeMux()
 		etcdhttp.HandleBasic(mux, e.Server)
 		h = mux
 	}
+	h = http.Handler(&cors.CORSHandler{Handler: h, Info: e.cfg.CorsInfo})
 
 	gopts := []grpc.ServerOption{}
 	if e.cfg.GRPCKeepAliveMinTime > time.Duration(0) {
@@ -745,7 +514,7 @@
 		}))
 	}
 
-	// start client servers in each goroutine
+	// start client servers in a goroutine
 	for _, sctx := range e.sctxs {
 		go func(s *serveCtx) {
 			e.errHandler(s.serve(e.Server, &e.cfg.ClientTLSInfo, h, e.errHandler, gopts...))
@@ -774,14 +543,7 @@
 			}
 			e.metricsListeners = append(e.metricsListeners, ml)
 			go func(u url.URL, ln net.Listener) {
-				if e.cfg.logger != nil {
-					e.cfg.logger.Info(
-						"serving metrics",
-						zap.String("address", u.String()),
-					)
-				} else {
-					plog.Info("listening for metrics on ", u.String())
-				}
+				plog.Info("listening for metrics on ", u.String())
 				e.errHandler(http.Serve(ln, metricsMux))
 			}(murl, ml)
 		}
@@ -801,21 +563,13 @@
 	}
 }
 
-// GetLogger returns the logger.
-func (e *Etcd) GetLogger() *zap.Logger {
-	e.cfg.loggerMu.RLock()
-	l := e.cfg.logger
-	e.cfg.loggerMu.RUnlock()
-	return l
-}
-
 func parseCompactionRetention(mode, retention string) (ret time.Duration, err error) {
 	h, err := strconv.Atoi(retention)
-	if err == nil {
+	if err == nil && h >= 0 {
 		switch mode {
-		case CompactorModeRevision:
+		case compactor.ModeRevision:
 			ret = time.Duration(int64(h))
-		case CompactorModePeriodic:
+		case compactor.ModePeriodic:
 			ret = time.Duration(int64(h)) * time.Hour
 		}
 	} else {
diff --git a/vendor/go.etcd.io/etcd/embed/serve.go b/vendor/go.etcd.io/etcd/embed/serve.go
index a3b20c4..62b8b57 100644
--- a/vendor/go.etcd.io/etcd/embed/serve.go
+++ b/vendor/go.etcd.io/etcd/embed/serve.go
@@ -16,41 +16,36 @@
 
 import (
 	"context"
-	"fmt"
 	"io/ioutil"
 	defaultLog "log"
 	"net"
 	"net/http"
 	"strings"
 
-	"go.etcd.io/etcd/clientv3/credentials"
-	"go.etcd.io/etcd/etcdserver"
-	"go.etcd.io/etcd/etcdserver/api/v3client"
-	"go.etcd.io/etcd/etcdserver/api/v3election"
-	"go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb"
-	v3electiongw "go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb/gw"
-	"go.etcd.io/etcd/etcdserver/api/v3lock"
-	"go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb"
-	v3lockgw "go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb/gw"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc"
-	etcdservergw "go.etcd.io/etcd/etcdserver/etcdserverpb/gw"
-	"go.etcd.io/etcd/pkg/debugutil"
-	"go.etcd.io/etcd/pkg/httputil"
-	"go.etcd.io/etcd/pkg/transport"
+	"github.com/coreos/etcd/etcdserver"
+	"github.com/coreos/etcd/etcdserver/api/v3client"
+	"github.com/coreos/etcd/etcdserver/api/v3election"
+	"github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb"
+	v3electiongw "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw"
+	"github.com/coreos/etcd/etcdserver/api/v3lock"
+	"github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb"
+	v3lockgw "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc"
+	etcdservergw "github.com/coreos/etcd/etcdserver/etcdserverpb/gw"
+	"github.com/coreos/etcd/pkg/debugutil"
+	"github.com/coreos/etcd/pkg/transport"
 
 	gw "github.com/grpc-ecosystem/grpc-gateway/runtime"
 	"github.com/soheilhy/cmux"
 	"github.com/tmc/grpc-websocket-proxy/wsproxy"
-	"go.uber.org/zap"
 	"golang.org/x/net/trace"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
 )
 
 type serveCtx struct {
-	lg       *zap.Logger
 	l        net.Listener
 	addr     string
-	network  string
 	secure   bool
 	insecure bool
 
@@ -68,14 +63,10 @@
 	http   *http.Server
 }
 
-func newServeCtx(lg *zap.Logger) *serveCtx {
+func newServeCtx() *serveCtx {
 	ctx, cancel := context.WithCancel(context.Background())
-	return &serveCtx{
-		lg:           lg,
-		ctx:          ctx,
-		cancel:       cancel,
-		userHandlers: make(map[string]http.Handler),
-		serversC:     make(chan *servers, 2), // in case sctx.insecure,sctx.secure true
+	return &serveCtx{ctx: ctx, cancel: cancel, userHandlers: make(map[string]http.Handler),
+		serversC: make(chan *servers, 2), // in case sctx.insecure,sctx.secure true
 	}
 }
 
@@ -90,10 +81,7 @@
 	gopts ...grpc.ServerOption) (err error) {
 	logger := defaultLog.New(ioutil.Discard, "etcdhttp", 0)
 	<-s.ReadyNotify()
-
-	if sctx.lg == nil {
-		plog.Info("ready to serve client requests")
-	}
+	plog.Info("ready to serve client requests")
 
 	m := cmux.New(sctx.l)
 	v3c := v3client.New(s)
@@ -118,31 +106,22 @@
 		go func() { errHandler(gs.Serve(grpcl)) }()
 
 		var gwmux *gw.ServeMux
-		if s.Cfg.EnableGRPCGateway {
-			gwmux, err = sctx.registerGateway([]grpc.DialOption{grpc.WithInsecure()})
-			if err != nil {
-				return err
-			}
+		gwmux, err = sctx.registerGateway([]grpc.DialOption{grpc.WithInsecure()})
+		if err != nil {
+			return err
 		}
 
 		httpmux := sctx.createMux(gwmux, handler)
 
 		srvhttp := &http.Server{
-			Handler:  createAccessController(sctx.lg, s, httpmux),
+			Handler:  wrapMux(httpmux),
 			ErrorLog: logger, // do not log user error
 		}
 		httpl := m.Match(cmux.HTTP1())
 		go func() { errHandler(srvhttp.Serve(httpl)) }()
 
 		sctx.serversC <- &servers{grpc: gs, http: srvhttp}
-		if sctx.lg != nil {
-			sctx.lg.Info(
-				"serving client traffic insecurely; this is strongly discouraged!",
-				zap.String("address", sctx.l.Addr().String()),
-			)
-		} else {
-			plog.Noticef("serving insecure client requests on %s, this is strongly discouraged!", sctx.l.Addr().String())
-		}
+		plog.Noticef("serving insecure client requests on %s, this is strongly discouraged!", sctx.l.Addr().String())
 	}
 
 	if sctx.secure {
@@ -158,17 +137,15 @@
 		}
 		handler = grpcHandlerFunc(gs, handler)
 
+		dtls := tlscfg.Clone()
+		// trust local server
+		dtls.InsecureSkipVerify = true
+		creds := credentials.NewTLS(dtls)
+		opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
 		var gwmux *gw.ServeMux
-		if s.Cfg.EnableGRPCGateway {
-			dtls := tlscfg.Clone()
-			// trust local server
-			dtls.InsecureSkipVerify = true
-			bundle := credentials.NewBundle(credentials.Config{TLSConfig: dtls})
-			opts := []grpc.DialOption{grpc.WithTransportCredentials(bundle.TransportCredentials())}
-			gwmux, err = sctx.registerGateway(opts)
-			if err != nil {
-				return err
-			}
+		gwmux, err = sctx.registerGateway(opts)
+		if err != nil {
+			return err
 		}
 
 		var tlsl net.Listener
@@ -180,21 +157,14 @@
 		httpmux := sctx.createMux(gwmux, handler)
 
 		srv := &http.Server{
-			Handler:   createAccessController(sctx.lg, s, httpmux),
+			Handler:   wrapMux(httpmux),
 			TLSConfig: tlscfg,
 			ErrorLog:  logger, // do not log user error
 		}
 		go func() { errHandler(srv.Serve(tlsl)) }()
 
 		sctx.serversC <- &servers{secure: true, grpc: gs, http: srv}
-		if sctx.lg != nil {
-			sctx.lg.Info(
-				"serving client traffic securely",
-				zap.String("address", sctx.l.Addr().String()),
-			)
-		} else {
-			plog.Infof("serving client requests on %s", sctx.l.Addr().String())
-		}
+		plog.Infof("serving client requests on %s", sctx.l.Addr().String())
 	}
 
 	close(sctx.serversC)
@@ -222,14 +192,7 @@
 
 func (sctx *serveCtx) registerGateway(opts []grpc.DialOption) (*gw.ServeMux, error) {
 	ctx := sctx.ctx
-
-	addr := sctx.addr
-	if network := sctx.network; network == "unix" {
-		// explicitly define unix network for gRPC socket support
-		addr = fmt.Sprintf("%s://%s", network, addr)
-	}
-
-	conn, err := grpc.DialContext(ctx, addr, opts...)
+	conn, err := grpc.DialContext(ctx, sctx.addr, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -253,15 +216,7 @@
 	go func() {
 		<-ctx.Done()
 		if cerr := conn.Close(); cerr != nil {
-			if sctx.lg != nil {
-				sctx.lg.Warn(
-					"failed to close connection",
-					zap.String("address", sctx.l.Addr().String()),
-					zap.Error(cerr),
-				)
-			} else {
-				plog.Warningf("failed to close conn to %s: %v", sctx.l.Addr().String(), cerr)
-			}
+			plog.Warningf("failed to close conn to %s: %v", sctx.l.Addr().String(), cerr)
 		}
 	}()
 
@@ -274,148 +229,43 @@
 		httpmux.Handle(path, h)
 	}
 
-	if gwmux != nil {
-		httpmux.Handle(
-			"/v3/",
-			wsproxy.WebsocketProxy(
-				gwmux,
-				wsproxy.WithRequestMutator(
-					// Default to the POST method for streams
-					func(_ *http.Request, outgoing *http.Request) *http.Request {
-						outgoing.Method = "POST"
-						return outgoing
-					},
-				),
+	httpmux.Handle(
+		"/v3beta/",
+		wsproxy.WebsocketProxy(
+			gwmux,
+			wsproxy.WithRequestMutator(
+				// Default to the POST method for streams
+				func(incoming *http.Request, outgoing *http.Request) *http.Request {
+					outgoing.Method = "POST"
+					return outgoing
+				},
 			),
-		)
-	}
+		),
+	)
 	if handler != nil {
 		httpmux.Handle("/", handler)
 	}
 	return httpmux
 }
 
-// createAccessController wraps HTTP multiplexer:
-// - mutate gRPC gateway request paths
-// - check hostname whitelist
-// client HTTP requests goes here first
-func createAccessController(lg *zap.Logger, s *etcdserver.EtcdServer, mux *http.ServeMux) http.Handler {
-	return &accessController{lg: lg, s: s, mux: mux}
-}
+// wraps HTTP multiplexer to mute requests to /v3alpha
+// TODO: deprecate this in 3.4 release
+func wrapMux(mux *http.ServeMux) http.Handler { return &v3alphaMutator{mux: mux} }
 
-type accessController struct {
-	lg  *zap.Logger
-	s   *etcdserver.EtcdServer
+type v3alphaMutator struct {
 	mux *http.ServeMux
 }
 
-func (ac *accessController) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	// redirect for backward compatibilities
-	if req != nil && req.URL != nil && strings.HasPrefix(req.URL.Path, "/v3beta/") {
-		req.URL.Path = strings.Replace(req.URL.Path, "/v3beta/", "/v3/", 1)
+func (m *v3alphaMutator) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	if req != nil && req.URL != nil && strings.HasPrefix(req.URL.Path, "/v3alpha/") {
+		req.URL.Path = strings.Replace(req.URL.Path, "/v3alpha/", "/v3beta/", 1)
 	}
-
-	if req.TLS == nil { // check origin if client connection is not secure
-		host := httputil.GetHostname(req)
-		if !ac.s.AccessController.IsHostWhitelisted(host) {
-			if ac.lg != nil {
-				ac.lg.Warn(
-					"rejecting HTTP request to prevent DNS rebinding attacks",
-					zap.String("host", host),
-				)
-			} else {
-				plog.Warningf("rejecting HTTP request from %q to prevent DNS rebinding attacks", host)
-			}
-			// TODO: use Go's "http.StatusMisdirectedRequest" (421)
-			// https://github.com/golang/go/commit/4b8a7eafef039af1834ef9bfa879257c4a72b7b5
-			http.Error(rw, errCVE20185702(host), 421)
-			return
-		}
-	} else if ac.s.Cfg.ClientCertAuthEnabled && ac.s.Cfg.EnableGRPCGateway &&
-		ac.s.AuthStore().IsAuthEnabled() && strings.HasPrefix(req.URL.Path, "/v3/") {
-		for _, chains := range req.TLS.VerifiedChains {
-			if len(chains) < 1 {
-				continue
-			}
-			if len(chains[0].Subject.CommonName) != 0 {
-				http.Error(rw, "CommonName of client sending a request against gateway will be ignored and not used as expected", 400)
-				return
-			}
-		}
-	}
-
-	// Write CORS header.
-	if ac.s.AccessController.OriginAllowed("*") {
-		addCORSHeader(rw, "*")
-	} else if origin := req.Header.Get("Origin"); ac.s.OriginAllowed(origin) {
-		addCORSHeader(rw, origin)
-	}
-
-	if req.Method == "OPTIONS" {
-		rw.WriteHeader(http.StatusOK)
-		return
-	}
-
-	ac.mux.ServeHTTP(rw, req)
-}
-
-// addCORSHeader adds the correct cors headers given an origin
-func addCORSHeader(w http.ResponseWriter, origin string) {
-	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
-	w.Header().Add("Access-Control-Allow-Origin", origin)
-	w.Header().Add("Access-Control-Allow-Headers", "accept, content-type, authorization")
-}
-
-// https://github.com/transmission/transmission/pull/468
-func errCVE20185702(host string) string {
-	return fmt.Sprintf(`
-etcd received your request, but the Host header was unrecognized.
-
-To fix this, choose one of the following options:
-- Enable TLS, then any HTTPS request will be allowed.
-- Add the hostname you want to use to the whitelist in settings.
-  - e.g. etcd --host-whitelist %q
-
-This requirement has been added to help prevent "DNS Rebinding" attacks (CVE-2018-5702).
-`, host)
-}
-
-// WrapCORS wraps existing handler with CORS.
-// TODO: deprecate this after v2 proxy deprecate
-func WrapCORS(cors map[string]struct{}, h http.Handler) http.Handler {
-	return &corsHandler{
-		ac: &etcdserver.AccessController{CORS: cors},
-		h:  h,
-	}
-}
-
-type corsHandler struct {
-	ac *etcdserver.AccessController
-	h  http.Handler
-}
-
-func (ch *corsHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	if ch.ac.OriginAllowed("*") {
-		addCORSHeader(rw, "*")
-	} else if origin := req.Header.Get("Origin"); ch.ac.OriginAllowed(origin) {
-		addCORSHeader(rw, origin)
-	}
-
-	if req.Method == "OPTIONS" {
-		rw.WriteHeader(http.StatusOK)
-		return
-	}
-
-	ch.h.ServeHTTP(rw, req)
+	m.mux.ServeHTTP(rw, req)
 }
 
 func (sctx *serveCtx) registerUserHandler(s string, h http.Handler) {
 	if sctx.userHandlers[s] != nil {
-		if sctx.lg != nil {
-			sctx.lg.Warn("path is already registered by user handler", zap.String("path", s))
-		} else {
-			plog.Warningf("path %s already registered by user handler", s)
-		}
+		plog.Warningf("path %s already registered by user handler", s)
 		return
 	}
 	sctx.userHandlers[s] = h
diff --git a/vendor/go.etcd.io/etcd/embed/util.go b/vendor/go.etcd.io/etcd/embed/util.go
index 40f3ce9..168e031 100644
--- a/vendor/go.etcd.io/etcd/embed/util.go
+++ b/vendor/go.etcd.io/etcd/embed/util.go
@@ -17,7 +17,7 @@
 import (
 	"path/filepath"
 
-	"go.etcd.io/etcd/wal"
+	"github.com/coreos/etcd/wal"
 )
 
 func isMemberInitialized(cfg *Config) bool {
@@ -25,5 +25,6 @@
 	if waldir == "" {
 		waldir = filepath.Join(cfg.Dir, "member", "wal")
 	}
+
 	return wal.Exist(waldir)
 }
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
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/apply.go b/vendor/go.etcd.io/etcd/etcdserver/apply.go
deleted file mode 100644
index 1f06ad0..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/apply.go
+++ /dev/null
@@ -1,1019 +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 etcdserver
-
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"sort"
-	"time"
-
-	"go.etcd.io/etcd/auth"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-	"go.etcd.io/etcd/pkg/types"
-
-	"github.com/gogo/protobuf/proto"
-	"go.uber.org/zap"
-)
-
-const (
-	warnApplyDuration = 100 * time.Millisecond
-)
-
-type applyResult struct {
-	resp proto.Message
-	err  error
-	// physc signals the physical effect of the request has completed in addition
-	// to being logically reflected by the node. Currently only used for
-	// Compaction requests.
-	physc <-chan struct{}
-}
-
-// applierV3 is the interface for processing V3 raft messages
-type applierV3 interface {
-	Apply(r *pb.InternalRaftRequest) *applyResult
-
-	Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error)
-	Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error)
-	DeleteRange(txn mvcc.TxnWrite, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error)
-	Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error)
-	Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error)
-
-	LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error)
-	LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
-
-	LeaseCheckpoint(lc *pb.LeaseCheckpointRequest) (*pb.LeaseCheckpointResponse, error)
-
-	Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error)
-
-	Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error)
-
-	AuthEnable() (*pb.AuthEnableResponse, error)
-	AuthDisable() (*pb.AuthDisableResponse, error)
-
-	UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-	UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-	UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-	UserGrantRole(ua *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-	UserGet(ua *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-	UserRevokeRole(ua *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-	RoleAdd(ua *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-	RoleGrantPermission(ua *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-	RoleGet(ua *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-	RoleRevokePermission(ua *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-	RoleDelete(ua *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-	UserList(ua *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-	RoleList(ua *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-}
-
-type checkReqFunc func(mvcc.ReadView, *pb.RequestOp) error
-
-type applierV3backend struct {
-	s *EtcdServer
-
-	checkPut   checkReqFunc
-	checkRange checkReqFunc
-}
-
-func (s *EtcdServer) newApplierV3Backend() applierV3 {
-	base := &applierV3backend{s: s}
-	base.checkPut = func(rv mvcc.ReadView, req *pb.RequestOp) error {
-		return base.checkRequestPut(rv, req)
-	}
-	base.checkRange = func(rv mvcc.ReadView, req *pb.RequestOp) error {
-		return base.checkRequestRange(rv, req)
-	}
-	return base
-}
-
-func (s *EtcdServer) newApplierV3() applierV3 {
-	return newAuthApplierV3(
-		s.AuthStore(),
-		newQuotaApplierV3(s, s.newApplierV3Backend()),
-		s.lessor,
-	)
-}
-
-func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResult {
-	ar := &applyResult{}
-	defer func(start time.Time) {
-		warnOfExpensiveRequest(a.s.getLogger(), start, &pb.InternalRaftStringer{Request: r}, ar.resp, ar.err)
-	}(time.Now())
-
-	// call into a.s.applyV3.F instead of a.F so upper appliers can check individual calls
-	switch {
-	case r.Range != nil:
-		ar.resp, ar.err = a.s.applyV3.Range(nil, r.Range)
-	case r.Put != nil:
-		ar.resp, ar.err = a.s.applyV3.Put(nil, r.Put)
-	case r.DeleteRange != nil:
-		ar.resp, ar.err = a.s.applyV3.DeleteRange(nil, r.DeleteRange)
-	case r.Txn != nil:
-		ar.resp, ar.err = a.s.applyV3.Txn(r.Txn)
-	case r.Compaction != nil:
-		ar.resp, ar.physc, ar.err = a.s.applyV3.Compaction(r.Compaction)
-	case r.LeaseGrant != nil:
-		ar.resp, ar.err = a.s.applyV3.LeaseGrant(r.LeaseGrant)
-	case r.LeaseRevoke != nil:
-		ar.resp, ar.err = a.s.applyV3.LeaseRevoke(r.LeaseRevoke)
-	case r.LeaseCheckpoint != nil:
-		ar.resp, ar.err = a.s.applyV3.LeaseCheckpoint(r.LeaseCheckpoint)
-	case r.Alarm != nil:
-		ar.resp, ar.err = a.s.applyV3.Alarm(r.Alarm)
-	case r.Authenticate != nil:
-		ar.resp, ar.err = a.s.applyV3.Authenticate(r.Authenticate)
-	case r.AuthEnable != nil:
-		ar.resp, ar.err = a.s.applyV3.AuthEnable()
-	case r.AuthDisable != nil:
-		ar.resp, ar.err = a.s.applyV3.AuthDisable()
-	case r.AuthUserAdd != nil:
-		ar.resp, ar.err = a.s.applyV3.UserAdd(r.AuthUserAdd)
-	case r.AuthUserDelete != nil:
-		ar.resp, ar.err = a.s.applyV3.UserDelete(r.AuthUserDelete)
-	case r.AuthUserChangePassword != nil:
-		ar.resp, ar.err = a.s.applyV3.UserChangePassword(r.AuthUserChangePassword)
-	case r.AuthUserGrantRole != nil:
-		ar.resp, ar.err = a.s.applyV3.UserGrantRole(r.AuthUserGrantRole)
-	case r.AuthUserGet != nil:
-		ar.resp, ar.err = a.s.applyV3.UserGet(r.AuthUserGet)
-	case r.AuthUserRevokeRole != nil:
-		ar.resp, ar.err = a.s.applyV3.UserRevokeRole(r.AuthUserRevokeRole)
-	case r.AuthRoleAdd != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleAdd(r.AuthRoleAdd)
-	case r.AuthRoleGrantPermission != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleGrantPermission(r.AuthRoleGrantPermission)
-	case r.AuthRoleGet != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleGet(r.AuthRoleGet)
-	case r.AuthRoleRevokePermission != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleRevokePermission(r.AuthRoleRevokePermission)
-	case r.AuthRoleDelete != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleDelete(r.AuthRoleDelete)
-	case r.AuthUserList != nil:
-		ar.resp, ar.err = a.s.applyV3.UserList(r.AuthUserList)
-	case r.AuthRoleList != nil:
-		ar.resp, ar.err = a.s.applyV3.RoleList(r.AuthRoleList)
-	default:
-		panic("not implemented")
-	}
-	return ar
-}
-
-func (a *applierV3backend) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (resp *pb.PutResponse, err error) {
-	resp = &pb.PutResponse{}
-	resp.Header = &pb.ResponseHeader{}
-
-	val, leaseID := p.Value, lease.LeaseID(p.Lease)
-	if txn == nil {
-		if leaseID != lease.NoLease {
-			if l := a.s.lessor.Lookup(leaseID); l == nil {
-				return nil, lease.ErrLeaseNotFound
-			}
-		}
-		txn = a.s.KV().Write()
-		defer txn.End()
-	}
-
-	var rr *mvcc.RangeResult
-	if p.IgnoreValue || p.IgnoreLease || p.PrevKv {
-		rr, err = txn.Range(p.Key, nil, mvcc.RangeOptions{})
-		if err != nil {
-			return nil, err
-		}
-	}
-	if p.IgnoreValue || p.IgnoreLease {
-		if rr == nil || len(rr.KVs) == 0 {
-			// ignore_{lease,value} flag expects previous key-value pair
-			return nil, ErrKeyNotFound
-		}
-	}
-	if p.IgnoreValue {
-		val = rr.KVs[0].Value
-	}
-	if p.IgnoreLease {
-		leaseID = lease.LeaseID(rr.KVs[0].Lease)
-	}
-	if p.PrevKv {
-		if rr != nil && len(rr.KVs) != 0 {
-			resp.PrevKv = &rr.KVs[0]
-		}
-	}
-
-	resp.Header.Revision = txn.Put(p.Key, val, leaseID)
-	return resp, nil
-}
-
-func (a *applierV3backend) DeleteRange(txn mvcc.TxnWrite, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	resp := &pb.DeleteRangeResponse{}
-	resp.Header = &pb.ResponseHeader{}
-	end := mkGteRange(dr.RangeEnd)
-
-	if txn == nil {
-		txn = a.s.kv.Write()
-		defer txn.End()
-	}
-
-	if dr.PrevKv {
-		rr, err := txn.Range(dr.Key, end, mvcc.RangeOptions{})
-		if err != nil {
-			return nil, err
-		}
-		if rr != nil {
-			resp.PrevKvs = make([]*mvccpb.KeyValue, len(rr.KVs))
-			for i := range rr.KVs {
-				resp.PrevKvs[i] = &rr.KVs[i]
-			}
-		}
-	}
-
-	resp.Deleted, resp.Header.Revision = txn.DeleteRange(dr.Key, end)
-	return resp, nil
-}
-
-func (a *applierV3backend) Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	resp := &pb.RangeResponse{}
-	resp.Header = &pb.ResponseHeader{}
-
-	if txn == nil {
-		txn = a.s.kv.Read()
-		defer txn.End()
-	}
-
-	limit := r.Limit
-	if r.SortOrder != pb.RangeRequest_NONE ||
-		r.MinModRevision != 0 || r.MaxModRevision != 0 ||
-		r.MinCreateRevision != 0 || r.MaxCreateRevision != 0 {
-		// fetch everything; sort and truncate afterwards
-		limit = 0
-	}
-	if limit > 0 {
-		// fetch one extra for 'more' flag
-		limit = limit + 1
-	}
-
-	ro := mvcc.RangeOptions{
-		Limit: limit,
-		Rev:   r.Revision,
-		Count: r.CountOnly,
-	}
-
-	rr, err := txn.Range(r.Key, mkGteRange(r.RangeEnd), ro)
-	if err != nil {
-		return nil, err
-	}
-
-	if r.MaxModRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision > r.MaxModRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MinModRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.ModRevision < r.MinModRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MaxCreateRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision > r.MaxCreateRevision }
-		pruneKVs(rr, f)
-	}
-	if r.MinCreateRevision != 0 {
-		f := func(kv *mvccpb.KeyValue) bool { return kv.CreateRevision < r.MinCreateRevision }
-		pruneKVs(rr, f)
-	}
-
-	sortOrder := r.SortOrder
-	if r.SortTarget != pb.RangeRequest_KEY && sortOrder == pb.RangeRequest_NONE {
-		// Since current mvcc.Range implementation returns results
-		// sorted by keys in lexiographically ascending order,
-		// sort ASCEND by default only when target is not 'KEY'
-		sortOrder = pb.RangeRequest_ASCEND
-	}
-	if sortOrder != pb.RangeRequest_NONE {
-		var sorter sort.Interface
-		switch {
-		case r.SortTarget == pb.RangeRequest_KEY:
-			sorter = &kvSortByKey{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_VERSION:
-			sorter = &kvSortByVersion{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_CREATE:
-			sorter = &kvSortByCreate{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_MOD:
-			sorter = &kvSortByMod{&kvSort{rr.KVs}}
-		case r.SortTarget == pb.RangeRequest_VALUE:
-			sorter = &kvSortByValue{&kvSort{rr.KVs}}
-		}
-		switch {
-		case sortOrder == pb.RangeRequest_ASCEND:
-			sort.Sort(sorter)
-		case sortOrder == pb.RangeRequest_DESCEND:
-			sort.Sort(sort.Reverse(sorter))
-		}
-	}
-
-	if r.Limit > 0 && len(rr.KVs) > int(r.Limit) {
-		rr.KVs = rr.KVs[:r.Limit]
-		resp.More = true
-	}
-
-	resp.Header.Revision = rr.Rev
-	resp.Count = int64(rr.Count)
-	resp.Kvs = make([]*mvccpb.KeyValue, len(rr.KVs))
-	for i := range rr.KVs {
-		if r.KeysOnly {
-			rr.KVs[i].Value = nil
-		}
-		resp.Kvs[i] = &rr.KVs[i]
-	}
-	return resp, nil
-}
-
-func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	isWrite := !isTxnReadonly(rt)
-	txn := mvcc.NewReadOnlyTxnWrite(a.s.KV().Read())
-
-	txnPath := compareToPath(txn, rt)
-	if isWrite {
-		if _, err := checkRequests(txn, rt, txnPath, a.checkPut); err != nil {
-			txn.End()
-			return nil, err
-		}
-	}
-	if _, err := checkRequests(txn, rt, txnPath, a.checkRange); err != nil {
-		txn.End()
-		return nil, err
-	}
-
-	txnResp, _ := newTxnResp(rt, txnPath)
-
-	// When executing mutable txn ops, etcd must hold the txn lock so
-	// readers do not see any intermediate results. Since writes are
-	// serialized on the raft loop, the revision in the read view will
-	// be the revision of the write txn.
-	if isWrite {
-		txn.End()
-		txn = a.s.KV().Write()
-	}
-	a.applyTxn(txn, rt, txnPath, txnResp)
-	rev := txn.Rev()
-	if len(txn.Changes()) != 0 {
-		rev++
-	}
-	txn.End()
-
-	txnResp.Header.Revision = rev
-	return txnResp, nil
-}
-
-// newTxnResp allocates a txn response for a txn request given a path.
-func newTxnResp(rt *pb.TxnRequest, txnPath []bool) (txnResp *pb.TxnResponse, txnCount int) {
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-	resps := make([]*pb.ResponseOp, len(reqs))
-	txnResp = &pb.TxnResponse{
-		Responses: resps,
-		Succeeded: txnPath[0],
-		Header:    &pb.ResponseHeader{},
-	}
-	for i, req := range reqs {
-		switch tv := req.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseRange{}}
-		case *pb.RequestOp_RequestPut:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponsePut{}}
-		case *pb.RequestOp_RequestDeleteRange:
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseDeleteRange{}}
-		case *pb.RequestOp_RequestTxn:
-			resp, txns := newTxnResp(tv.RequestTxn, txnPath[1:])
-			resps[i] = &pb.ResponseOp{Response: &pb.ResponseOp_ResponseTxn{ResponseTxn: resp}}
-			txnPath = txnPath[1+txns:]
-			txnCount += txns + 1
-		default:
-		}
-	}
-	return txnResp, txnCount
-}
-
-func compareToPath(rv mvcc.ReadView, rt *pb.TxnRequest) []bool {
-	txnPath := make([]bool, 1)
-	ops := rt.Success
-	if txnPath[0] = applyCompares(rv, rt.Compare); !txnPath[0] {
-		ops = rt.Failure
-	}
-	for _, op := range ops {
-		tv, ok := op.Request.(*pb.RequestOp_RequestTxn)
-		if !ok || tv.RequestTxn == nil {
-			continue
-		}
-		txnPath = append(txnPath, compareToPath(rv, tv.RequestTxn)...)
-	}
-	return txnPath
-}
-
-func applyCompares(rv mvcc.ReadView, cmps []*pb.Compare) bool {
-	for _, c := range cmps {
-		if !applyCompare(rv, c) {
-			return false
-		}
-	}
-	return true
-}
-
-// applyCompare applies the compare request.
-// If the comparison succeeds, it returns true. Otherwise, returns false.
-func applyCompare(rv mvcc.ReadView, c *pb.Compare) bool {
-	// TODO: possible optimizations
-	// * chunk reads for large ranges to conserve memory
-	// * rewrite rules for common patterns:
-	//	ex. "[a, b) createrev > 0" => "limit 1 /\ kvs > 0"
-	// * caching
-	rr, err := rv.Range(c.Key, mkGteRange(c.RangeEnd), mvcc.RangeOptions{})
-	if err != nil {
-		return false
-	}
-	if len(rr.KVs) == 0 {
-		if c.Target == pb.Compare_VALUE {
-			// Always fail if comparing a value on a key/keys that doesn't exist;
-			// nil == empty string in grpc; no way to represent missing value
-			return false
-		}
-		return compareKV(c, mvccpb.KeyValue{})
-	}
-	for _, kv := range rr.KVs {
-		if !compareKV(c, kv) {
-			return false
-		}
-	}
-	return true
-}
-
-func compareKV(c *pb.Compare, ckv mvccpb.KeyValue) bool {
-	var result int
-	rev := int64(0)
-	switch c.Target {
-	case pb.Compare_VALUE:
-		v := []byte{}
-		if tv, _ := c.TargetUnion.(*pb.Compare_Value); tv != nil {
-			v = tv.Value
-		}
-		result = bytes.Compare(ckv.Value, v)
-	case pb.Compare_CREATE:
-		if tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision); tv != nil {
-			rev = tv.CreateRevision
-		}
-		result = compareInt64(ckv.CreateRevision, rev)
-	case pb.Compare_MOD:
-		if tv, _ := c.TargetUnion.(*pb.Compare_ModRevision); tv != nil {
-			rev = tv.ModRevision
-		}
-		result = compareInt64(ckv.ModRevision, rev)
-	case pb.Compare_VERSION:
-		if tv, _ := c.TargetUnion.(*pb.Compare_Version); tv != nil {
-			rev = tv.Version
-		}
-		result = compareInt64(ckv.Version, rev)
-	case pb.Compare_LEASE:
-		if tv, _ := c.TargetUnion.(*pb.Compare_Lease); tv != nil {
-			rev = tv.Lease
-		}
-		result = compareInt64(ckv.Lease, rev)
-	}
-	switch c.Result {
-	case pb.Compare_EQUAL:
-		return result == 0
-	case pb.Compare_NOT_EQUAL:
-		return result != 0
-	case pb.Compare_GREATER:
-		return result > 0
-	case pb.Compare_LESS:
-		return result < 0
-	}
-	return true
-}
-
-func (a *applierV3backend) applyTxn(txn mvcc.TxnWrite, rt *pb.TxnRequest, txnPath []bool, tresp *pb.TxnResponse) (txns int) {
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-
-	lg := a.s.getLogger()
-	for i, req := range reqs {
-		respi := tresp.Responses[i].Response
-		switch tv := req.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			resp, err := a.Range(txn, tv.RequestRange)
-			if err != nil {
-				if lg != nil {
-					lg.Panic("unexpected error during txn", zap.Error(err))
-				} else {
-					plog.Panicf("unexpected error during txn: %v", err)
-				}
-			}
-			respi.(*pb.ResponseOp_ResponseRange).ResponseRange = resp
-		case *pb.RequestOp_RequestPut:
-			resp, err := a.Put(txn, tv.RequestPut)
-			if err != nil {
-				if lg != nil {
-					lg.Panic("unexpected error during txn", zap.Error(err))
-				} else {
-					plog.Panicf("unexpected error during txn: %v", err)
-				}
-			}
-			respi.(*pb.ResponseOp_ResponsePut).ResponsePut = resp
-		case *pb.RequestOp_RequestDeleteRange:
-			resp, err := a.DeleteRange(txn, tv.RequestDeleteRange)
-			if err != nil {
-				if lg != nil {
-					lg.Panic("unexpected error during txn", zap.Error(err))
-				} else {
-					plog.Panicf("unexpected error during txn: %v", err)
-				}
-			}
-			respi.(*pb.ResponseOp_ResponseDeleteRange).ResponseDeleteRange = resp
-		case *pb.RequestOp_RequestTxn:
-			resp := respi.(*pb.ResponseOp_ResponseTxn).ResponseTxn
-			applyTxns := a.applyTxn(txn, tv.RequestTxn, txnPath[1:], resp)
-			txns += applyTxns + 1
-			txnPath = txnPath[applyTxns+1:]
-		default:
-			// empty union
-		}
-	}
-	return txns
-}
-
-func (a *applierV3backend) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) {
-	resp := &pb.CompactionResponse{}
-	resp.Header = &pb.ResponseHeader{}
-	ch, err := a.s.KV().Compact(compaction.Revision)
-	if err != nil {
-		return nil, ch, err
-	}
-	// get the current revision. which key to get is not important.
-	rr, _ := a.s.KV().Range([]byte("compaction"), nil, mvcc.RangeOptions{})
-	resp.Header.Revision = rr.Rev
-	return resp, ch, err
-}
-
-func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	l, err := a.s.lessor.Grant(lease.LeaseID(lc.ID), lc.TTL)
-	resp := &pb.LeaseGrantResponse{}
-	if err == nil {
-		resp.ID = int64(l.ID)
-		resp.TTL = l.TTL()
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	err := a.s.lessor.Revoke(lease.LeaseID(lc.ID))
-	return &pb.LeaseRevokeResponse{Header: newHeader(a.s)}, err
-}
-
-func (a *applierV3backend) LeaseCheckpoint(lc *pb.LeaseCheckpointRequest) (*pb.LeaseCheckpointResponse, error) {
-	for _, c := range lc.Checkpoints {
-		err := a.s.lessor.Checkpoint(lease.LeaseID(c.ID), c.Remaining_TTL)
-		if err != nil {
-			return &pb.LeaseCheckpointResponse{Header: newHeader(a.s)}, err
-		}
-	}
-	return &pb.LeaseCheckpointResponse{Header: newHeader(a.s)}, nil
-}
-
-func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	resp := &pb.AlarmResponse{}
-	oldCount := len(a.s.alarmStore.Get(ar.Alarm))
-
-	lg := a.s.getLogger()
-	switch ar.Action {
-	case pb.AlarmRequest_GET:
-		resp.Alarms = a.s.alarmStore.Get(ar.Alarm)
-	case pb.AlarmRequest_ACTIVATE:
-		m := a.s.alarmStore.Activate(types.ID(ar.MemberID), ar.Alarm)
-		if m == nil {
-			break
-		}
-		resp.Alarms = append(resp.Alarms, m)
-		activated := oldCount == 0 && len(a.s.alarmStore.Get(m.Alarm)) == 1
-		if !activated {
-			break
-		}
-
-		if lg != nil {
-			lg.Warn("alarm raised", zap.String("alarm", m.Alarm.String()), zap.String("from", types.ID(m.MemberID).String()))
-		} else {
-			plog.Warningf("alarm %v raised by peer %s", m.Alarm, types.ID(m.MemberID))
-		}
-		switch m.Alarm {
-		case pb.AlarmType_CORRUPT:
-			a.s.applyV3 = newApplierV3Corrupt(a)
-		case pb.AlarmType_NOSPACE:
-			a.s.applyV3 = newApplierV3Capped(a)
-		default:
-			if lg != nil {
-				lg.Warn("unimplemented alarm activation", zap.String("alarm", fmt.Sprintf("%+v", m)))
-			} else {
-				plog.Errorf("unimplemented alarm activation (%+v)", m)
-			}
-		}
-	case pb.AlarmRequest_DEACTIVATE:
-		m := a.s.alarmStore.Deactivate(types.ID(ar.MemberID), ar.Alarm)
-		if m == nil {
-			break
-		}
-		resp.Alarms = append(resp.Alarms, m)
-		deactivated := oldCount > 0 && len(a.s.alarmStore.Get(ar.Alarm)) == 0
-		if !deactivated {
-			break
-		}
-
-		switch m.Alarm {
-		case pb.AlarmType_NOSPACE, pb.AlarmType_CORRUPT:
-			// TODO: check kv hash before deactivating CORRUPT?
-			if lg != nil {
-				lg.Warn("alarm disarmed", zap.String("alarm", m.Alarm.String()), zap.String("from", types.ID(m.MemberID).String()))
-			} else {
-				plog.Infof("alarm disarmed %+v", ar)
-			}
-			a.s.applyV3 = a.s.newApplierV3()
-		default:
-			if lg != nil {
-				lg.Warn("unimplemented alarm deactivation", zap.String("alarm", fmt.Sprintf("%+v", m)))
-			} else {
-				plog.Errorf("unimplemented alarm deactivation (%+v)", m)
-			}
-		}
-	default:
-		return nil, nil
-	}
-	return resp, nil
-}
-
-type applierV3Capped struct {
-	applierV3
-	q backendQuota
-}
-
-// newApplierV3Capped creates an applyV3 that will reject Puts and transactions
-// with Puts so that the number of keys in the store is capped.
-func newApplierV3Capped(base applierV3) applierV3 { return &applierV3Capped{applierV3: base} }
-
-func (a *applierV3Capped) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	return nil, ErrNoSpace
-}
-
-func (a *applierV3Capped) Txn(r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if a.q.Cost(r) > 0 {
-		return nil, ErrNoSpace
-	}
-	return a.applierV3.Txn(r)
-}
-
-func (a *applierV3Capped) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	return nil, ErrNoSpace
-}
-
-func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) {
-	err := a.s.AuthStore().AuthEnable()
-	if err != nil {
-		return nil, err
-	}
-	return &pb.AuthEnableResponse{Header: newHeader(a.s)}, nil
-}
-
-func (a *applierV3backend) AuthDisable() (*pb.AuthDisableResponse, error) {
-	a.s.AuthStore().AuthDisable()
-	return &pb.AuthDisableResponse{Header: newHeader(a.s)}, nil
-}
-
-func (a *applierV3backend) Authenticate(r *pb.InternalAuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	ctx := context.WithValue(context.WithValue(a.s.ctx, auth.AuthenticateParamIndex{}, a.s.consistIndex.ConsistentIndex()), auth.AuthenticateParamSimpleTokenPrefix{}, r.SimpleToken)
-	resp, err := a.s.AuthStore().Authenticate(ctx, r.Name, r.Password)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := a.s.AuthStore().UserAdd(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := a.s.AuthStore().UserDelete(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := a.s.AuthStore().UserChangePassword(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := a.s.AuthStore().UserGrantRole(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := a.s.AuthStore().UserGet(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := a.s.AuthStore().UserRevokeRole(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := a.s.AuthStore().RoleAdd(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleGrantPermission(r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := a.s.AuthStore().RoleGrantPermission(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := a.s.AuthStore().RoleGet(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleRevokePermission(r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := a.s.AuthStore().RoleRevokePermission(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := a.s.AuthStore().RoleDelete(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) UserList(r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := a.s.AuthStore().UserList(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-func (a *applierV3backend) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := a.s.AuthStore().RoleList(r)
-	if resp != nil {
-		resp.Header = newHeader(a.s)
-	}
-	return resp, err
-}
-
-type quotaApplierV3 struct {
-	applierV3
-	q Quota
-}
-
-func newQuotaApplierV3(s *EtcdServer, app applierV3) applierV3 {
-	return &quotaApplierV3{app, NewBackendQuota(s, "v3-applier")}
-}
-
-func (a *quotaApplierV3) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	ok := a.q.Available(p)
-	resp, err := a.applierV3.Put(txn, p)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-func (a *quotaApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	ok := a.q.Available(rt)
-	resp, err := a.applierV3.Txn(rt)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-func (a *quotaApplierV3) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	ok := a.q.Available(lc)
-	resp, err := a.applierV3.LeaseGrant(lc)
-	if err == nil && !ok {
-		err = ErrNoSpace
-	}
-	return resp, err
-}
-
-type kvSort struct{ kvs []mvccpb.KeyValue }
-
-func (s *kvSort) Swap(i, j int) {
-	t := s.kvs[i]
-	s.kvs[i] = s.kvs[j]
-	s.kvs[j] = t
-}
-func (s *kvSort) Len() int { return len(s.kvs) }
-
-type kvSortByKey struct{ *kvSort }
-
-func (s *kvSortByKey) Less(i, j int) bool {
-	return bytes.Compare(s.kvs[i].Key, s.kvs[j].Key) < 0
-}
-
-type kvSortByVersion struct{ *kvSort }
-
-func (s *kvSortByVersion) Less(i, j int) bool {
-	return (s.kvs[i].Version - s.kvs[j].Version) < 0
-}
-
-type kvSortByCreate struct{ *kvSort }
-
-func (s *kvSortByCreate) Less(i, j int) bool {
-	return (s.kvs[i].CreateRevision - s.kvs[j].CreateRevision) < 0
-}
-
-type kvSortByMod struct{ *kvSort }
-
-func (s *kvSortByMod) Less(i, j int) bool {
-	return (s.kvs[i].ModRevision - s.kvs[j].ModRevision) < 0
-}
-
-type kvSortByValue struct{ *kvSort }
-
-func (s *kvSortByValue) Less(i, j int) bool {
-	return bytes.Compare(s.kvs[i].Value, s.kvs[j].Value) < 0
-}
-
-func checkRequests(rv mvcc.ReadView, rt *pb.TxnRequest, txnPath []bool, f checkReqFunc) (int, error) {
-	txnCount := 0
-	reqs := rt.Success
-	if !txnPath[0] {
-		reqs = rt.Failure
-	}
-	for _, req := range reqs {
-		if tv, ok := req.Request.(*pb.RequestOp_RequestTxn); ok && tv.RequestTxn != nil {
-			txns, err := checkRequests(rv, tv.RequestTxn, txnPath[1:], f)
-			if err != nil {
-				return 0, err
-			}
-			txnCount += txns + 1
-			txnPath = txnPath[txns+1:]
-			continue
-		}
-		if err := f(rv, req); err != nil {
-			return 0, err
-		}
-	}
-	return txnCount, nil
-}
-
-func (a *applierV3backend) checkRequestPut(rv mvcc.ReadView, reqOp *pb.RequestOp) error {
-	tv, ok := reqOp.Request.(*pb.RequestOp_RequestPut)
-	if !ok || tv.RequestPut == nil {
-		return nil
-	}
-	req := tv.RequestPut
-	if req.IgnoreValue || req.IgnoreLease {
-		// expects previous key-value, error if not exist
-		rr, err := rv.Range(req.Key, nil, mvcc.RangeOptions{})
-		if err != nil {
-			return err
-		}
-		if rr == nil || len(rr.KVs) == 0 {
-			return ErrKeyNotFound
-		}
-	}
-	if lease.LeaseID(req.Lease) != lease.NoLease {
-		if l := a.s.lessor.Lookup(lease.LeaseID(req.Lease)); l == nil {
-			return lease.ErrLeaseNotFound
-		}
-	}
-	return nil
-}
-
-func (a *applierV3backend) checkRequestRange(rv mvcc.ReadView, reqOp *pb.RequestOp) error {
-	tv, ok := reqOp.Request.(*pb.RequestOp_RequestRange)
-	if !ok || tv.RequestRange == nil {
-		return nil
-	}
-	req := tv.RequestRange
-	switch {
-	case req.Revision == 0:
-		return nil
-	case req.Revision > rv.Rev():
-		return mvcc.ErrFutureRev
-	case req.Revision < rv.FirstRev():
-		return mvcc.ErrCompacted
-	}
-	return nil
-}
-
-func compareInt64(a, b int64) int {
-	switch {
-	case a < b:
-		return -1
-	case a > b:
-		return 1
-	default:
-		return 0
-	}
-}
-
-// mkGteRange determines if the range end is a >= range. This works around grpc
-// sending empty byte strings as nil; >= is encoded in the range end as '\0'.
-// If it is a GTE range, then []byte{} is returned to indicate the empty byte
-// string (vs nil being no byte string).
-func mkGteRange(rangeEnd []byte) []byte {
-	if len(rangeEnd) == 1 && rangeEnd[0] == 0 {
-		return []byte{}
-	}
-	return rangeEnd
-}
-
-func noSideEffect(r *pb.InternalRaftRequest) bool {
-	return r.Range != nil || r.AuthUserGet != nil || r.AuthRoleGet != nil
-}
-
-func removeNeedlessRangeReqs(txn *pb.TxnRequest) {
-	f := func(ops []*pb.RequestOp) []*pb.RequestOp {
-		j := 0
-		for i := 0; i < len(ops); i++ {
-			if _, ok := ops[i].Request.(*pb.RequestOp_RequestRange); ok {
-				continue
-			}
-			ops[j] = ops[i]
-			j++
-		}
-
-		return ops[:j]
-	}
-
-	txn.Success = f(txn.Success)
-	txn.Failure = f(txn.Failure)
-}
-
-func pruneKVs(rr *mvcc.RangeResult, isPrunable func(*mvccpb.KeyValue) bool) {
-	j := 0
-	for i := range rr.KVs {
-		rr.KVs[j] = rr.KVs[i]
-		if !isPrunable(&rr.KVs[i]) {
-			j++
-		}
-	}
-	rr.KVs = rr.KVs[:j]
-}
-
-func newHeader(s *EtcdServer) *pb.ResponseHeader {
-	return &pb.ResponseHeader{
-		ClusterId: uint64(s.Cluster().ID()),
-		MemberId:  uint64(s.ID()),
-		Revision:  s.KV().Rev(),
-		RaftTerm:  s.Term(),
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/apply_auth.go b/vendor/go.etcd.io/etcd/etcdserver/apply_auth.go
deleted file mode 100644
index 4b094ad..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/apply_auth.go
+++ /dev/null
@@ -1,242 +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 etcdserver
-
-import (
-	"sync"
-
-	"go.etcd.io/etcd/auth"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc"
-)
-
-type authApplierV3 struct {
-	applierV3
-	as     auth.AuthStore
-	lessor lease.Lessor
-
-	// mu serializes Apply so that user isn't corrupted and so that
-	// serialized requests don't leak data from TOCTOU errors
-	mu sync.Mutex
-
-	authInfo auth.AuthInfo
-}
-
-func newAuthApplierV3(as auth.AuthStore, base applierV3, lessor lease.Lessor) *authApplierV3 {
-	return &authApplierV3{applierV3: base, as: as, lessor: lessor}
-}
-
-func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult {
-	aa.mu.Lock()
-	defer aa.mu.Unlock()
-	if r.Header != nil {
-		// backward-compatible with pre-3.0 releases when internalRaftRequest
-		// does not have header field
-		aa.authInfo.Username = r.Header.Username
-		aa.authInfo.Revision = r.Header.AuthRevision
-	}
-	if needAdminPermission(r) {
-		if err := aa.as.IsAdminPermitted(&aa.authInfo); err != nil {
-			aa.authInfo.Username = ""
-			aa.authInfo.Revision = 0
-			return &applyResult{err: err}
-		}
-	}
-	ret := aa.applierV3.Apply(r)
-	aa.authInfo.Username = ""
-	aa.authInfo.Revision = 0
-	return ret
-}
-
-func (aa *authApplierV3) Put(txn mvcc.TxnWrite, r *pb.PutRequest) (*pb.PutResponse, error) {
-	if err := aa.as.IsPutPermitted(&aa.authInfo, r.Key); err != nil {
-		return nil, err
-	}
-
-	if err := aa.checkLeasePuts(lease.LeaseID(r.Lease)); err != nil {
-		// The specified lease is already attached with a key that cannot
-		// be written by this user. It means the user cannot revoke the
-		// lease so attaching the lease to the newly written key should
-		// be forbidden.
-		return nil, err
-	}
-
-	if r.PrevKv {
-		err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, nil)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return aa.applierV3.Put(txn, r)
-}
-
-func (aa *authApplierV3) Range(txn mvcc.TxnRead, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	if err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.Range(txn, r)
-}
-
-func (aa *authApplierV3) DeleteRange(txn mvcc.TxnWrite, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	if err := aa.as.IsDeleteRangePermitted(&aa.authInfo, r.Key, r.RangeEnd); err != nil {
-		return nil, err
-	}
-	if r.PrevKv {
-		err := aa.as.IsRangePermitted(&aa.authInfo, r.Key, r.RangeEnd)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return aa.applierV3.DeleteRange(txn, r)
-}
-
-func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs []*pb.RequestOp) error {
-	for _, requ := range reqs {
-		switch tv := requ.Request.(type) {
-		case *pb.RequestOp_RequestRange:
-			if tv.RequestRange == nil {
-				continue
-			}
-
-			if err := as.IsRangePermitted(ai, tv.RequestRange.Key, tv.RequestRange.RangeEnd); err != nil {
-				return err
-			}
-
-		case *pb.RequestOp_RequestPut:
-			if tv.RequestPut == nil {
-				continue
-			}
-
-			if err := as.IsPutPermitted(ai, tv.RequestPut.Key); err != nil {
-				return err
-			}
-
-		case *pb.RequestOp_RequestDeleteRange:
-			if tv.RequestDeleteRange == nil {
-				continue
-			}
-
-			if tv.RequestDeleteRange.PrevKv {
-				err := as.IsRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
-				if err != nil {
-					return err
-				}
-			}
-
-			err := as.IsDeleteRangePermitted(ai, tv.RequestDeleteRange.Key, tv.RequestDeleteRange.RangeEnd)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnRequest) error {
-	for _, c := range rt.Compare {
-		if err := as.IsRangePermitted(ai, c.Key, c.RangeEnd); err != nil {
-			return err
-		}
-	}
-	if err := checkTxnReqsPermission(as, ai, rt.Success); err != nil {
-		return err
-	}
-	return checkTxnReqsPermission(as, ai, rt.Failure)
-}
-
-func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if err := checkTxnAuth(aa.as, &aa.authInfo, rt); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.Txn(rt)
-}
-
-func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	if err := aa.checkLeasePuts(lease.LeaseID(lc.ID)); err != nil {
-		return nil, err
-	}
-	return aa.applierV3.LeaseRevoke(lc)
-}
-
-func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
-	lease := aa.lessor.Lookup(leaseID)
-	if lease != nil {
-		for _, key := range lease.Keys() {
-			if err := aa.as.IsPutPermitted(&aa.authInfo, []byte(key)); err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-func (aa *authApplierV3) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	err := aa.as.IsAdminPermitted(&aa.authInfo)
-	if err != nil && r.Name != aa.authInfo.Username {
-		aa.authInfo.Username = ""
-		aa.authInfo.Revision = 0
-		return &pb.AuthUserGetResponse{}, err
-	}
-
-	return aa.applierV3.UserGet(r)
-}
-
-func (aa *authApplierV3) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	err := aa.as.IsAdminPermitted(&aa.authInfo)
-	if err != nil && !aa.as.HasRole(aa.authInfo.Username, r.Role) {
-		aa.authInfo.Username = ""
-		aa.authInfo.Revision = 0
-		return &pb.AuthRoleGetResponse{}, err
-	}
-
-	return aa.applierV3.RoleGet(r)
-}
-
-func needAdminPermission(r *pb.InternalRaftRequest) bool {
-	switch {
-	case r.AuthEnable != nil:
-		return true
-	case r.AuthDisable != nil:
-		return true
-	case r.AuthUserAdd != nil:
-		return true
-	case r.AuthUserDelete != nil:
-		return true
-	case r.AuthUserChangePassword != nil:
-		return true
-	case r.AuthUserGrantRole != nil:
-		return true
-	case r.AuthUserRevokeRole != nil:
-		return true
-	case r.AuthRoleAdd != nil:
-		return true
-	case r.AuthRoleGrantPermission != nil:
-		return true
-	case r.AuthRoleRevokePermission != nil:
-		return true
-	case r.AuthRoleDelete != nil:
-		return true
-	case r.AuthUserList != nil:
-		return true
-	case r.AuthRoleList != nil:
-		return true
-	default:
-		return false
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/apply_v2.go b/vendor/go.etcd.io/etcd/etcdserver/apply_v2.go
deleted file mode 100644
index c77df19..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/apply_v2.go
+++ /dev/null
@@ -1,147 +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 etcdserver
-
-import (
-	"encoding/json"
-	"path"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	"go.etcd.io/etcd/pkg/pbutil"
-
-	"github.com/coreos/go-semver/semver"
-	"go.uber.org/zap"
-)
-
-// ApplierV2 is the interface for processing V2 raft messages
-type ApplierV2 interface {
-	Delete(r *RequestV2) Response
-	Post(r *RequestV2) Response
-	Put(r *RequestV2) Response
-	QGet(r *RequestV2) Response
-	Sync(r *RequestV2) Response
-}
-
-func NewApplierV2(lg *zap.Logger, s v2store.Store, c *membership.RaftCluster) ApplierV2 {
-	return &applierV2store{lg: lg, store: s, cluster: c}
-}
-
-type applierV2store struct {
-	lg      *zap.Logger
-	store   v2store.Store
-	cluster *membership.RaftCluster
-}
-
-func (a *applierV2store) Delete(r *RequestV2) Response {
-	switch {
-	case r.PrevIndex > 0 || r.PrevValue != "":
-		return toResponse(a.store.CompareAndDelete(r.Path, r.PrevValue, r.PrevIndex))
-	default:
-		return toResponse(a.store.Delete(r.Path, r.Dir, r.Recursive))
-	}
-}
-
-func (a *applierV2store) Post(r *RequestV2) Response {
-	return toResponse(a.store.Create(r.Path, r.Dir, r.Val, true, r.TTLOptions()))
-}
-
-func (a *applierV2store) Put(r *RequestV2) Response {
-	ttlOptions := r.TTLOptions()
-	exists, existsSet := pbutil.GetBool(r.PrevExist)
-	switch {
-	case existsSet:
-		if exists {
-			if r.PrevIndex == 0 && r.PrevValue == "" {
-				return toResponse(a.store.Update(r.Path, r.Val, ttlOptions))
-			}
-			return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions))
-		}
-		return toResponse(a.store.Create(r.Path, r.Dir, r.Val, false, ttlOptions))
-	case r.PrevIndex > 0 || r.PrevValue != "":
-		return toResponse(a.store.CompareAndSwap(r.Path, r.PrevValue, r.PrevIndex, r.Val, ttlOptions))
-	default:
-		if storeMemberAttributeRegexp.MatchString(r.Path) {
-			id := membership.MustParseMemberIDFromKey(path.Dir(r.Path))
-			var attr membership.Attributes
-			if err := json.Unmarshal([]byte(r.Val), &attr); err != nil {
-				if a.lg != nil {
-					a.lg.Panic("failed to unmarshal", zap.String("value", r.Val), zap.Error(err))
-				} else {
-					plog.Panicf("unmarshal %s should never fail: %v", r.Val, err)
-				}
-			}
-			if a.cluster != nil {
-				a.cluster.UpdateAttributes(id, attr)
-			}
-			// return an empty response since there is no consumer.
-			return Response{}
-		}
-		if r.Path == membership.StoreClusterVersionKey() {
-			if a.cluster != nil {
-				a.cluster.SetVersion(semver.Must(semver.NewVersion(r.Val)), api.UpdateCapability)
-			}
-			// return an empty response since there is no consumer.
-			return Response{}
-		}
-		return toResponse(a.store.Set(r.Path, r.Dir, r.Val, ttlOptions))
-	}
-}
-
-func (a *applierV2store) QGet(r *RequestV2) Response {
-	return toResponse(a.store.Get(r.Path, r.Recursive, r.Sorted))
-}
-
-func (a *applierV2store) Sync(r *RequestV2) Response {
-	a.store.DeleteExpiredKeys(time.Unix(0, r.Time))
-	return Response{}
-}
-
-// applyV2Request interprets r as a call to v2store.X
-// and returns a Response interpreted from v2store.Event
-func (s *EtcdServer) applyV2Request(r *RequestV2) Response {
-	defer warnOfExpensiveRequest(s.getLogger(), time.Now(), r, nil, nil)
-
-	switch r.Method {
-	case "POST":
-		return s.applyV2.Post(r)
-	case "PUT":
-		return s.applyV2.Put(r)
-	case "DELETE":
-		return s.applyV2.Delete(r)
-	case "QGET":
-		return s.applyV2.QGet(r)
-	case "SYNC":
-		return s.applyV2.Sync(r)
-	default:
-		// This should never be reached, but just in case:
-		return Response{Err: ErrUnknownMethod}
-	}
-}
-
-func (r *RequestV2) TTLOptions() v2store.TTLOptionSet {
-	refresh, _ := pbutil.GetBool(r.Refresh)
-	ttlOptions := v2store.TTLOptionSet{Refresh: refresh}
-	if r.Expiration != 0 {
-		ttlOptions.ExpireTime = time.Unix(0, r.Expiration)
-	}
-	return ttlOptions
-}
-
-func toResponse(ev *v2store.Event, err error) Response {
-	return Response{Event: ev, Err: err}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/backend.go b/vendor/go.etcd.io/etcd/etcdserver/backend.go
deleted file mode 100644
index 01ba192..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/backend.go
+++ /dev/null
@@ -1,112 +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 etcdserver
-
-import (
-	"fmt"
-	"os"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	"go.uber.org/zap"
-)
-
-func newBackend(cfg ServerConfig) backend.Backend {
-	bcfg := backend.DefaultBackendConfig()
-	bcfg.Path = cfg.backendPath()
-	if cfg.BackendBatchLimit != 0 {
-		bcfg.BatchLimit = cfg.BackendBatchLimit
-		if cfg.Logger != nil {
-			cfg.Logger.Info("setting backend batch limit", zap.Int("batch limit", cfg.BackendBatchLimit))
-		}
-	}
-	if cfg.BackendBatchInterval != 0 {
-		bcfg.BatchInterval = cfg.BackendBatchInterval
-		if cfg.Logger != nil {
-			cfg.Logger.Info("setting backend batch interval", zap.Duration("batch interval", cfg.BackendBatchInterval))
-		}
-	}
-	bcfg.BackendFreelistType = cfg.BackendFreelistType
-	bcfg.Logger = cfg.Logger
-	if cfg.QuotaBackendBytes > 0 && cfg.QuotaBackendBytes != DefaultQuotaBytes {
-		// permit 10% excess over quota for disarm
-		bcfg.MmapSize = uint64(cfg.QuotaBackendBytes + cfg.QuotaBackendBytes/10)
-	}
-	return backend.New(bcfg)
-}
-
-// openSnapshotBackend renames a snapshot db to the current etcd db and opens it.
-func openSnapshotBackend(cfg ServerConfig, ss *snap.Snapshotter, snapshot raftpb.Snapshot) (backend.Backend, error) {
-	snapPath, err := ss.DBFilePath(snapshot.Metadata.Index)
-	if err != nil {
-		return nil, fmt.Errorf("failed to find database snapshot file (%v)", err)
-	}
-	if err := os.Rename(snapPath, cfg.backendPath()); err != nil {
-		return nil, fmt.Errorf("failed to rename database snapshot file (%v)", err)
-	}
-	return openBackend(cfg), nil
-}
-
-// openBackend returns a backend using the current etcd db.
-func openBackend(cfg ServerConfig) backend.Backend {
-	fn := cfg.backendPath()
-
-	now, beOpened := time.Now(), make(chan backend.Backend)
-	go func() {
-		beOpened <- newBackend(cfg)
-	}()
-
-	select {
-	case be := <-beOpened:
-		if cfg.Logger != nil {
-			cfg.Logger.Info("opened backend db", zap.String("path", fn), zap.Duration("took", time.Since(now)))
-		}
-		return be
-
-	case <-time.After(10 * time.Second):
-		if cfg.Logger != nil {
-			cfg.Logger.Info(
-				"db file is flocked by another process, or taking too long",
-				zap.String("path", fn),
-				zap.Duration("took", time.Since(now)),
-			)
-		} else {
-			plog.Warningf("another etcd process is using %q and holds the file lock, or loading backend file is taking >10 seconds", fn)
-			plog.Warningf("waiting for it to exit before starting...")
-		}
-	}
-
-	return <-beOpened
-}
-
-// recoverBackendSnapshot recovers the DB from a snapshot in case etcd crashes
-// before updating the backend db after persisting raft snapshot to disk,
-// violating the invariant snapshot.Metadata.Index < db.consistentIndex. In this
-// case, replace the db with the snapshot db sent by the leader.
-func recoverSnapshotBackend(cfg ServerConfig, oldbe backend.Backend, snapshot raftpb.Snapshot) (backend.Backend, error) {
-	var cIndex consistentIndex
-	kv := mvcc.New(cfg.Logger, oldbe, &lease.FakeLessor{}, &cIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit})
-	defer kv.Close()
-	if snapshot.Metadata.Index <= kv.ConsistentIndex() {
-		return oldbe, nil
-	}
-	oldbe.Close()
-	return openSnapshotBackend(cfg, snap.New(cfg.Logger, cfg.SnapDir()), snapshot)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/cluster_util.go b/vendor/go.etcd.io/etcd/etcdserver/cluster_util.go
deleted file mode 100644
index f92706c..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/cluster_util.go
+++ /dev/null
@@ -1,407 +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 etcdserver
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"sort"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/version"
-
-	"github.com/coreos/go-semver/semver"
-	"go.uber.org/zap"
-)
-
-// isMemberBootstrapped tries to check if the given member has been bootstrapped
-// in the given cluster.
-func isMemberBootstrapped(lg *zap.Logger, cl *membership.RaftCluster, member string, rt http.RoundTripper, timeout time.Duration) bool {
-	rcl, err := getClusterFromRemotePeers(lg, getRemotePeerURLs(cl, member), timeout, false, rt)
-	if err != nil {
-		return false
-	}
-	id := cl.MemberByName(member).ID
-	m := rcl.Member(id)
-	if m == nil {
-		return false
-	}
-	if len(m.ClientURLs) > 0 {
-		return true
-	}
-	return false
-}
-
-// GetClusterFromRemotePeers takes a set of URLs representing etcd peers, and
-// attempts to construct a Cluster by accessing the members endpoint on one of
-// these URLs. The first URL to provide a response is used. If no URLs provide
-// a response, or a Cluster cannot be successfully created from a received
-// response, an error is returned.
-// Each request has a 10-second timeout. Because the upper limit of TTL is 5s,
-// 10 second is enough for building connection and finishing request.
-func GetClusterFromRemotePeers(lg *zap.Logger, urls []string, rt http.RoundTripper) (*membership.RaftCluster, error) {
-	return getClusterFromRemotePeers(lg, urls, 10*time.Second, true, rt)
-}
-
-// If logerr is true, it prints out more error messages.
-func getClusterFromRemotePeers(lg *zap.Logger, urls []string, timeout time.Duration, logerr bool, rt http.RoundTripper) (*membership.RaftCluster, error) {
-	cc := &http.Client{
-		Transport: rt,
-		Timeout:   timeout,
-	}
-	for _, u := range urls {
-		addr := u + "/members"
-		resp, err := cc.Get(addr)
-		if err != nil {
-			if logerr {
-				if lg != nil {
-					lg.Warn("failed to get cluster response", zap.String("address", addr), zap.Error(err))
-				} else {
-					plog.Warningf("could not get cluster response from %s: %v", u, err)
-				}
-			}
-			continue
-		}
-		b, err := ioutil.ReadAll(resp.Body)
-		resp.Body.Close()
-		if err != nil {
-			if logerr {
-				if lg != nil {
-					lg.Warn("failed to read body of cluster response", zap.String("address", addr), zap.Error(err))
-				} else {
-					plog.Warningf("could not read the body of cluster response: %v", err)
-				}
-			}
-			continue
-		}
-		var membs []*membership.Member
-		if err = json.Unmarshal(b, &membs); err != nil {
-			if logerr {
-				if lg != nil {
-					lg.Warn("failed to unmarshal cluster response", zap.String("address", addr), zap.Error(err))
-				} else {
-					plog.Warningf("could not unmarshal cluster response: %v", err)
-				}
-			}
-			continue
-		}
-		id, err := types.IDFromString(resp.Header.Get("X-Etcd-Cluster-ID"))
-		if err != nil {
-			if logerr {
-				if lg != nil {
-					lg.Warn(
-						"failed to parse cluster ID",
-						zap.String("address", addr),
-						zap.String("header", resp.Header.Get("X-Etcd-Cluster-ID")),
-						zap.Error(err),
-					)
-				} else {
-					plog.Warningf("could not parse the cluster ID from cluster res: %v", err)
-				}
-			}
-			continue
-		}
-
-		// check the length of membership members
-		// if the membership members are present then prepare and return raft cluster
-		// if membership members are not present then the raft cluster formed will be
-		// an invalid empty cluster hence return failed to get raft cluster member(s) from the given urls error
-		if len(membs) > 0 {
-			return membership.NewClusterFromMembers(lg, "", id, membs), nil
-		}
-		return nil, fmt.Errorf("failed to get raft cluster member(s) from the given URLs")
-	}
-	return nil, fmt.Errorf("could not retrieve cluster information from the given URLs")
-}
-
-// getRemotePeerURLs returns peer urls of remote members in the cluster. The
-// returned list is sorted in ascending lexicographical order.
-func getRemotePeerURLs(cl *membership.RaftCluster, local string) []string {
-	us := make([]string, 0)
-	for _, m := range cl.Members() {
-		if m.Name == local {
-			continue
-		}
-		us = append(us, m.PeerURLs...)
-	}
-	sort.Strings(us)
-	return us
-}
-
-// getVersions returns the versions of the members in the given cluster.
-// The key of the returned map is the member's ID. The value of the returned map
-// is the semver versions string, including server and cluster.
-// If it fails to get the version of a member, the key will be nil.
-func getVersions(lg *zap.Logger, cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) map[string]*version.Versions {
-	members := cl.Members()
-	vers := make(map[string]*version.Versions)
-	for _, m := range members {
-		if m.ID == local {
-			cv := "not_decided"
-			if cl.Version() != nil {
-				cv = cl.Version().String()
-			}
-			vers[m.ID.String()] = &version.Versions{Server: version.Version, Cluster: cv}
-			continue
-		}
-		ver, err := getVersion(lg, m, rt)
-		if err != nil {
-			if lg != nil {
-				lg.Warn("failed to get version", zap.String("remote-member-id", m.ID.String()), zap.Error(err))
-			} else {
-				plog.Warningf("cannot get the version of member %s (%v)", m.ID, err)
-			}
-			vers[m.ID.String()] = nil
-		} else {
-			vers[m.ID.String()] = ver
-		}
-	}
-	return vers
-}
-
-// decideClusterVersion decides the cluster version based on the versions map.
-// The returned version is the min server version in the map, or nil if the min
-// version in unknown.
-func decideClusterVersion(lg *zap.Logger, vers map[string]*version.Versions) *semver.Version {
-	var cv *semver.Version
-	lv := semver.Must(semver.NewVersion(version.Version))
-
-	for mid, ver := range vers {
-		if ver == nil {
-			return nil
-		}
-		v, err := semver.NewVersion(ver.Server)
-		if err != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to parse server version of remote member",
-					zap.String("remote-member-id", mid),
-					zap.String("remote-member-version", ver.Server),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("cannot understand the version of member %s (%v)", mid, err)
-			}
-			return nil
-		}
-		if lv.LessThan(*v) {
-			if lg != nil {
-				lg.Warn(
-					"leader found higher-versioned member",
-					zap.String("local-member-version", lv.String()),
-					zap.String("remote-member-id", mid),
-					zap.String("remote-member-version", ver.Server),
-				)
-			} else {
-				plog.Warningf("the local etcd version %s is not up-to-date", lv.String())
-				plog.Warningf("member %s has a higher version %s", mid, ver.Server)
-			}
-		}
-		if cv == nil {
-			cv = v
-		} else if v.LessThan(*cv) {
-			cv = v
-		}
-	}
-	return cv
-}
-
-// isCompatibleWithCluster return true if the local member has a compatible version with
-// the current running cluster.
-// The version is considered as compatible when at least one of the other members in the cluster has a
-// cluster version in the range of [MinClusterVersion, Version] and no known members has a cluster version
-// out of the range.
-// We set this rule since when the local member joins, another member might be offline.
-func isCompatibleWithCluster(lg *zap.Logger, cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) bool {
-	vers := getVersions(lg, cl, local, rt)
-	minV := semver.Must(semver.NewVersion(version.MinClusterVersion))
-	maxV := semver.Must(semver.NewVersion(version.Version))
-	maxV = &semver.Version{
-		Major: maxV.Major,
-		Minor: maxV.Minor,
-	}
-	return isCompatibleWithVers(lg, vers, local, minV, maxV)
-}
-
-func isCompatibleWithVers(lg *zap.Logger, vers map[string]*version.Versions, local types.ID, minV, maxV *semver.Version) bool {
-	var ok bool
-	for id, v := range vers {
-		// ignore comparison with local version
-		if id == local.String() {
-			continue
-		}
-		if v == nil {
-			continue
-		}
-		clusterv, err := semver.NewVersion(v.Cluster)
-		if err != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to parse cluster version of remote member",
-					zap.String("remote-member-id", id),
-					zap.String("remote-member-cluster-version", v.Cluster),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("cannot understand the cluster version of member %s (%v)", id, err)
-			}
-			continue
-		}
-		if clusterv.LessThan(*minV) {
-			if lg != nil {
-				lg.Warn(
-					"cluster version of remote member is not compatible; too low",
-					zap.String("remote-member-id", id),
-					zap.String("remote-member-cluster-version", clusterv.String()),
-					zap.String("minimum-cluster-version-supported", minV.String()),
-				)
-			} else {
-				plog.Warningf("the running cluster version(%v) is lower than the minimal cluster version(%v) supported", clusterv.String(), minV.String())
-			}
-			return false
-		}
-		if maxV.LessThan(*clusterv) {
-			if lg != nil {
-				lg.Warn(
-					"cluster version of remote member is not compatible; too high",
-					zap.String("remote-member-id", id),
-					zap.String("remote-member-cluster-version", clusterv.String()),
-					zap.String("minimum-cluster-version-supported", minV.String()),
-				)
-			} else {
-				plog.Warningf("the running cluster version(%v) is higher than the maximum cluster version(%v) supported", clusterv.String(), maxV.String())
-			}
-			return false
-		}
-		ok = true
-	}
-	return ok
-}
-
-// getVersion returns the Versions of the given member via its
-// peerURLs. Returns the last error if it fails to get the version.
-func getVersion(lg *zap.Logger, m *membership.Member, rt http.RoundTripper) (*version.Versions, error) {
-	cc := &http.Client{
-		Transport: rt,
-	}
-	var (
-		err  error
-		resp *http.Response
-	)
-
-	for _, u := range m.PeerURLs {
-		addr := u + "/version"
-		resp, err = cc.Get(addr)
-		if err != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to reach the peer URL",
-					zap.String("address", addr),
-					zap.String("remote-member-id", m.ID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("failed to reach the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			}
-			continue
-		}
-		var b []byte
-		b, err = ioutil.ReadAll(resp.Body)
-		resp.Body.Close()
-		if err != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to read body of response",
-					zap.String("address", addr),
-					zap.String("remote-member-id", m.ID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("failed to read out the response body from the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			}
-			continue
-		}
-		var vers version.Versions
-		if err = json.Unmarshal(b, &vers); err != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to unmarshal response",
-					zap.String("address", addr),
-					zap.String("remote-member-id", m.ID.String()),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("failed to unmarshal the response body got from the peerURL(%s) of member %s (%v)", u, m.ID, err)
-			}
-			continue
-		}
-		return &vers, nil
-	}
-	return nil, err
-}
-
-func promoteMemberHTTP(ctx context.Context, url string, id uint64, peerRt http.RoundTripper) ([]*membership.Member, error) {
-	cc := &http.Client{Transport: peerRt}
-	// TODO: refactor member http handler code
-	// cannot import etcdhttp, so manually construct url
-	requestUrl := url + "/members/promote/" + fmt.Sprintf("%d", id)
-	req, err := http.NewRequest("POST", requestUrl, nil)
-	if err != nil {
-		return nil, err
-	}
-	req = req.WithContext(ctx)
-	resp, err := cc.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, err
-	}
-
-	if resp.StatusCode == http.StatusRequestTimeout {
-		return nil, ErrTimeout
-	}
-	if resp.StatusCode == http.StatusPreconditionFailed {
-		// both ErrMemberNotLearner and ErrLearnerNotReady have same http status code
-		if strings.Contains(string(b), ErrLearnerNotReady.Error()) {
-			return nil, ErrLearnerNotReady
-		}
-		if strings.Contains(string(b), membership.ErrMemberNotLearner.Error()) {
-			return nil, membership.ErrMemberNotLearner
-		}
-		return nil, fmt.Errorf("member promote: unknown error(%s)", string(b))
-	}
-	if resp.StatusCode == http.StatusNotFound {
-		return nil, membership.ErrIDNotFound
-	}
-
-	if resp.StatusCode != http.StatusOK { // all other types of errors
-		return nil, fmt.Errorf("member promote: unknown error(%s)", string(b))
-	}
-
-	var membs []*membership.Member
-	if err := json.Unmarshal(b, &membs); err != nil {
-		return nil, err
-	}
-	return membs, nil
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/config.go b/vendor/go.etcd.io/etcd/etcdserver/config.go
deleted file mode 100644
index 88cd721..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/config.go
+++ /dev/null
@@ -1,307 +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 etcdserver
-
-import (
-	"context"
-	"fmt"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/pkg/netutil"
-	"go.etcd.io/etcd/pkg/transport"
-	"go.etcd.io/etcd/pkg/types"
-
-	bolt "go.etcd.io/bbolt"
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-)
-
-// ServerConfig holds the configuration of etcd as taken from the command line or discovery.
-type ServerConfig struct {
-	Name           string
-	DiscoveryURL   string
-	DiscoveryProxy string
-	ClientURLs     types.URLs
-	PeerURLs       types.URLs
-	DataDir        string
-	// DedicatedWALDir config will make the etcd to write the WAL to the WALDir
-	// rather than the dataDir/member/wal.
-	DedicatedWALDir string
-
-	SnapshotCount uint64
-
-	// SnapshotCatchUpEntries is the number of entries for a slow follower
-	// to catch-up after compacting the raft storage entries.
-	// We expect the follower has a millisecond level latency with the leader.
-	// The max throughput is around 10K. Keep a 5K entries is enough for helping
-	// follower to catch up.
-	// WARNING: only change this for tests. Always use "DefaultSnapshotCatchUpEntries"
-	SnapshotCatchUpEntries uint64
-
-	MaxSnapFiles uint
-	MaxWALFiles  uint
-
-	// BackendBatchInterval is the maximum time before commit the backend transaction.
-	BackendBatchInterval time.Duration
-	// BackendBatchLimit is the maximum operations before commit the backend transaction.
-	BackendBatchLimit int
-
-	// BackendFreelistType is the type of the backend boltdb freelist.
-	BackendFreelistType bolt.FreelistType
-
-	InitialPeerURLsMap  types.URLsMap
-	InitialClusterToken string
-	NewCluster          bool
-	PeerTLSInfo         transport.TLSInfo
-
-	CORS map[string]struct{}
-
-	// HostWhitelist lists acceptable hostnames from client requests.
-	// If server is insecure (no TLS), server only accepts requests
-	// whose Host header value exists in this white list.
-	HostWhitelist map[string]struct{}
-
-	TickMs        uint
-	ElectionTicks int
-
-	// InitialElectionTickAdvance is true, then local member fast-forwards
-	// election ticks to speed up "initial" leader election trigger. This
-	// benefits the case of larger election ticks. For instance, cross
-	// datacenter deployment may require longer election timeout of 10-second.
-	// If true, local node does not need wait up to 10-second. Instead,
-	// forwards its election ticks to 8-second, and have only 2-second left
-	// before leader election.
-	//
-	// Major assumptions are that:
-	//  - cluster has no active leader thus advancing ticks enables faster
-	//    leader election, or
-	//  - cluster already has an established leader, and rejoining follower
-	//    is likely to receive heartbeats from the leader after tick advance
-	//    and before election timeout.
-	//
-	// However, when network from leader to rejoining follower is congested,
-	// and the follower does not receive leader heartbeat within left election
-	// ticks, disruptive election has to happen thus affecting cluster
-	// availabilities.
-	//
-	// Disabling this would slow down initial bootstrap process for cross
-	// datacenter deployments. Make your own tradeoffs by configuring
-	// --initial-election-tick-advance at the cost of slow initial bootstrap.
-	//
-	// If single-node, it advances ticks regardless.
-	//
-	// See https://github.com/etcd-io/etcd/issues/9333 for more detail.
-	InitialElectionTickAdvance bool
-
-	BootstrapTimeout time.Duration
-
-	AutoCompactionRetention time.Duration
-	AutoCompactionMode      string
-	CompactionBatchLimit    int
-	QuotaBackendBytes       int64
-	MaxTxnOps               uint
-
-	// MaxRequestBytes is the maximum request size to send over raft.
-	MaxRequestBytes uint
-
-	StrictReconfigCheck bool
-
-	// ClientCertAuthEnabled is true when cert has been signed by the client CA.
-	ClientCertAuthEnabled bool
-
-	AuthToken  string
-	BcryptCost uint
-
-	// InitialCorruptCheck is true to check data corruption on boot
-	// before serving any peer/client traffic.
-	InitialCorruptCheck bool
-	CorruptCheckTime    time.Duration
-
-	// PreVote is true to enable Raft Pre-Vote.
-	PreVote bool
-
-	// Logger logs server-side operations.
-	// If not nil, it disables "capnslog" and uses the given logger.
-	Logger *zap.Logger
-
-	// LoggerConfig is server logger configuration for Raft logger.
-	// Must be either: "LoggerConfig != nil" or "LoggerCore != nil && LoggerWriteSyncer != nil".
-	LoggerConfig *zap.Config
-	// LoggerCore is "zapcore.Core" for raft logger.
-	// Must be either: "LoggerConfig != nil" or "LoggerCore != nil && LoggerWriteSyncer != nil".
-	LoggerCore        zapcore.Core
-	LoggerWriteSyncer zapcore.WriteSyncer
-
-	Debug bool
-
-	ForceNewCluster bool
-
-	// EnableLeaseCheckpoint enables primary lessor to persist lease remainingTTL to prevent indefinite auto-renewal of long lived leases.
-	EnableLeaseCheckpoint bool
-	// LeaseCheckpointInterval time.Duration is the wait duration between lease checkpoints.
-	LeaseCheckpointInterval time.Duration
-
-	EnableGRPCGateway bool
-}
-
-// VerifyBootstrap sanity-checks the initial config for bootstrap case
-// and returns an error for things that should never happen.
-func (c *ServerConfig) VerifyBootstrap() error {
-	if err := c.hasLocalMember(); err != nil {
-		return err
-	}
-	if err := c.advertiseMatchesCluster(); err != nil {
-		return err
-	}
-	if checkDuplicateURL(c.InitialPeerURLsMap) {
-		return fmt.Errorf("initial cluster %s has duplicate url", c.InitialPeerURLsMap)
-	}
-	if c.InitialPeerURLsMap.String() == "" && c.DiscoveryURL == "" {
-		return fmt.Errorf("initial cluster unset and no discovery URL found")
-	}
-	return nil
-}
-
-// VerifyJoinExisting sanity-checks the initial config for join existing cluster
-// case and returns an error for things that should never happen.
-func (c *ServerConfig) VerifyJoinExisting() error {
-	// The member has announced its peer urls to the cluster before starting; no need to
-	// set the configuration again.
-	if err := c.hasLocalMember(); err != nil {
-		return err
-	}
-	if checkDuplicateURL(c.InitialPeerURLsMap) {
-		return fmt.Errorf("initial cluster %s has duplicate url", c.InitialPeerURLsMap)
-	}
-	if c.DiscoveryURL != "" {
-		return fmt.Errorf("discovery URL should not be set when joining existing initial cluster")
-	}
-	return nil
-}
-
-// hasLocalMember checks that the cluster at least contains the local server.
-func (c *ServerConfig) hasLocalMember() error {
-	if urls := c.InitialPeerURLsMap[c.Name]; urls == nil {
-		return fmt.Errorf("couldn't find local name %q in the initial cluster configuration", c.Name)
-	}
-	return nil
-}
-
-// advertiseMatchesCluster confirms peer URLs match those in the cluster peer list.
-func (c *ServerConfig) advertiseMatchesCluster() error {
-	urls, apurls := c.InitialPeerURLsMap[c.Name], c.PeerURLs.StringSlice()
-	urls.Sort()
-	sort.Strings(apurls)
-	ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
-	defer cancel()
-	ok, err := netutil.URLStringsEqual(ctx, c.Logger, apurls, urls.StringSlice())
-	if ok {
-		return nil
-	}
-
-	initMap, apMap := make(map[string]struct{}), make(map[string]struct{})
-	for _, url := range c.PeerURLs {
-		apMap[url.String()] = struct{}{}
-	}
-	for _, url := range c.InitialPeerURLsMap[c.Name] {
-		initMap[url.String()] = struct{}{}
-	}
-
-	missing := []string{}
-	for url := range initMap {
-		if _, ok := apMap[url]; !ok {
-			missing = append(missing, url)
-		}
-	}
-	if len(missing) > 0 {
-		for i := range missing {
-			missing[i] = c.Name + "=" + missing[i]
-		}
-		mstr := strings.Join(missing, ",")
-		apStr := strings.Join(apurls, ",")
-		return fmt.Errorf("--initial-cluster has %s but missing from --initial-advertise-peer-urls=%s (%v)", mstr, apStr, err)
-	}
-
-	for url := range apMap {
-		if _, ok := initMap[url]; !ok {
-			missing = append(missing, url)
-		}
-	}
-	if len(missing) > 0 {
-		mstr := strings.Join(missing, ",")
-		umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
-		return fmt.Errorf("--initial-advertise-peer-urls has %s but missing from --initial-cluster=%s", mstr, umap.String())
-	}
-
-	// resolved URLs from "--initial-advertise-peer-urls" and "--initial-cluster" did not match or failed
-	apStr := strings.Join(apurls, ",")
-	umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
-	return fmt.Errorf("failed to resolve %s to match --initial-cluster=%s (%v)", apStr, umap.String(), err)
-}
-
-func (c *ServerConfig) MemberDir() string { return filepath.Join(c.DataDir, "member") }
-
-func (c *ServerConfig) WALDir() string {
-	if c.DedicatedWALDir != "" {
-		return c.DedicatedWALDir
-	}
-	return filepath.Join(c.MemberDir(), "wal")
-}
-
-func (c *ServerConfig) SnapDir() string { return filepath.Join(c.MemberDir(), "snap") }
-
-func (c *ServerConfig) ShouldDiscover() bool { return c.DiscoveryURL != "" }
-
-// ReqTimeout returns timeout for request to finish.
-func (c *ServerConfig) ReqTimeout() time.Duration {
-	// 5s for queue waiting, computation and disk IO delay
-	// + 2 * election timeout for possible leader election
-	return 5*time.Second + 2*time.Duration(c.ElectionTicks*int(c.TickMs))*time.Millisecond
-}
-
-func (c *ServerConfig) electionTimeout() time.Duration {
-	return time.Duration(c.ElectionTicks*int(c.TickMs)) * time.Millisecond
-}
-
-func (c *ServerConfig) peerDialTimeout() time.Duration {
-	// 1s for queue wait and election timeout
-	return time.Second + time.Duration(c.ElectionTicks*int(c.TickMs))*time.Millisecond
-}
-
-func checkDuplicateURL(urlsmap types.URLsMap) bool {
-	um := make(map[string]bool)
-	for _, urls := range urlsmap {
-		for _, url := range urls {
-			u := url.String()
-			if um[u] {
-				return true
-			}
-			um[u] = true
-		}
-	}
-	return false
-}
-
-func (c *ServerConfig) bootstrapTimeout() time.Duration {
-	if c.BootstrapTimeout != 0 {
-		return c.BootstrapTimeout
-	}
-	return time.Second
-}
-
-func (c *ServerConfig) backendPath() string { return filepath.Join(c.SnapDir(), "db") }
diff --git a/vendor/go.etcd.io/etcd/etcdserver/consistent_index.go b/vendor/go.etcd.io/etcd/etcdserver/consistent_index.go
deleted file mode 100644
index d513f67..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/consistent_index.go
+++ /dev/null
@@ -1,33 +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 etcdserver
-
-import (
-	"sync/atomic"
-)
-
-// consistentIndex represents the offset of an entry in a consistent replica log.
-// It implements the mvcc.ConsistentIndexGetter interface.
-// It is always set to the offset of current entry before executing the entry,
-// so ConsistentWatchableKV could get the consistent index from it.
-type consistentIndex uint64
-
-func (i *consistentIndex) setConsistentIndex(v uint64) {
-	atomic.StoreUint64((*uint64)(i), v)
-}
-
-func (i *consistentIndex) ConsistentIndex() uint64 {
-	return atomic.LoadUint64((*uint64)(i))
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/corrupt.go b/vendor/go.etcd.io/etcd/etcdserver/corrupt.go
deleted file mode 100644
index 32678a7..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/corrupt.go
+++ /dev/null
@@ -1,411 +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 etcdserver
-
-import (
-	"context"
-	"fmt"
-	"time"
-
-	"go.etcd.io/etcd/clientv3"
-	"go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/pkg/types"
-
-	"go.uber.org/zap"
-)
-
-// CheckInitialHashKV compares initial hash values with its peers
-// before serving any peer/client traffic. Only mismatch when hashes
-// are different at requested revision, with same compact revision.
-func (s *EtcdServer) CheckInitialHashKV() error {
-	if !s.Cfg.InitialCorruptCheck {
-		return nil
-	}
-
-	lg := s.getLogger()
-
-	if lg != nil {
-		lg.Info(
-			"starting initial corruption check",
-			zap.String("local-member-id", s.ID().String()),
-			zap.Duration("timeout", s.Cfg.ReqTimeout()),
-		)
-	} else {
-		plog.Infof("%s starting initial corruption check with timeout %v...", s.ID(), s.Cfg.ReqTimeout())
-	}
-
-	h, rev, crev, err := s.kv.HashByRev(0)
-	if err != nil {
-		return fmt.Errorf("%s failed to fetch hash (%v)", s.ID(), err)
-	}
-	peers := s.getPeerHashKVs(rev)
-	mismatch := 0
-	for _, p := range peers {
-		if p.resp != nil {
-			peerID := types.ID(p.resp.Header.MemberId)
-			fields := []zap.Field{
-				zap.String("local-member-id", s.ID().String()),
-				zap.Int64("local-member-revision", rev),
-				zap.Int64("local-member-compact-revision", crev),
-				zap.Uint32("local-member-hash", h),
-				zap.String("remote-peer-id", peerID.String()),
-				zap.Strings("remote-peer-endpoints", p.eps),
-				zap.Int64("remote-peer-revision", p.resp.Header.Revision),
-				zap.Int64("remote-peer-compact-revision", p.resp.CompactRevision),
-				zap.Uint32("remote-peer-hash", p.resp.Hash),
-			}
-
-			if h != p.resp.Hash {
-				if crev == p.resp.CompactRevision {
-					if lg != nil {
-						lg.Warn("found different hash values from remote peer", fields...)
-					} else {
-						plog.Errorf("%s's hash %d != %s's hash %d (revision %d, peer revision %d, compact revision %d)", s.ID(), h, peerID, p.resp.Hash, rev, p.resp.Header.Revision, crev)
-					}
-					mismatch++
-				} else {
-					if lg != nil {
-						lg.Warn("found different compact revision values from remote peer", fields...)
-					} else {
-						plog.Warningf("%s cannot check hash of peer(%s): peer has a different compact revision %d (revision:%d)", s.ID(), peerID, p.resp.CompactRevision, rev)
-					}
-				}
-			}
-
-			continue
-		}
-
-		if p.err != nil {
-			switch p.err {
-			case rpctypes.ErrFutureRev:
-				if lg != nil {
-					lg.Warn(
-						"cannot fetch hash from slow remote peer",
-						zap.String("local-member-id", s.ID().String()),
-						zap.Int64("local-member-revision", rev),
-						zap.Int64("local-member-compact-revision", crev),
-						zap.Uint32("local-member-hash", h),
-						zap.String("remote-peer-id", p.id.String()),
-						zap.Strings("remote-peer-endpoints", p.eps),
-						zap.Error(err),
-					)
-				} else {
-					plog.Warningf("%s cannot check the hash of peer(%q) at revision %d: peer is lagging behind(%q)", s.ID(), p.eps, rev, p.err.Error())
-				}
-			case rpctypes.ErrCompacted:
-				if lg != nil {
-					lg.Warn(
-						"cannot fetch hash from remote peer; local member is behind",
-						zap.String("local-member-id", s.ID().String()),
-						zap.Int64("local-member-revision", rev),
-						zap.Int64("local-member-compact-revision", crev),
-						zap.Uint32("local-member-hash", h),
-						zap.String("remote-peer-id", p.id.String()),
-						zap.Strings("remote-peer-endpoints", p.eps),
-						zap.Error(err),
-					)
-				} else {
-					plog.Warningf("%s cannot check the hash of peer(%q) at revision %d: local node is lagging behind(%q)", s.ID(), p.eps, rev, p.err.Error())
-				}
-			}
-		}
-	}
-	if mismatch > 0 {
-		return fmt.Errorf("%s found data inconsistency with peers", s.ID())
-	}
-
-	if lg != nil {
-		lg.Info(
-			"initial corruption checking passed; no corruption",
-			zap.String("local-member-id", s.ID().String()),
-		)
-	} else {
-		plog.Infof("%s succeeded on initial corruption checking: no corruption", s.ID())
-	}
-	return nil
-}
-
-func (s *EtcdServer) monitorKVHash() {
-	t := s.Cfg.CorruptCheckTime
-	if t == 0 {
-		return
-	}
-
-	lg := s.getLogger()
-	if lg != nil {
-		lg.Info(
-			"enabled corruption checking",
-			zap.String("local-member-id", s.ID().String()),
-			zap.Duration("interval", t),
-		)
-	} else {
-		plog.Infof("enabled corruption checking with %s interval", t)
-	}
-
-	for {
-		select {
-		case <-s.stopping:
-			return
-		case <-time.After(t):
-		}
-		if !s.isLeader() {
-			continue
-		}
-		if err := s.checkHashKV(); err != nil {
-			if lg != nil {
-				lg.Warn("failed to check hash KV", zap.Error(err))
-			} else {
-				plog.Debugf("check hash kv failed %v", err)
-			}
-		}
-	}
-}
-
-func (s *EtcdServer) checkHashKV() error {
-	lg := s.getLogger()
-
-	h, rev, crev, err := s.kv.HashByRev(0)
-	if err != nil {
-		return err
-	}
-	peers := s.getPeerHashKVs(rev)
-
-	ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-	err = s.linearizableReadNotify(ctx)
-	cancel()
-	if err != nil {
-		return err
-	}
-
-	h2, rev2, crev2, err := s.kv.HashByRev(0)
-	if err != nil {
-		return err
-	}
-
-	alarmed := false
-	mismatch := func(id uint64) {
-		if alarmed {
-			return
-		}
-		alarmed = true
-		a := &pb.AlarmRequest{
-			MemberID: id,
-			Action:   pb.AlarmRequest_ACTIVATE,
-			Alarm:    pb.AlarmType_CORRUPT,
-		}
-		s.goAttach(func() {
-			s.raftRequest(s.ctx, pb.InternalRaftRequest{Alarm: a})
-		})
-	}
-
-	if h2 != h && rev2 == rev && crev == crev2 {
-		if lg != nil {
-			lg.Warn(
-				"found hash mismatch",
-				zap.Int64("revision-1", rev),
-				zap.Int64("compact-revision-1", crev),
-				zap.Uint32("hash-1", h),
-				zap.Int64("revision-2", rev2),
-				zap.Int64("compact-revision-2", crev2),
-				zap.Uint32("hash-2", h2),
-			)
-		} else {
-			plog.Warningf("mismatched hashes %d and %d for revision %d", h, h2, rev)
-		}
-		mismatch(uint64(s.ID()))
-	}
-
-	for _, p := range peers {
-		if p.resp == nil {
-			continue
-		}
-		id := p.resp.Header.MemberId
-
-		// leader expects follower's latest revision less than or equal to leader's
-		if p.resp.Header.Revision > rev2 {
-			if lg != nil {
-				lg.Warn(
-					"revision from follower must be less than or equal to leader's",
-					zap.Int64("leader-revision", rev2),
-					zap.Int64("follower-revision", p.resp.Header.Revision),
-					zap.String("follower-peer-id", types.ID(id).String()),
-				)
-			} else {
-				plog.Warningf(
-					"revision %d from member %v, expected at most %d",
-					p.resp.Header.Revision,
-					types.ID(id),
-					rev2)
-			}
-			mismatch(id)
-		}
-
-		// leader expects follower's latest compact revision less than or equal to leader's
-		if p.resp.CompactRevision > crev2 {
-			if lg != nil {
-				lg.Warn(
-					"compact revision from follower must be less than or equal to leader's",
-					zap.Int64("leader-compact-revision", crev2),
-					zap.Int64("follower-compact-revision", p.resp.CompactRevision),
-					zap.String("follower-peer-id", types.ID(id).String()),
-				)
-			} else {
-				plog.Warningf(
-					"compact revision %d from member %v, expected at most %d",
-					p.resp.CompactRevision,
-					types.ID(id),
-					crev2,
-				)
-			}
-			mismatch(id)
-		}
-
-		// follower's compact revision is leader's old one, then hashes must match
-		if p.resp.CompactRevision == crev && p.resp.Hash != h {
-			if lg != nil {
-				lg.Warn(
-					"same compact revision then hashes must match",
-					zap.Int64("leader-compact-revision", crev2),
-					zap.Uint32("leader-hash", h),
-					zap.Int64("follower-compact-revision", p.resp.CompactRevision),
-					zap.Uint32("follower-hash", p.resp.Hash),
-					zap.String("follower-peer-id", types.ID(id).String()),
-				)
-			} else {
-				plog.Warningf(
-					"hash %d at revision %d from member %v, expected hash %d",
-					p.resp.Hash,
-					rev,
-					types.ID(id),
-					h,
-				)
-			}
-			mismatch(id)
-		}
-	}
-	return nil
-}
-
-type peerHashKVResp struct {
-	id  types.ID
-	eps []string
-
-	resp *clientv3.HashKVResponse
-	err  error
-}
-
-func (s *EtcdServer) getPeerHashKVs(rev int64) (resps []*peerHashKVResp) {
-	// TODO: handle the case when "s.cluster.Members" have not
-	// been populated (e.g. no snapshot to load from disk)
-	mbs := s.cluster.Members()
-	pss := make([]peerHashKVResp, len(mbs))
-	for _, m := range mbs {
-		if m.ID == s.ID() {
-			continue
-		}
-		pss = append(pss, peerHashKVResp{id: m.ID, eps: m.PeerURLs})
-	}
-
-	lg := s.getLogger()
-
-	for _, p := range pss {
-		if len(p.eps) == 0 {
-			continue
-		}
-		cli, cerr := clientv3.New(clientv3.Config{
-			DialTimeout: s.Cfg.ReqTimeout(),
-			Endpoints:   p.eps,
-		})
-		if cerr != nil {
-			if lg != nil {
-				lg.Warn(
-					"failed to create client to peer URL",
-					zap.String("local-member-id", s.ID().String()),
-					zap.String("remote-peer-id", p.id.String()),
-					zap.Strings("remote-peer-endpoints", p.eps),
-					zap.Error(cerr),
-				)
-			} else {
-				plog.Warningf("%s failed to create client to peer %q for hash checking (%q)", s.ID(), p.eps, cerr.Error())
-			}
-			continue
-		}
-
-		respsLen := len(resps)
-		for _, c := range cli.Endpoints() {
-			ctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-			var resp *clientv3.HashKVResponse
-			resp, cerr = cli.HashKV(ctx, c, rev)
-			cancel()
-			if cerr == nil {
-				resps = append(resps, &peerHashKVResp{id: p.id, eps: p.eps, resp: resp, err: nil})
-				break
-			}
-			if lg != nil {
-				lg.Warn(
-					"failed hash kv request",
-					zap.String("local-member-id", s.ID().String()),
-					zap.Int64("requested-revision", rev),
-					zap.String("remote-peer-endpoint", c),
-					zap.Error(cerr),
-				)
-			} else {
-				plog.Warningf("%s hash-kv error %q on peer %q with revision %d", s.ID(), cerr.Error(), c, rev)
-			}
-		}
-		cli.Close()
-
-		if respsLen == len(resps) {
-			resps = append(resps, &peerHashKVResp{id: p.id, eps: p.eps, resp: nil, err: cerr})
-		}
-	}
-	return resps
-}
-
-type applierV3Corrupt struct {
-	applierV3
-}
-
-func newApplierV3Corrupt(a applierV3) *applierV3Corrupt { return &applierV3Corrupt{a} }
-
-func (a *applierV3Corrupt) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb.PutResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Range(txn mvcc.TxnRead, p *pb.RangeRequest) (*pb.RangeResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) DeleteRange(txn mvcc.TxnWrite, p *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) {
-	return nil, nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	return nil, ErrCorrupt
-}
-
-func (a *applierV3Corrupt) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	return nil, ErrCorrupt
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/doc.go b/vendor/go.etcd.io/etcd/etcdserver/doc.go
deleted file mode 100644
index b195d2d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/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 etcdserver defines how etcd servers interact and store their states.
-package etcdserver
diff --git a/vendor/go.etcd.io/etcd/etcdserver/errors.go b/vendor/go.etcd.io/etcd/etcdserver/errors.go
deleted file mode 100644
index d0fe289..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/errors.go
+++ /dev/null
@@ -1,51 +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 etcdserver
-
-import (
-	"errors"
-	"fmt"
-)
-
-var (
-	ErrUnknownMethod              = errors.New("etcdserver: unknown method")
-	ErrStopped                    = errors.New("etcdserver: server stopped")
-	ErrCanceled                   = errors.New("etcdserver: request cancelled")
-	ErrTimeout                    = errors.New("etcdserver: request timed out")
-	ErrTimeoutDueToLeaderFail     = errors.New("etcdserver: request timed out, possibly due to previous leader failure")
-	ErrTimeoutDueToConnectionLost = errors.New("etcdserver: request timed out, possibly due to connection lost")
-	ErrTimeoutLeaderTransfer      = errors.New("etcdserver: request timed out, leader transfer took too long")
-	ErrLeaderChanged              = errors.New("etcdserver: leader changed")
-	ErrNotEnoughStartedMembers    = errors.New("etcdserver: re-configuration failed due to not enough started members")
-	ErrLearnerNotReady            = errors.New("etcdserver: can only promote a learner member which is in sync with leader")
-	ErrNoLeader                   = errors.New("etcdserver: no leader")
-	ErrNotLeader                  = errors.New("etcdserver: not leader")
-	ErrRequestTooLarge            = errors.New("etcdserver: request is too large")
-	ErrNoSpace                    = errors.New("etcdserver: no space")
-	ErrTooManyRequests            = errors.New("etcdserver: too many requests")
-	ErrUnhealthy                  = errors.New("etcdserver: unhealthy cluster")
-	ErrKeyNotFound                = errors.New("etcdserver: key not found")
-	ErrCorrupt                    = errors.New("etcdserver: corrupt cluster")
-	ErrBadLeaderTransferee        = errors.New("etcdserver: bad leader transferee")
-)
-
-type DiscoveryError struct {
-	Op  string
-	Err error
-}
-
-func (e DiscoveryError) Error() string {
-	return fmt.Sprintf("failed to %s discovery cluster (%v)", e.Op, e.Err)
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.pb.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.pb.go
deleted file mode 100644
index 9e9b42c..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.pb.go
+++ /dev/null
@@ -1,1041 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: etcdserver.proto
-
-/*
-	Package etcdserverpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		etcdserver.proto
-		raft_internal.proto
-		rpc.proto
-
-	It has these top-level messages:
-		Request
-		Metadata
-		RequestHeader
-		InternalRaftRequest
-		EmptyResponse
-		InternalAuthenticateRequest
-		ResponseHeader
-		RangeRequest
-		RangeResponse
-		PutRequest
-		PutResponse
-		DeleteRangeRequest
-		DeleteRangeResponse
-		RequestOp
-		ResponseOp
-		Compare
-		TxnRequest
-		TxnResponse
-		CompactionRequest
-		CompactionResponse
-		HashRequest
-		HashKVRequest
-		HashKVResponse
-		HashResponse
-		SnapshotRequest
-		SnapshotResponse
-		WatchRequest
-		WatchCreateRequest
-		WatchCancelRequest
-		WatchProgressRequest
-		WatchResponse
-		LeaseGrantRequest
-		LeaseGrantResponse
-		LeaseRevokeRequest
-		LeaseRevokeResponse
-		LeaseCheckpoint
-		LeaseCheckpointRequest
-		LeaseCheckpointResponse
-		LeaseKeepAliveRequest
-		LeaseKeepAliveResponse
-		LeaseTimeToLiveRequest
-		LeaseTimeToLiveResponse
-		LeaseLeasesRequest
-		LeaseStatus
-		LeaseLeasesResponse
-		Member
-		MemberAddRequest
-		MemberAddResponse
-		MemberRemoveRequest
-		MemberRemoveResponse
-		MemberUpdateRequest
-		MemberUpdateResponse
-		MemberListRequest
-		MemberListResponse
-		MemberPromoteRequest
-		MemberPromoteResponse
-		DefragmentRequest
-		DefragmentResponse
-		MoveLeaderRequest
-		MoveLeaderResponse
-		AlarmRequest
-		AlarmMember
-		AlarmResponse
-		StatusRequest
-		StatusResponse
-		AuthEnableRequest
-		AuthDisableRequest
-		AuthenticateRequest
-		AuthUserAddRequest
-		AuthUserGetRequest
-		AuthUserDeleteRequest
-		AuthUserChangePasswordRequest
-		AuthUserGrantRoleRequest
-		AuthUserRevokeRoleRequest
-		AuthRoleAddRequest
-		AuthRoleGetRequest
-		AuthUserListRequest
-		AuthRoleListRequest
-		AuthRoleDeleteRequest
-		AuthRoleGrantPermissionRequest
-		AuthRoleRevokePermissionRequest
-		AuthEnableResponse
-		AuthDisableResponse
-		AuthenticateResponse
-		AuthUserAddResponse
-		AuthUserGetResponse
-		AuthUserDeleteResponse
-		AuthUserChangePasswordResponse
-		AuthUserGrantRoleResponse
-		AuthUserRevokeRoleResponse
-		AuthRoleAddResponse
-		AuthRoleGetResponse
-		AuthRoleListResponse
-		AuthUserListResponse
-		AuthRoleDeleteResponse
-		AuthRoleGrantPermissionResponse
-		AuthRoleRevokePermissionResponse
-*/
-package etcdserverpb
-
-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 Request struct {
-	ID               uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"`
-	Method           string `protobuf:"bytes,2,opt,name=Method" json:"Method"`
-	Path             string `protobuf:"bytes,3,opt,name=Path" json:"Path"`
-	Val              string `protobuf:"bytes,4,opt,name=Val" json:"Val"`
-	Dir              bool   `protobuf:"varint,5,opt,name=Dir" json:"Dir"`
-	PrevValue        string `protobuf:"bytes,6,opt,name=PrevValue" json:"PrevValue"`
-	PrevIndex        uint64 `protobuf:"varint,7,opt,name=PrevIndex" json:"PrevIndex"`
-	PrevExist        *bool  `protobuf:"varint,8,opt,name=PrevExist" json:"PrevExist,omitempty"`
-	Expiration       int64  `protobuf:"varint,9,opt,name=Expiration" json:"Expiration"`
-	Wait             bool   `protobuf:"varint,10,opt,name=Wait" json:"Wait"`
-	Since            uint64 `protobuf:"varint,11,opt,name=Since" json:"Since"`
-	Recursive        bool   `protobuf:"varint,12,opt,name=Recursive" json:"Recursive"`
-	Sorted           bool   `protobuf:"varint,13,opt,name=Sorted" json:"Sorted"`
-	Quorum           bool   `protobuf:"varint,14,opt,name=Quorum" json:"Quorum"`
-	Time             int64  `protobuf:"varint,15,opt,name=Time" json:"Time"`
-	Stream           bool   `protobuf:"varint,16,opt,name=Stream" json:"Stream"`
-	Refresh          *bool  `protobuf:"varint,17,opt,name=Refresh" json:"Refresh,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Request) Reset()                    { *m = Request{} }
-func (m *Request) String() string            { return proto.CompactTextString(m) }
-func (*Request) ProtoMessage()               {}
-func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{0} }
-
-type Metadata struct {
-	NodeID           uint64 `protobuf:"varint,1,opt,name=NodeID" json:"NodeID"`
-	ClusterID        uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Metadata) Reset()                    { *m = Metadata{} }
-func (m *Metadata) String() string            { return proto.CompactTextString(m) }
-func (*Metadata) ProtoMessage()               {}
-func (*Metadata) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{1} }
-
-func init() {
-	proto.RegisterType((*Request)(nil), "etcdserverpb.Request")
-	proto.RegisterType((*Metadata)(nil), "etcdserverpb.Metadata")
-}
-func (m *Request) 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 *Request) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.ID))
-	dAtA[i] = 0x12
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Method)))
-	i += copy(dAtA[i:], m.Method)
-	dAtA[i] = 0x1a
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Path)))
-	i += copy(dAtA[i:], m.Path)
-	dAtA[i] = 0x22
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.Val)))
-	i += copy(dAtA[i:], m.Val)
-	dAtA[i] = 0x28
-	i++
-	if m.Dir {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x32
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(len(m.PrevValue)))
-	i += copy(dAtA[i:], m.PrevValue)
-	dAtA[i] = 0x38
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.PrevIndex))
-	if m.PrevExist != nil {
-		dAtA[i] = 0x40
-		i++
-		if *m.PrevExist {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	dAtA[i] = 0x48
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.Expiration))
-	dAtA[i] = 0x50
-	i++
-	if m.Wait {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x58
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.Since))
-	dAtA[i] = 0x60
-	i++
-	if m.Recursive {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x68
-	i++
-	if m.Sorted {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x70
-	i++
-	if m.Quorum {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x78
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.Time))
-	dAtA[i] = 0x80
-	i++
-	dAtA[i] = 0x1
-	i++
-	if m.Stream {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	if m.Refresh != nil {
-		dAtA[i] = 0x88
-		i++
-		dAtA[i] = 0x1
-		i++
-		if *m.Refresh {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *Metadata) 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 *Metadata) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.NodeID))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintEtcdserver(dAtA, i, uint64(m.ClusterID))
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func encodeVarintEtcdserver(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 *Request) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovEtcdserver(uint64(m.ID))
-	l = len(m.Method)
-	n += 1 + l + sovEtcdserver(uint64(l))
-	l = len(m.Path)
-	n += 1 + l + sovEtcdserver(uint64(l))
-	l = len(m.Val)
-	n += 1 + l + sovEtcdserver(uint64(l))
-	n += 2
-	l = len(m.PrevValue)
-	n += 1 + l + sovEtcdserver(uint64(l))
-	n += 1 + sovEtcdserver(uint64(m.PrevIndex))
-	if m.PrevExist != nil {
-		n += 2
-	}
-	n += 1 + sovEtcdserver(uint64(m.Expiration))
-	n += 2
-	n += 1 + sovEtcdserver(uint64(m.Since))
-	n += 2
-	n += 2
-	n += 2
-	n += 1 + sovEtcdserver(uint64(m.Time))
-	n += 3
-	if m.Refresh != nil {
-		n += 3
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *Metadata) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovEtcdserver(uint64(m.NodeID))
-	n += 1 + sovEtcdserver(uint64(m.ClusterID))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func sovEtcdserver(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozEtcdserver(x uint64) (n int) {
-	return sovEtcdserver(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *Request) 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 ErrIntOverflowEtcdserver
-			}
-			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: Request: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Method", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Method = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Path = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Val", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Val = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Dir", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Dir = bool(v != 0)
-		case 6:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevValue", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.PrevValue = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 7:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevIndex", wireType)
-			}
-			m.PrevIndex = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.PrevIndex |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 8:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevExist", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			b := bool(v != 0)
-			m.PrevExist = &b
-		case 9:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Expiration", wireType)
-			}
-			m.Expiration = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Expiration |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 10:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Wait = bool(v != 0)
-		case 11:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Since", wireType)
-			}
-			m.Since = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Since |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 12:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Recursive", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Recursive = bool(v != 0)
-		case 13:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Sorted", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Sorted = bool(v != 0)
-		case 14:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Quorum", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Quorum = bool(v != 0)
-		case 15:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType)
-			}
-			m.Time = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Time |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 16:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Stream", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Stream = bool(v != 0)
-		case 17:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Refresh", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			b := bool(v != 0)
-			m.Refresh = &b
-		default:
-			iNdEx = preIndex
-			skippy, err := skipEtcdserver(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			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 (m *Metadata) 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 ErrIntOverflowEtcdserver
-			}
-			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: Metadata: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NodeID", wireType)
-			}
-			m.NodeID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.NodeID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ClusterID", wireType)
-			}
-			m.ClusterID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowEtcdserver
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ClusterID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipEtcdserver(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthEtcdserver
-			}
-			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 skipEtcdserver(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, ErrIntOverflowEtcdserver
-			}
-			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, ErrIntOverflowEtcdserver
-				}
-				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, ErrIntOverflowEtcdserver
-				}
-				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, ErrInvalidLengthEtcdserver
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowEtcdserver
-					}
-					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 := skipEtcdserver(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 (
-	ErrInvalidLengthEtcdserver = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowEtcdserver   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("etcdserver.proto", fileDescriptorEtcdserver) }
-
-var fileDescriptorEtcdserver = []byte{
-	// 380 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0xd2, 0xdd, 0x6e, 0xda, 0x30,
-	0x14, 0x07, 0x70, 0x0c, 0xe1, 0xcb, 0x63, 0x1b, 0xb3, 0xd0, 0x74, 0x84, 0xa6, 0x2c, 0x42, 0xbb,
-	0xc8, 0xd5, 0xf6, 0x0e, 0x2c, 0x5c, 0x44, 0x2a, 0x15, 0x0d, 0x15, 0xbd, 0x76, 0xc9, 0x29, 0x58,
-	0x02, 0x4c, 0x1d, 0x07, 0xf1, 0x06, 0x7d, 0x85, 0x3e, 0x12, 0x97, 0x7d, 0x82, 0xaa, 0xa5, 0x2f,
-	0x52, 0x39, 0x24, 0xc4, 0xed, 0x5d, 0xf4, 0xfb, 0x9f, 0x1c, 0x1f, 0x7f, 0xd0, 0x2e, 0xea, 0x79,
-	0x9c, 0xa0, 0xda, 0xa1, 0xfa, 0xbb, 0x55, 0x52, 0x4b, 0xd6, 0x29, 0x65, 0x7b, 0xdb, 0xef, 0x2d,
-	0xe4, 0x42, 0x66, 0xc1, 0x3f, 0xf3, 0x75, 0xaa, 0x19, 0x3c, 0x38, 0xb4, 0x19, 0xe1, 0x7d, 0x8a,
-	0x89, 0x66, 0x3d, 0x5a, 0x0d, 0x03, 0x20, 0x1e, 0xf1, 0x9d, 0xa1, 0x73, 0x78, 0xfe, 0x5d, 0x89,
-	0xaa, 0x61, 0xc0, 0x7e, 0xd1, 0xc6, 0x18, 0xf5, 0x52, 0xc6, 0x50, 0xf5, 0x88, 0xdf, 0xce, 0x93,
-	0xdc, 0x18, 0x50, 0x67, 0xc2, 0xf5, 0x12, 0x6a, 0x56, 0x96, 0x09, 0xfb, 0x49, 0x6b, 0x33, 0xbe,
-	0x02, 0xc7, 0x0a, 0x0c, 0x18, 0x0f, 0x84, 0x82, 0xba, 0x47, 0xfc, 0x56, 0xe1, 0x81, 0x50, 0x6c,
-	0x40, 0xdb, 0x13, 0x85, 0xbb, 0x19, 0x5f, 0xa5, 0x08, 0x0d, 0xeb, 0xaf, 0x92, 0x8b, 0x9a, 0x70,
-	0x13, 0xe3, 0x1e, 0x9a, 0xd6, 0xa0, 0x25, 0x17, 0x35, 0xa3, 0xbd, 0x48, 0x34, 0xb4, 0xce, 0xab,
-	0x90, 0xa8, 0x64, 0xf6, 0x87, 0xd2, 0xd1, 0x7e, 0x2b, 0x14, 0xd7, 0x42, 0x6e, 0xa0, 0xed, 0x11,
-	0xbf, 0x96, 0x37, 0xb2, 0xdc, 0xec, 0xed, 0x86, 0x0b, 0x0d, 0xd4, 0x1a, 0x35, 0x13, 0xd6, 0xa7,
-	0xf5, 0xa9, 0xd8, 0xcc, 0x11, 0xbe, 0x58, 0x33, 0x9c, 0xc8, 0xac, 0x1f, 0xe1, 0x3c, 0x55, 0x89,
-	0xd8, 0x21, 0x74, 0xac, 0x5f, 0x4b, 0x36, 0x67, 0x3a, 0x95, 0x4a, 0x63, 0x0c, 0x5f, 0xad, 0x82,
-	0xdc, 0x4c, 0x7a, 0x95, 0x4a, 0x95, 0xae, 0xe1, 0x9b, 0x9d, 0x9e, 0xcc, 0x4c, 0x75, 0x2d, 0xd6,
-	0x08, 0xdf, 0xad, 0xa9, 0x33, 0xc9, 0xba, 0x6a, 0x85, 0x7c, 0x0d, 0xdd, 0x0f, 0x5d, 0x33, 0x63,
-	0xae, 0xb9, 0xe8, 0x3b, 0x85, 0xc9, 0x12, 0x7e, 0x58, 0xa7, 0x52, 0xe0, 0xe0, 0x82, 0xb6, 0xc6,
-	0xa8, 0x79, 0xcc, 0x35, 0x37, 0x9d, 0x2e, 0x65, 0x8c, 0x9f, 0x5e, 0x43, 0x6e, 0x66, 0x87, 0xff,
-	0x57, 0x69, 0xa2, 0x51, 0x85, 0x41, 0xf6, 0x28, 0xce, 0xb7, 0x70, 0xe6, 0x61, 0xef, 0xf0, 0xea,
-	0x56, 0x0e, 0x47, 0x97, 0x3c, 0x1d, 0x5d, 0xf2, 0x72, 0x74, 0xc9, 0xe3, 0x9b, 0x5b, 0x79, 0x0f,
-	0x00, 0x00, 0xff, 0xff, 0xee, 0x40, 0xba, 0xd6, 0xa4, 0x02, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.proto b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.proto
deleted file mode 100644
index 25e0aca..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/etcdserver.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-syntax = "proto2";
-package etcdserverpb;
-
-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 Request {
-	optional uint64 ID         =  1 [(gogoproto.nullable) = false];
-	optional string Method     =  2 [(gogoproto.nullable) = false];
-	optional string Path       =  3 [(gogoproto.nullable) = false];
-	optional string Val        =  4 [(gogoproto.nullable) = false];
-	optional bool   Dir        =  5 [(gogoproto.nullable) = false];
-	optional string PrevValue  =  6 [(gogoproto.nullable) = false];
-	optional uint64 PrevIndex  =  7 [(gogoproto.nullable) = false];
-	optional bool   PrevExist  =  8 [(gogoproto.nullable) = true];
-	optional int64  Expiration =  9 [(gogoproto.nullable) = false];
-	optional bool   Wait       = 10 [(gogoproto.nullable) = false];
-	optional uint64 Since      = 11 [(gogoproto.nullable) = false];
-	optional bool   Recursive  = 12 [(gogoproto.nullable) = false];
-	optional bool   Sorted     = 13 [(gogoproto.nullable) = false];
-	optional bool   Quorum     = 14 [(gogoproto.nullable) = false];
-	optional int64  Time       = 15 [(gogoproto.nullable) = false];
-	optional bool   Stream     = 16 [(gogoproto.nullable) = false];
-	optional bool   Refresh    = 17 [(gogoproto.nullable) = true];
-}
-
-message Metadata {
-	optional uint64 NodeID    = 1 [(gogoproto.nullable) = false];
-	optional uint64 ClusterID = 2 [(gogoproto.nullable) = false];
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go
deleted file mode 100644
index 904c321..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/gw/rpc.pb.gw.go
+++ /dev/null
@@ -1,2318 +0,0 @@
-// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
-// source: etcdserver/etcdserverpb/rpc.proto
-
-/*
-Package etcdserverpb is a reverse proxy.
-
-It translates gRPC into RESTful JSON APIs.
-*/
-package gw
-
-import (
-	"go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"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_KV_Range_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.RangeRequest
-	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.Range(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Put_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.PutRequest
-	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.Put(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_DeleteRange_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.DeleteRangeRequest
-	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.DeleteRange(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Txn_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.TxnRequest
-	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.Txn(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_KV_Compact_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.CompactionRequest
-	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.Compact(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Watch_Watch_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.WatchClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Watch_WatchClient, runtime.ServerMetadata, error) {
-	var metadata runtime.ServerMetadata
-	stream, err := client.Watch(ctx)
-	if err != nil {
-		grpclog.Printf("Failed to start streaming: %v", err)
-		return nil, metadata, err
-	}
-	dec := marshaler.NewDecoder(req.Body)
-	handleSend := func() error {
-		var protoReq etcdserverpb.WatchRequest
-		err := dec.Decode(&protoReq)
-		if err == io.EOF {
-			return err
-		}
-		if err != nil {
-			grpclog.Printf("Failed to decode request: %v", err)
-			return err
-		}
-		if err := stream.Send(&protoReq); err != nil {
-			grpclog.Printf("Failed to send request: %v", err)
-			return err
-		}
-		return nil
-	}
-	if err := handleSend(); err != nil {
-		if cerr := stream.CloseSend(); cerr != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", cerr)
-		}
-		if err == io.EOF {
-			return stream, metadata, nil
-		}
-		return nil, metadata, err
-	}
-	go func() {
-		for {
-			if err := handleSend(); err != nil {
-				break
-			}
-		}
-		if err := stream.CloseSend(); err != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", err)
-		}
-	}()
-	header, err := stream.Header()
-	if err != nil {
-		grpclog.Printf("Failed to get header from client: %v", err)
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-}
-
-func request_Lease_LeaseGrant_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseGrantRequest
-	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.LeaseGrant(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseRevoke_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseRevokeRequest
-	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.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseRevoke_1(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseRevokeRequest
-	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.LeaseRevoke(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseKeepAlive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Lease_LeaseKeepAliveClient, runtime.ServerMetadata, error) {
-	var metadata runtime.ServerMetadata
-	stream, err := client.LeaseKeepAlive(ctx)
-	if err != nil {
-		grpclog.Printf("Failed to start streaming: %v", err)
-		return nil, metadata, err
-	}
-	dec := marshaler.NewDecoder(req.Body)
-	handleSend := func() error {
-		var protoReq etcdserverpb.LeaseKeepAliveRequest
-		err := dec.Decode(&protoReq)
-		if err == io.EOF {
-			return err
-		}
-		if err != nil {
-			grpclog.Printf("Failed to decode request: %v", err)
-			return err
-		}
-		if err := stream.Send(&protoReq); err != nil {
-			grpclog.Printf("Failed to send request: %v", err)
-			return err
-		}
-		return nil
-	}
-	if err := handleSend(); err != nil {
-		if cerr := stream.CloseSend(); cerr != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", cerr)
-		}
-		if err == io.EOF {
-			return stream, metadata, nil
-		}
-		return nil, metadata, err
-	}
-	go func() {
-		for {
-			if err := handleSend(); err != nil {
-				break
-			}
-		}
-		if err := stream.CloseSend(); err != nil {
-			grpclog.Printf("Failed to terminate client stream: %v", err)
-		}
-	}()
-	header, err := stream.Header()
-	if err != nil {
-		grpclog.Printf("Failed to get header from client: %v", err)
-		return nil, metadata, err
-	}
-	metadata.HeaderMD = header
-	return stream, metadata, nil
-}
-
-func request_Lease_LeaseTimeToLive_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseTimeToLiveRequest
-	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.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseTimeToLive_1(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseTimeToLiveRequest
-	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.LeaseTimeToLive(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseLeases_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseLeasesRequest
-	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.LeaseLeases(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Lease_LeaseLeases_1(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.LeaseLeasesRequest
-	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.LeaseLeases(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberAddRequest
-	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.MemberAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberRemove_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberRemoveRequest
-	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.MemberRemove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberUpdate_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberUpdateRequest
-	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.MemberUpdate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberListRequest
-	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.MemberList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Cluster_MemberPromote_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MemberPromoteRequest
-	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.MemberPromote(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Alarm_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AlarmRequest
-	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.Alarm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Status_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.StatusRequest
-	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.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Defragment_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.DefragmentRequest
-	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.Defragment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Hash_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.HashRequest
-	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.Hash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_HashKV_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.HashKVRequest
-	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.HashKV(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Maintenance_Snapshot_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (etcdserverpb.Maintenance_SnapshotClient, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.SnapshotRequest
-	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.Snapshot(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_Maintenance_MoveLeader_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.MoveLeaderRequest
-	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.MoveLeader(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_AuthEnable_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthEnableRequest
-	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.AuthEnable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_AuthDisable_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthDisableRequest
-	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.AuthDisable(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_Authenticate_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthenticateRequest
-	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.Authenticate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserAddRequest
-	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.UserAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserGet_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserGetRequest
-	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.UserGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserListRequest
-	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.UserList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserDeleteRequest
-	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.UserDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserChangePassword_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserChangePasswordRequest
-	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.UserChangePassword(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserGrantRole_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserGrantRoleRequest
-	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.UserGrantRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_UserRevokeRole_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthUserRevokeRoleRequest
-	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.UserRevokeRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleAdd_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleAddRequest
-	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.RoleAdd(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleGet_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleGetRequest
-	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.RoleGet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleList_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleListRequest
-	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.RoleList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleDeleteRequest
-	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.RoleDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleGrantPermission_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleGrantPermissionRequest
-	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.RoleGrantPermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-func request_Auth_RoleRevokePermission_0(ctx context.Context, marshaler runtime.Marshaler, client etcdserverpb.AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
-	var protoReq etcdserverpb.AuthRoleRevokePermissionRequest
-	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.RoleRevokePermission(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
-	return msg, metadata, err
-
-}
-
-// RegisterKVHandlerFromEndpoint is same as RegisterKVHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterKVHandlerFromEndpoint(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 RegisterKVHandler(ctx, mux, conn)
-}
-
-// RegisterKVHandler registers the http handlers for service KV to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterKVHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterKVHandlerClient(ctx, mux, etcdserverpb.NewKVClient(conn))
-}
-
-// RegisterKVHandler registers the http handlers for service KV to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "KVClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "KVClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "KVClient" to call the correct interceptors.
-func RegisterKVHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.KVClient) error {
-
-	mux.Handle("POST", pattern_KV_Range_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_KV_Range_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Range_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Put_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_KV_Put_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Put_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_DeleteRange_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_KV_DeleteRange_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_DeleteRange_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Txn_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_KV_Txn_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Txn_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_KV_Compact_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_KV_Compact_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_KV_Compact_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_KV_Range_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "kv", "range"}, ""))
-
-	pattern_KV_Put_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "kv", "put"}, ""))
-
-	pattern_KV_DeleteRange_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "kv", "deleterange"}, ""))
-
-	pattern_KV_Txn_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "kv", "txn"}, ""))
-
-	pattern_KV_Compact_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "kv", "compaction"}, ""))
-)
-
-var (
-	forward_KV_Range_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Put_0 = runtime.ForwardResponseMessage
-
-	forward_KV_DeleteRange_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Txn_0 = runtime.ForwardResponseMessage
-
-	forward_KV_Compact_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterWatchHandlerFromEndpoint is same as RegisterWatchHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterWatchHandlerFromEndpoint(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 RegisterWatchHandler(ctx, mux, conn)
-}
-
-// RegisterWatchHandler registers the http handlers for service Watch to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterWatchHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterWatchHandlerClient(ctx, mux, etcdserverpb.NewWatchClient(conn))
-}
-
-// RegisterWatchHandler registers the http handlers for service Watch to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "WatchClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WatchClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "WatchClient" to call the correct interceptors.
-func RegisterWatchHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.WatchClient) error {
-
-	mux.Handle("POST", pattern_Watch_Watch_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_Watch_Watch_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Watch_Watch_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Watch_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v3", "watch"}, ""))
-)
-
-var (
-	forward_Watch_Watch_0 = runtime.ForwardResponseStream
-)
-
-// RegisterLeaseHandlerFromEndpoint is same as RegisterLeaseHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterLeaseHandlerFromEndpoint(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 RegisterLeaseHandler(ctx, mux, conn)
-}
-
-// RegisterLeaseHandler registers the http handlers for service Lease to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterLeaseHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterLeaseHandlerClient(ctx, mux, etcdserverpb.NewLeaseClient(conn))
-}
-
-// RegisterLeaseHandler registers the http handlers for service Lease to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "LeaseClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LeaseClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "LeaseClient" to call the correct interceptors.
-func RegisterLeaseHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.LeaseClient) error {
-
-	mux.Handle("POST", pattern_Lease_LeaseGrant_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_Lease_LeaseGrant_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseRevoke_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_Lease_LeaseRevoke_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseRevoke_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseRevoke_1, 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_Lease_LeaseRevoke_1(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseRevoke_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseKeepAlive_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_Lease_LeaseKeepAlive_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseKeepAlive_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseTimeToLive_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_Lease_LeaseTimeToLive_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseTimeToLive_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseTimeToLive_1, 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_Lease_LeaseTimeToLive_1(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseTimeToLive_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseLeases_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_Lease_LeaseLeases_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseLeases_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Lease_LeaseLeases_1, 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_Lease_LeaseLeases_1(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Lease_LeaseLeases_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Lease_LeaseGrant_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lease", "grant"}, ""))
-
-	pattern_Lease_LeaseRevoke_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lease", "revoke"}, ""))
-
-	pattern_Lease_LeaseRevoke_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "kv", "lease", "revoke"}, ""))
-
-	pattern_Lease_LeaseKeepAlive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lease", "keepalive"}, ""))
-
-	pattern_Lease_LeaseTimeToLive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lease", "timetolive"}, ""))
-
-	pattern_Lease_LeaseTimeToLive_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "kv", "lease", "timetolive"}, ""))
-
-	pattern_Lease_LeaseLeases_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "lease", "leases"}, ""))
-
-	pattern_Lease_LeaseLeases_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "kv", "lease", "leases"}, ""))
-)
-
-var (
-	forward_Lease_LeaseGrant_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseRevoke_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseRevoke_1 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseKeepAlive_0 = runtime.ForwardResponseStream
-
-	forward_Lease_LeaseTimeToLive_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseTimeToLive_1 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseLeases_0 = runtime.ForwardResponseMessage
-
-	forward_Lease_LeaseLeases_1 = runtime.ForwardResponseMessage
-)
-
-// RegisterClusterHandlerFromEndpoint is same as RegisterClusterHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterClusterHandlerFromEndpoint(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 RegisterClusterHandler(ctx, mux, conn)
-}
-
-// RegisterClusterHandler registers the http handlers for service Cluster to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterClusterHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterClusterHandlerClient(ctx, mux, etcdserverpb.NewClusterClient(conn))
-}
-
-// RegisterClusterHandler registers the http handlers for service Cluster to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "ClusterClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ClusterClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "ClusterClient" to call the correct interceptors.
-func RegisterClusterHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.ClusterClient) error {
-
-	mux.Handle("POST", pattern_Cluster_MemberAdd_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_Cluster_MemberAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberRemove_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_Cluster_MemberRemove_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberRemove_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberUpdate_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_Cluster_MemberUpdate_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberUpdate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberList_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_Cluster_MemberList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Cluster_MemberPromote_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_Cluster_MemberPromote_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Cluster_MemberPromote_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Cluster_MemberAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "cluster", "member", "add"}, ""))
-
-	pattern_Cluster_MemberRemove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "cluster", "member", "remove"}, ""))
-
-	pattern_Cluster_MemberUpdate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "cluster", "member", "update"}, ""))
-
-	pattern_Cluster_MemberList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "cluster", "member", "list"}, ""))
-
-	pattern_Cluster_MemberPromote_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "cluster", "member", "promote"}, ""))
-)
-
-var (
-	forward_Cluster_MemberAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberRemove_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberUpdate_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberList_0 = runtime.ForwardResponseMessage
-
-	forward_Cluster_MemberPromote_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterMaintenanceHandlerFromEndpoint is same as RegisterMaintenanceHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterMaintenanceHandlerFromEndpoint(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 RegisterMaintenanceHandler(ctx, mux, conn)
-}
-
-// RegisterMaintenanceHandler registers the http handlers for service Maintenance to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterMaintenanceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterMaintenanceHandlerClient(ctx, mux, etcdserverpb.NewMaintenanceClient(conn))
-}
-
-// RegisterMaintenanceHandler registers the http handlers for service Maintenance to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "MaintenanceClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MaintenanceClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "MaintenanceClient" to call the correct interceptors.
-func RegisterMaintenanceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.MaintenanceClient) error {
-
-	mux.Handle("POST", pattern_Maintenance_Alarm_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_Maintenance_Alarm_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Alarm_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Status_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_Maintenance_Status_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Status_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Defragment_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_Maintenance_Defragment_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Defragment_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Hash_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_Maintenance_Hash_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Hash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_HashKV_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_Maintenance_HashKV_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_HashKV_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_Snapshot_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_Maintenance_Snapshot_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_Snapshot_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Maintenance_MoveLeader_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_Maintenance_MoveLeader_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Maintenance_MoveLeader_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Maintenance_Alarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "alarm"}, ""))
-
-	pattern_Maintenance_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "status"}, ""))
-
-	pattern_Maintenance_Defragment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "defragment"}, ""))
-
-	pattern_Maintenance_Hash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "hash"}, ""))
-
-	pattern_Maintenance_HashKV_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "hash"}, ""))
-
-	pattern_Maintenance_Snapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "snapshot"}, ""))
-
-	pattern_Maintenance_MoveLeader_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "maintenance", "transfer-leadership"}, ""))
-)
-
-var (
-	forward_Maintenance_Alarm_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Status_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Defragment_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Hash_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_HashKV_0 = runtime.ForwardResponseMessage
-
-	forward_Maintenance_Snapshot_0 = runtime.ForwardResponseStream
-
-	forward_Maintenance_MoveLeader_0 = runtime.ForwardResponseMessage
-)
-
-// RegisterAuthHandlerFromEndpoint is same as RegisterAuthHandler but
-// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
-func RegisterAuthHandlerFromEndpoint(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 RegisterAuthHandler(ctx, mux, conn)
-}
-
-// RegisterAuthHandler registers the http handlers for service Auth to "mux".
-// The handlers forward requests to the grpc endpoint over "conn".
-func RegisterAuthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
-	return RegisterAuthHandlerClient(ctx, mux, etcdserverpb.NewAuthClient(conn))
-}
-
-// RegisterAuthHandler registers the http handlers for service Auth to "mux".
-// The handlers forward requests to the grpc endpoint over the given implementation of "AuthClient".
-// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthClient"
-// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
-// "AuthClient" to call the correct interceptors.
-func RegisterAuthHandlerClient(ctx context.Context, mux *runtime.ServeMux, client etcdserverpb.AuthClient) error {
-
-	mux.Handle("POST", pattern_Auth_AuthEnable_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_Auth_AuthEnable_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_AuthEnable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_AuthDisable_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_Auth_AuthDisable_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_AuthDisable_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_Authenticate_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_Auth_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_Authenticate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserAdd_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_Auth_UserAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserGet_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_Auth_UserGet_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserGet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserList_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_Auth_UserList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserDelete_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_Auth_UserDelete_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserChangePassword_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_Auth_UserChangePassword_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserChangePassword_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserGrantRole_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_Auth_UserGrantRole_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserGrantRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_UserRevokeRole_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_Auth_UserRevokeRole_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_UserRevokeRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleAdd_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_Auth_RoleAdd_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleAdd_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleGet_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_Auth_RoleGet_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleGet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleList_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_Auth_RoleList_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleDelete_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_Auth_RoleDelete_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleDelete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleGrantPermission_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_Auth_RoleGrantPermission_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleGrantPermission_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	mux.Handle("POST", pattern_Auth_RoleRevokePermission_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_Auth_RoleRevokePermission_0(rctx, inboundMarshaler, client, req, pathParams)
-		ctx = runtime.NewServerMetadataContext(ctx, md)
-		if err != nil {
-			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
-			return
-		}
-
-		forward_Auth_RoleRevokePermission_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
-
-	})
-
-	return nil
-}
-
-var (
-	pattern_Auth_AuthEnable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "auth", "enable"}, ""))
-
-	pattern_Auth_AuthDisable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "auth", "disable"}, ""))
-
-	pattern_Auth_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3", "auth", "authenticate"}, ""))
-
-	pattern_Auth_UserAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "add"}, ""))
-
-	pattern_Auth_UserGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "get"}, ""))
-
-	pattern_Auth_UserList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "list"}, ""))
-
-	pattern_Auth_UserDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "delete"}, ""))
-
-	pattern_Auth_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "changepw"}, ""))
-
-	pattern_Auth_UserGrantRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "grant"}, ""))
-
-	pattern_Auth_UserRevokeRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "user", "revoke"}, ""))
-
-	pattern_Auth_RoleAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "add"}, ""))
-
-	pattern_Auth_RoleGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "get"}, ""))
-
-	pattern_Auth_RoleList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "list"}, ""))
-
-	pattern_Auth_RoleDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "delete"}, ""))
-
-	pattern_Auth_RoleGrantPermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "grant"}, ""))
-
-	pattern_Auth_RoleRevokePermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3", "auth", "role", "revoke"}, ""))
-)
-
-var (
-	forward_Auth_AuthEnable_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_AuthDisable_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_Authenticate_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserGet_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserList_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserDelete_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserChangePassword_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserGrantRole_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_UserRevokeRole_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleAdd_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleGet_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleList_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleDelete_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleGrantPermission_0 = runtime.ForwardResponseMessage
-
-	forward_Auth_RoleRevokePermission_0 = runtime.ForwardResponseMessage
-)
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.pb.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.pb.go
deleted file mode 100644
index b170499..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.pb.go
+++ /dev/null
@@ -1,2127 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: raft_internal.proto
-
-package etcdserverpb
-
-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
-
-type RequestHeader struct {
-	ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// username is a username that is associated with an auth token of gRPC connection
-	Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"`
-	// auth_revision is a revision number of auth.authStore. It is not related to mvcc
-	AuthRevision uint64 `protobuf:"varint,3,opt,name=auth_revision,json=authRevision,proto3" json:"auth_revision,omitempty"`
-}
-
-func (m *RequestHeader) Reset()                    { *m = RequestHeader{} }
-func (m *RequestHeader) String() string            { return proto.CompactTextString(m) }
-func (*RequestHeader) ProtoMessage()               {}
-func (*RequestHeader) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{0} }
-
-// An InternalRaftRequest is the union of all requests which can be
-// sent via raft.
-type InternalRaftRequest struct {
-	Header                   *RequestHeader                   `protobuf:"bytes,100,opt,name=header" json:"header,omitempty"`
-	ID                       uint64                           `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	V2                       *Request                         `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"`
-	Range                    *RangeRequest                    `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"`
-	Put                      *PutRequest                      `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"`
-	DeleteRange              *DeleteRangeRequest              `protobuf:"bytes,5,opt,name=delete_range,json=deleteRange" json:"delete_range,omitempty"`
-	Txn                      *TxnRequest                      `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"`
-	Compaction               *CompactionRequest               `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"`
-	LeaseGrant               *LeaseGrantRequest               `protobuf:"bytes,8,opt,name=lease_grant,json=leaseGrant" json:"lease_grant,omitempty"`
-	LeaseRevoke              *LeaseRevokeRequest              `protobuf:"bytes,9,opt,name=lease_revoke,json=leaseRevoke" json:"lease_revoke,omitempty"`
-	Alarm                    *AlarmRequest                    `protobuf:"bytes,10,opt,name=alarm" json:"alarm,omitempty"`
-	LeaseCheckpoint          *LeaseCheckpointRequest          `protobuf:"bytes,11,opt,name=lease_checkpoint,json=leaseCheckpoint" json:"lease_checkpoint,omitempty"`
-	AuthEnable               *AuthEnableRequest               `protobuf:"bytes,1000,opt,name=auth_enable,json=authEnable" json:"auth_enable,omitempty"`
-	AuthDisable              *AuthDisableRequest              `protobuf:"bytes,1011,opt,name=auth_disable,json=authDisable" json:"auth_disable,omitempty"`
-	Authenticate             *InternalAuthenticateRequest     `protobuf:"bytes,1012,opt,name=authenticate" json:"authenticate,omitempty"`
-	AuthUserAdd              *AuthUserAddRequest              `protobuf:"bytes,1100,opt,name=auth_user_add,json=authUserAdd" json:"auth_user_add,omitempty"`
-	AuthUserDelete           *AuthUserDeleteRequest           `protobuf:"bytes,1101,opt,name=auth_user_delete,json=authUserDelete" json:"auth_user_delete,omitempty"`
-	AuthUserGet              *AuthUserGetRequest              `protobuf:"bytes,1102,opt,name=auth_user_get,json=authUserGet" json:"auth_user_get,omitempty"`
-	AuthUserChangePassword   *AuthUserChangePasswordRequest   `protobuf:"bytes,1103,opt,name=auth_user_change_password,json=authUserChangePassword" json:"auth_user_change_password,omitempty"`
-	AuthUserGrantRole        *AuthUserGrantRoleRequest        `protobuf:"bytes,1104,opt,name=auth_user_grant_role,json=authUserGrantRole" json:"auth_user_grant_role,omitempty"`
-	AuthUserRevokeRole       *AuthUserRevokeRoleRequest       `protobuf:"bytes,1105,opt,name=auth_user_revoke_role,json=authUserRevokeRole" json:"auth_user_revoke_role,omitempty"`
-	AuthUserList             *AuthUserListRequest             `protobuf:"bytes,1106,opt,name=auth_user_list,json=authUserList" json:"auth_user_list,omitempty"`
-	AuthRoleList             *AuthRoleListRequest             `protobuf:"bytes,1107,opt,name=auth_role_list,json=authRoleList" json:"auth_role_list,omitempty"`
-	AuthRoleAdd              *AuthRoleAddRequest              `protobuf:"bytes,1200,opt,name=auth_role_add,json=authRoleAdd" json:"auth_role_add,omitempty"`
-	AuthRoleDelete           *AuthRoleDeleteRequest           `protobuf:"bytes,1201,opt,name=auth_role_delete,json=authRoleDelete" json:"auth_role_delete,omitempty"`
-	AuthRoleGet              *AuthRoleGetRequest              `protobuf:"bytes,1202,opt,name=auth_role_get,json=authRoleGet" json:"auth_role_get,omitempty"`
-	AuthRoleGrantPermission  *AuthRoleGrantPermissionRequest  `protobuf:"bytes,1203,opt,name=auth_role_grant_permission,json=authRoleGrantPermission" json:"auth_role_grant_permission,omitempty"`
-	AuthRoleRevokePermission *AuthRoleRevokePermissionRequest `protobuf:"bytes,1204,opt,name=auth_role_revoke_permission,json=authRoleRevokePermission" json:"auth_role_revoke_permission,omitempty"`
-}
-
-func (m *InternalRaftRequest) Reset()                    { *m = InternalRaftRequest{} }
-func (m *InternalRaftRequest) String() string            { return proto.CompactTextString(m) }
-func (*InternalRaftRequest) ProtoMessage()               {}
-func (*InternalRaftRequest) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{1} }
-
-type EmptyResponse struct {
-}
-
-func (m *EmptyResponse) Reset()                    { *m = EmptyResponse{} }
-func (m *EmptyResponse) String() string            { return proto.CompactTextString(m) }
-func (*EmptyResponse) ProtoMessage()               {}
-func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescriptorRaftInternal, []int{2} }
-
-// What is the difference between AuthenticateRequest (defined in rpc.proto) and InternalAuthenticateRequest?
-// InternalAuthenticateRequest has a member that is filled by etcdserver and shouldn't be user-facing.
-// For avoiding misusage the field, we have an internal version of AuthenticateRequest.
-type InternalAuthenticateRequest struct {
-	Name     string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
-	// simple_token is generated in API layer (etcdserver/v3_server.go)
-	SimpleToken string `protobuf:"bytes,3,opt,name=simple_token,json=simpleToken,proto3" json:"simple_token,omitempty"`
-}
-
-func (m *InternalAuthenticateRequest) Reset()         { *m = InternalAuthenticateRequest{} }
-func (m *InternalAuthenticateRequest) String() string { return proto.CompactTextString(m) }
-func (*InternalAuthenticateRequest) ProtoMessage()    {}
-func (*InternalAuthenticateRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptorRaftInternal, []int{3}
-}
-
-func init() {
-	proto.RegisterType((*RequestHeader)(nil), "etcdserverpb.RequestHeader")
-	proto.RegisterType((*InternalRaftRequest)(nil), "etcdserverpb.InternalRaftRequest")
-	proto.RegisterType((*EmptyResponse)(nil), "etcdserverpb.EmptyResponse")
-	proto.RegisterType((*InternalAuthenticateRequest)(nil), "etcdserverpb.InternalAuthenticateRequest")
-}
-func (m *RequestHeader) 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 *RequestHeader) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.ID))
-	}
-	if len(m.Username) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Username)))
-		i += copy(dAtA[i:], m.Username)
-	}
-	if m.AuthRevision != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRevision))
-	}
-	return i, nil
-}
-
-func (m *InternalRaftRequest) 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 *InternalRaftRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.ID))
-	}
-	if m.V2 != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.V2.Size()))
-		n1, err := m.V2.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	if m.Range != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Range.Size()))
-		n2, err := m.Range.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	if m.Put != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Put.Size()))
-		n3, err := m.Put.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n3
-	}
-	if m.DeleteRange != nil {
-		dAtA[i] = 0x2a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.DeleteRange.Size()))
-		n4, err := m.DeleteRange.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n4
-	}
-	if m.Txn != nil {
-		dAtA[i] = 0x32
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Txn.Size()))
-		n5, err := m.Txn.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n5
-	}
-	if m.Compaction != nil {
-		dAtA[i] = 0x3a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Compaction.Size()))
-		n6, err := m.Compaction.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n6
-	}
-	if m.LeaseGrant != nil {
-		dAtA[i] = 0x42
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.LeaseGrant.Size()))
-		n7, err := m.LeaseGrant.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n7
-	}
-	if m.LeaseRevoke != nil {
-		dAtA[i] = 0x4a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.LeaseRevoke.Size()))
-		n8, err := m.LeaseRevoke.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n8
-	}
-	if m.Alarm != nil {
-		dAtA[i] = 0x52
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Alarm.Size()))
-		n9, err := m.Alarm.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n9
-	}
-	if m.LeaseCheckpoint != nil {
-		dAtA[i] = 0x5a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.LeaseCheckpoint.Size()))
-		n10, err := m.LeaseCheckpoint.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n10
-	}
-	if m.Header != nil {
-		dAtA[i] = 0xa2
-		i++
-		dAtA[i] = 0x6
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Header.Size()))
-		n11, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n11
-	}
-	if m.AuthEnable != nil {
-		dAtA[i] = 0xc2
-		i++
-		dAtA[i] = 0x3e
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthEnable.Size()))
-		n12, err := m.AuthEnable.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n12
-	}
-	if m.AuthDisable != nil {
-		dAtA[i] = 0x9a
-		i++
-		dAtA[i] = 0x3f
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthDisable.Size()))
-		n13, err := m.AuthDisable.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n13
-	}
-	if m.Authenticate != nil {
-		dAtA[i] = 0xa2
-		i++
-		dAtA[i] = 0x3f
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.Authenticate.Size()))
-		n14, err := m.Authenticate.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n14
-	}
-	if m.AuthUserAdd != nil {
-		dAtA[i] = 0xe2
-		i++
-		dAtA[i] = 0x44
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserAdd.Size()))
-		n15, err := m.AuthUserAdd.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n15
-	}
-	if m.AuthUserDelete != nil {
-		dAtA[i] = 0xea
-		i++
-		dAtA[i] = 0x44
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserDelete.Size()))
-		n16, err := m.AuthUserDelete.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n16
-	}
-	if m.AuthUserGet != nil {
-		dAtA[i] = 0xf2
-		i++
-		dAtA[i] = 0x44
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserGet.Size()))
-		n17, err := m.AuthUserGet.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n17
-	}
-	if m.AuthUserChangePassword != nil {
-		dAtA[i] = 0xfa
-		i++
-		dAtA[i] = 0x44
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserChangePassword.Size()))
-		n18, err := m.AuthUserChangePassword.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n18
-	}
-	if m.AuthUserGrantRole != nil {
-		dAtA[i] = 0x82
-		i++
-		dAtA[i] = 0x45
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserGrantRole.Size()))
-		n19, err := m.AuthUserGrantRole.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n19
-	}
-	if m.AuthUserRevokeRole != nil {
-		dAtA[i] = 0x8a
-		i++
-		dAtA[i] = 0x45
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserRevokeRole.Size()))
-		n20, err := m.AuthUserRevokeRole.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n20
-	}
-	if m.AuthUserList != nil {
-		dAtA[i] = 0x92
-		i++
-		dAtA[i] = 0x45
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthUserList.Size()))
-		n21, err := m.AuthUserList.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n21
-	}
-	if m.AuthRoleList != nil {
-		dAtA[i] = 0x9a
-		i++
-		dAtA[i] = 0x45
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleList.Size()))
-		n22, err := m.AuthRoleList.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n22
-	}
-	if m.AuthRoleAdd != nil {
-		dAtA[i] = 0x82
-		i++
-		dAtA[i] = 0x4b
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleAdd.Size()))
-		n23, err := m.AuthRoleAdd.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n23
-	}
-	if m.AuthRoleDelete != nil {
-		dAtA[i] = 0x8a
-		i++
-		dAtA[i] = 0x4b
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleDelete.Size()))
-		n24, err := m.AuthRoleDelete.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n24
-	}
-	if m.AuthRoleGet != nil {
-		dAtA[i] = 0x92
-		i++
-		dAtA[i] = 0x4b
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleGet.Size()))
-		n25, err := m.AuthRoleGet.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n25
-	}
-	if m.AuthRoleGrantPermission != nil {
-		dAtA[i] = 0x9a
-		i++
-		dAtA[i] = 0x4b
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleGrantPermission.Size()))
-		n26, err := m.AuthRoleGrantPermission.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n26
-	}
-	if m.AuthRoleRevokePermission != nil {
-		dAtA[i] = 0xa2
-		i++
-		dAtA[i] = 0x4b
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(m.AuthRoleRevokePermission.Size()))
-		n27, err := m.AuthRoleRevokePermission.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n27
-	}
-	return i, nil
-}
-
-func (m *EmptyResponse) 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 *EmptyResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *InternalAuthenticateRequest) 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 *InternalAuthenticateRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Password) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.Password)))
-		i += copy(dAtA[i:], m.Password)
-	}
-	if len(m.SimpleToken) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRaftInternal(dAtA, i, uint64(len(m.SimpleToken)))
-		i += copy(dAtA[i:], m.SimpleToken)
-	}
-	return i, nil
-}
-
-func encodeVarintRaftInternal(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 *RequestHeader) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRaftInternal(uint64(m.ID))
-	}
-	l = len(m.Username)
-	if l > 0 {
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRevision != 0 {
-		n += 1 + sovRaftInternal(uint64(m.AuthRevision))
-	}
-	return n
-}
-
-func (m *InternalRaftRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRaftInternal(uint64(m.ID))
-	}
-	if m.V2 != nil {
-		l = m.V2.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Range != nil {
-		l = m.Range.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Put != nil {
-		l = m.Put.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.DeleteRange != nil {
-		l = m.DeleteRange.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Txn != nil {
-		l = m.Txn.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Compaction != nil {
-		l = m.Compaction.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.LeaseGrant != nil {
-		l = m.LeaseGrant.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.LeaseRevoke != nil {
-		l = m.LeaseRevoke.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Alarm != nil {
-		l = m.Alarm.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.LeaseCheckpoint != nil {
-		l = m.LeaseCheckpoint.Size()
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthEnable != nil {
-		l = m.AuthEnable.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthDisable != nil {
-		l = m.AuthDisable.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.Authenticate != nil {
-		l = m.Authenticate.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserAdd != nil {
-		l = m.AuthUserAdd.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserDelete != nil {
-		l = m.AuthUserDelete.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserGet != nil {
-		l = m.AuthUserGet.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserChangePassword != nil {
-		l = m.AuthUserChangePassword.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserGrantRole != nil {
-		l = m.AuthUserGrantRole.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserRevokeRole != nil {
-		l = m.AuthUserRevokeRole.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthUserList != nil {
-		l = m.AuthUserList.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleList != nil {
-		l = m.AuthRoleList.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleAdd != nil {
-		l = m.AuthRoleAdd.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleDelete != nil {
-		l = m.AuthRoleDelete.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleGet != nil {
-		l = m.AuthRoleGet.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleGrantPermission != nil {
-		l = m.AuthRoleGrantPermission.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	if m.AuthRoleRevokePermission != nil {
-		l = m.AuthRoleRevokePermission.Size()
-		n += 2 + l + sovRaftInternal(uint64(l))
-	}
-	return n
-}
-
-func (m *EmptyResponse) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *InternalAuthenticateRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	l = len(m.Password)
-	if l > 0 {
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	l = len(m.SimpleToken)
-	if l > 0 {
-		n += 1 + l + sovRaftInternal(uint64(l))
-	}
-	return n
-}
-
-func sovRaftInternal(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozRaftInternal(x uint64) (n int) {
-	return sovRaftInternal(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *RequestHeader) 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 ErrIntOverflowRaftInternal
-			}
-			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: RequestHeader: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: RequestHeader: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Username", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Username = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRevision", wireType)
-			}
-			m.AuthRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.AuthRevision |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaftInternal(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *InternalRaftRequest) 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 ErrIntOverflowRaftInternal
-			}
-			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: InternalRaftRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: InternalRaftRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field V2", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.V2 == nil {
-				m.V2 = &Request{}
-			}
-			if err := m.V2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Range", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Range == nil {
-				m.Range = &RangeRequest{}
-			}
-			if err := m.Range.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Put", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Put == nil {
-				m.Put = &PutRequest{}
-			}
-			if err := m.Put.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 5:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DeleteRange", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.DeleteRange == nil {
-				m.DeleteRange = &DeleteRangeRequest{}
-			}
-			if err := m.DeleteRange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 6:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Txn", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Txn == nil {
-				m.Txn = &TxnRequest{}
-			}
-			if err := m.Txn.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 7:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Compaction", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Compaction == nil {
-				m.Compaction = &CompactionRequest{}
-			}
-			if err := m.Compaction.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 8:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LeaseGrant", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.LeaseGrant == nil {
-				m.LeaseGrant = &LeaseGrantRequest{}
-			}
-			if err := m.LeaseGrant.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 9:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LeaseRevoke", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.LeaseRevoke == nil {
-				m.LeaseRevoke = &LeaseRevokeRequest{}
-			}
-			if err := m.LeaseRevoke.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 10:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Alarm == nil {
-				m.Alarm = &AlarmRequest{}
-			}
-			if err := m.Alarm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 11:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LeaseCheckpoint", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.LeaseCheckpoint == nil {
-				m.LeaseCheckpoint = &LeaseCheckpointRequest{}
-			}
-			if err := m.LeaseCheckpoint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 100:
-			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 ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &RequestHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1000:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthEnable", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthEnable == nil {
-				m.AuthEnable = &AuthEnableRequest{}
-			}
-			if err := m.AuthEnable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1011:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthDisable", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthDisable == nil {
-				m.AuthDisable = &AuthDisableRequest{}
-			}
-			if err := m.AuthDisable.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1012:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Authenticate", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Authenticate == nil {
-				m.Authenticate = &InternalAuthenticateRequest{}
-			}
-			if err := m.Authenticate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1100:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserAdd", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserAdd == nil {
-				m.AuthUserAdd = &AuthUserAddRequest{}
-			}
-			if err := m.AuthUserAdd.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1101:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserDelete", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserDelete == nil {
-				m.AuthUserDelete = &AuthUserDeleteRequest{}
-			}
-			if err := m.AuthUserDelete.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1102:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserGet", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserGet == nil {
-				m.AuthUserGet = &AuthUserGetRequest{}
-			}
-			if err := m.AuthUserGet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1103:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserChangePassword", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserChangePassword == nil {
-				m.AuthUserChangePassword = &AuthUserChangePasswordRequest{}
-			}
-			if err := m.AuthUserChangePassword.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1104:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserGrantRole", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserGrantRole == nil {
-				m.AuthUserGrantRole = &AuthUserGrantRoleRequest{}
-			}
-			if err := m.AuthUserGrantRole.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1105:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserRevokeRole", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserRevokeRole == nil {
-				m.AuthUserRevokeRole = &AuthUserRevokeRoleRequest{}
-			}
-			if err := m.AuthUserRevokeRole.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1106:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthUserList", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthUserList == nil {
-				m.AuthUserList = &AuthUserListRequest{}
-			}
-			if err := m.AuthUserList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1107:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleList", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleList == nil {
-				m.AuthRoleList = &AuthRoleListRequest{}
-			}
-			if err := m.AuthRoleList.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1200:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleAdd", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleAdd == nil {
-				m.AuthRoleAdd = &AuthRoleAddRequest{}
-			}
-			if err := m.AuthRoleAdd.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1201:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleDelete", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleDelete == nil {
-				m.AuthRoleDelete = &AuthRoleDeleteRequest{}
-			}
-			if err := m.AuthRoleDelete.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1202:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleGet", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleGet == nil {
-				m.AuthRoleGet = &AuthRoleGetRequest{}
-			}
-			if err := m.AuthRoleGet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1203:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleGrantPermission", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleGrantPermission == nil {
-				m.AuthRoleGrantPermission = &AuthRoleGrantPermissionRequest{}
-			}
-			if err := m.AuthRoleGrantPermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 1204:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleRevokePermission", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.AuthRoleRevokePermission == nil {
-				m.AuthRoleRevokePermission = &AuthRoleRevokePermissionRequest{}
-			}
-			if err := m.AuthRoleRevokePermission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaftInternal(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *EmptyResponse) 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 ErrIntOverflowRaftInternal
-			}
-			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: EmptyResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: EmptyResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaftInternal(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *InternalAuthenticateRequest) 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 ErrIntOverflowRaftInternal
-			}
-			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: InternalAuthenticateRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: InternalAuthenticateRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Password = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SimpleToken", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaftInternal
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.SimpleToken = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaftInternal(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaftInternal
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipRaftInternal(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, ErrIntOverflowRaftInternal
-			}
-			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, ErrIntOverflowRaftInternal
-				}
-				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, ErrIntOverflowRaftInternal
-				}
-				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, ErrInvalidLengthRaftInternal
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowRaftInternal
-					}
-					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 := skipRaftInternal(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 (
-	ErrInvalidLengthRaftInternal = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowRaftInternal   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("raft_internal.proto", fileDescriptorRaftInternal) }
-
-var fileDescriptorRaftInternal = []byte{
-	// 867 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x96, 0xcb, 0x52, 0x33, 0x45,
-	0x14, 0xc7, 0x49, 0xb8, 0xa6, 0x13, 0x2e, 0x36, 0xa0, 0x6d, 0xa8, 0x8a, 0x10, 0xbc, 0xe0, 0x0d,
-	0xad, 0xf0, 0x00, 0x1a, 0x13, 0x0a, 0xa8, 0xa2, 0x90, 0x9a, 0xc2, 0x2a, 0xab, 0x5c, 0x8c, 0xcd,
-	0xcc, 0x21, 0x19, 0x99, 0xcc, 0x8c, 0x3d, 0x9d, 0x88, 0x6f, 0xe2, 0x63, 0x78, 0xdb, 0xbb, 0x65,
-	0xe1, 0x05, 0xf5, 0x05, 0x14, 0x37, 0xee, 0xbf, 0xef, 0x01, 0xbe, 0xea, 0xcb, 0xf4, 0x64, 0x92,
-	0x0e, 0xbb, 0xc9, 0x39, 0xff, 0xf3, 0xfb, 0x9f, 0x99, 0x3e, 0x07, 0x1a, 0x6d, 0x32, 0x7a, 0xc3,
-	0xdd, 0x20, 0xe2, 0xc0, 0x22, 0x1a, 0x1e, 0x26, 0x2c, 0xe6, 0x31, 0xae, 0x01, 0xf7, 0xfc, 0x14,
-	0xd8, 0x08, 0x58, 0x72, 0x5d, 0xdf, 0xea, 0xc5, 0xbd, 0x58, 0x26, 0x3e, 0x10, 0x4f, 0x4a, 0x53,
-	0xdf, 0xc8, 0x35, 0x3a, 0x52, 0x61, 0x89, 0xa7, 0x1e, 0x9b, 0x5f, 0xa2, 0x55, 0x07, 0xbe, 0x1e,
-	0x42, 0xca, 0x4f, 0x81, 0xfa, 0xc0, 0xf0, 0x1a, 0x2a, 0x9f, 0x75, 0x49, 0x69, 0xb7, 0x74, 0xb0,
-	0xe0, 0x94, 0xcf, 0xba, 0xb8, 0x8e, 0x56, 0x86, 0xa9, 0xb0, 0x1c, 0x00, 0x29, 0xef, 0x96, 0x0e,
-	0x2a, 0x8e, 0xf9, 0x8d, 0xf7, 0xd1, 0x2a, 0x1d, 0xf2, 0xbe, 0xcb, 0x60, 0x14, 0xa4, 0x41, 0x1c,
-	0x91, 0x79, 0x59, 0x56, 0x13, 0x41, 0x47, 0xc7, 0x9a, 0xbf, 0xac, 0xa3, 0xcd, 0x33, 0xdd, 0xb5,
-	0x43, 0x6f, 0xb8, 0xb6, 0x9b, 0x32, 0x7a, 0x03, 0x95, 0x47, 0x2d, 0x69, 0x51, 0x6d, 0x6d, 0x1f,
-	0x8e, 0xbf, 0xd7, 0xa1, 0x2e, 0x71, 0xca, 0xa3, 0x16, 0xfe, 0x10, 0x2d, 0x32, 0x1a, 0xf5, 0x40,
-	0x7a, 0x55, 0x5b, 0xf5, 0x09, 0xa5, 0x48, 0x65, 0x72, 0x25, 0xc4, 0xef, 0xa0, 0xf9, 0x64, 0xc8,
-	0xc9, 0x82, 0xd4, 0x93, 0xa2, 0xfe, 0x72, 0x98, 0xf5, 0xe3, 0x08, 0x11, 0xee, 0xa0, 0x9a, 0x0f,
-	0x21, 0x70, 0x70, 0x95, 0xc9, 0xa2, 0x2c, 0xda, 0x2d, 0x16, 0x75, 0xa5, 0xa2, 0x60, 0x55, 0xf5,
-	0xf3, 0x98, 0x30, 0xe4, 0x77, 0x11, 0x59, 0xb2, 0x19, 0x5e, 0xdd, 0x45, 0xc6, 0x90, 0xdf, 0x45,
-	0xf8, 0x23, 0x84, 0xbc, 0x78, 0x90, 0x50, 0x8f, 0x8b, 0xef, 0xb7, 0x2c, 0x4b, 0x5e, 0x2b, 0x96,
-	0x74, 0x4c, 0x3e, 0xab, 0x1c, 0x2b, 0xc1, 0x1f, 0xa3, 0x6a, 0x08, 0x34, 0x05, 0xb7, 0xc7, 0x68,
-	0xc4, 0xc9, 0x8a, 0x8d, 0x70, 0x2e, 0x04, 0x27, 0x22, 0x6f, 0x08, 0xa1, 0x09, 0x89, 0x77, 0x56,
-	0x04, 0x06, 0xa3, 0xf8, 0x16, 0x48, 0xc5, 0xf6, 0xce, 0x12, 0xe1, 0x48, 0x81, 0x79, 0xe7, 0x30,
-	0x8f, 0x89, 0x63, 0xa1, 0x21, 0x65, 0x03, 0x82, 0x6c, 0xc7, 0xd2, 0x16, 0x29, 0x73, 0x2c, 0x52,
-	0x88, 0x3f, 0x45, 0x1b, 0xca, 0xd6, 0xeb, 0x83, 0x77, 0x9b, 0xc4, 0x41, 0xc4, 0x49, 0x55, 0x16,
-	0xbf, 0x6e, 0xb1, 0xee, 0x18, 0x51, 0x86, 0x59, 0x0f, 0x8b, 0x71, 0x7c, 0x84, 0x96, 0xfa, 0x72,
-	0x86, 0x89, 0x2f, 0x31, 0x3b, 0xd6, 0x21, 0x52, 0x63, 0xee, 0x68, 0x29, 0x6e, 0xa3, 0xaa, 0x1c,
-	0x61, 0x88, 0xe8, 0x75, 0x08, 0xe4, 0x7f, 0xeb, 0x09, 0xb4, 0x87, 0xbc, 0x7f, 0x2c, 0x05, 0xe6,
-	0xfb, 0x51, 0x13, 0xc2, 0x5d, 0x24, 0x07, 0xde, 0xf5, 0x83, 0x54, 0x32, 0x9e, 0x2d, 0xdb, 0x3e,
-	0xa0, 0x60, 0x74, 0x95, 0xc2, 0x7c, 0x40, 0x9a, 0xc7, 0xf0, 0x85, 0xa2, 0x40, 0xc4, 0x03, 0x8f,
-	0x72, 0x20, 0xcf, 0x15, 0xe5, 0xed, 0x22, 0x25, 0x5b, 0xa4, 0xf6, 0x98, 0x34, 0xc3, 0x15, 0xea,
-	0xf1, 0xb1, 0xde, 0x4d, 0xb1, 0xac, 0x2e, 0xf5, 0x7d, 0xf2, 0xeb, 0xca, 0xac, 0xb6, 0x3e, 0x4b,
-	0x81, 0xb5, 0x7d, 0xbf, 0xd0, 0x96, 0x8e, 0xe1, 0x0b, 0xb4, 0x91, 0x63, 0xd4, 0x90, 0x93, 0xdf,
-	0x14, 0x69, 0xdf, 0x4e, 0xd2, 0xdb, 0xa1, 0x61, 0x6b, 0xb4, 0x10, 0x2e, 0xb6, 0xd5, 0x03, 0x4e,
-	0x7e, 0x7f, 0xb2, 0xad, 0x13, 0xe0, 0x53, 0x6d, 0x9d, 0x00, 0xc7, 0x3d, 0xf4, 0x6a, 0x8e, 0xf1,
-	0xfa, 0x62, 0xed, 0xdc, 0x84, 0xa6, 0xe9, 0x37, 0x31, 0xf3, 0xc9, 0x1f, 0x0a, 0xf9, 0xae, 0x1d,
-	0xd9, 0x91, 0xea, 0x4b, 0x2d, 0xce, 0xe8, 0x2f, 0x53, 0x6b, 0x1a, 0x7f, 0x8e, 0xb6, 0xc6, 0xfa,
-	0x15, 0xfb, 0xe2, 0xb2, 0x38, 0x04, 0xf2, 0xa0, 0x3c, 0xde, 0x9c, 0xd1, 0xb6, 0xdc, 0xb5, 0x38,
-	0x3f, 0xea, 0x97, 0xe8, 0x64, 0x06, 0x7f, 0x81, 0xb6, 0x73, 0xb2, 0x5a, 0x3d, 0x85, 0xfe, 0x53,
-	0xa1, 0xdf, 0xb2, 0xa3, 0xf5, 0x0e, 0x8e, 0xb1, 0x31, 0x9d, 0x4a, 0xe1, 0x53, 0xb4, 0x96, 0xc3,
-	0xc3, 0x20, 0xe5, 0xe4, 0x2f, 0x45, 0xdd, 0xb3, 0x53, 0xcf, 0x83, 0x94, 0x17, 0xe6, 0x28, 0x0b,
-	0x1a, 0x92, 0x68, 0x4d, 0x91, 0xfe, 0x9e, 0x49, 0x12, 0xd6, 0x53, 0xa4, 0x2c, 0x68, 0x8e, 0x5e,
-	0x92, 0xc4, 0x44, 0x7e, 0x5f, 0x99, 0x75, 0xf4, 0xa2, 0x66, 0x72, 0x22, 0x75, 0xcc, 0x4c, 0xa4,
-	0xc4, 0xe8, 0x89, 0xfc, 0xa1, 0x32, 0x6b, 0x22, 0x45, 0x95, 0x65, 0x22, 0xf3, 0x70, 0xb1, 0x2d,
-	0x31, 0x91, 0x3f, 0x3e, 0xd9, 0xd6, 0xe4, 0x44, 0xea, 0x18, 0xfe, 0x0a, 0xd5, 0xc7, 0x30, 0x72,
-	0x50, 0x12, 0x60, 0x83, 0x20, 0x95, 0xff, 0x18, 0x7f, 0x52, 0xcc, 0xf7, 0x66, 0x30, 0x85, 0xfc,
-	0xd2, 0xa8, 0x33, 0xfe, 0x2b, 0xd4, 0x9e, 0xc7, 0x03, 0xb4, 0x93, 0x7b, 0xe9, 0xd1, 0x19, 0x33,
-	0xfb, 0x59, 0x99, 0xbd, 0x6f, 0x37, 0x53, 0x53, 0x32, 0xed, 0x46, 0xe8, 0x0c, 0x41, 0x73, 0x1d,
-	0xad, 0x1e, 0x0f, 0x12, 0xfe, 0xad, 0x03, 0x69, 0x12, 0x47, 0x29, 0x34, 0x13, 0xb4, 0xf3, 0xc4,
-	0x1f, 0x22, 0x8c, 0xd1, 0x82, 0xbc, 0x2e, 0x94, 0xe4, 0x75, 0x41, 0x3e, 0x8b, 0x6b, 0x84, 0xd9,
-	0x4f, 0x7d, 0x8d, 0xc8, 0x7e, 0xe3, 0x3d, 0x54, 0x4b, 0x83, 0x41, 0x12, 0x82, 0xcb, 0xe3, 0x5b,
-	0x50, 0xb7, 0x88, 0x8a, 0x53, 0x55, 0xb1, 0x2b, 0x11, 0xfa, 0x64, 0xeb, 0xfe, 0xdf, 0xc6, 0xdc,
-	0xfd, 0x63, 0xa3, 0xf4, 0xf0, 0xd8, 0x28, 0xfd, 0xf3, 0xd8, 0x28, 0x7d, 0xf7, 0x5f, 0x63, 0xee,
-	0x7a, 0x49, 0xde, 0x61, 0x8e, 0x5e, 0x04, 0x00, 0x00, 0xff, 0xff, 0xed, 0x36, 0xf0, 0x6f, 0x1b,
-	0x09, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.proto b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.proto
deleted file mode 100644
index 7111f45..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal.proto
+++ /dev/null
@@ -1,75 +0,0 @@
-syntax = "proto3";
-package etcdserverpb;
-
-import "gogoproto/gogo.proto";
-import "etcdserver.proto";
-import "rpc.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-
-message RequestHeader {
-  uint64 ID = 1;
-  // username is a username that is associated with an auth token of gRPC connection
-  string username = 2;
-  // auth_revision is a revision number of auth.authStore. It is not related to mvcc
-  uint64 auth_revision = 3;
-}
-
-// An InternalRaftRequest is the union of all requests which can be
-// sent via raft.
-message InternalRaftRequest {
-  RequestHeader header = 100;
-  uint64 ID = 1;
-
-  Request v2 = 2;
-
-  RangeRequest range = 3;
-  PutRequest put = 4;
-  DeleteRangeRequest delete_range = 5;
-  TxnRequest txn = 6;
-  CompactionRequest compaction = 7;
-
-  LeaseGrantRequest lease_grant = 8;
-  LeaseRevokeRequest lease_revoke = 9;
-
-  AlarmRequest alarm = 10;
-
-  LeaseCheckpointRequest lease_checkpoint = 11;
-
-  AuthEnableRequest auth_enable = 1000;
-  AuthDisableRequest auth_disable = 1011;
-
-  InternalAuthenticateRequest authenticate = 1012;
-
-  AuthUserAddRequest auth_user_add = 1100;
-  AuthUserDeleteRequest auth_user_delete = 1101;
-  AuthUserGetRequest auth_user_get = 1102;
-  AuthUserChangePasswordRequest auth_user_change_password = 1103;
-  AuthUserGrantRoleRequest auth_user_grant_role = 1104;
-  AuthUserRevokeRoleRequest auth_user_revoke_role = 1105;
-  AuthUserListRequest auth_user_list = 1106;
-  AuthRoleListRequest auth_role_list = 1107;
-
-  AuthRoleAddRequest auth_role_add = 1200;
-  AuthRoleDeleteRequest auth_role_delete = 1201;
-  AuthRoleGetRequest auth_role_get = 1202;
-  AuthRoleGrantPermissionRequest auth_role_grant_permission = 1203;
-  AuthRoleRevokePermissionRequest auth_role_revoke_permission = 1204;
-}
-
-message EmptyResponse {
-}
-
-// What is the difference between AuthenticateRequest (defined in rpc.proto) and InternalAuthenticateRequest?
-// InternalAuthenticateRequest has a member that is filled by etcdserver and shouldn't be user-facing.
-// For avoiding misusage the field, we have an internal version of AuthenticateRequest.
-message InternalAuthenticateRequest {
-  string name = 1;
-  string password = 2;
-
-  // simple_token is generated in API layer (etcdserver/v3_server.go)
-  string simple_token = 3;
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go
deleted file mode 100644
index 3d3536a..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/raft_internal_stringer.go
+++ /dev/null
@@ -1,183 +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 etcdserverpb
-
-import (
-	"fmt"
-	"strings"
-
-	proto "github.com/golang/protobuf/proto"
-)
-
-// InternalRaftStringer implements custom proto Stringer:
-// redact password, replace value fields with value_size fields.
-type InternalRaftStringer struct {
-	Request *InternalRaftRequest
-}
-
-func (as *InternalRaftStringer) String() string {
-	switch {
-	case as.Request.LeaseGrant != nil:
-		return fmt.Sprintf("header:<%s> lease_grant:<ttl:%d-second id:%016x>",
-			as.Request.Header.String(),
-			as.Request.LeaseGrant.TTL,
-			as.Request.LeaseGrant.ID,
-		)
-	case as.Request.LeaseRevoke != nil:
-		return fmt.Sprintf("header:<%s> lease_revoke:<id:%016x>",
-			as.Request.Header.String(),
-			as.Request.LeaseRevoke.ID,
-		)
-	case as.Request.Authenticate != nil:
-		return fmt.Sprintf("header:<%s> authenticate:<name:%s simple_token:%s>",
-			as.Request.Header.String(),
-			as.Request.Authenticate.Name,
-			as.Request.Authenticate.SimpleToken,
-		)
-	case as.Request.AuthUserAdd != nil:
-		return fmt.Sprintf("header:<%s> auth_user_add:<name:%s>",
-			as.Request.Header.String(),
-			as.Request.AuthUserAdd.Name,
-		)
-	case as.Request.AuthUserChangePassword != nil:
-		return fmt.Sprintf("header:<%s> auth_user_change_password:<name:%s>",
-			as.Request.Header.String(),
-			as.Request.AuthUserChangePassword.Name,
-		)
-	case as.Request.Put != nil:
-		return fmt.Sprintf("header:<%s> put:<%s>",
-			as.Request.Header.String(),
-			NewLoggablePutRequest(as.Request.Put).String(),
-		)
-	case as.Request.Txn != nil:
-		return fmt.Sprintf("header:<%s> txn:<%s>",
-			as.Request.Header.String(),
-			NewLoggableTxnRequest(as.Request.Txn).String(),
-		)
-	default:
-		// nothing to redact
-	}
-	return as.Request.String()
-}
-
-// txnRequestStringer implements a custom proto String to replace value bytes fields with value size
-// fields in any nested txn and put operations.
-type txnRequestStringer struct {
-	Request *TxnRequest
-}
-
-func NewLoggableTxnRequest(request *TxnRequest) *txnRequestStringer {
-	return &txnRequestStringer{request}
-}
-
-func (as *txnRequestStringer) String() string {
-	var compare []string
-	for _, c := range as.Request.Compare {
-		switch cv := c.TargetUnion.(type) {
-		case *Compare_Value:
-			compare = append(compare, newLoggableValueCompare(c, cv).String())
-		default:
-			// nothing to redact
-			compare = append(compare, c.String())
-		}
-	}
-	var success []string
-	for _, s := range as.Request.Success {
-		success = append(success, newLoggableRequestOp(s).String())
-	}
-	var failure []string
-	for _, f := range as.Request.Failure {
-		failure = append(failure, newLoggableRequestOp(f).String())
-	}
-	return fmt.Sprintf("compare:<%s> success:<%s> failure:<%s>",
-		strings.Join(compare, " "),
-		strings.Join(success, " "),
-		strings.Join(failure, " "),
-	)
-}
-
-// requestOpStringer implements a custom proto String to replace value bytes fields with value
-// size fields in any nested txn and put operations.
-type requestOpStringer struct {
-	Op *RequestOp
-}
-
-func newLoggableRequestOp(op *RequestOp) *requestOpStringer {
-	return &requestOpStringer{op}
-}
-
-func (as *requestOpStringer) String() string {
-	switch op := as.Op.Request.(type) {
-	case *RequestOp_RequestPut:
-		return fmt.Sprintf("request_put:<%s>", NewLoggablePutRequest(op.RequestPut).String())
-	case *RequestOp_RequestTxn:
-		return fmt.Sprintf("request_txn:<%s>", NewLoggableTxnRequest(op.RequestTxn).String())
-	default:
-		// nothing to redact
-	}
-	return as.Op.String()
-}
-
-// loggableValueCompare implements a custom proto String for Compare.Value union member types to
-// replace the value bytes field with a value size field.
-// To preserve proto encoding of the key and range_end bytes, a faked out proto type is used here.
-type loggableValueCompare struct {
-	Result    Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult"`
-	Target    Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget"`
-	Key       []byte                `protobuf:"bytes,3,opt,name=key,proto3"`
-	ValueSize int                   `protobuf:"bytes,7,opt,name=value_size,proto3"`
-	RangeEnd  []byte                `protobuf:"bytes,64,opt,name=range_end,proto3"`
-}
-
-func newLoggableValueCompare(c *Compare, cv *Compare_Value) *loggableValueCompare {
-	return &loggableValueCompare{
-		c.Result,
-		c.Target,
-		c.Key,
-		len(cv.Value),
-		c.RangeEnd,
-	}
-}
-
-func (m *loggableValueCompare) Reset()         { *m = loggableValueCompare{} }
-func (m *loggableValueCompare) String() string { return proto.CompactTextString(m) }
-func (*loggableValueCompare) ProtoMessage()    {}
-
-// loggablePutRequest implements a custom proto String to replace value bytes field with a value
-// size field.
-// To preserve proto encoding of the key bytes, a faked out proto type is used here.
-type loggablePutRequest struct {
-	Key         []byte `protobuf:"bytes,1,opt,name=key,proto3"`
-	ValueSize   int    `protobuf:"varint,2,opt,name=value_size,proto3"`
-	Lease       int64  `protobuf:"varint,3,opt,name=lease,proto3"`
-	PrevKv      bool   `protobuf:"varint,4,opt,name=prev_kv,proto3"`
-	IgnoreValue bool   `protobuf:"varint,5,opt,name=ignore_value,proto3"`
-	IgnoreLease bool   `protobuf:"varint,6,opt,name=ignore_lease,proto3"`
-}
-
-func NewLoggablePutRequest(request *PutRequest) *loggablePutRequest {
-	return &loggablePutRequest{
-		request.Key,
-		len(request.Value),
-		request.Lease,
-		request.PrevKv,
-		request.IgnoreValue,
-		request.IgnoreLease,
-	}
-}
-
-func (m *loggablePutRequest) Reset()         { *m = loggablePutRequest{} }
-func (m *loggablePutRequest) String() string { return proto.CompactTextString(m) }
-func (*loggablePutRequest) ProtoMessage()    {}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go
deleted file mode 100644
index 199ee62..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.pb.go
+++ /dev/null
@@ -1,20086 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: rpc.proto
-
-package etcdserverpb
-
-import (
-	"fmt"
-
-	proto "github.com/golang/protobuf/proto"
-
-	math "math"
-
-	_ "github.com/gogo/protobuf/gogoproto"
-
-	mvccpb "go.etcd.io/etcd/mvcc/mvccpb"
-
-	authpb "go.etcd.io/etcd/auth/authpb"
-
-	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
-
-type AlarmType int32
-
-const (
-	AlarmType_NONE    AlarmType = 0
-	AlarmType_NOSPACE AlarmType = 1
-	AlarmType_CORRUPT AlarmType = 2
-)
-
-var AlarmType_name = map[int32]string{
-	0: "NONE",
-	1: "NOSPACE",
-	2: "CORRUPT",
-}
-var AlarmType_value = map[string]int32{
-	"NONE":    0,
-	"NOSPACE": 1,
-	"CORRUPT": 2,
-}
-
-func (x AlarmType) String() string {
-	return proto.EnumName(AlarmType_name, int32(x))
-}
-func (AlarmType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} }
-
-type RangeRequest_SortOrder int32
-
-const (
-	RangeRequest_NONE    RangeRequest_SortOrder = 0
-	RangeRequest_ASCEND  RangeRequest_SortOrder = 1
-	RangeRequest_DESCEND RangeRequest_SortOrder = 2
-)
-
-var RangeRequest_SortOrder_name = map[int32]string{
-	0: "NONE",
-	1: "ASCEND",
-	2: "DESCEND",
-}
-var RangeRequest_SortOrder_value = map[string]int32{
-	"NONE":    0,
-	"ASCEND":  1,
-	"DESCEND": 2,
-}
-
-func (x RangeRequest_SortOrder) String() string {
-	return proto.EnumName(RangeRequest_SortOrder_name, int32(x))
-}
-func (RangeRequest_SortOrder) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1, 0} }
-
-type RangeRequest_SortTarget int32
-
-const (
-	RangeRequest_KEY     RangeRequest_SortTarget = 0
-	RangeRequest_VERSION RangeRequest_SortTarget = 1
-	RangeRequest_CREATE  RangeRequest_SortTarget = 2
-	RangeRequest_MOD     RangeRequest_SortTarget = 3
-	RangeRequest_VALUE   RangeRequest_SortTarget = 4
-)
-
-var RangeRequest_SortTarget_name = map[int32]string{
-	0: "KEY",
-	1: "VERSION",
-	2: "CREATE",
-	3: "MOD",
-	4: "VALUE",
-}
-var RangeRequest_SortTarget_value = map[string]int32{
-	"KEY":     0,
-	"VERSION": 1,
-	"CREATE":  2,
-	"MOD":     3,
-	"VALUE":   4,
-}
-
-func (x RangeRequest_SortTarget) String() string {
-	return proto.EnumName(RangeRequest_SortTarget_name, int32(x))
-}
-func (RangeRequest_SortTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1, 1} }
-
-type Compare_CompareResult int32
-
-const (
-	Compare_EQUAL     Compare_CompareResult = 0
-	Compare_GREATER   Compare_CompareResult = 1
-	Compare_LESS      Compare_CompareResult = 2
-	Compare_NOT_EQUAL Compare_CompareResult = 3
-)
-
-var Compare_CompareResult_name = map[int32]string{
-	0: "EQUAL",
-	1: "GREATER",
-	2: "LESS",
-	3: "NOT_EQUAL",
-}
-var Compare_CompareResult_value = map[string]int32{
-	"EQUAL":     0,
-	"GREATER":   1,
-	"LESS":      2,
-	"NOT_EQUAL": 3,
-}
-
-func (x Compare_CompareResult) String() string {
-	return proto.EnumName(Compare_CompareResult_name, int32(x))
-}
-func (Compare_CompareResult) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9, 0} }
-
-type Compare_CompareTarget int32
-
-const (
-	Compare_VERSION Compare_CompareTarget = 0
-	Compare_CREATE  Compare_CompareTarget = 1
-	Compare_MOD     Compare_CompareTarget = 2
-	Compare_VALUE   Compare_CompareTarget = 3
-	Compare_LEASE   Compare_CompareTarget = 4
-)
-
-var Compare_CompareTarget_name = map[int32]string{
-	0: "VERSION",
-	1: "CREATE",
-	2: "MOD",
-	3: "VALUE",
-	4: "LEASE",
-}
-var Compare_CompareTarget_value = map[string]int32{
-	"VERSION": 0,
-	"CREATE":  1,
-	"MOD":     2,
-	"VALUE":   3,
-	"LEASE":   4,
-}
-
-func (x Compare_CompareTarget) String() string {
-	return proto.EnumName(Compare_CompareTarget_name, int32(x))
-}
-func (Compare_CompareTarget) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9, 1} }
-
-type WatchCreateRequest_FilterType int32
-
-const (
-	// filter out put event.
-	WatchCreateRequest_NOPUT WatchCreateRequest_FilterType = 0
-	// filter out delete event.
-	WatchCreateRequest_NODELETE WatchCreateRequest_FilterType = 1
-)
-
-var WatchCreateRequest_FilterType_name = map[int32]string{
-	0: "NOPUT",
-	1: "NODELETE",
-}
-var WatchCreateRequest_FilterType_value = map[string]int32{
-	"NOPUT":    0,
-	"NODELETE": 1,
-}
-
-func (x WatchCreateRequest_FilterType) String() string {
-	return proto.EnumName(WatchCreateRequest_FilterType_name, int32(x))
-}
-func (WatchCreateRequest_FilterType) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{21, 0}
-}
-
-type AlarmRequest_AlarmAction int32
-
-const (
-	AlarmRequest_GET        AlarmRequest_AlarmAction = 0
-	AlarmRequest_ACTIVATE   AlarmRequest_AlarmAction = 1
-	AlarmRequest_DEACTIVATE AlarmRequest_AlarmAction = 2
-)
-
-var AlarmRequest_AlarmAction_name = map[int32]string{
-	0: "GET",
-	1: "ACTIVATE",
-	2: "DEACTIVATE",
-}
-var AlarmRequest_AlarmAction_value = map[string]int32{
-	"GET":        0,
-	"ACTIVATE":   1,
-	"DEACTIVATE": 2,
-}
-
-func (x AlarmRequest_AlarmAction) String() string {
-	return proto.EnumName(AlarmRequest_AlarmAction_name, int32(x))
-}
-func (AlarmRequest_AlarmAction) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{54, 0}
-}
-
-type ResponseHeader struct {
-	// cluster_id is the ID of the cluster which sent the response.
-	ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"`
-	// member_id is the ID of the member which sent the response.
-	MemberId uint64 `protobuf:"varint,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"`
-	// revision is the key-value store revision when the request was applied.
-	// For watch progress responses, the header.revision indicates progress. All future events
-	// recieved in this stream are guaranteed to have a higher revision number than the
-	// header.revision number.
-	Revision int64 `protobuf:"varint,3,opt,name=revision,proto3" json:"revision,omitempty"`
-	// raft_term is the raft term when the request was applied.
-	RaftTerm uint64 `protobuf:"varint,4,opt,name=raft_term,json=raftTerm,proto3" json:"raft_term,omitempty"`
-}
-
-func (m *ResponseHeader) Reset()                    { *m = ResponseHeader{} }
-func (m *ResponseHeader) String() string            { return proto.CompactTextString(m) }
-func (*ResponseHeader) ProtoMessage()               {}
-func (*ResponseHeader) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{0} }
-
-func (m *ResponseHeader) GetClusterId() uint64 {
-	if m != nil {
-		return m.ClusterId
-	}
-	return 0
-}
-
-func (m *ResponseHeader) GetMemberId() uint64 {
-	if m != nil {
-		return m.MemberId
-	}
-	return 0
-}
-
-func (m *ResponseHeader) GetRevision() int64 {
-	if m != nil {
-		return m.Revision
-	}
-	return 0
-}
-
-func (m *ResponseHeader) GetRaftTerm() uint64 {
-	if m != nil {
-		return m.RaftTerm
-	}
-	return 0
-}
-
-type RangeRequest struct {
-	// key is the first key for the range. If range_end is not given, the request only looks up key.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-	// range_end is the upper bound on the requested range [key, range_end).
-	// If range_end is '\0', the range is all keys >= key.
-	// If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"),
-	// then the range request gets all keys prefixed with key.
-	// If both key and range_end are '\0', then the range request returns all keys.
-	RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-	// limit is a limit on the number of keys returned for the request. When limit is set to 0,
-	// it is treated as no limit.
-	Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
-	// revision is the point-in-time of the key-value store to use for the range.
-	// If revision is less or equal to zero, the range is over the newest key-value store.
-	// If the revision has been compacted, ErrCompacted is returned as a response.
-	Revision int64 `protobuf:"varint,4,opt,name=revision,proto3" json:"revision,omitempty"`
-	// sort_order is the order for returned sorted results.
-	SortOrder RangeRequest_SortOrder `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,proto3,enum=etcdserverpb.RangeRequest_SortOrder" json:"sort_order,omitempty"`
-	// sort_target is the key-value field to use for sorting.
-	SortTarget RangeRequest_SortTarget `protobuf:"varint,6,opt,name=sort_target,json=sortTarget,proto3,enum=etcdserverpb.RangeRequest_SortTarget" json:"sort_target,omitempty"`
-	// serializable sets the range request to use serializable member-local reads.
-	// Range requests are linearizable by default; linearizable requests have higher
-	// latency and lower throughput than serializable requests but reflect the current
-	// consensus of the cluster. For better performance, in exchange for possible stale reads,
-	// a serializable range request is served locally without needing to reach consensus
-	// with other nodes in the cluster.
-	Serializable bool `protobuf:"varint,7,opt,name=serializable,proto3" json:"serializable,omitempty"`
-	// keys_only when set returns only the keys and not the values.
-	KeysOnly bool `protobuf:"varint,8,opt,name=keys_only,json=keysOnly,proto3" json:"keys_only,omitempty"`
-	// count_only when set returns only the count of the keys in the range.
-	CountOnly bool `protobuf:"varint,9,opt,name=count_only,json=countOnly,proto3" json:"count_only,omitempty"`
-	// min_mod_revision is the lower bound for returned key mod revisions; all keys with
-	// lesser mod revisions will be filtered away.
-	MinModRevision int64 `protobuf:"varint,10,opt,name=min_mod_revision,json=minModRevision,proto3" json:"min_mod_revision,omitempty"`
-	// max_mod_revision is the upper bound for returned key mod revisions; all keys with
-	// greater mod revisions will be filtered away.
-	MaxModRevision int64 `protobuf:"varint,11,opt,name=max_mod_revision,json=maxModRevision,proto3" json:"max_mod_revision,omitempty"`
-	// min_create_revision is the lower bound for returned key create revisions; all keys with
-	// lesser create revisions will be filtered away.
-	MinCreateRevision int64 `protobuf:"varint,12,opt,name=min_create_revision,json=minCreateRevision,proto3" json:"min_create_revision,omitempty"`
-	// max_create_revision is the upper bound for returned key create revisions; all keys with
-	// greater create revisions will be filtered away.
-	MaxCreateRevision int64 `protobuf:"varint,13,opt,name=max_create_revision,json=maxCreateRevision,proto3" json:"max_create_revision,omitempty"`
-}
-
-func (m *RangeRequest) Reset()                    { *m = RangeRequest{} }
-func (m *RangeRequest) String() string            { return proto.CompactTextString(m) }
-func (*RangeRequest) ProtoMessage()               {}
-func (*RangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{1} }
-
-func (m *RangeRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *RangeRequest) GetRangeEnd() []byte {
-	if m != nil {
-		return m.RangeEnd
-	}
-	return nil
-}
-
-func (m *RangeRequest) GetLimit() int64 {
-	if m != nil {
-		return m.Limit
-	}
-	return 0
-}
-
-func (m *RangeRequest) GetRevision() int64 {
-	if m != nil {
-		return m.Revision
-	}
-	return 0
-}
-
-func (m *RangeRequest) GetSortOrder() RangeRequest_SortOrder {
-	if m != nil {
-		return m.SortOrder
-	}
-	return RangeRequest_NONE
-}
-
-func (m *RangeRequest) GetSortTarget() RangeRequest_SortTarget {
-	if m != nil {
-		return m.SortTarget
-	}
-	return RangeRequest_KEY
-}
-
-func (m *RangeRequest) GetSerializable() bool {
-	if m != nil {
-		return m.Serializable
-	}
-	return false
-}
-
-func (m *RangeRequest) GetKeysOnly() bool {
-	if m != nil {
-		return m.KeysOnly
-	}
-	return false
-}
-
-func (m *RangeRequest) GetCountOnly() bool {
-	if m != nil {
-		return m.CountOnly
-	}
-	return false
-}
-
-func (m *RangeRequest) GetMinModRevision() int64 {
-	if m != nil {
-		return m.MinModRevision
-	}
-	return 0
-}
-
-func (m *RangeRequest) GetMaxModRevision() int64 {
-	if m != nil {
-		return m.MaxModRevision
-	}
-	return 0
-}
-
-func (m *RangeRequest) GetMinCreateRevision() int64 {
-	if m != nil {
-		return m.MinCreateRevision
-	}
-	return 0
-}
-
-func (m *RangeRequest) GetMaxCreateRevision() int64 {
-	if m != nil {
-		return m.MaxCreateRevision
-	}
-	return 0
-}
-
-type RangeResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// kvs is the list of key-value pairs matched by the range request.
-	// kvs is empty when count is requested.
-	Kvs []*mvccpb.KeyValue `protobuf:"bytes,2,rep,name=kvs" json:"kvs,omitempty"`
-	// more indicates if there are more keys to return in the requested range.
-	More bool `protobuf:"varint,3,opt,name=more,proto3" json:"more,omitempty"`
-	// count is set to the number of keys within the range when requested.
-	Count int64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
-}
-
-func (m *RangeResponse) Reset()                    { *m = RangeResponse{} }
-func (m *RangeResponse) String() string            { return proto.CompactTextString(m) }
-func (*RangeResponse) ProtoMessage()               {}
-func (*RangeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{2} }
-
-func (m *RangeResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *RangeResponse) GetKvs() []*mvccpb.KeyValue {
-	if m != nil {
-		return m.Kvs
-	}
-	return nil
-}
-
-func (m *RangeResponse) GetMore() bool {
-	if m != nil {
-		return m.More
-	}
-	return false
-}
-
-func (m *RangeResponse) GetCount() int64 {
-	if m != nil {
-		return m.Count
-	}
-	return 0
-}
-
-type PutRequest struct {
-	// key is the key, in bytes, to put into the key-value store.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-	// value is the value, in bytes, to associate with the key in the key-value store.
-	Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
-	// lease is the lease ID to associate with the key in the key-value store. A lease
-	// value of 0 indicates no lease.
-	Lease int64 `protobuf:"varint,3,opt,name=lease,proto3" json:"lease,omitempty"`
-	// If prev_kv is set, etcd gets the previous key-value pair before changing it.
-	// The previous key-value pair will be returned in the put response.
-	PrevKv bool `protobuf:"varint,4,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"`
-	// If ignore_value is set, etcd updates the key using its current value.
-	// Returns an error if the key does not exist.
-	IgnoreValue bool `protobuf:"varint,5,opt,name=ignore_value,json=ignoreValue,proto3" json:"ignore_value,omitempty"`
-	// If ignore_lease is set, etcd updates the key using its current lease.
-	// Returns an error if the key does not exist.
-	IgnoreLease bool `protobuf:"varint,6,opt,name=ignore_lease,json=ignoreLease,proto3" json:"ignore_lease,omitempty"`
-}
-
-func (m *PutRequest) Reset()                    { *m = PutRequest{} }
-func (m *PutRequest) String() string            { return proto.CompactTextString(m) }
-func (*PutRequest) ProtoMessage()               {}
-func (*PutRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{3} }
-
-func (m *PutRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *PutRequest) GetValue() []byte {
-	if m != nil {
-		return m.Value
-	}
-	return nil
-}
-
-func (m *PutRequest) GetLease() int64 {
-	if m != nil {
-		return m.Lease
-	}
-	return 0
-}
-
-func (m *PutRequest) GetPrevKv() bool {
-	if m != nil {
-		return m.PrevKv
-	}
-	return false
-}
-
-func (m *PutRequest) GetIgnoreValue() bool {
-	if m != nil {
-		return m.IgnoreValue
-	}
-	return false
-}
-
-func (m *PutRequest) GetIgnoreLease() bool {
-	if m != nil {
-		return m.IgnoreLease
-	}
-	return false
-}
-
-type PutResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// if prev_kv is set in the request, the previous key-value pair will be returned.
-	PrevKv *mvccpb.KeyValue `protobuf:"bytes,2,opt,name=prev_kv,json=prevKv" json:"prev_kv,omitempty"`
-}
-
-func (m *PutResponse) Reset()                    { *m = PutResponse{} }
-func (m *PutResponse) String() string            { return proto.CompactTextString(m) }
-func (*PutResponse) ProtoMessage()               {}
-func (*PutResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{4} }
-
-func (m *PutResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *PutResponse) GetPrevKv() *mvccpb.KeyValue {
-	if m != nil {
-		return m.PrevKv
-	}
-	return nil
-}
-
-type DeleteRangeRequest struct {
-	// key is the first key to delete in the range.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-	// range_end is the key following the last key to delete for the range [key, range_end).
-	// If range_end is not given, the range is defined to contain only the key argument.
-	// If range_end is one bit larger than the given key, then the range is all the keys
-	// with the prefix (the given key).
-	// If range_end is '\0', the range is all keys greater than or equal to the key argument.
-	RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-	// If prev_kv is set, etcd gets the previous key-value pairs before deleting it.
-	// The previous key-value pairs will be returned in the delete response.
-	PrevKv bool `protobuf:"varint,3,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"`
-}
-
-func (m *DeleteRangeRequest) Reset()                    { *m = DeleteRangeRequest{} }
-func (m *DeleteRangeRequest) String() string            { return proto.CompactTextString(m) }
-func (*DeleteRangeRequest) ProtoMessage()               {}
-func (*DeleteRangeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{5} }
-
-func (m *DeleteRangeRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *DeleteRangeRequest) GetRangeEnd() []byte {
-	if m != nil {
-		return m.RangeEnd
-	}
-	return nil
-}
-
-func (m *DeleteRangeRequest) GetPrevKv() bool {
-	if m != nil {
-		return m.PrevKv
-	}
-	return false
-}
-
-type DeleteRangeResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// deleted is the number of keys deleted by the delete range request.
-	Deleted int64 `protobuf:"varint,2,opt,name=deleted,proto3" json:"deleted,omitempty"`
-	// if prev_kv is set in the request, the previous key-value pairs will be returned.
-	PrevKvs []*mvccpb.KeyValue `protobuf:"bytes,3,rep,name=prev_kvs,json=prevKvs" json:"prev_kvs,omitempty"`
-}
-
-func (m *DeleteRangeResponse) Reset()                    { *m = DeleteRangeResponse{} }
-func (m *DeleteRangeResponse) String() string            { return proto.CompactTextString(m) }
-func (*DeleteRangeResponse) ProtoMessage()               {}
-func (*DeleteRangeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{6} }
-
-func (m *DeleteRangeResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *DeleteRangeResponse) GetDeleted() int64 {
-	if m != nil {
-		return m.Deleted
-	}
-	return 0
-}
-
-func (m *DeleteRangeResponse) GetPrevKvs() []*mvccpb.KeyValue {
-	if m != nil {
-		return m.PrevKvs
-	}
-	return nil
-}
-
-type RequestOp struct {
-	// request is a union of request types accepted by a transaction.
-	//
-	// Types that are valid to be assigned to Request:
-	//	*RequestOp_RequestRange
-	//	*RequestOp_RequestPut
-	//	*RequestOp_RequestDeleteRange
-	//	*RequestOp_RequestTxn
-	Request isRequestOp_Request `protobuf_oneof:"request"`
-}
-
-func (m *RequestOp) Reset()                    { *m = RequestOp{} }
-func (m *RequestOp) String() string            { return proto.CompactTextString(m) }
-func (*RequestOp) ProtoMessage()               {}
-func (*RequestOp) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{7} }
-
-type isRequestOp_Request interface {
-	isRequestOp_Request()
-	MarshalTo([]byte) (int, error)
-	Size() int
-}
-
-type RequestOp_RequestRange struct {
-	RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,json=requestRange,oneof"`
-}
-type RequestOp_RequestPut struct {
-	RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,json=requestPut,oneof"`
-}
-type RequestOp_RequestDeleteRange struct {
-	RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,json=requestDeleteRange,oneof"`
-}
-type RequestOp_RequestTxn struct {
-	RequestTxn *TxnRequest `protobuf:"bytes,4,opt,name=request_txn,json=requestTxn,oneof"`
-}
-
-func (*RequestOp_RequestRange) isRequestOp_Request()       {}
-func (*RequestOp_RequestPut) isRequestOp_Request()         {}
-func (*RequestOp_RequestDeleteRange) isRequestOp_Request() {}
-func (*RequestOp_RequestTxn) isRequestOp_Request()         {}
-
-func (m *RequestOp) GetRequest() isRequestOp_Request {
-	if m != nil {
-		return m.Request
-	}
-	return nil
-}
-
-func (m *RequestOp) GetRequestRange() *RangeRequest {
-	if x, ok := m.GetRequest().(*RequestOp_RequestRange); ok {
-		return x.RequestRange
-	}
-	return nil
-}
-
-func (m *RequestOp) GetRequestPut() *PutRequest {
-	if x, ok := m.GetRequest().(*RequestOp_RequestPut); ok {
-		return x.RequestPut
-	}
-	return nil
-}
-
-func (m *RequestOp) GetRequestDeleteRange() *DeleteRangeRequest {
-	if x, ok := m.GetRequest().(*RequestOp_RequestDeleteRange); ok {
-		return x.RequestDeleteRange
-	}
-	return nil
-}
-
-func (m *RequestOp) GetRequestTxn() *TxnRequest {
-	if x, ok := m.GetRequest().(*RequestOp_RequestTxn); ok {
-		return x.RequestTxn
-	}
-	return nil
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*RequestOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _RequestOp_OneofMarshaler, _RequestOp_OneofUnmarshaler, _RequestOp_OneofSizer, []interface{}{
-		(*RequestOp_RequestRange)(nil),
-		(*RequestOp_RequestPut)(nil),
-		(*RequestOp_RequestDeleteRange)(nil),
-		(*RequestOp_RequestTxn)(nil),
-	}
-}
-
-func _RequestOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*RequestOp)
-	// request
-	switch x := m.Request.(type) {
-	case *RequestOp_RequestRange:
-		_ = b.EncodeVarint(1<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.RequestRange); err != nil {
-			return err
-		}
-	case *RequestOp_RequestPut:
-		_ = b.EncodeVarint(2<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.RequestPut); err != nil {
-			return err
-		}
-	case *RequestOp_RequestDeleteRange:
-		_ = b.EncodeVarint(3<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.RequestDeleteRange); err != nil {
-			return err
-		}
-	case *RequestOp_RequestTxn:
-		_ = b.EncodeVarint(4<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.RequestTxn); err != nil {
-			return err
-		}
-	case nil:
-	default:
-		return fmt.Errorf("RequestOp.Request has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _RequestOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*RequestOp)
-	switch tag {
-	case 1: // request.request_range
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(RangeRequest)
-		err := b.DecodeMessage(msg)
-		m.Request = &RequestOp_RequestRange{msg}
-		return true, err
-	case 2: // request.request_put
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(PutRequest)
-		err := b.DecodeMessage(msg)
-		m.Request = &RequestOp_RequestPut{msg}
-		return true, err
-	case 3: // request.request_delete_range
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(DeleteRangeRequest)
-		err := b.DecodeMessage(msg)
-		m.Request = &RequestOp_RequestDeleteRange{msg}
-		return true, err
-	case 4: // request.request_txn
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(TxnRequest)
-		err := b.DecodeMessage(msg)
-		m.Request = &RequestOp_RequestTxn{msg}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _RequestOp_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*RequestOp)
-	// request
-	switch x := m.Request.(type) {
-	case *RequestOp_RequestRange:
-		s := proto.Size(x.RequestRange)
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *RequestOp_RequestPut:
-		s := proto.Size(x.RequestPut)
-		n += proto.SizeVarint(2<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *RequestOp_RequestDeleteRange:
-		s := proto.Size(x.RequestDeleteRange)
-		n += proto.SizeVarint(3<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *RequestOp_RequestTxn:
-		s := proto.Size(x.RequestTxn)
-		n += proto.SizeVarint(4<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type ResponseOp struct {
-	// response is a union of response types returned by a transaction.
-	//
-	// Types that are valid to be assigned to Response:
-	//	*ResponseOp_ResponseRange
-	//	*ResponseOp_ResponsePut
-	//	*ResponseOp_ResponseDeleteRange
-	//	*ResponseOp_ResponseTxn
-	Response isResponseOp_Response `protobuf_oneof:"response"`
-}
-
-func (m *ResponseOp) Reset()                    { *m = ResponseOp{} }
-func (m *ResponseOp) String() string            { return proto.CompactTextString(m) }
-func (*ResponseOp) ProtoMessage()               {}
-func (*ResponseOp) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{8} }
-
-type isResponseOp_Response interface {
-	isResponseOp_Response()
-	MarshalTo([]byte) (int, error)
-	Size() int
-}
-
-type ResponseOp_ResponseRange struct {
-	ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,json=responseRange,oneof"`
-}
-type ResponseOp_ResponsePut struct {
-	ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,json=responsePut,oneof"`
-}
-type ResponseOp_ResponseDeleteRange struct {
-	ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,json=responseDeleteRange,oneof"`
-}
-type ResponseOp_ResponseTxn struct {
-	ResponseTxn *TxnResponse `protobuf:"bytes,4,opt,name=response_txn,json=responseTxn,oneof"`
-}
-
-func (*ResponseOp_ResponseRange) isResponseOp_Response()       {}
-func (*ResponseOp_ResponsePut) isResponseOp_Response()         {}
-func (*ResponseOp_ResponseDeleteRange) isResponseOp_Response() {}
-func (*ResponseOp_ResponseTxn) isResponseOp_Response()         {}
-
-func (m *ResponseOp) GetResponse() isResponseOp_Response {
-	if m != nil {
-		return m.Response
-	}
-	return nil
-}
-
-func (m *ResponseOp) GetResponseRange() *RangeResponse {
-	if x, ok := m.GetResponse().(*ResponseOp_ResponseRange); ok {
-		return x.ResponseRange
-	}
-	return nil
-}
-
-func (m *ResponseOp) GetResponsePut() *PutResponse {
-	if x, ok := m.GetResponse().(*ResponseOp_ResponsePut); ok {
-		return x.ResponsePut
-	}
-	return nil
-}
-
-func (m *ResponseOp) GetResponseDeleteRange() *DeleteRangeResponse {
-	if x, ok := m.GetResponse().(*ResponseOp_ResponseDeleteRange); ok {
-		return x.ResponseDeleteRange
-	}
-	return nil
-}
-
-func (m *ResponseOp) GetResponseTxn() *TxnResponse {
-	if x, ok := m.GetResponse().(*ResponseOp_ResponseTxn); ok {
-		return x.ResponseTxn
-	}
-	return nil
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*ResponseOp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _ResponseOp_OneofMarshaler, _ResponseOp_OneofUnmarshaler, _ResponseOp_OneofSizer, []interface{}{
-		(*ResponseOp_ResponseRange)(nil),
-		(*ResponseOp_ResponsePut)(nil),
-		(*ResponseOp_ResponseDeleteRange)(nil),
-		(*ResponseOp_ResponseTxn)(nil),
-	}
-}
-
-func _ResponseOp_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*ResponseOp)
-	// response
-	switch x := m.Response.(type) {
-	case *ResponseOp_ResponseRange:
-		_ = b.EncodeVarint(1<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ResponseRange); err != nil {
-			return err
-		}
-	case *ResponseOp_ResponsePut:
-		_ = b.EncodeVarint(2<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ResponsePut); err != nil {
-			return err
-		}
-	case *ResponseOp_ResponseDeleteRange:
-		_ = b.EncodeVarint(3<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ResponseDeleteRange); err != nil {
-			return err
-		}
-	case *ResponseOp_ResponseTxn:
-		_ = b.EncodeVarint(4<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ResponseTxn); err != nil {
-			return err
-		}
-	case nil:
-	default:
-		return fmt.Errorf("ResponseOp.Response has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _ResponseOp_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*ResponseOp)
-	switch tag {
-	case 1: // response.response_range
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(RangeResponse)
-		err := b.DecodeMessage(msg)
-		m.Response = &ResponseOp_ResponseRange{msg}
-		return true, err
-	case 2: // response.response_put
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(PutResponse)
-		err := b.DecodeMessage(msg)
-		m.Response = &ResponseOp_ResponsePut{msg}
-		return true, err
-	case 3: // response.response_delete_range
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(DeleteRangeResponse)
-		err := b.DecodeMessage(msg)
-		m.Response = &ResponseOp_ResponseDeleteRange{msg}
-		return true, err
-	case 4: // response.response_txn
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(TxnResponse)
-		err := b.DecodeMessage(msg)
-		m.Response = &ResponseOp_ResponseTxn{msg}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _ResponseOp_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*ResponseOp)
-	// response
-	switch x := m.Response.(type) {
-	case *ResponseOp_ResponseRange:
-		s := proto.Size(x.ResponseRange)
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *ResponseOp_ResponsePut:
-		s := proto.Size(x.ResponsePut)
-		n += proto.SizeVarint(2<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *ResponseOp_ResponseDeleteRange:
-		s := proto.Size(x.ResponseDeleteRange)
-		n += proto.SizeVarint(3<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *ResponseOp_ResponseTxn:
-		s := proto.Size(x.ResponseTxn)
-		n += proto.SizeVarint(4<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type Compare struct {
-	// result is logical comparison operation for this comparison.
-	Result Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult" json:"result,omitempty"`
-	// target is the key-value field to inspect for the comparison.
-	Target Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget" json:"target,omitempty"`
-	// key is the subject key for the comparison operation.
-	Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"`
-	// Types that are valid to be assigned to TargetUnion:
-	//	*Compare_Version
-	//	*Compare_CreateRevision
-	//	*Compare_ModRevision
-	//	*Compare_Value
-	//	*Compare_Lease
-	TargetUnion isCompare_TargetUnion `protobuf_oneof:"target_union"`
-	// range_end compares the given target to all keys in the range [key, range_end).
-	// See RangeRequest for more details on key ranges.
-	RangeEnd []byte `protobuf:"bytes,64,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-}
-
-func (m *Compare) Reset()                    { *m = Compare{} }
-func (m *Compare) String() string            { return proto.CompactTextString(m) }
-func (*Compare) ProtoMessage()               {}
-func (*Compare) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{9} }
-
-type isCompare_TargetUnion interface {
-	isCompare_TargetUnion()
-	MarshalTo([]byte) (int, error)
-	Size() int
-}
-
-type Compare_Version struct {
-	Version int64 `protobuf:"varint,4,opt,name=version,proto3,oneof"`
-}
-type Compare_CreateRevision struct {
-	CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,json=createRevision,proto3,oneof"`
-}
-type Compare_ModRevision struct {
-	ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,json=modRevision,proto3,oneof"`
-}
-type Compare_Value struct {
-	Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"`
-}
-type Compare_Lease struct {
-	Lease int64 `protobuf:"varint,8,opt,name=lease,proto3,oneof"`
-}
-
-func (*Compare_Version) isCompare_TargetUnion()        {}
-func (*Compare_CreateRevision) isCompare_TargetUnion() {}
-func (*Compare_ModRevision) isCompare_TargetUnion()    {}
-func (*Compare_Value) isCompare_TargetUnion()          {}
-func (*Compare_Lease) isCompare_TargetUnion()          {}
-
-func (m *Compare) GetTargetUnion() isCompare_TargetUnion {
-	if m != nil {
-		return m.TargetUnion
-	}
-	return nil
-}
-
-func (m *Compare) GetResult() Compare_CompareResult {
-	if m != nil {
-		return m.Result
-	}
-	return Compare_EQUAL
-}
-
-func (m *Compare) GetTarget() Compare_CompareTarget {
-	if m != nil {
-		return m.Target
-	}
-	return Compare_VERSION
-}
-
-func (m *Compare) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *Compare) GetVersion() int64 {
-	if x, ok := m.GetTargetUnion().(*Compare_Version); ok {
-		return x.Version
-	}
-	return 0
-}
-
-func (m *Compare) GetCreateRevision() int64 {
-	if x, ok := m.GetTargetUnion().(*Compare_CreateRevision); ok {
-		return x.CreateRevision
-	}
-	return 0
-}
-
-func (m *Compare) GetModRevision() int64 {
-	if x, ok := m.GetTargetUnion().(*Compare_ModRevision); ok {
-		return x.ModRevision
-	}
-	return 0
-}
-
-func (m *Compare) GetValue() []byte {
-	if x, ok := m.GetTargetUnion().(*Compare_Value); ok {
-		return x.Value
-	}
-	return nil
-}
-
-func (m *Compare) GetLease() int64 {
-	if x, ok := m.GetTargetUnion().(*Compare_Lease); ok {
-		return x.Lease
-	}
-	return 0
-}
-
-func (m *Compare) GetRangeEnd() []byte {
-	if m != nil {
-		return m.RangeEnd
-	}
-	return nil
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*Compare) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _Compare_OneofMarshaler, _Compare_OneofUnmarshaler, _Compare_OneofSizer, []interface{}{
-		(*Compare_Version)(nil),
-		(*Compare_CreateRevision)(nil),
-		(*Compare_ModRevision)(nil),
-		(*Compare_Value)(nil),
-		(*Compare_Lease)(nil),
-	}
-}
-
-func _Compare_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*Compare)
-	// target_union
-	switch x := m.TargetUnion.(type) {
-	case *Compare_Version:
-		_ = b.EncodeVarint(4<<3 | proto.WireVarint)
-		_ = b.EncodeVarint(uint64(x.Version))
-	case *Compare_CreateRevision:
-		_ = b.EncodeVarint(5<<3 | proto.WireVarint)
-		_ = b.EncodeVarint(uint64(x.CreateRevision))
-	case *Compare_ModRevision:
-		_ = b.EncodeVarint(6<<3 | proto.WireVarint)
-		_ = b.EncodeVarint(uint64(x.ModRevision))
-	case *Compare_Value:
-		_ = b.EncodeVarint(7<<3 | proto.WireBytes)
-		_ = b.EncodeRawBytes(x.Value)
-	case *Compare_Lease:
-		_ = b.EncodeVarint(8<<3 | proto.WireVarint)
-		_ = b.EncodeVarint(uint64(x.Lease))
-	case nil:
-	default:
-		return fmt.Errorf("Compare.TargetUnion has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _Compare_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*Compare)
-	switch tag {
-	case 4: // target_union.version
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.TargetUnion = &Compare_Version{int64(x)}
-		return true, err
-	case 5: // target_union.create_revision
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.TargetUnion = &Compare_CreateRevision{int64(x)}
-		return true, err
-	case 6: // target_union.mod_revision
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.TargetUnion = &Compare_ModRevision{int64(x)}
-		return true, err
-	case 7: // target_union.value
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeRawBytes(true)
-		m.TargetUnion = &Compare_Value{x}
-		return true, err
-	case 8: // target_union.lease
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.TargetUnion = &Compare_Lease{int64(x)}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _Compare_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*Compare)
-	// target_union
-	switch x := m.TargetUnion.(type) {
-	case *Compare_Version:
-		n += proto.SizeVarint(4<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.Version))
-	case *Compare_CreateRevision:
-		n += proto.SizeVarint(5<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.CreateRevision))
-	case *Compare_ModRevision:
-		n += proto.SizeVarint(6<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.ModRevision))
-	case *Compare_Value:
-		n += proto.SizeVarint(7<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.Value)))
-		n += len(x.Value)
-	case *Compare_Lease:
-		n += proto.SizeVarint(8<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.Lease))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-// From google paxosdb paper:
-// Our implementation hinges around a powerful primitive which we call MultiOp. All other database
-// operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically
-// and consists of three components:
-// 1. A list of tests called guard. Each test in guard checks a single entry in the database. It may check
-// for the absence or presence of a value, or compare with a given value. Two different tests in the guard
-// may apply to the same or different entries in the database. All tests in the guard are applied and
-// MultiOp returns the results. If all tests are true, MultiOp executes t op (see item 2 below), otherwise
-// it executes f op (see item 3 below).
-// 2. A list of database operations called t op. Each operation in the list is either an insert, delete, or
-// lookup operation, and applies to a single database entry. Two different operations in the list may apply
-// to the same or different entries in the database. These operations are executed
-// if guard evaluates to
-// true.
-// 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false.
-type TxnRequest struct {
-	// compare is a list of predicates representing a conjunction of terms.
-	// If the comparisons succeed, then the success requests will be processed in order,
-	// and the response will contain their respective responses in order.
-	// If the comparisons fail, then the failure requests will be processed in order,
-	// and the response will contain their respective responses in order.
-	Compare []*Compare `protobuf:"bytes,1,rep,name=compare" json:"compare,omitempty"`
-	// success is a list of requests which will be applied when compare evaluates to true.
-	Success []*RequestOp `protobuf:"bytes,2,rep,name=success" json:"success,omitempty"`
-	// failure is a list of requests which will be applied when compare evaluates to false.
-	Failure []*RequestOp `protobuf:"bytes,3,rep,name=failure" json:"failure,omitempty"`
-}
-
-func (m *TxnRequest) Reset()                    { *m = TxnRequest{} }
-func (m *TxnRequest) String() string            { return proto.CompactTextString(m) }
-func (*TxnRequest) ProtoMessage()               {}
-func (*TxnRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{10} }
-
-func (m *TxnRequest) GetCompare() []*Compare {
-	if m != nil {
-		return m.Compare
-	}
-	return nil
-}
-
-func (m *TxnRequest) GetSuccess() []*RequestOp {
-	if m != nil {
-		return m.Success
-	}
-	return nil
-}
-
-func (m *TxnRequest) GetFailure() []*RequestOp {
-	if m != nil {
-		return m.Failure
-	}
-	return nil
-}
-
-type TxnResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// succeeded is set to true if the compare evaluated to true or false otherwise.
-	Succeeded bool `protobuf:"varint,2,opt,name=succeeded,proto3" json:"succeeded,omitempty"`
-	// responses is a list of responses corresponding to the results from applying
-	// success if succeeded is true or failure if succeeded is false.
-	Responses []*ResponseOp `protobuf:"bytes,3,rep,name=responses" json:"responses,omitempty"`
-}
-
-func (m *TxnResponse) Reset()                    { *m = TxnResponse{} }
-func (m *TxnResponse) String() string            { return proto.CompactTextString(m) }
-func (*TxnResponse) ProtoMessage()               {}
-func (*TxnResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{11} }
-
-func (m *TxnResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *TxnResponse) GetSucceeded() bool {
-	if m != nil {
-		return m.Succeeded
-	}
-	return false
-}
-
-func (m *TxnResponse) GetResponses() []*ResponseOp {
-	if m != nil {
-		return m.Responses
-	}
-	return nil
-}
-
-// CompactionRequest compacts the key-value store up to a given revision. All superseded keys
-// with a revision less than the compaction revision will be removed.
-type CompactionRequest struct {
-	// revision is the key-value store revision for the compaction operation.
-	Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"`
-	// physical is set so the RPC will wait until the compaction is physically
-	// applied to the local database such that compacted entries are totally
-	// removed from the backend database.
-	Physical bool `protobuf:"varint,2,opt,name=physical,proto3" json:"physical,omitempty"`
-}
-
-func (m *CompactionRequest) Reset()                    { *m = CompactionRequest{} }
-func (m *CompactionRequest) String() string            { return proto.CompactTextString(m) }
-func (*CompactionRequest) ProtoMessage()               {}
-func (*CompactionRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{12} }
-
-func (m *CompactionRequest) GetRevision() int64 {
-	if m != nil {
-		return m.Revision
-	}
-	return 0
-}
-
-func (m *CompactionRequest) GetPhysical() bool {
-	if m != nil {
-		return m.Physical
-	}
-	return false
-}
-
-type CompactionResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *CompactionResponse) Reset()                    { *m = CompactionResponse{} }
-func (m *CompactionResponse) String() string            { return proto.CompactTextString(m) }
-func (*CompactionResponse) ProtoMessage()               {}
-func (*CompactionResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{13} }
-
-func (m *CompactionResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type HashRequest struct {
-}
-
-func (m *HashRequest) Reset()                    { *m = HashRequest{} }
-func (m *HashRequest) String() string            { return proto.CompactTextString(m) }
-func (*HashRequest) ProtoMessage()               {}
-func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{14} }
-
-type HashKVRequest struct {
-	// revision is the key-value store revision for the hash operation.
-	Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"`
-}
-
-func (m *HashKVRequest) Reset()                    { *m = HashKVRequest{} }
-func (m *HashKVRequest) String() string            { return proto.CompactTextString(m) }
-func (*HashKVRequest) ProtoMessage()               {}
-func (*HashKVRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{15} }
-
-func (m *HashKVRequest) GetRevision() int64 {
-	if m != nil {
-		return m.Revision
-	}
-	return 0
-}
-
-type HashKVResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// hash is the hash value computed from the responding member's MVCC keys up to a given revision.
-	Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"`
-	// compact_revision is the compacted revision of key-value store when hash begins.
-	CompactRevision int64 `protobuf:"varint,3,opt,name=compact_revision,json=compactRevision,proto3" json:"compact_revision,omitempty"`
-}
-
-func (m *HashKVResponse) Reset()                    { *m = HashKVResponse{} }
-func (m *HashKVResponse) String() string            { return proto.CompactTextString(m) }
-func (*HashKVResponse) ProtoMessage()               {}
-func (*HashKVResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{16} }
-
-func (m *HashKVResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *HashKVResponse) GetHash() uint32 {
-	if m != nil {
-		return m.Hash
-	}
-	return 0
-}
-
-func (m *HashKVResponse) GetCompactRevision() int64 {
-	if m != nil {
-		return m.CompactRevision
-	}
-	return 0
-}
-
-type HashResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// hash is the hash value computed from the responding member's KV's backend.
-	Hash uint32 `protobuf:"varint,2,opt,name=hash,proto3" json:"hash,omitempty"`
-}
-
-func (m *HashResponse) Reset()                    { *m = HashResponse{} }
-func (m *HashResponse) String() string            { return proto.CompactTextString(m) }
-func (*HashResponse) ProtoMessage()               {}
-func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{17} }
-
-func (m *HashResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *HashResponse) GetHash() uint32 {
-	if m != nil {
-		return m.Hash
-	}
-	return 0
-}
-
-type SnapshotRequest struct {
-}
-
-func (m *SnapshotRequest) Reset()                    { *m = SnapshotRequest{} }
-func (m *SnapshotRequest) String() string            { return proto.CompactTextString(m) }
-func (*SnapshotRequest) ProtoMessage()               {}
-func (*SnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{18} }
-
-type SnapshotResponse struct {
-	// header has the current key-value store information. The first header in the snapshot
-	// stream indicates the point in time of the snapshot.
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// remaining_bytes is the number of blob bytes to be sent after this message
-	RemainingBytes uint64 `protobuf:"varint,2,opt,name=remaining_bytes,json=remainingBytes,proto3" json:"remaining_bytes,omitempty"`
-	// blob contains the next chunk of the snapshot in the snapshot stream.
-	Blob []byte `protobuf:"bytes,3,opt,name=blob,proto3" json:"blob,omitempty"`
-}
-
-func (m *SnapshotResponse) Reset()                    { *m = SnapshotResponse{} }
-func (m *SnapshotResponse) String() string            { return proto.CompactTextString(m) }
-func (*SnapshotResponse) ProtoMessage()               {}
-func (*SnapshotResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{19} }
-
-func (m *SnapshotResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *SnapshotResponse) GetRemainingBytes() uint64 {
-	if m != nil {
-		return m.RemainingBytes
-	}
-	return 0
-}
-
-func (m *SnapshotResponse) GetBlob() []byte {
-	if m != nil {
-		return m.Blob
-	}
-	return nil
-}
-
-type WatchRequest struct {
-	// request_union is a request to either create a new watcher or cancel an existing watcher.
-	//
-	// Types that are valid to be assigned to RequestUnion:
-	//	*WatchRequest_CreateRequest
-	//	*WatchRequest_CancelRequest
-	//	*WatchRequest_ProgressRequest
-	RequestUnion isWatchRequest_RequestUnion `protobuf_oneof:"request_union"`
-}
-
-func (m *WatchRequest) Reset()                    { *m = WatchRequest{} }
-func (m *WatchRequest) String() string            { return proto.CompactTextString(m) }
-func (*WatchRequest) ProtoMessage()               {}
-func (*WatchRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{20} }
-
-type isWatchRequest_RequestUnion interface {
-	isWatchRequest_RequestUnion()
-	MarshalTo([]byte) (int, error)
-	Size() int
-}
-
-type WatchRequest_CreateRequest struct {
-	CreateRequest *WatchCreateRequest `protobuf:"bytes,1,opt,name=create_request,json=createRequest,oneof"`
-}
-type WatchRequest_CancelRequest struct {
-	CancelRequest *WatchCancelRequest `protobuf:"bytes,2,opt,name=cancel_request,json=cancelRequest,oneof"`
-}
-type WatchRequest_ProgressRequest struct {
-	ProgressRequest *WatchProgressRequest `protobuf:"bytes,3,opt,name=progress_request,json=progressRequest,oneof"`
-}
-
-func (*WatchRequest_CreateRequest) isWatchRequest_RequestUnion()   {}
-func (*WatchRequest_CancelRequest) isWatchRequest_RequestUnion()   {}
-func (*WatchRequest_ProgressRequest) isWatchRequest_RequestUnion() {}
-
-func (m *WatchRequest) GetRequestUnion() isWatchRequest_RequestUnion {
-	if m != nil {
-		return m.RequestUnion
-	}
-	return nil
-}
-
-func (m *WatchRequest) GetCreateRequest() *WatchCreateRequest {
-	if x, ok := m.GetRequestUnion().(*WatchRequest_CreateRequest); ok {
-		return x.CreateRequest
-	}
-	return nil
-}
-
-func (m *WatchRequest) GetCancelRequest() *WatchCancelRequest {
-	if x, ok := m.GetRequestUnion().(*WatchRequest_CancelRequest); ok {
-		return x.CancelRequest
-	}
-	return nil
-}
-
-func (m *WatchRequest) GetProgressRequest() *WatchProgressRequest {
-	if x, ok := m.GetRequestUnion().(*WatchRequest_ProgressRequest); ok {
-		return x.ProgressRequest
-	}
-	return nil
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*WatchRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _WatchRequest_OneofMarshaler, _WatchRequest_OneofUnmarshaler, _WatchRequest_OneofSizer, []interface{}{
-		(*WatchRequest_CreateRequest)(nil),
-		(*WatchRequest_CancelRequest)(nil),
-		(*WatchRequest_ProgressRequest)(nil),
-	}
-}
-
-func _WatchRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*WatchRequest)
-	// request_union
-	switch x := m.RequestUnion.(type) {
-	case *WatchRequest_CreateRequest:
-		_ = b.EncodeVarint(1<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.CreateRequest); err != nil {
-			return err
-		}
-	case *WatchRequest_CancelRequest:
-		_ = b.EncodeVarint(2<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.CancelRequest); err != nil {
-			return err
-		}
-	case *WatchRequest_ProgressRequest:
-		_ = b.EncodeVarint(3<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.ProgressRequest); err != nil {
-			return err
-		}
-	case nil:
-	default:
-		return fmt.Errorf("WatchRequest.RequestUnion has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _WatchRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*WatchRequest)
-	switch tag {
-	case 1: // request_union.create_request
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(WatchCreateRequest)
-		err := b.DecodeMessage(msg)
-		m.RequestUnion = &WatchRequest_CreateRequest{msg}
-		return true, err
-	case 2: // request_union.cancel_request
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(WatchCancelRequest)
-		err := b.DecodeMessage(msg)
-		m.RequestUnion = &WatchRequest_CancelRequest{msg}
-		return true, err
-	case 3: // request_union.progress_request
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(WatchProgressRequest)
-		err := b.DecodeMessage(msg)
-		m.RequestUnion = &WatchRequest_ProgressRequest{msg}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _WatchRequest_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*WatchRequest)
-	// request_union
-	switch x := m.RequestUnion.(type) {
-	case *WatchRequest_CreateRequest:
-		s := proto.Size(x.CreateRequest)
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *WatchRequest_CancelRequest:
-		s := proto.Size(x.CancelRequest)
-		n += proto.SizeVarint(2<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *WatchRequest_ProgressRequest:
-		s := proto.Size(x.ProgressRequest)
-		n += proto.SizeVarint(3<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type WatchCreateRequest struct {
-	// key is the key to register for watching.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-	// range_end is the end of the range [key, range_end) to watch. If range_end is not given,
-	// only the key argument is watched. If range_end is equal to '\0', all keys greater than
-	// or equal to the key argument are watched.
-	// If the range_end is one bit larger than the given key,
-	// then all keys with the prefix (the given key) will be watched.
-	RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-	// start_revision is an optional revision to watch from (inclusive). No start_revision is "now".
-	StartRevision int64 `protobuf:"varint,3,opt,name=start_revision,json=startRevision,proto3" json:"start_revision,omitempty"`
-	// progress_notify is set so that the etcd server will periodically send a WatchResponse with
-	// no events to the new watcher if there are no recent events. It is useful when clients
-	// wish to recover a disconnected watcher starting from a recent known revision.
-	// The etcd server may decide how often it will send notifications based on current load.
-	ProgressNotify bool `protobuf:"varint,4,opt,name=progress_notify,json=progressNotify,proto3" json:"progress_notify,omitempty"`
-	// filters filter the events at server side before it sends back to the watcher.
-	Filters []WatchCreateRequest_FilterType `protobuf:"varint,5,rep,packed,name=filters,enum=etcdserverpb.WatchCreateRequest_FilterType" json:"filters,omitempty"`
-	// If prev_kv is set, created watcher gets the previous KV before the event happens.
-	// If the previous KV is already compacted, nothing will be returned.
-	PrevKv bool `protobuf:"varint,6,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"`
-	// If watch_id is provided and non-zero, it will be assigned to this watcher.
-	// Since creating a watcher in etcd is not a synchronous operation,
-	// this can be used ensure that ordering is correct when creating multiple
-	// watchers on the same stream. Creating a watcher with an ID already in
-	// use on the stream will cause an error to be returned.
-	WatchId int64 `protobuf:"varint,7,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
-	// fragment enables splitting large revisions into multiple watch responses.
-	Fragment bool `protobuf:"varint,8,opt,name=fragment,proto3" json:"fragment,omitempty"`
-}
-
-func (m *WatchCreateRequest) Reset()                    { *m = WatchCreateRequest{} }
-func (m *WatchCreateRequest) String() string            { return proto.CompactTextString(m) }
-func (*WatchCreateRequest) ProtoMessage()               {}
-func (*WatchCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{21} }
-
-func (m *WatchCreateRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *WatchCreateRequest) GetRangeEnd() []byte {
-	if m != nil {
-		return m.RangeEnd
-	}
-	return nil
-}
-
-func (m *WatchCreateRequest) GetStartRevision() int64 {
-	if m != nil {
-		return m.StartRevision
-	}
-	return 0
-}
-
-func (m *WatchCreateRequest) GetProgressNotify() bool {
-	if m != nil {
-		return m.ProgressNotify
-	}
-	return false
-}
-
-func (m *WatchCreateRequest) GetFilters() []WatchCreateRequest_FilterType {
-	if m != nil {
-		return m.Filters
-	}
-	return nil
-}
-
-func (m *WatchCreateRequest) GetPrevKv() bool {
-	if m != nil {
-		return m.PrevKv
-	}
-	return false
-}
-
-func (m *WatchCreateRequest) GetWatchId() int64 {
-	if m != nil {
-		return m.WatchId
-	}
-	return 0
-}
-
-func (m *WatchCreateRequest) GetFragment() bool {
-	if m != nil {
-		return m.Fragment
-	}
-	return false
-}
-
-type WatchCancelRequest struct {
-	// watch_id is the watcher id to cancel so that no more events are transmitted.
-	WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
-}
-
-func (m *WatchCancelRequest) Reset()                    { *m = WatchCancelRequest{} }
-func (m *WatchCancelRequest) String() string            { return proto.CompactTextString(m) }
-func (*WatchCancelRequest) ProtoMessage()               {}
-func (*WatchCancelRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{22} }
-
-func (m *WatchCancelRequest) GetWatchId() int64 {
-	if m != nil {
-		return m.WatchId
-	}
-	return 0
-}
-
-// Requests the a watch stream progress status be sent in the watch response stream as soon as
-// possible.
-type WatchProgressRequest struct {
-}
-
-func (m *WatchProgressRequest) Reset()                    { *m = WatchProgressRequest{} }
-func (m *WatchProgressRequest) String() string            { return proto.CompactTextString(m) }
-func (*WatchProgressRequest) ProtoMessage()               {}
-func (*WatchProgressRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{23} }
-
-type WatchResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// watch_id is the ID of the watcher that corresponds to the response.
-	WatchId int64 `protobuf:"varint,2,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
-	// created is set to true if the response is for a create watch request.
-	// The client should record the watch_id and expect to receive events for
-	// the created watcher from the same stream.
-	// All events sent to the created watcher will attach with the same watch_id.
-	Created bool `protobuf:"varint,3,opt,name=created,proto3" json:"created,omitempty"`
-	// canceled is set to true if the response is for a cancel watch request.
-	// No further events will be sent to the canceled watcher.
-	Canceled bool `protobuf:"varint,4,opt,name=canceled,proto3" json:"canceled,omitempty"`
-	// compact_revision is set to the minimum index if a watcher tries to watch
-	// at a compacted index.
-	//
-	// This happens when creating a watcher at a compacted revision or the watcher cannot
-	// catch up with the progress of the key-value store.
-	//
-	// The client should treat the watcher as canceled and should not try to create any
-	// watcher with the same start_revision again.
-	CompactRevision int64 `protobuf:"varint,5,opt,name=compact_revision,json=compactRevision,proto3" json:"compact_revision,omitempty"`
-	// cancel_reason indicates the reason for canceling the watcher.
-	CancelReason string `protobuf:"bytes,6,opt,name=cancel_reason,json=cancelReason,proto3" json:"cancel_reason,omitempty"`
-	// framgment is true if large watch response was split over multiple responses.
-	Fragment bool            `protobuf:"varint,7,opt,name=fragment,proto3" json:"fragment,omitempty"`
-	Events   []*mvccpb.Event `protobuf:"bytes,11,rep,name=events" json:"events,omitempty"`
-}
-
-func (m *WatchResponse) Reset()                    { *m = WatchResponse{} }
-func (m *WatchResponse) String() string            { return proto.CompactTextString(m) }
-func (*WatchResponse) ProtoMessage()               {}
-func (*WatchResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{24} }
-
-func (m *WatchResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *WatchResponse) GetWatchId() int64 {
-	if m != nil {
-		return m.WatchId
-	}
-	return 0
-}
-
-func (m *WatchResponse) GetCreated() bool {
-	if m != nil {
-		return m.Created
-	}
-	return false
-}
-
-func (m *WatchResponse) GetCanceled() bool {
-	if m != nil {
-		return m.Canceled
-	}
-	return false
-}
-
-func (m *WatchResponse) GetCompactRevision() int64 {
-	if m != nil {
-		return m.CompactRevision
-	}
-	return 0
-}
-
-func (m *WatchResponse) GetCancelReason() string {
-	if m != nil {
-		return m.CancelReason
-	}
-	return ""
-}
-
-func (m *WatchResponse) GetFragment() bool {
-	if m != nil {
-		return m.Fragment
-	}
-	return false
-}
-
-func (m *WatchResponse) GetEvents() []*mvccpb.Event {
-	if m != nil {
-		return m.Events
-	}
-	return nil
-}
-
-type LeaseGrantRequest struct {
-	// TTL is the advisory time-to-live in seconds. Expired lease will return -1.
-	TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"`
-	// ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID.
-	ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *LeaseGrantRequest) Reset()                    { *m = LeaseGrantRequest{} }
-func (m *LeaseGrantRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseGrantRequest) ProtoMessage()               {}
-func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{25} }
-
-func (m *LeaseGrantRequest) GetTTL() int64 {
-	if m != nil {
-		return m.TTL
-	}
-	return 0
-}
-
-func (m *LeaseGrantRequest) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type LeaseGrantResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// ID is the lease ID for the granted lease.
-	ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
-	// TTL is the server chosen lease time-to-live in seconds.
-	TTL   int64  `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"`
-	Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"`
-}
-
-func (m *LeaseGrantResponse) Reset()                    { *m = LeaseGrantResponse{} }
-func (m *LeaseGrantResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseGrantResponse) ProtoMessage()               {}
-func (*LeaseGrantResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{26} }
-
-func (m *LeaseGrantResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LeaseGrantResponse) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *LeaseGrantResponse) GetTTL() int64 {
-	if m != nil {
-		return m.TTL
-	}
-	return 0
-}
-
-func (m *LeaseGrantResponse) GetError() string {
-	if m != nil {
-		return m.Error
-	}
-	return ""
-}
-
-type LeaseRevokeRequest struct {
-	// ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted.
-	ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *LeaseRevokeRequest) Reset()                    { *m = LeaseRevokeRequest{} }
-func (m *LeaseRevokeRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseRevokeRequest) ProtoMessage()               {}
-func (*LeaseRevokeRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{27} }
-
-func (m *LeaseRevokeRequest) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type LeaseRevokeResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *LeaseRevokeResponse) Reset()                    { *m = LeaseRevokeResponse{} }
-func (m *LeaseRevokeResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseRevokeResponse) ProtoMessage()               {}
-func (*LeaseRevokeResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{28} }
-
-func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type LeaseCheckpoint struct {
-	// ID is the lease ID to checkpoint.
-	ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// Remaining_TTL is the remaining time until expiry of the lease.
-	Remaining_TTL int64 `protobuf:"varint,2,opt,name=remaining_TTL,json=remainingTTL,proto3" json:"remaining_TTL,omitempty"`
-}
-
-func (m *LeaseCheckpoint) Reset()                    { *m = LeaseCheckpoint{} }
-func (m *LeaseCheckpoint) String() string            { return proto.CompactTextString(m) }
-func (*LeaseCheckpoint) ProtoMessage()               {}
-func (*LeaseCheckpoint) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{29} }
-
-func (m *LeaseCheckpoint) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *LeaseCheckpoint) GetRemaining_TTL() int64 {
-	if m != nil {
-		return m.Remaining_TTL
-	}
-	return 0
-}
-
-type LeaseCheckpointRequest struct {
-	Checkpoints []*LeaseCheckpoint `protobuf:"bytes,1,rep,name=checkpoints" json:"checkpoints,omitempty"`
-}
-
-func (m *LeaseCheckpointRequest) Reset()                    { *m = LeaseCheckpointRequest{} }
-func (m *LeaseCheckpointRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseCheckpointRequest) ProtoMessage()               {}
-func (*LeaseCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{30} }
-
-func (m *LeaseCheckpointRequest) GetCheckpoints() []*LeaseCheckpoint {
-	if m != nil {
-		return m.Checkpoints
-	}
-	return nil
-}
-
-type LeaseCheckpointResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *LeaseCheckpointResponse) Reset()                    { *m = LeaseCheckpointResponse{} }
-func (m *LeaseCheckpointResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseCheckpointResponse) ProtoMessage()               {}
-func (*LeaseCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{31} }
-
-func (m *LeaseCheckpointResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type LeaseKeepAliveRequest struct {
-	// ID is the lease ID for the lease to keep alive.
-	ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *LeaseKeepAliveRequest) Reset()                    { *m = LeaseKeepAliveRequest{} }
-func (m *LeaseKeepAliveRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseKeepAliveRequest) ProtoMessage()               {}
-func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{32} }
-
-func (m *LeaseKeepAliveRequest) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type LeaseKeepAliveResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// ID is the lease ID from the keep alive request.
-	ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
-	// TTL is the new time-to-live for the lease.
-	TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"`
-}
-
-func (m *LeaseKeepAliveResponse) Reset()                    { *m = LeaseKeepAliveResponse{} }
-func (m *LeaseKeepAliveResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseKeepAliveResponse) ProtoMessage()               {}
-func (*LeaseKeepAliveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{33} }
-
-func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LeaseKeepAliveResponse) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *LeaseKeepAliveResponse) GetTTL() int64 {
-	if m != nil {
-		return m.TTL
-	}
-	return 0
-}
-
-type LeaseTimeToLiveRequest struct {
-	// ID is the lease ID for the lease.
-	ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// keys is true to query all the keys attached to this lease.
-	Keys bool `protobuf:"varint,2,opt,name=keys,proto3" json:"keys,omitempty"`
-}
-
-func (m *LeaseTimeToLiveRequest) Reset()                    { *m = LeaseTimeToLiveRequest{} }
-func (m *LeaseTimeToLiveRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseTimeToLiveRequest) ProtoMessage()               {}
-func (*LeaseTimeToLiveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{34} }
-
-func (m *LeaseTimeToLiveRequest) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *LeaseTimeToLiveRequest) GetKeys() bool {
-	if m != nil {
-		return m.Keys
-	}
-	return false
-}
-
-type LeaseTimeToLiveResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// ID is the lease ID from the keep alive request.
-	ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
-	// TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds.
-	TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"`
-	// GrantedTTL is the initial granted time in seconds upon lease creation/renewal.
-	GrantedTTL int64 `protobuf:"varint,4,opt,name=grantedTTL,proto3" json:"grantedTTL,omitempty"`
-	// Keys is the list of keys attached to this lease.
-	Keys [][]byte `protobuf:"bytes,5,rep,name=keys" json:"keys,omitempty"`
-}
-
-func (m *LeaseTimeToLiveResponse) Reset()                    { *m = LeaseTimeToLiveResponse{} }
-func (m *LeaseTimeToLiveResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseTimeToLiveResponse) ProtoMessage()               {}
-func (*LeaseTimeToLiveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{35} }
-
-func (m *LeaseTimeToLiveResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LeaseTimeToLiveResponse) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *LeaseTimeToLiveResponse) GetTTL() int64 {
-	if m != nil {
-		return m.TTL
-	}
-	return 0
-}
-
-func (m *LeaseTimeToLiveResponse) GetGrantedTTL() int64 {
-	if m != nil {
-		return m.GrantedTTL
-	}
-	return 0
-}
-
-func (m *LeaseTimeToLiveResponse) GetKeys() [][]byte {
-	if m != nil {
-		return m.Keys
-	}
-	return nil
-}
-
-type LeaseLeasesRequest struct {
-}
-
-func (m *LeaseLeasesRequest) Reset()                    { *m = LeaseLeasesRequest{} }
-func (m *LeaseLeasesRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseLeasesRequest) ProtoMessage()               {}
-func (*LeaseLeasesRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{36} }
-
-type LeaseStatus struct {
-	ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *LeaseStatus) Reset()                    { *m = LeaseStatus{} }
-func (m *LeaseStatus) String() string            { return proto.CompactTextString(m) }
-func (*LeaseStatus) ProtoMessage()               {}
-func (*LeaseStatus) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{37} }
-
-func (m *LeaseStatus) GetID() int64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type LeaseLeasesResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	Leases []*LeaseStatus  `protobuf:"bytes,2,rep,name=leases" json:"leases,omitempty"`
-}
-
-func (m *LeaseLeasesResponse) Reset()                    { *m = LeaseLeasesResponse{} }
-func (m *LeaseLeasesResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseLeasesResponse) ProtoMessage()               {}
-func (*LeaseLeasesResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{38} }
-
-func (m *LeaseLeasesResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *LeaseLeasesResponse) GetLeases() []*LeaseStatus {
-	if m != nil {
-		return m.Leases
-	}
-	return nil
-}
-
-type Member struct {
-	// ID is the member ID for this member.
-	ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// name is the human-readable name of the member. If the member is not started, the name will be an empty string.
-	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	// peerURLs is the list of URLs the member exposes to the cluster for communication.
-	PeerURLs []string `protobuf:"bytes,3,rep,name=peerURLs" json:"peerURLs,omitempty"`
-	// clientURLs is the list of URLs the member exposes to clients for communication. If the member is not started, clientURLs will be empty.
-	ClientURLs []string `protobuf:"bytes,4,rep,name=clientURLs" json:"clientURLs,omitempty"`
-	// isLearner indicates if the member is raft learner.
-	IsLearner bool `protobuf:"varint,5,opt,name=isLearner,proto3" json:"isLearner,omitempty"`
-}
-
-func (m *Member) Reset()                    { *m = Member{} }
-func (m *Member) String() string            { return proto.CompactTextString(m) }
-func (*Member) ProtoMessage()               {}
-func (*Member) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{39} }
-
-func (m *Member) GetID() uint64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *Member) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *Member) GetPeerURLs() []string {
-	if m != nil {
-		return m.PeerURLs
-	}
-	return nil
-}
-
-func (m *Member) GetClientURLs() []string {
-	if m != nil {
-		return m.ClientURLs
-	}
-	return nil
-}
-
-func (m *Member) GetIsLearner() bool {
-	if m != nil {
-		return m.IsLearner
-	}
-	return false
-}
-
-type MemberAddRequest struct {
-	// peerURLs is the list of URLs the added member will use to communicate with the cluster.
-	PeerURLs []string `protobuf:"bytes,1,rep,name=peerURLs" json:"peerURLs,omitempty"`
-	// isLearner indicates if the added member is raft learner.
-	IsLearner bool `protobuf:"varint,2,opt,name=isLearner,proto3" json:"isLearner,omitempty"`
-}
-
-func (m *MemberAddRequest) Reset()                    { *m = MemberAddRequest{} }
-func (m *MemberAddRequest) String() string            { return proto.CompactTextString(m) }
-func (*MemberAddRequest) ProtoMessage()               {}
-func (*MemberAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{40} }
-
-func (m *MemberAddRequest) GetPeerURLs() []string {
-	if m != nil {
-		return m.PeerURLs
-	}
-	return nil
-}
-
-func (m *MemberAddRequest) GetIsLearner() bool {
-	if m != nil {
-		return m.IsLearner
-	}
-	return false
-}
-
-type MemberAddResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// member is the member information for the added member.
-	Member *Member `protobuf:"bytes,2,opt,name=member" json:"member,omitempty"`
-	// members is a list of all members after adding the new member.
-	Members []*Member `protobuf:"bytes,3,rep,name=members" json:"members,omitempty"`
-}
-
-func (m *MemberAddResponse) Reset()                    { *m = MemberAddResponse{} }
-func (m *MemberAddResponse) String() string            { return proto.CompactTextString(m) }
-func (*MemberAddResponse) ProtoMessage()               {}
-func (*MemberAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{41} }
-
-func (m *MemberAddResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *MemberAddResponse) GetMember() *Member {
-	if m != nil {
-		return m.Member
-	}
-	return nil
-}
-
-func (m *MemberAddResponse) GetMembers() []*Member {
-	if m != nil {
-		return m.Members
-	}
-	return nil
-}
-
-type MemberRemoveRequest struct {
-	// ID is the member ID of the member to remove.
-	ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *MemberRemoveRequest) Reset()                    { *m = MemberRemoveRequest{} }
-func (m *MemberRemoveRequest) String() string            { return proto.CompactTextString(m) }
-func (*MemberRemoveRequest) ProtoMessage()               {}
-func (*MemberRemoveRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{42} }
-
-func (m *MemberRemoveRequest) GetID() uint64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type MemberRemoveResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// members is a list of all members after removing the member.
-	Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"`
-}
-
-func (m *MemberRemoveResponse) Reset()                    { *m = MemberRemoveResponse{} }
-func (m *MemberRemoveResponse) String() string            { return proto.CompactTextString(m) }
-func (*MemberRemoveResponse) ProtoMessage()               {}
-func (*MemberRemoveResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{43} }
-
-func (m *MemberRemoveResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *MemberRemoveResponse) GetMembers() []*Member {
-	if m != nil {
-		return m.Members
-	}
-	return nil
-}
-
-type MemberUpdateRequest struct {
-	// ID is the member ID of the member to update.
-	ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	// peerURLs is the new list of URLs the member will use to communicate with the cluster.
-	PeerURLs []string `protobuf:"bytes,2,rep,name=peerURLs" json:"peerURLs,omitempty"`
-}
-
-func (m *MemberUpdateRequest) Reset()                    { *m = MemberUpdateRequest{} }
-func (m *MemberUpdateRequest) String() string            { return proto.CompactTextString(m) }
-func (*MemberUpdateRequest) ProtoMessage()               {}
-func (*MemberUpdateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{44} }
-
-func (m *MemberUpdateRequest) GetID() uint64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-func (m *MemberUpdateRequest) GetPeerURLs() []string {
-	if m != nil {
-		return m.PeerURLs
-	}
-	return nil
-}
-
-type MemberUpdateResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// members is a list of all members after updating the member.
-	Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"`
-}
-
-func (m *MemberUpdateResponse) Reset()                    { *m = MemberUpdateResponse{} }
-func (m *MemberUpdateResponse) String() string            { return proto.CompactTextString(m) }
-func (*MemberUpdateResponse) ProtoMessage()               {}
-func (*MemberUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{45} }
-
-func (m *MemberUpdateResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *MemberUpdateResponse) GetMembers() []*Member {
-	if m != nil {
-		return m.Members
-	}
-	return nil
-}
-
-type MemberListRequest struct {
-}
-
-func (m *MemberListRequest) Reset()                    { *m = MemberListRequest{} }
-func (m *MemberListRequest) String() string            { return proto.CompactTextString(m) }
-func (*MemberListRequest) ProtoMessage()               {}
-func (*MemberListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{46} }
-
-type MemberListResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// members is a list of all members associated with the cluster.
-	Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"`
-}
-
-func (m *MemberListResponse) Reset()                    { *m = MemberListResponse{} }
-func (m *MemberListResponse) String() string            { return proto.CompactTextString(m) }
-func (*MemberListResponse) ProtoMessage()               {}
-func (*MemberListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{47} }
-
-func (m *MemberListResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *MemberListResponse) GetMembers() []*Member {
-	if m != nil {
-		return m.Members
-	}
-	return nil
-}
-
-type MemberPromoteRequest struct {
-	// ID is the member ID of the member to promote.
-	ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-}
-
-func (m *MemberPromoteRequest) Reset()                    { *m = MemberPromoteRequest{} }
-func (m *MemberPromoteRequest) String() string            { return proto.CompactTextString(m) }
-func (*MemberPromoteRequest) ProtoMessage()               {}
-func (*MemberPromoteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{48} }
-
-func (m *MemberPromoteRequest) GetID() uint64 {
-	if m != nil {
-		return m.ID
-	}
-	return 0
-}
-
-type MemberPromoteResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// members is a list of all members after promoting the member.
-	Members []*Member `protobuf:"bytes,2,rep,name=members" json:"members,omitempty"`
-}
-
-func (m *MemberPromoteResponse) Reset()                    { *m = MemberPromoteResponse{} }
-func (m *MemberPromoteResponse) String() string            { return proto.CompactTextString(m) }
-func (*MemberPromoteResponse) ProtoMessage()               {}
-func (*MemberPromoteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{49} }
-
-func (m *MemberPromoteResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *MemberPromoteResponse) GetMembers() []*Member {
-	if m != nil {
-		return m.Members
-	}
-	return nil
-}
-
-type DefragmentRequest struct {
-}
-
-func (m *DefragmentRequest) Reset()                    { *m = DefragmentRequest{} }
-func (m *DefragmentRequest) String() string            { return proto.CompactTextString(m) }
-func (*DefragmentRequest) ProtoMessage()               {}
-func (*DefragmentRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{50} }
-
-type DefragmentResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *DefragmentResponse) Reset()                    { *m = DefragmentResponse{} }
-func (m *DefragmentResponse) String() string            { return proto.CompactTextString(m) }
-func (*DefragmentResponse) ProtoMessage()               {}
-func (*DefragmentResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{51} }
-
-func (m *DefragmentResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type MoveLeaderRequest struct {
-	// targetID is the node ID for the new leader.
-	TargetID uint64 `protobuf:"varint,1,opt,name=targetID,proto3" json:"targetID,omitempty"`
-}
-
-func (m *MoveLeaderRequest) Reset()                    { *m = MoveLeaderRequest{} }
-func (m *MoveLeaderRequest) String() string            { return proto.CompactTextString(m) }
-func (*MoveLeaderRequest) ProtoMessage()               {}
-func (*MoveLeaderRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{52} }
-
-func (m *MoveLeaderRequest) GetTargetID() uint64 {
-	if m != nil {
-		return m.TargetID
-	}
-	return 0
-}
-
-type MoveLeaderResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *MoveLeaderResponse) Reset()                    { *m = MoveLeaderResponse{} }
-func (m *MoveLeaderResponse) String() string            { return proto.CompactTextString(m) }
-func (*MoveLeaderResponse) ProtoMessage()               {}
-func (*MoveLeaderResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{53} }
-
-func (m *MoveLeaderResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AlarmRequest struct {
-	// action is the kind of alarm request to issue. The action
-	// may GET alarm statuses, ACTIVATE an alarm, or DEACTIVATE a
-	// raised alarm.
-	Action AlarmRequest_AlarmAction `protobuf:"varint,1,opt,name=action,proto3,enum=etcdserverpb.AlarmRequest_AlarmAction" json:"action,omitempty"`
-	// memberID is the ID of the member associated with the alarm. If memberID is 0, the
-	// alarm request covers all members.
-	MemberID uint64 `protobuf:"varint,2,opt,name=memberID,proto3" json:"memberID,omitempty"`
-	// alarm is the type of alarm to consider for this request.
-	Alarm AlarmType `protobuf:"varint,3,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"`
-}
-
-func (m *AlarmRequest) Reset()                    { *m = AlarmRequest{} }
-func (m *AlarmRequest) String() string            { return proto.CompactTextString(m) }
-func (*AlarmRequest) ProtoMessage()               {}
-func (*AlarmRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{54} }
-
-func (m *AlarmRequest) GetAction() AlarmRequest_AlarmAction {
-	if m != nil {
-		return m.Action
-	}
-	return AlarmRequest_GET
-}
-
-func (m *AlarmRequest) GetMemberID() uint64 {
-	if m != nil {
-		return m.MemberID
-	}
-	return 0
-}
-
-func (m *AlarmRequest) GetAlarm() AlarmType {
-	if m != nil {
-		return m.Alarm
-	}
-	return AlarmType_NONE
-}
-
-type AlarmMember struct {
-	// memberID is the ID of the member associated with the raised alarm.
-	MemberID uint64 `protobuf:"varint,1,opt,name=memberID,proto3" json:"memberID,omitempty"`
-	// alarm is the type of alarm which has been raised.
-	Alarm AlarmType `protobuf:"varint,2,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"`
-}
-
-func (m *AlarmMember) Reset()                    { *m = AlarmMember{} }
-func (m *AlarmMember) String() string            { return proto.CompactTextString(m) }
-func (*AlarmMember) ProtoMessage()               {}
-func (*AlarmMember) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{55} }
-
-func (m *AlarmMember) GetMemberID() uint64 {
-	if m != nil {
-		return m.MemberID
-	}
-	return 0
-}
-
-func (m *AlarmMember) GetAlarm() AlarmType {
-	if m != nil {
-		return m.Alarm
-	}
-	return AlarmType_NONE
-}
-
-type AlarmResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// alarms is a list of alarms associated with the alarm request.
-	Alarms []*AlarmMember `protobuf:"bytes,2,rep,name=alarms" json:"alarms,omitempty"`
-}
-
-func (m *AlarmResponse) Reset()                    { *m = AlarmResponse{} }
-func (m *AlarmResponse) String() string            { return proto.CompactTextString(m) }
-func (*AlarmResponse) ProtoMessage()               {}
-func (*AlarmResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{56} }
-
-func (m *AlarmResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AlarmResponse) GetAlarms() []*AlarmMember {
-	if m != nil {
-		return m.Alarms
-	}
-	return nil
-}
-
-type StatusRequest struct {
-}
-
-func (m *StatusRequest) Reset()                    { *m = StatusRequest{} }
-func (m *StatusRequest) String() string            { return proto.CompactTextString(m) }
-func (*StatusRequest) ProtoMessage()               {}
-func (*StatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{57} }
-
-type StatusResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// version is the cluster protocol version used by the responding member.
-	Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
-	// dbSize is the size of the backend database physically allocated, in bytes, of the responding member.
-	DbSize int64 `protobuf:"varint,3,opt,name=dbSize,proto3" json:"dbSize,omitempty"`
-	// leader is the member ID which the responding member believes is the current leader.
-	Leader uint64 `protobuf:"varint,4,opt,name=leader,proto3" json:"leader,omitempty"`
-	// raftIndex is the current raft committed index of the responding member.
-	RaftIndex uint64 `protobuf:"varint,5,opt,name=raftIndex,proto3" json:"raftIndex,omitempty"`
-	// raftTerm is the current raft term of the responding member.
-	RaftTerm uint64 `protobuf:"varint,6,opt,name=raftTerm,proto3" json:"raftTerm,omitempty"`
-	// raftAppliedIndex is the current raft applied index of the responding member.
-	RaftAppliedIndex uint64 `protobuf:"varint,7,opt,name=raftAppliedIndex,proto3" json:"raftAppliedIndex,omitempty"`
-	// errors contains alarm/health information and status.
-	Errors []string `protobuf:"bytes,8,rep,name=errors" json:"errors,omitempty"`
-	// dbSizeInUse is the size of the backend database logically in use, in bytes, of the responding member.
-	DbSizeInUse int64 `protobuf:"varint,9,opt,name=dbSizeInUse,proto3" json:"dbSizeInUse,omitempty"`
-	// isLearner indicates if the member is raft learner.
-	IsLearner bool `protobuf:"varint,10,opt,name=isLearner,proto3" json:"isLearner,omitempty"`
-}
-
-func (m *StatusResponse) Reset()                    { *m = StatusResponse{} }
-func (m *StatusResponse) String() string            { return proto.CompactTextString(m) }
-func (*StatusResponse) ProtoMessage()               {}
-func (*StatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{58} }
-
-func (m *StatusResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *StatusResponse) GetVersion() string {
-	if m != nil {
-		return m.Version
-	}
-	return ""
-}
-
-func (m *StatusResponse) GetDbSize() int64 {
-	if m != nil {
-		return m.DbSize
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetLeader() uint64 {
-	if m != nil {
-		return m.Leader
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetRaftIndex() uint64 {
-	if m != nil {
-		return m.RaftIndex
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetRaftTerm() uint64 {
-	if m != nil {
-		return m.RaftTerm
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetRaftAppliedIndex() uint64 {
-	if m != nil {
-		return m.RaftAppliedIndex
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetErrors() []string {
-	if m != nil {
-		return m.Errors
-	}
-	return nil
-}
-
-func (m *StatusResponse) GetDbSizeInUse() int64 {
-	if m != nil {
-		return m.DbSizeInUse
-	}
-	return 0
-}
-
-func (m *StatusResponse) GetIsLearner() bool {
-	if m != nil {
-		return m.IsLearner
-	}
-	return false
-}
-
-type AuthEnableRequest struct {
-}
-
-func (m *AuthEnableRequest) Reset()                    { *m = AuthEnableRequest{} }
-func (m *AuthEnableRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthEnableRequest) ProtoMessage()               {}
-func (*AuthEnableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{59} }
-
-type AuthDisableRequest struct {
-}
-
-func (m *AuthDisableRequest) Reset()                    { *m = AuthDisableRequest{} }
-func (m *AuthDisableRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthDisableRequest) ProtoMessage()               {}
-func (*AuthDisableRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{60} }
-
-type AuthenticateRequest struct {
-	Name     string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
-}
-
-func (m *AuthenticateRequest) Reset()                    { *m = AuthenticateRequest{} }
-func (m *AuthenticateRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthenticateRequest) ProtoMessage()               {}
-func (*AuthenticateRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{61} }
-
-func (m *AuthenticateRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *AuthenticateRequest) GetPassword() string {
-	if m != nil {
-		return m.Password
-	}
-	return ""
-}
-
-type AuthUserAddRequest struct {
-	Name     string                 `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Password string                 `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
-	Options  *authpb.UserAddOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"`
-}
-
-func (m *AuthUserAddRequest) Reset()                    { *m = AuthUserAddRequest{} }
-func (m *AuthUserAddRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserAddRequest) ProtoMessage()               {}
-func (*AuthUserAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{62} }
-
-func (m *AuthUserAddRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *AuthUserAddRequest) GetPassword() string {
-	if m != nil {
-		return m.Password
-	}
-	return ""
-}
-
-func (m *AuthUserAddRequest) GetOptions() *authpb.UserAddOptions {
-	if m != nil {
-		return m.Options
-	}
-	return nil
-}
-
-type AuthUserGetRequest struct {
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-}
-
-func (m *AuthUserGetRequest) Reset()                    { *m = AuthUserGetRequest{} }
-func (m *AuthUserGetRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserGetRequest) ProtoMessage()               {}
-func (*AuthUserGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{63} }
-
-func (m *AuthUserGetRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-type AuthUserDeleteRequest struct {
-	// name is the name of the user to delete.
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-}
-
-func (m *AuthUserDeleteRequest) Reset()                    { *m = AuthUserDeleteRequest{} }
-func (m *AuthUserDeleteRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserDeleteRequest) ProtoMessage()               {}
-func (*AuthUserDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{64} }
-
-func (m *AuthUserDeleteRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-type AuthUserChangePasswordRequest struct {
-	// name is the name of the user whose password is being changed.
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// password is the new password for the user.
-	Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
-}
-
-func (m *AuthUserChangePasswordRequest) Reset()         { *m = AuthUserChangePasswordRequest{} }
-func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) }
-func (*AuthUserChangePasswordRequest) ProtoMessage()    {}
-func (*AuthUserChangePasswordRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{65}
-}
-
-func (m *AuthUserChangePasswordRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *AuthUserChangePasswordRequest) GetPassword() string {
-	if m != nil {
-		return m.Password
-	}
-	return ""
-}
-
-type AuthUserGrantRoleRequest struct {
-	// user is the name of the user which should be granted a given role.
-	User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
-	// role is the name of the role to grant to the user.
-	Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"`
-}
-
-func (m *AuthUserGrantRoleRequest) Reset()                    { *m = AuthUserGrantRoleRequest{} }
-func (m *AuthUserGrantRoleRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserGrantRoleRequest) ProtoMessage()               {}
-func (*AuthUserGrantRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{66} }
-
-func (m *AuthUserGrantRoleRequest) GetUser() string {
-	if m != nil {
-		return m.User
-	}
-	return ""
-}
-
-func (m *AuthUserGrantRoleRequest) GetRole() string {
-	if m != nil {
-		return m.Role
-	}
-	return ""
-}
-
-type AuthUserRevokeRoleRequest struct {
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"`
-}
-
-func (m *AuthUserRevokeRoleRequest) Reset()                    { *m = AuthUserRevokeRoleRequest{} }
-func (m *AuthUserRevokeRoleRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserRevokeRoleRequest) ProtoMessage()               {}
-func (*AuthUserRevokeRoleRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{67} }
-
-func (m *AuthUserRevokeRoleRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *AuthUserRevokeRoleRequest) GetRole() string {
-	if m != nil {
-		return m.Role
-	}
-	return ""
-}
-
-type AuthRoleAddRequest struct {
-	// name is the name of the role to add to the authentication system.
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-}
-
-func (m *AuthRoleAddRequest) Reset()                    { *m = AuthRoleAddRequest{} }
-func (m *AuthRoleAddRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleAddRequest) ProtoMessage()               {}
-func (*AuthRoleAddRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{68} }
-
-func (m *AuthRoleAddRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-type AuthRoleGetRequest struct {
-	Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
-}
-
-func (m *AuthRoleGetRequest) Reset()                    { *m = AuthRoleGetRequest{} }
-func (m *AuthRoleGetRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleGetRequest) ProtoMessage()               {}
-func (*AuthRoleGetRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{69} }
-
-func (m *AuthRoleGetRequest) GetRole() string {
-	if m != nil {
-		return m.Role
-	}
-	return ""
-}
-
-type AuthUserListRequest struct {
-}
-
-func (m *AuthUserListRequest) Reset()                    { *m = AuthUserListRequest{} }
-func (m *AuthUserListRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserListRequest) ProtoMessage()               {}
-func (*AuthUserListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{70} }
-
-type AuthRoleListRequest struct {
-}
-
-func (m *AuthRoleListRequest) Reset()                    { *m = AuthRoleListRequest{} }
-func (m *AuthRoleListRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleListRequest) ProtoMessage()               {}
-func (*AuthRoleListRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{71} }
-
-type AuthRoleDeleteRequest struct {
-	Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
-}
-
-func (m *AuthRoleDeleteRequest) Reset()                    { *m = AuthRoleDeleteRequest{} }
-func (m *AuthRoleDeleteRequest) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleDeleteRequest) ProtoMessage()               {}
-func (*AuthRoleDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{72} }
-
-func (m *AuthRoleDeleteRequest) GetRole() string {
-	if m != nil {
-		return m.Role
-	}
-	return ""
-}
-
-type AuthRoleGrantPermissionRequest struct {
-	// name is the name of the role which will be granted the permission.
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// perm is the permission to grant to the role.
-	Perm *authpb.Permission `protobuf:"bytes,2,opt,name=perm" json:"perm,omitempty"`
-}
-
-func (m *AuthRoleGrantPermissionRequest) Reset()         { *m = AuthRoleGrantPermissionRequest{} }
-func (m *AuthRoleGrantPermissionRequest) String() string { return proto.CompactTextString(m) }
-func (*AuthRoleGrantPermissionRequest) ProtoMessage()    {}
-func (*AuthRoleGrantPermissionRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{73}
-}
-
-func (m *AuthRoleGrantPermissionRequest) GetName() string {
-	if m != nil {
-		return m.Name
-	}
-	return ""
-}
-
-func (m *AuthRoleGrantPermissionRequest) GetPerm() *authpb.Permission {
-	if m != nil {
-		return m.Perm
-	}
-	return nil
-}
-
-type AuthRoleRevokePermissionRequest struct {
-	Role     string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
-	Key      []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-	RangeEnd []byte `protobuf:"bytes,3,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
-}
-
-func (m *AuthRoleRevokePermissionRequest) Reset()         { *m = AuthRoleRevokePermissionRequest{} }
-func (m *AuthRoleRevokePermissionRequest) String() string { return proto.CompactTextString(m) }
-func (*AuthRoleRevokePermissionRequest) ProtoMessage()    {}
-func (*AuthRoleRevokePermissionRequest) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{74}
-}
-
-func (m *AuthRoleRevokePermissionRequest) GetRole() string {
-	if m != nil {
-		return m.Role
-	}
-	return ""
-}
-
-func (m *AuthRoleRevokePermissionRequest) GetKey() []byte {
-	if m != nil {
-		return m.Key
-	}
-	return nil
-}
-
-func (m *AuthRoleRevokePermissionRequest) GetRangeEnd() []byte {
-	if m != nil {
-		return m.RangeEnd
-	}
-	return nil
-}
-
-type AuthEnableResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthEnableResponse) Reset()                    { *m = AuthEnableResponse{} }
-func (m *AuthEnableResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthEnableResponse) ProtoMessage()               {}
-func (*AuthEnableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{75} }
-
-func (m *AuthEnableResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthDisableResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthDisableResponse) Reset()                    { *m = AuthDisableResponse{} }
-func (m *AuthDisableResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthDisableResponse) ProtoMessage()               {}
-func (*AuthDisableResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{76} }
-
-func (m *AuthDisableResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthenticateResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	// token is an authorized token that can be used in succeeding RPCs
-	Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
-}
-
-func (m *AuthenticateResponse) Reset()                    { *m = AuthenticateResponse{} }
-func (m *AuthenticateResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthenticateResponse) ProtoMessage()               {}
-func (*AuthenticateResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{77} }
-
-func (m *AuthenticateResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AuthenticateResponse) GetToken() string {
-	if m != nil {
-		return m.Token
-	}
-	return ""
-}
-
-type AuthUserAddResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthUserAddResponse) Reset()                    { *m = AuthUserAddResponse{} }
-func (m *AuthUserAddResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserAddResponse) ProtoMessage()               {}
-func (*AuthUserAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{78} }
-
-func (m *AuthUserAddResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthUserGetResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	Roles  []string        `protobuf:"bytes,2,rep,name=roles" json:"roles,omitempty"`
-}
-
-func (m *AuthUserGetResponse) Reset()                    { *m = AuthUserGetResponse{} }
-func (m *AuthUserGetResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserGetResponse) ProtoMessage()               {}
-func (*AuthUserGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{79} }
-
-func (m *AuthUserGetResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AuthUserGetResponse) GetRoles() []string {
-	if m != nil {
-		return m.Roles
-	}
-	return nil
-}
-
-type AuthUserDeleteResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthUserDeleteResponse) Reset()                    { *m = AuthUserDeleteResponse{} }
-func (m *AuthUserDeleteResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserDeleteResponse) ProtoMessage()               {}
-func (*AuthUserDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{80} }
-
-func (m *AuthUserDeleteResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthUserChangePasswordResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthUserChangePasswordResponse) Reset()         { *m = AuthUserChangePasswordResponse{} }
-func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) }
-func (*AuthUserChangePasswordResponse) ProtoMessage()    {}
-func (*AuthUserChangePasswordResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{81}
-}
-
-func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthUserGrantRoleResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthUserGrantRoleResponse) Reset()                    { *m = AuthUserGrantRoleResponse{} }
-func (m *AuthUserGrantRoleResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserGrantRoleResponse) ProtoMessage()               {}
-func (*AuthUserGrantRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{82} }
-
-func (m *AuthUserGrantRoleResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthUserRevokeRoleResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthUserRevokeRoleResponse) Reset()                    { *m = AuthUserRevokeRoleResponse{} }
-func (m *AuthUserRevokeRoleResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserRevokeRoleResponse) ProtoMessage()               {}
-func (*AuthUserRevokeRoleResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{83} }
-
-func (m *AuthUserRevokeRoleResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthRoleAddResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthRoleAddResponse) Reset()                    { *m = AuthRoleAddResponse{} }
-func (m *AuthRoleAddResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleAddResponse) ProtoMessage()               {}
-func (*AuthRoleAddResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{84} }
-
-func (m *AuthRoleAddResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthRoleGetResponse struct {
-	Header *ResponseHeader      `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	Perm   []*authpb.Permission `protobuf:"bytes,2,rep,name=perm" json:"perm,omitempty"`
-}
-
-func (m *AuthRoleGetResponse) Reset()                    { *m = AuthRoleGetResponse{} }
-func (m *AuthRoleGetResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleGetResponse) ProtoMessage()               {}
-func (*AuthRoleGetResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{85} }
-
-func (m *AuthRoleGetResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AuthRoleGetResponse) GetPerm() []*authpb.Permission {
-	if m != nil {
-		return m.Perm
-	}
-	return nil
-}
-
-type AuthRoleListResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	Roles  []string        `protobuf:"bytes,2,rep,name=roles" json:"roles,omitempty"`
-}
-
-func (m *AuthRoleListResponse) Reset()                    { *m = AuthRoleListResponse{} }
-func (m *AuthRoleListResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleListResponse) ProtoMessage()               {}
-func (*AuthRoleListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{86} }
-
-func (m *AuthRoleListResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AuthRoleListResponse) GetRoles() []string {
-	if m != nil {
-		return m.Roles
-	}
-	return nil
-}
-
-type AuthUserListResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-	Users  []string        `protobuf:"bytes,2,rep,name=users" json:"users,omitempty"`
-}
-
-func (m *AuthUserListResponse) Reset()                    { *m = AuthUserListResponse{} }
-func (m *AuthUserListResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthUserListResponse) ProtoMessage()               {}
-func (*AuthUserListResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{87} }
-
-func (m *AuthUserListResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func (m *AuthUserListResponse) GetUsers() []string {
-	if m != nil {
-		return m.Users
-	}
-	return nil
-}
-
-type AuthRoleDeleteResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthRoleDeleteResponse) Reset()                    { *m = AuthRoleDeleteResponse{} }
-func (m *AuthRoleDeleteResponse) String() string            { return proto.CompactTextString(m) }
-func (*AuthRoleDeleteResponse) ProtoMessage()               {}
-func (*AuthRoleDeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpc, []int{88} }
-
-func (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthRoleGrantPermissionResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthRoleGrantPermissionResponse) Reset()         { *m = AuthRoleGrantPermissionResponse{} }
-func (m *AuthRoleGrantPermissionResponse) String() string { return proto.CompactTextString(m) }
-func (*AuthRoleGrantPermissionResponse) ProtoMessage()    {}
-func (*AuthRoleGrantPermissionResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{89}
-}
-
-func (m *AuthRoleGrantPermissionResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-type AuthRoleRevokePermissionResponse struct {
-	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
-}
-
-func (m *AuthRoleRevokePermissionResponse) Reset()         { *m = AuthRoleRevokePermissionResponse{} }
-func (m *AuthRoleRevokePermissionResponse) String() string { return proto.CompactTextString(m) }
-func (*AuthRoleRevokePermissionResponse) ProtoMessage()    {}
-func (*AuthRoleRevokePermissionResponse) Descriptor() ([]byte, []int) {
-	return fileDescriptorRpc, []int{90}
-}
-
-func (m *AuthRoleRevokePermissionResponse) GetHeader() *ResponseHeader {
-	if m != nil {
-		return m.Header
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*ResponseHeader)(nil), "etcdserverpb.ResponseHeader")
-	proto.RegisterType((*RangeRequest)(nil), "etcdserverpb.RangeRequest")
-	proto.RegisterType((*RangeResponse)(nil), "etcdserverpb.RangeResponse")
-	proto.RegisterType((*PutRequest)(nil), "etcdserverpb.PutRequest")
-	proto.RegisterType((*PutResponse)(nil), "etcdserverpb.PutResponse")
-	proto.RegisterType((*DeleteRangeRequest)(nil), "etcdserverpb.DeleteRangeRequest")
-	proto.RegisterType((*DeleteRangeResponse)(nil), "etcdserverpb.DeleteRangeResponse")
-	proto.RegisterType((*RequestOp)(nil), "etcdserverpb.RequestOp")
-	proto.RegisterType((*ResponseOp)(nil), "etcdserverpb.ResponseOp")
-	proto.RegisterType((*Compare)(nil), "etcdserverpb.Compare")
-	proto.RegisterType((*TxnRequest)(nil), "etcdserverpb.TxnRequest")
-	proto.RegisterType((*TxnResponse)(nil), "etcdserverpb.TxnResponse")
-	proto.RegisterType((*CompactionRequest)(nil), "etcdserverpb.CompactionRequest")
-	proto.RegisterType((*CompactionResponse)(nil), "etcdserverpb.CompactionResponse")
-	proto.RegisterType((*HashRequest)(nil), "etcdserverpb.HashRequest")
-	proto.RegisterType((*HashKVRequest)(nil), "etcdserverpb.HashKVRequest")
-	proto.RegisterType((*HashKVResponse)(nil), "etcdserverpb.HashKVResponse")
-	proto.RegisterType((*HashResponse)(nil), "etcdserverpb.HashResponse")
-	proto.RegisterType((*SnapshotRequest)(nil), "etcdserverpb.SnapshotRequest")
-	proto.RegisterType((*SnapshotResponse)(nil), "etcdserverpb.SnapshotResponse")
-	proto.RegisterType((*WatchRequest)(nil), "etcdserverpb.WatchRequest")
-	proto.RegisterType((*WatchCreateRequest)(nil), "etcdserverpb.WatchCreateRequest")
-	proto.RegisterType((*WatchCancelRequest)(nil), "etcdserverpb.WatchCancelRequest")
-	proto.RegisterType((*WatchProgressRequest)(nil), "etcdserverpb.WatchProgressRequest")
-	proto.RegisterType((*WatchResponse)(nil), "etcdserverpb.WatchResponse")
-	proto.RegisterType((*LeaseGrantRequest)(nil), "etcdserverpb.LeaseGrantRequest")
-	proto.RegisterType((*LeaseGrantResponse)(nil), "etcdserverpb.LeaseGrantResponse")
-	proto.RegisterType((*LeaseRevokeRequest)(nil), "etcdserverpb.LeaseRevokeRequest")
-	proto.RegisterType((*LeaseRevokeResponse)(nil), "etcdserverpb.LeaseRevokeResponse")
-	proto.RegisterType((*LeaseCheckpoint)(nil), "etcdserverpb.LeaseCheckpoint")
-	proto.RegisterType((*LeaseCheckpointRequest)(nil), "etcdserverpb.LeaseCheckpointRequest")
-	proto.RegisterType((*LeaseCheckpointResponse)(nil), "etcdserverpb.LeaseCheckpointResponse")
-	proto.RegisterType((*LeaseKeepAliveRequest)(nil), "etcdserverpb.LeaseKeepAliveRequest")
-	proto.RegisterType((*LeaseKeepAliveResponse)(nil), "etcdserverpb.LeaseKeepAliveResponse")
-	proto.RegisterType((*LeaseTimeToLiveRequest)(nil), "etcdserverpb.LeaseTimeToLiveRequest")
-	proto.RegisterType((*LeaseTimeToLiveResponse)(nil), "etcdserverpb.LeaseTimeToLiveResponse")
-	proto.RegisterType((*LeaseLeasesRequest)(nil), "etcdserverpb.LeaseLeasesRequest")
-	proto.RegisterType((*LeaseStatus)(nil), "etcdserverpb.LeaseStatus")
-	proto.RegisterType((*LeaseLeasesResponse)(nil), "etcdserverpb.LeaseLeasesResponse")
-	proto.RegisterType((*Member)(nil), "etcdserverpb.Member")
-	proto.RegisterType((*MemberAddRequest)(nil), "etcdserverpb.MemberAddRequest")
-	proto.RegisterType((*MemberAddResponse)(nil), "etcdserverpb.MemberAddResponse")
-	proto.RegisterType((*MemberRemoveRequest)(nil), "etcdserverpb.MemberRemoveRequest")
-	proto.RegisterType((*MemberRemoveResponse)(nil), "etcdserverpb.MemberRemoveResponse")
-	proto.RegisterType((*MemberUpdateRequest)(nil), "etcdserverpb.MemberUpdateRequest")
-	proto.RegisterType((*MemberUpdateResponse)(nil), "etcdserverpb.MemberUpdateResponse")
-	proto.RegisterType((*MemberListRequest)(nil), "etcdserverpb.MemberListRequest")
-	proto.RegisterType((*MemberListResponse)(nil), "etcdserverpb.MemberListResponse")
-	proto.RegisterType((*MemberPromoteRequest)(nil), "etcdserverpb.MemberPromoteRequest")
-	proto.RegisterType((*MemberPromoteResponse)(nil), "etcdserverpb.MemberPromoteResponse")
-	proto.RegisterType((*DefragmentRequest)(nil), "etcdserverpb.DefragmentRequest")
-	proto.RegisterType((*DefragmentResponse)(nil), "etcdserverpb.DefragmentResponse")
-	proto.RegisterType((*MoveLeaderRequest)(nil), "etcdserverpb.MoveLeaderRequest")
-	proto.RegisterType((*MoveLeaderResponse)(nil), "etcdserverpb.MoveLeaderResponse")
-	proto.RegisterType((*AlarmRequest)(nil), "etcdserverpb.AlarmRequest")
-	proto.RegisterType((*AlarmMember)(nil), "etcdserverpb.AlarmMember")
-	proto.RegisterType((*AlarmResponse)(nil), "etcdserverpb.AlarmResponse")
-	proto.RegisterType((*StatusRequest)(nil), "etcdserverpb.StatusRequest")
-	proto.RegisterType((*StatusResponse)(nil), "etcdserverpb.StatusResponse")
-	proto.RegisterType((*AuthEnableRequest)(nil), "etcdserverpb.AuthEnableRequest")
-	proto.RegisterType((*AuthDisableRequest)(nil), "etcdserverpb.AuthDisableRequest")
-	proto.RegisterType((*AuthenticateRequest)(nil), "etcdserverpb.AuthenticateRequest")
-	proto.RegisterType((*AuthUserAddRequest)(nil), "etcdserverpb.AuthUserAddRequest")
-	proto.RegisterType((*AuthUserGetRequest)(nil), "etcdserverpb.AuthUserGetRequest")
-	proto.RegisterType((*AuthUserDeleteRequest)(nil), "etcdserverpb.AuthUserDeleteRequest")
-	proto.RegisterType((*AuthUserChangePasswordRequest)(nil), "etcdserverpb.AuthUserChangePasswordRequest")
-	proto.RegisterType((*AuthUserGrantRoleRequest)(nil), "etcdserverpb.AuthUserGrantRoleRequest")
-	proto.RegisterType((*AuthUserRevokeRoleRequest)(nil), "etcdserverpb.AuthUserRevokeRoleRequest")
-	proto.RegisterType((*AuthRoleAddRequest)(nil), "etcdserverpb.AuthRoleAddRequest")
-	proto.RegisterType((*AuthRoleGetRequest)(nil), "etcdserverpb.AuthRoleGetRequest")
-	proto.RegisterType((*AuthUserListRequest)(nil), "etcdserverpb.AuthUserListRequest")
-	proto.RegisterType((*AuthRoleListRequest)(nil), "etcdserverpb.AuthRoleListRequest")
-	proto.RegisterType((*AuthRoleDeleteRequest)(nil), "etcdserverpb.AuthRoleDeleteRequest")
-	proto.RegisterType((*AuthRoleGrantPermissionRequest)(nil), "etcdserverpb.AuthRoleGrantPermissionRequest")
-	proto.RegisterType((*AuthRoleRevokePermissionRequest)(nil), "etcdserverpb.AuthRoleRevokePermissionRequest")
-	proto.RegisterType((*AuthEnableResponse)(nil), "etcdserverpb.AuthEnableResponse")
-	proto.RegisterType((*AuthDisableResponse)(nil), "etcdserverpb.AuthDisableResponse")
-	proto.RegisterType((*AuthenticateResponse)(nil), "etcdserverpb.AuthenticateResponse")
-	proto.RegisterType((*AuthUserAddResponse)(nil), "etcdserverpb.AuthUserAddResponse")
-	proto.RegisterType((*AuthUserGetResponse)(nil), "etcdserverpb.AuthUserGetResponse")
-	proto.RegisterType((*AuthUserDeleteResponse)(nil), "etcdserverpb.AuthUserDeleteResponse")
-	proto.RegisterType((*AuthUserChangePasswordResponse)(nil), "etcdserverpb.AuthUserChangePasswordResponse")
-	proto.RegisterType((*AuthUserGrantRoleResponse)(nil), "etcdserverpb.AuthUserGrantRoleResponse")
-	proto.RegisterType((*AuthUserRevokeRoleResponse)(nil), "etcdserverpb.AuthUserRevokeRoleResponse")
-	proto.RegisterType((*AuthRoleAddResponse)(nil), "etcdserverpb.AuthRoleAddResponse")
-	proto.RegisterType((*AuthRoleGetResponse)(nil), "etcdserverpb.AuthRoleGetResponse")
-	proto.RegisterType((*AuthRoleListResponse)(nil), "etcdserverpb.AuthRoleListResponse")
-	proto.RegisterType((*AuthUserListResponse)(nil), "etcdserverpb.AuthUserListResponse")
-	proto.RegisterType((*AuthRoleDeleteResponse)(nil), "etcdserverpb.AuthRoleDeleteResponse")
-	proto.RegisterType((*AuthRoleGrantPermissionResponse)(nil), "etcdserverpb.AuthRoleGrantPermissionResponse")
-	proto.RegisterType((*AuthRoleRevokePermissionResponse)(nil), "etcdserverpb.AuthRoleRevokePermissionResponse")
-	proto.RegisterEnum("etcdserverpb.AlarmType", AlarmType_name, AlarmType_value)
-	proto.RegisterEnum("etcdserverpb.RangeRequest_SortOrder", RangeRequest_SortOrder_name, RangeRequest_SortOrder_value)
-	proto.RegisterEnum("etcdserverpb.RangeRequest_SortTarget", RangeRequest_SortTarget_name, RangeRequest_SortTarget_value)
-	proto.RegisterEnum("etcdserverpb.Compare_CompareResult", Compare_CompareResult_name, Compare_CompareResult_value)
-	proto.RegisterEnum("etcdserverpb.Compare_CompareTarget", Compare_CompareTarget_name, Compare_CompareTarget_value)
-	proto.RegisterEnum("etcdserverpb.WatchCreateRequest_FilterType", WatchCreateRequest_FilterType_name, WatchCreateRequest_FilterType_value)
-	proto.RegisterEnum("etcdserverpb.AlarmRequest_AlarmAction", AlarmRequest_AlarmAction_name, AlarmRequest_AlarmAction_value)
-}
-
-// 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 KV service
-
-type KVClient interface {
-	// Range gets the keys in the range from the key-value store.
-	Range(ctx context.Context, in *RangeRequest, opts ...grpc.CallOption) (*RangeResponse, error)
-	// Put puts the given key into the key-value store.
-	// A put request increments the revision of the key-value store
-	// and generates one event in the event history.
-	Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*PutResponse, error)
-	// DeleteRange deletes the given range from the key-value store.
-	// A delete request increments the revision of the key-value store
-	// and generates a delete event in the event history for every deleted key.
-	DeleteRange(ctx context.Context, in *DeleteRangeRequest, opts ...grpc.CallOption) (*DeleteRangeResponse, error)
-	// Txn processes multiple requests in a single transaction.
-	// A txn request increments the revision of the key-value store
-	// and generates events with the same revision for every completed request.
-	// It is not allowed to modify the same key several times within one txn.
-	Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error)
-	// Compact compacts the event history in the etcd key-value store. The key-value
-	// store should be periodically compacted or the event history will continue to grow
-	// indefinitely.
-	Compact(ctx context.Context, in *CompactionRequest, opts ...grpc.CallOption) (*CompactionResponse, error)
-}
-
-type kVClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewKVClient(cc *grpc.ClientConn) KVClient {
-	return &kVClient{cc}
-}
-
-func (c *kVClient) Range(ctx context.Context, in *RangeRequest, opts ...grpc.CallOption) (*RangeResponse, error) {
-	out := new(RangeResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.KV/Range", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *kVClient) Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*PutResponse, error) {
-	out := new(PutResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.KV/Put", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *kVClient) DeleteRange(ctx context.Context, in *DeleteRangeRequest, opts ...grpc.CallOption) (*DeleteRangeResponse, error) {
-	out := new(DeleteRangeResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.KV/DeleteRange", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *kVClient) Txn(ctx context.Context, in *TxnRequest, opts ...grpc.CallOption) (*TxnResponse, error) {
-	out := new(TxnResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.KV/Txn", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *kVClient) Compact(ctx context.Context, in *CompactionRequest, opts ...grpc.CallOption) (*CompactionResponse, error) {
-	out := new(CompactionResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.KV/Compact", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for KV service
-
-type KVServer interface {
-	// Range gets the keys in the range from the key-value store.
-	Range(context.Context, *RangeRequest) (*RangeResponse, error)
-	// Put puts the given key into the key-value store.
-	// A put request increments the revision of the key-value store
-	// and generates one event in the event history.
-	Put(context.Context, *PutRequest) (*PutResponse, error)
-	// DeleteRange deletes the given range from the key-value store.
-	// A delete request increments the revision of the key-value store
-	// and generates a delete event in the event history for every deleted key.
-	DeleteRange(context.Context, *DeleteRangeRequest) (*DeleteRangeResponse, error)
-	// Txn processes multiple requests in a single transaction.
-	// A txn request increments the revision of the key-value store
-	// and generates events with the same revision for every completed request.
-	// It is not allowed to modify the same key several times within one txn.
-	Txn(context.Context, *TxnRequest) (*TxnResponse, error)
-	// Compact compacts the event history in the etcd key-value store. The key-value
-	// store should be periodically compacted or the event history will continue to grow
-	// indefinitely.
-	Compact(context.Context, *CompactionRequest) (*CompactionResponse, error)
-}
-
-func RegisterKVServer(s *grpc.Server, srv KVServer) {
-	s.RegisterService(&_KV_serviceDesc, srv)
-}
-
-func _KV_Range_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(RangeRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KVServer).Range(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.KV/Range",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KVServer).Range(ctx, req.(*RangeRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _KV_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PutRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KVServer).Put(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.KV/Put",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KVServer).Put(ctx, req.(*PutRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _KV_DeleteRange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(DeleteRangeRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KVServer).DeleteRange(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.KV/DeleteRange",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KVServer).DeleteRange(ctx, req.(*DeleteRangeRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _KV_Txn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(TxnRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KVServer).Txn(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.KV/Txn",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KVServer).Txn(ctx, req.(*TxnRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _KV_Compact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(CompactionRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(KVServer).Compact(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.KV/Compact",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KVServer).Compact(ctx, req.(*CompactionRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _KV_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.KV",
-	HandlerType: (*KVServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "Range",
-			Handler:    _KV_Range_Handler,
-		},
-		{
-			MethodName: "Put",
-			Handler:    _KV_Put_Handler,
-		},
-		{
-			MethodName: "DeleteRange",
-			Handler:    _KV_DeleteRange_Handler,
-		},
-		{
-			MethodName: "Txn",
-			Handler:    _KV_Txn_Handler,
-		},
-		{
-			MethodName: "Compact",
-			Handler:    _KV_Compact_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc.proto",
-}
-
-// Client API for Watch service
-
-type WatchClient interface {
-	// Watch watches for events happening or that have happened. Both input and output
-	// are streams; the input stream is for creating and canceling watchers and the output
-	// stream sends events. One watch RPC can watch on multiple key ranges, streaming events
-	// for several watches at once. The entire event history can be watched starting from the
-	// last compaction revision.
-	Watch(ctx context.Context, opts ...grpc.CallOption) (Watch_WatchClient, error)
-}
-
-type watchClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewWatchClient(cc *grpc.ClientConn) WatchClient {
-	return &watchClient{cc}
-}
-
-func (c *watchClient) Watch(ctx context.Context, opts ...grpc.CallOption) (Watch_WatchClient, error) {
-	stream, err := grpc.NewClientStream(ctx, &_Watch_serviceDesc.Streams[0], c.cc, "/etcdserverpb.Watch/Watch", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &watchWatchClient{stream}
-	return x, nil
-}
-
-type Watch_WatchClient interface {
-	Send(*WatchRequest) error
-	Recv() (*WatchResponse, error)
-	grpc.ClientStream
-}
-
-type watchWatchClient struct {
-	grpc.ClientStream
-}
-
-func (x *watchWatchClient) Send(m *WatchRequest) error {
-	return x.ClientStream.SendMsg(m)
-}
-
-func (x *watchWatchClient) Recv() (*WatchResponse, error) {
-	m := new(WatchResponse)
-	if err := x.ClientStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-// Server API for Watch service
-
-type WatchServer interface {
-	// Watch watches for events happening or that have happened. Both input and output
-	// are streams; the input stream is for creating and canceling watchers and the output
-	// stream sends events. One watch RPC can watch on multiple key ranges, streaming events
-	// for several watches at once. The entire event history can be watched starting from the
-	// last compaction revision.
-	Watch(Watch_WatchServer) error
-}
-
-func RegisterWatchServer(s *grpc.Server, srv WatchServer) {
-	s.RegisterService(&_Watch_serviceDesc, srv)
-}
-
-func _Watch_Watch_Handler(srv interface{}, stream grpc.ServerStream) error {
-	return srv.(WatchServer).Watch(&watchWatchServer{stream})
-}
-
-type Watch_WatchServer interface {
-	Send(*WatchResponse) error
-	Recv() (*WatchRequest, error)
-	grpc.ServerStream
-}
-
-type watchWatchServer struct {
-	grpc.ServerStream
-}
-
-func (x *watchWatchServer) Send(m *WatchResponse) error {
-	return x.ServerStream.SendMsg(m)
-}
-
-func (x *watchWatchServer) Recv() (*WatchRequest, error) {
-	m := new(WatchRequest)
-	if err := x.ServerStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-var _Watch_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.Watch",
-	HandlerType: (*WatchServer)(nil),
-	Methods:     []grpc.MethodDesc{},
-	Streams: []grpc.StreamDesc{
-		{
-			StreamName:    "Watch",
-			Handler:       _Watch_Watch_Handler,
-			ServerStreams: true,
-			ClientStreams: true,
-		},
-	},
-	Metadata: "rpc.proto",
-}
-
-// Client API for Lease service
-
-type LeaseClient interface {
-	// LeaseGrant creates a lease which expires if the server does not receive a keepAlive
-	// within a given time to live period. All keys attached to the lease will be expired and
-	// deleted if the lease expires. Each expired key generates a delete event in the event history.
-	LeaseGrant(ctx context.Context, in *LeaseGrantRequest, opts ...grpc.CallOption) (*LeaseGrantResponse, error)
-	// LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.
-	LeaseRevoke(ctx context.Context, in *LeaseRevokeRequest, opts ...grpc.CallOption) (*LeaseRevokeResponse, error)
-	// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client
-	// to the server and streaming keep alive responses from the server to the client.
-	LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (Lease_LeaseKeepAliveClient, error)
-	// LeaseTimeToLive retrieves lease information.
-	LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*LeaseTimeToLiveResponse, error)
-	// LeaseLeases lists all existing leases.
-	LeaseLeases(ctx context.Context, in *LeaseLeasesRequest, opts ...grpc.CallOption) (*LeaseLeasesResponse, error)
-}
-
-type leaseClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewLeaseClient(cc *grpc.ClientConn) LeaseClient {
-	return &leaseClient{cc}
-}
-
-func (c *leaseClient) LeaseGrant(ctx context.Context, in *LeaseGrantRequest, opts ...grpc.CallOption) (*LeaseGrantResponse, error) {
-	out := new(LeaseGrantResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseGrant", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *leaseClient) LeaseRevoke(ctx context.Context, in *LeaseRevokeRequest, opts ...grpc.CallOption) (*LeaseRevokeResponse, error) {
-	out := new(LeaseRevokeResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseRevoke", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *leaseClient) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (Lease_LeaseKeepAliveClient, error) {
-	stream, err := grpc.NewClientStream(ctx, &_Lease_serviceDesc.Streams[0], c.cc, "/etcdserverpb.Lease/LeaseKeepAlive", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &leaseLeaseKeepAliveClient{stream}
-	return x, nil
-}
-
-type Lease_LeaseKeepAliveClient interface {
-	Send(*LeaseKeepAliveRequest) error
-	Recv() (*LeaseKeepAliveResponse, error)
-	grpc.ClientStream
-}
-
-type leaseLeaseKeepAliveClient struct {
-	grpc.ClientStream
-}
-
-func (x *leaseLeaseKeepAliveClient) Send(m *LeaseKeepAliveRequest) error {
-	return x.ClientStream.SendMsg(m)
-}
-
-func (x *leaseLeaseKeepAliveClient) Recv() (*LeaseKeepAliveResponse, error) {
-	m := new(LeaseKeepAliveResponse)
-	if err := x.ClientStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func (c *leaseClient) LeaseTimeToLive(ctx context.Context, in *LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*LeaseTimeToLiveResponse, error) {
-	out := new(LeaseTimeToLiveResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseTimeToLive", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *leaseClient) LeaseLeases(ctx context.Context, in *LeaseLeasesRequest, opts ...grpc.CallOption) (*LeaseLeasesResponse, error) {
-	out := new(LeaseLeasesResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseLeases", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Lease service
-
-type LeaseServer interface {
-	// LeaseGrant creates a lease which expires if the server does not receive a keepAlive
-	// within a given time to live period. All keys attached to the lease will be expired and
-	// deleted if the lease expires. Each expired key generates a delete event in the event history.
-	LeaseGrant(context.Context, *LeaseGrantRequest) (*LeaseGrantResponse, error)
-	// LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.
-	LeaseRevoke(context.Context, *LeaseRevokeRequest) (*LeaseRevokeResponse, error)
-	// LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client
-	// to the server and streaming keep alive responses from the server to the client.
-	LeaseKeepAlive(Lease_LeaseKeepAliveServer) error
-	// LeaseTimeToLive retrieves lease information.
-	LeaseTimeToLive(context.Context, *LeaseTimeToLiveRequest) (*LeaseTimeToLiveResponse, error)
-	// LeaseLeases lists all existing leases.
-	LeaseLeases(context.Context, *LeaseLeasesRequest) (*LeaseLeasesResponse, error)
-}
-
-func RegisterLeaseServer(s *grpc.Server, srv LeaseServer) {
-	s.RegisterService(&_Lease_serviceDesc, srv)
-}
-
-func _Lease_LeaseGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LeaseGrantRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LeaseServer).LeaseGrant(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Lease/LeaseGrant",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LeaseServer).LeaseGrant(ctx, req.(*LeaseGrantRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Lease_LeaseRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LeaseRevokeRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LeaseServer).LeaseRevoke(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Lease/LeaseRevoke",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LeaseServer).LeaseRevoke(ctx, req.(*LeaseRevokeRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Lease_LeaseKeepAlive_Handler(srv interface{}, stream grpc.ServerStream) error {
-	return srv.(LeaseServer).LeaseKeepAlive(&leaseLeaseKeepAliveServer{stream})
-}
-
-type Lease_LeaseKeepAliveServer interface {
-	Send(*LeaseKeepAliveResponse) error
-	Recv() (*LeaseKeepAliveRequest, error)
-	grpc.ServerStream
-}
-
-type leaseLeaseKeepAliveServer struct {
-	grpc.ServerStream
-}
-
-func (x *leaseLeaseKeepAliveServer) Send(m *LeaseKeepAliveResponse) error {
-	return x.ServerStream.SendMsg(m)
-}
-
-func (x *leaseLeaseKeepAliveServer) Recv() (*LeaseKeepAliveRequest, error) {
-	m := new(LeaseKeepAliveRequest)
-	if err := x.ServerStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func _Lease_LeaseTimeToLive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LeaseTimeToLiveRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LeaseServer).LeaseTimeToLive(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Lease/LeaseTimeToLive",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LeaseServer).LeaseTimeToLive(ctx, req.(*LeaseTimeToLiveRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Lease_LeaseLeases_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(LeaseLeasesRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(LeaseServer).LeaseLeases(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Lease/LeaseLeases",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(LeaseServer).LeaseLeases(ctx, req.(*LeaseLeasesRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Lease_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.Lease",
-	HandlerType: (*LeaseServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "LeaseGrant",
-			Handler:    _Lease_LeaseGrant_Handler,
-		},
-		{
-			MethodName: "LeaseRevoke",
-			Handler:    _Lease_LeaseRevoke_Handler,
-		},
-		{
-			MethodName: "LeaseTimeToLive",
-			Handler:    _Lease_LeaseTimeToLive_Handler,
-		},
-		{
-			MethodName: "LeaseLeases",
-			Handler:    _Lease_LeaseLeases_Handler,
-		},
-	},
-	Streams: []grpc.StreamDesc{
-		{
-			StreamName:    "LeaseKeepAlive",
-			Handler:       _Lease_LeaseKeepAlive_Handler,
-			ServerStreams: true,
-			ClientStreams: true,
-		},
-	},
-	Metadata: "rpc.proto",
-}
-
-// Client API for Cluster service
-
-type ClusterClient interface {
-	// MemberAdd adds a member into the cluster.
-	MemberAdd(ctx context.Context, in *MemberAddRequest, opts ...grpc.CallOption) (*MemberAddResponse, error)
-	// MemberRemove removes an existing member from the cluster.
-	MemberRemove(ctx context.Context, in *MemberRemoveRequest, opts ...grpc.CallOption) (*MemberRemoveResponse, error)
-	// MemberUpdate updates the member configuration.
-	MemberUpdate(ctx context.Context, in *MemberUpdateRequest, opts ...grpc.CallOption) (*MemberUpdateResponse, error)
-	// MemberList lists all the members in the cluster.
-	MemberList(ctx context.Context, in *MemberListRequest, opts ...grpc.CallOption) (*MemberListResponse, error)
-	// MemberPromote promotes a member from raft learner (non-voting) to raft voting member.
-	MemberPromote(ctx context.Context, in *MemberPromoteRequest, opts ...grpc.CallOption) (*MemberPromoteResponse, error)
-}
-
-type clusterClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewClusterClient(cc *grpc.ClientConn) ClusterClient {
-	return &clusterClient{cc}
-}
-
-func (c *clusterClient) MemberAdd(ctx context.Context, in *MemberAddRequest, opts ...grpc.CallOption) (*MemberAddResponse, error) {
-	out := new(MemberAddResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Cluster/MemberAdd", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *clusterClient) MemberRemove(ctx context.Context, in *MemberRemoveRequest, opts ...grpc.CallOption) (*MemberRemoveResponse, error) {
-	out := new(MemberRemoveResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Cluster/MemberRemove", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *clusterClient) MemberUpdate(ctx context.Context, in *MemberUpdateRequest, opts ...grpc.CallOption) (*MemberUpdateResponse, error) {
-	out := new(MemberUpdateResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Cluster/MemberUpdate", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *clusterClient) MemberList(ctx context.Context, in *MemberListRequest, opts ...grpc.CallOption) (*MemberListResponse, error) {
-	out := new(MemberListResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Cluster/MemberList", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *clusterClient) MemberPromote(ctx context.Context, in *MemberPromoteRequest, opts ...grpc.CallOption) (*MemberPromoteResponse, error) {
-	out := new(MemberPromoteResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Cluster/MemberPromote", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Cluster service
-
-type ClusterServer interface {
-	// MemberAdd adds a member into the cluster.
-	MemberAdd(context.Context, *MemberAddRequest) (*MemberAddResponse, error)
-	// MemberRemove removes an existing member from the cluster.
-	MemberRemove(context.Context, *MemberRemoveRequest) (*MemberRemoveResponse, error)
-	// MemberUpdate updates the member configuration.
-	MemberUpdate(context.Context, *MemberUpdateRequest) (*MemberUpdateResponse, error)
-	// MemberList lists all the members in the cluster.
-	MemberList(context.Context, *MemberListRequest) (*MemberListResponse, error)
-	// MemberPromote promotes a member from raft learner (non-voting) to raft voting member.
-	MemberPromote(context.Context, *MemberPromoteRequest) (*MemberPromoteResponse, error)
-}
-
-func RegisterClusterServer(s *grpc.Server, srv ClusterServer) {
-	s.RegisterService(&_Cluster_serviceDesc, srv)
-}
-
-func _Cluster_MemberAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MemberAddRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ClusterServer).MemberAdd(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Cluster/MemberAdd",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ClusterServer).MemberAdd(ctx, req.(*MemberAddRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Cluster_MemberRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MemberRemoveRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ClusterServer).MemberRemove(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Cluster/MemberRemove",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ClusterServer).MemberRemove(ctx, req.(*MemberRemoveRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Cluster_MemberUpdate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MemberUpdateRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ClusterServer).MemberUpdate(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Cluster/MemberUpdate",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ClusterServer).MemberUpdate(ctx, req.(*MemberUpdateRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Cluster_MemberList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MemberListRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ClusterServer).MemberList(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Cluster/MemberList",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ClusterServer).MemberList(ctx, req.(*MemberListRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Cluster_MemberPromote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MemberPromoteRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(ClusterServer).MemberPromote(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Cluster/MemberPromote",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(ClusterServer).MemberPromote(ctx, req.(*MemberPromoteRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Cluster_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.Cluster",
-	HandlerType: (*ClusterServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "MemberAdd",
-			Handler:    _Cluster_MemberAdd_Handler,
-		},
-		{
-			MethodName: "MemberRemove",
-			Handler:    _Cluster_MemberRemove_Handler,
-		},
-		{
-			MethodName: "MemberUpdate",
-			Handler:    _Cluster_MemberUpdate_Handler,
-		},
-		{
-			MethodName: "MemberList",
-			Handler:    _Cluster_MemberList_Handler,
-		},
-		{
-			MethodName: "MemberPromote",
-			Handler:    _Cluster_MemberPromote_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc.proto",
-}
-
-// Client API for Maintenance service
-
-type MaintenanceClient interface {
-	// Alarm activates, deactivates, and queries alarms regarding cluster health.
-	Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error)
-	// Status gets the status of the member.
-	Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
-	// Defragment defragments a member's backend database to recover storage space.
-	Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error)
-	// Hash computes the hash of whole backend keyspace,
-	// including key, lease, and other buckets in storage.
-	// This is designed for testing ONLY!
-	// Do not rely on this in production with ongoing transactions,
-	// since Hash operation does not hold MVCC locks.
-	// Use "HashKV" API instead for "key" bucket consistency checks.
-	Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error)
-	// HashKV computes the hash of all MVCC keys up to a given revision.
-	// It only iterates "key" bucket in backend storage.
-	HashKV(ctx context.Context, in *HashKVRequest, opts ...grpc.CallOption) (*HashKVResponse, error)
-	// Snapshot sends a snapshot of the entire backend from a member over a stream to a client.
-	Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error)
-	// MoveLeader requests current leader node to transfer its leadership to transferee.
-	MoveLeader(ctx context.Context, in *MoveLeaderRequest, opts ...grpc.CallOption) (*MoveLeaderResponse, error)
-}
-
-type maintenanceClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewMaintenanceClient(cc *grpc.ClientConn) MaintenanceClient {
-	return &maintenanceClient{cc}
-}
-
-func (c *maintenanceClient) Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error) {
-	out := new(AlarmResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Alarm", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *maintenanceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
-	out := new(StatusResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Status", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *maintenanceClient) Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error) {
-	out := new(DefragmentResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Defragment", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *maintenanceClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) {
-	out := new(HashResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Hash", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *maintenanceClient) HashKV(ctx context.Context, in *HashKVRequest, opts ...grpc.CallOption) (*HashKVResponse, error) {
-	out := new(HashKVResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/HashKV", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *maintenanceClient) Snapshot(ctx context.Context, in *SnapshotRequest, opts ...grpc.CallOption) (Maintenance_SnapshotClient, error) {
-	stream, err := grpc.NewClientStream(ctx, &_Maintenance_serviceDesc.Streams[0], c.cc, "/etcdserverpb.Maintenance/Snapshot", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &maintenanceSnapshotClient{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 Maintenance_SnapshotClient interface {
-	Recv() (*SnapshotResponse, error)
-	grpc.ClientStream
-}
-
-type maintenanceSnapshotClient struct {
-	grpc.ClientStream
-}
-
-func (x *maintenanceSnapshotClient) Recv() (*SnapshotResponse, error) {
-	m := new(SnapshotResponse)
-	if err := x.ClientStream.RecvMsg(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func (c *maintenanceClient) MoveLeader(ctx context.Context, in *MoveLeaderRequest, opts ...grpc.CallOption) (*MoveLeaderResponse, error) {
-	out := new(MoveLeaderResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/MoveLeader", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Maintenance service
-
-type MaintenanceServer interface {
-	// Alarm activates, deactivates, and queries alarms regarding cluster health.
-	Alarm(context.Context, *AlarmRequest) (*AlarmResponse, error)
-	// Status gets the status of the member.
-	Status(context.Context, *StatusRequest) (*StatusResponse, error)
-	// Defragment defragments a member's backend database to recover storage space.
-	Defragment(context.Context, *DefragmentRequest) (*DefragmentResponse, error)
-	// Hash computes the hash of whole backend keyspace,
-	// including key, lease, and other buckets in storage.
-	// This is designed for testing ONLY!
-	// Do not rely on this in production with ongoing transactions,
-	// since Hash operation does not hold MVCC locks.
-	// Use "HashKV" API instead for "key" bucket consistency checks.
-	Hash(context.Context, *HashRequest) (*HashResponse, error)
-	// HashKV computes the hash of all MVCC keys up to a given revision.
-	// It only iterates "key" bucket in backend storage.
-	HashKV(context.Context, *HashKVRequest) (*HashKVResponse, error)
-	// Snapshot sends a snapshot of the entire backend from a member over a stream to a client.
-	Snapshot(*SnapshotRequest, Maintenance_SnapshotServer) error
-	// MoveLeader requests current leader node to transfer its leadership to transferee.
-	MoveLeader(context.Context, *MoveLeaderRequest) (*MoveLeaderResponse, error)
-}
-
-func RegisterMaintenanceServer(s *grpc.Server, srv MaintenanceServer) {
-	s.RegisterService(&_Maintenance_serviceDesc, srv)
-}
-
-func _Maintenance_Alarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AlarmRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).Alarm(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/Alarm",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).Alarm(ctx, req.(*AlarmRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Maintenance_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(StatusRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).Status(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/Status",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).Status(ctx, req.(*StatusRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Maintenance_Defragment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(DefragmentRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).Defragment(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/Defragment",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).Defragment(ctx, req.(*DefragmentRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Maintenance_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(HashRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).Hash(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/Hash",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).Hash(ctx, req.(*HashRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Maintenance_HashKV_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(HashKVRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).HashKV(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/HashKV",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).HashKV(ctx, req.(*HashKVRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Maintenance_Snapshot_Handler(srv interface{}, stream grpc.ServerStream) error {
-	m := new(SnapshotRequest)
-	if err := stream.RecvMsg(m); err != nil {
-		return err
-	}
-	return srv.(MaintenanceServer).Snapshot(m, &maintenanceSnapshotServer{stream})
-}
-
-type Maintenance_SnapshotServer interface {
-	Send(*SnapshotResponse) error
-	grpc.ServerStream
-}
-
-type maintenanceSnapshotServer struct {
-	grpc.ServerStream
-}
-
-func (x *maintenanceSnapshotServer) Send(m *SnapshotResponse) error {
-	return x.ServerStream.SendMsg(m)
-}
-
-func _Maintenance_MoveLeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(MoveLeaderRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MaintenanceServer).MoveLeader(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Maintenance/MoveLeader",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MaintenanceServer).MoveLeader(ctx, req.(*MoveLeaderRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Maintenance_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.Maintenance",
-	HandlerType: (*MaintenanceServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "Alarm",
-			Handler:    _Maintenance_Alarm_Handler,
-		},
-		{
-			MethodName: "Status",
-			Handler:    _Maintenance_Status_Handler,
-		},
-		{
-			MethodName: "Defragment",
-			Handler:    _Maintenance_Defragment_Handler,
-		},
-		{
-			MethodName: "Hash",
-			Handler:    _Maintenance_Hash_Handler,
-		},
-		{
-			MethodName: "HashKV",
-			Handler:    _Maintenance_HashKV_Handler,
-		},
-		{
-			MethodName: "MoveLeader",
-			Handler:    _Maintenance_MoveLeader_Handler,
-		},
-	},
-	Streams: []grpc.StreamDesc{
-		{
-			StreamName:    "Snapshot",
-			Handler:       _Maintenance_Snapshot_Handler,
-			ServerStreams: true,
-		},
-	},
-	Metadata: "rpc.proto",
-}
-
-// Client API for Auth service
-
-type AuthClient interface {
-	// AuthEnable enables authentication.
-	AuthEnable(ctx context.Context, in *AuthEnableRequest, opts ...grpc.CallOption) (*AuthEnableResponse, error)
-	// AuthDisable disables authentication.
-	AuthDisable(ctx context.Context, in *AuthDisableRequest, opts ...grpc.CallOption) (*AuthDisableResponse, error)
-	// Authenticate processes an authenticate request.
-	Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error)
-	// UserAdd adds a new user. User name cannot be empty.
-	UserAdd(ctx context.Context, in *AuthUserAddRequest, opts ...grpc.CallOption) (*AuthUserAddResponse, error)
-	// UserGet gets detailed user information.
-	UserGet(ctx context.Context, in *AuthUserGetRequest, opts ...grpc.CallOption) (*AuthUserGetResponse, error)
-	// UserList gets a list of all users.
-	UserList(ctx context.Context, in *AuthUserListRequest, opts ...grpc.CallOption) (*AuthUserListResponse, error)
-	// UserDelete deletes a specified user.
-	UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error)
-	// UserChangePassword changes the password of a specified user.
-	UserChangePassword(ctx context.Context, in *AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*AuthUserChangePasswordResponse, error)
-	// UserGrant grants a role to a specified user.
-	UserGrantRole(ctx context.Context, in *AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*AuthUserGrantRoleResponse, error)
-	// UserRevokeRole revokes a role of specified user.
-	UserRevokeRole(ctx context.Context, in *AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*AuthUserRevokeRoleResponse, error)
-	// RoleAdd adds a new role. Role name cannot be empty.
-	RoleAdd(ctx context.Context, in *AuthRoleAddRequest, opts ...grpc.CallOption) (*AuthRoleAddResponse, error)
-	// RoleGet gets detailed role information.
-	RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts ...grpc.CallOption) (*AuthRoleGetResponse, error)
-	// RoleList gets lists of all roles.
-	RoleList(ctx context.Context, in *AuthRoleListRequest, opts ...grpc.CallOption) (*AuthRoleListResponse, error)
-	// RoleDelete deletes a specified role.
-	RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error)
-	// RoleGrantPermission grants a permission of a specified key or range to a specified role.
-	RoleGrantPermission(ctx context.Context, in *AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*AuthRoleGrantPermissionResponse, error)
-	// RoleRevokePermission revokes a key or range permission of a specified role.
-	RoleRevokePermission(ctx context.Context, in *AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*AuthRoleRevokePermissionResponse, error)
-}
-
-type authClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewAuthClient(cc *grpc.ClientConn) AuthClient {
-	return &authClient{cc}
-}
-
-func (c *authClient) AuthEnable(ctx context.Context, in *AuthEnableRequest, opts ...grpc.CallOption) (*AuthEnableResponse, error) {
-	out := new(AuthEnableResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/AuthEnable", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) AuthDisable(ctx context.Context, in *AuthDisableRequest, opts ...grpc.CallOption) (*AuthDisableResponse, error) {
-	out := new(AuthDisableResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/AuthDisable", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) {
-	out := new(AuthenticateResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/Authenticate", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserAdd(ctx context.Context, in *AuthUserAddRequest, opts ...grpc.CallOption) (*AuthUserAddResponse, error) {
-	out := new(AuthUserAddResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserAdd", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserGet(ctx context.Context, in *AuthUserGetRequest, opts ...grpc.CallOption) (*AuthUserGetResponse, error) {
-	out := new(AuthUserGetResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGet", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserList(ctx context.Context, in *AuthUserListRequest, opts ...grpc.CallOption) (*AuthUserListResponse, error) {
-	out := new(AuthUserListResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserList", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error) {
-	out := new(AuthUserDeleteResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserDelete", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserChangePassword(ctx context.Context, in *AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*AuthUserChangePasswordResponse, error) {
-	out := new(AuthUserChangePasswordResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserChangePassword", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserGrantRole(ctx context.Context, in *AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*AuthUserGrantRoleResponse, error) {
-	out := new(AuthUserGrantRoleResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGrantRole", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) UserRevokeRole(ctx context.Context, in *AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*AuthUserRevokeRoleResponse, error) {
-	out := new(AuthUserRevokeRoleResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserRevokeRole", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleAdd(ctx context.Context, in *AuthRoleAddRequest, opts ...grpc.CallOption) (*AuthRoleAddResponse, error) {
-	out := new(AuthRoleAddResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleAdd", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts ...grpc.CallOption) (*AuthRoleGetResponse, error) {
-	out := new(AuthRoleGetResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGet", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleList(ctx context.Context, in *AuthRoleListRequest, opts ...grpc.CallOption) (*AuthRoleListResponse, error) {
-	out := new(AuthRoleListResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleList", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error) {
-	out := new(AuthRoleDeleteResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleDelete", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleGrantPermission(ctx context.Context, in *AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*AuthRoleGrantPermissionResponse, error) {
-	out := new(AuthRoleGrantPermissionResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGrantPermission", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *authClient) RoleRevokePermission(ctx context.Context, in *AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*AuthRoleRevokePermissionResponse, error) {
-	out := new(AuthRoleRevokePermissionResponse)
-	err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleRevokePermission", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for Auth service
-
-type AuthServer interface {
-	// AuthEnable enables authentication.
-	AuthEnable(context.Context, *AuthEnableRequest) (*AuthEnableResponse, error)
-	// AuthDisable disables authentication.
-	AuthDisable(context.Context, *AuthDisableRequest) (*AuthDisableResponse, error)
-	// Authenticate processes an authenticate request.
-	Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error)
-	// UserAdd adds a new user. User name cannot be empty.
-	UserAdd(context.Context, *AuthUserAddRequest) (*AuthUserAddResponse, error)
-	// UserGet gets detailed user information.
-	UserGet(context.Context, *AuthUserGetRequest) (*AuthUserGetResponse, error)
-	// UserList gets a list of all users.
-	UserList(context.Context, *AuthUserListRequest) (*AuthUserListResponse, error)
-	// UserDelete deletes a specified user.
-	UserDelete(context.Context, *AuthUserDeleteRequest) (*AuthUserDeleteResponse, error)
-	// UserChangePassword changes the password of a specified user.
-	UserChangePassword(context.Context, *AuthUserChangePasswordRequest) (*AuthUserChangePasswordResponse, error)
-	// UserGrant grants a role to a specified user.
-	UserGrantRole(context.Context, *AuthUserGrantRoleRequest) (*AuthUserGrantRoleResponse, error)
-	// UserRevokeRole revokes a role of specified user.
-	UserRevokeRole(context.Context, *AuthUserRevokeRoleRequest) (*AuthUserRevokeRoleResponse, error)
-	// RoleAdd adds a new role. Role name cannot be empty.
-	RoleAdd(context.Context, *AuthRoleAddRequest) (*AuthRoleAddResponse, error)
-	// RoleGet gets detailed role information.
-	RoleGet(context.Context, *AuthRoleGetRequest) (*AuthRoleGetResponse, error)
-	// RoleList gets lists of all roles.
-	RoleList(context.Context, *AuthRoleListRequest) (*AuthRoleListResponse, error)
-	// RoleDelete deletes a specified role.
-	RoleDelete(context.Context, *AuthRoleDeleteRequest) (*AuthRoleDeleteResponse, error)
-	// RoleGrantPermission grants a permission of a specified key or range to a specified role.
-	RoleGrantPermission(context.Context, *AuthRoleGrantPermissionRequest) (*AuthRoleGrantPermissionResponse, error)
-	// RoleRevokePermission revokes a key or range permission of a specified role.
-	RoleRevokePermission(context.Context, *AuthRoleRevokePermissionRequest) (*AuthRoleRevokePermissionResponse, error)
-}
-
-func RegisterAuthServer(s *grpc.Server, srv AuthServer) {
-	s.RegisterService(&_Auth_serviceDesc, srv)
-}
-
-func _Auth_AuthEnable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthEnableRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).AuthEnable(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/AuthEnable",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).AuthEnable(ctx, req.(*AuthEnableRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_AuthDisable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthDisableRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).AuthDisable(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/AuthDisable",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).AuthDisable(ctx, req.(*AuthDisableRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthenticateRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).Authenticate(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/Authenticate",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).Authenticate(ctx, req.(*AuthenticateRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserAddRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserAdd(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserAdd",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserAdd(ctx, req.(*AuthUserAddRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserGetRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserGet(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserGet",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserGet(ctx, req.(*AuthUserGetRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserListRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserList(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserList",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserList(ctx, req.(*AuthUserListRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserDeleteRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserDelete(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserDelete",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserDelete(ctx, req.(*AuthUserDeleteRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserChangePasswordRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserChangePassword(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserChangePassword",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserChangePassword(ctx, req.(*AuthUserChangePasswordRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserGrantRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserGrantRoleRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserGrantRole(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserGrantRole",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserGrantRole(ctx, req.(*AuthUserGrantRoleRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_UserRevokeRole_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthUserRevokeRoleRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).UserRevokeRole(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/UserRevokeRole",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).UserRevokeRole(ctx, req.(*AuthUserRevokeRoleRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleAddRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleAdd(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleAdd",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleAdd(ctx, req.(*AuthRoleAddRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleGetRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleGet(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleGet",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleGet(ctx, req.(*AuthRoleGetRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleListRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleList(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleList",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleList(ctx, req.(*AuthRoleListRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleDeleteRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleDelete(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleDelete",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleDelete(ctx, req.(*AuthRoleDeleteRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleGrantPermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleGrantPermissionRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleGrantPermission(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleGrantPermission",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleGrantPermission(ctx, req.(*AuthRoleGrantPermissionRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-func _Auth_RoleRevokePermission_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(AuthRoleRevokePermissionRequest)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(AuthServer).RoleRevokePermission(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/etcdserverpb.Auth/RoleRevokePermission",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(AuthServer).RoleRevokePermission(ctx, req.(*AuthRoleRevokePermissionRequest))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _Auth_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "etcdserverpb.Auth",
-	HandlerType: (*AuthServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "AuthEnable",
-			Handler:    _Auth_AuthEnable_Handler,
-		},
-		{
-			MethodName: "AuthDisable",
-			Handler:    _Auth_AuthDisable_Handler,
-		},
-		{
-			MethodName: "Authenticate",
-			Handler:    _Auth_Authenticate_Handler,
-		},
-		{
-			MethodName: "UserAdd",
-			Handler:    _Auth_UserAdd_Handler,
-		},
-		{
-			MethodName: "UserGet",
-			Handler:    _Auth_UserGet_Handler,
-		},
-		{
-			MethodName: "UserList",
-			Handler:    _Auth_UserList_Handler,
-		},
-		{
-			MethodName: "UserDelete",
-			Handler:    _Auth_UserDelete_Handler,
-		},
-		{
-			MethodName: "UserChangePassword",
-			Handler:    _Auth_UserChangePassword_Handler,
-		},
-		{
-			MethodName: "UserGrantRole",
-			Handler:    _Auth_UserGrantRole_Handler,
-		},
-		{
-			MethodName: "UserRevokeRole",
-			Handler:    _Auth_UserRevokeRole_Handler,
-		},
-		{
-			MethodName: "RoleAdd",
-			Handler:    _Auth_RoleAdd_Handler,
-		},
-		{
-			MethodName: "RoleGet",
-			Handler:    _Auth_RoleGet_Handler,
-		},
-		{
-			MethodName: "RoleList",
-			Handler:    _Auth_RoleList_Handler,
-		},
-		{
-			MethodName: "RoleDelete",
-			Handler:    _Auth_RoleDelete_Handler,
-		},
-		{
-			MethodName: "RoleGrantPermission",
-			Handler:    _Auth_RoleGrantPermission_Handler,
-		},
-		{
-			MethodName: "RoleRevokePermission",
-			Handler:    _Auth_RoleRevokePermission_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "rpc.proto",
-}
-
-func (m *ResponseHeader) 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 *ResponseHeader) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ClusterId != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ClusterId))
-	}
-	if m.MemberId != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MemberId))
-	}
-	if m.Revision != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Revision))
-	}
-	if m.RaftTerm != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm))
-	}
-	return i, nil
-}
-
-func (m *RangeRequest) 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 *RangeRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	if m.Limit != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Limit))
-	}
-	if m.Revision != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Revision))
-	}
-	if m.SortOrder != 0 {
-		dAtA[i] = 0x28
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.SortOrder))
-	}
-	if m.SortTarget != 0 {
-		dAtA[i] = 0x30
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.SortTarget))
-	}
-	if m.Serializable {
-		dAtA[i] = 0x38
-		i++
-		if m.Serializable {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.KeysOnly {
-		dAtA[i] = 0x40
-		i++
-		if m.KeysOnly {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.CountOnly {
-		dAtA[i] = 0x48
-		i++
-		if m.CountOnly {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.MinModRevision != 0 {
-		dAtA[i] = 0x50
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MinModRevision))
-	}
-	if m.MaxModRevision != 0 {
-		dAtA[i] = 0x58
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MaxModRevision))
-	}
-	if m.MinCreateRevision != 0 {
-		dAtA[i] = 0x60
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MinCreateRevision))
-	}
-	if m.MaxCreateRevision != 0 {
-		dAtA[i] = 0x68
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MaxCreateRevision))
-	}
-	return i, nil
-}
-
-func (m *RangeResponse) 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 *RangeResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n1, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	if len(m.Kvs) > 0 {
-		for _, msg := range m.Kvs {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	if m.More {
-		dAtA[i] = 0x18
-		i++
-		if m.More {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.Count != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Count))
-	}
-	return i, nil
-}
-
-func (m *PutRequest) 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 *PutRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.Value) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
-	}
-	if m.Lease != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Lease))
-	}
-	if m.PrevKv {
-		dAtA[i] = 0x20
-		i++
-		if m.PrevKv {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.IgnoreValue {
-		dAtA[i] = 0x28
-		i++
-		if m.IgnoreValue {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.IgnoreLease {
-		dAtA[i] = 0x30
-		i++
-		if m.IgnoreLease {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *PutResponse) 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 *PutResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n2, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	if m.PrevKv != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.PrevKv.Size()))
-		n3, err := m.PrevKv.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n3
-	}
-	return i, nil
-}
-
-func (m *DeleteRangeRequest) 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 *DeleteRangeRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	if m.PrevKv {
-		dAtA[i] = 0x18
-		i++
-		if m.PrevKv {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *DeleteRangeResponse) 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 *DeleteRangeResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n4, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n4
-	}
-	if m.Deleted != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Deleted))
-	}
-	if len(m.PrevKvs) > 0 {
-		for _, msg := range m.PrevKvs {
-			dAtA[i] = 0x1a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *RequestOp) 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 *RequestOp) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Request != nil {
-		nn5, err := m.Request.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += nn5
-	}
-	return i, nil
-}
-
-func (m *RequestOp_RequestRange) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.RequestRange != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RequestRange.Size()))
-		n6, err := m.RequestRange.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n6
-	}
-	return i, nil
-}
-func (m *RequestOp_RequestPut) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.RequestPut != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RequestPut.Size()))
-		n7, err := m.RequestPut.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n7
-	}
-	return i, nil
-}
-func (m *RequestOp_RequestDeleteRange) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.RequestDeleteRange != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RequestDeleteRange.Size()))
-		n8, err := m.RequestDeleteRange.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n8
-	}
-	return i, nil
-}
-func (m *RequestOp_RequestTxn) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.RequestTxn != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RequestTxn.Size()))
-		n9, err := m.RequestTxn.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n9
-	}
-	return i, nil
-}
-func (m *ResponseOp) 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 *ResponseOp) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Response != nil {
-		nn10, err := m.Response.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += nn10
-	}
-	return i, nil
-}
-
-func (m *ResponseOp_ResponseRange) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.ResponseRange != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ResponseRange.Size()))
-		n11, err := m.ResponseRange.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n11
-	}
-	return i, nil
-}
-func (m *ResponseOp_ResponsePut) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.ResponsePut != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ResponsePut.Size()))
-		n12, err := m.ResponsePut.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n12
-	}
-	return i, nil
-}
-func (m *ResponseOp_ResponseDeleteRange) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.ResponseDeleteRange != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ResponseDeleteRange.Size()))
-		n13, err := m.ResponseDeleteRange.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n13
-	}
-	return i, nil
-}
-func (m *ResponseOp_ResponseTxn) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.ResponseTxn != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ResponseTxn.Size()))
-		n14, err := m.ResponseTxn.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n14
-	}
-	return i, nil
-}
-func (m *Compare) 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 *Compare) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Result != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Result))
-	}
-	if m.Target != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Target))
-	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if m.TargetUnion != nil {
-		nn15, err := m.TargetUnion.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += nn15
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x82
-		i++
-		dAtA[i] = 0x4
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	return i, nil
-}
-
-func (m *Compare_Version) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	dAtA[i] = 0x20
-	i++
-	i = encodeVarintRpc(dAtA, i, uint64(m.Version))
-	return i, nil
-}
-func (m *Compare_CreateRevision) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	dAtA[i] = 0x28
-	i++
-	i = encodeVarintRpc(dAtA, i, uint64(m.CreateRevision))
-	return i, nil
-}
-func (m *Compare_ModRevision) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	dAtA[i] = 0x30
-	i++
-	i = encodeVarintRpc(dAtA, i, uint64(m.ModRevision))
-	return i, nil
-}
-func (m *Compare_Value) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.Value != nil {
-		dAtA[i] = 0x3a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
-	}
-	return i, nil
-}
-func (m *Compare_Lease) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	dAtA[i] = 0x40
-	i++
-	i = encodeVarintRpc(dAtA, i, uint64(m.Lease))
-	return i, nil
-}
-func (m *TxnRequest) 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 *TxnRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Compare) > 0 {
-		for _, msg := range m.Compare {
-			dAtA[i] = 0xa
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	if len(m.Success) > 0 {
-		for _, msg := range m.Success {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	if len(m.Failure) > 0 {
-		for _, msg := range m.Failure {
-			dAtA[i] = 0x1a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *TxnResponse) 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 *TxnResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n16, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n16
-	}
-	if m.Succeeded {
-		dAtA[i] = 0x10
-		i++
-		if m.Succeeded {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if len(m.Responses) > 0 {
-		for _, msg := range m.Responses {
-			dAtA[i] = 0x1a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *CompactionRequest) 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 *CompactionRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Revision != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Revision))
-	}
-	if m.Physical {
-		dAtA[i] = 0x10
-		i++
-		if m.Physical {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *CompactionResponse) 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 *CompactionResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n17, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n17
-	}
-	return i, nil
-}
-
-func (m *HashRequest) 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 *HashRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *HashKVRequest) 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 *HashKVRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Revision != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Revision))
-	}
-	return i, nil
-}
-
-func (m *HashKVResponse) 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 *HashKVResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n18, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n18
-	}
-	if m.Hash != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Hash))
-	}
-	if m.CompactRevision != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.CompactRevision))
-	}
-	return i, nil
-}
-
-func (m *HashResponse) 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 *HashResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n19, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n19
-	}
-	if m.Hash != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Hash))
-	}
-	return i, nil
-}
-
-func (m *SnapshotRequest) 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 *SnapshotRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *SnapshotResponse) 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 *SnapshotResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n20, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n20
-	}
-	if m.RemainingBytes != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RemainingBytes))
-	}
-	if len(m.Blob) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Blob)))
-		i += copy(dAtA[i:], m.Blob)
-	}
-	return i, nil
-}
-
-func (m *WatchRequest) 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 *WatchRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.RequestUnion != nil {
-		nn21, err := m.RequestUnion.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += nn21
-	}
-	return i, nil
-}
-
-func (m *WatchRequest_CreateRequest) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.CreateRequest != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.CreateRequest.Size()))
-		n22, err := m.CreateRequest.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n22
-	}
-	return i, nil
-}
-func (m *WatchRequest_CancelRequest) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.CancelRequest != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.CancelRequest.Size()))
-		n23, err := m.CancelRequest.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n23
-	}
-	return i, nil
-}
-func (m *WatchRequest_ProgressRequest) MarshalTo(dAtA []byte) (int, error) {
-	i := 0
-	if m.ProgressRequest != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ProgressRequest.Size()))
-		n24, err := m.ProgressRequest.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n24
-	}
-	return i, nil
-}
-func (m *WatchCreateRequest) 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 *WatchCreateRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	if m.StartRevision != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.StartRevision))
-	}
-	if m.ProgressNotify {
-		dAtA[i] = 0x20
-		i++
-		if m.ProgressNotify {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if len(m.Filters) > 0 {
-		dAtA26 := make([]byte, len(m.Filters)*10)
-		var j25 int
-		for _, num := range m.Filters {
-			for num >= 1<<7 {
-				dAtA26[j25] = uint8(uint64(num)&0x7f | 0x80)
-				num >>= 7
-				j25++
-			}
-			dAtA26[j25] = uint8(num)
-			j25++
-		}
-		dAtA[i] = 0x2a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(j25))
-		i += copy(dAtA[i:], dAtA26[:j25])
-	}
-	if m.PrevKv {
-		dAtA[i] = 0x30
-		i++
-		if m.PrevKv {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.WatchId != 0 {
-		dAtA[i] = 0x38
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.WatchId))
-	}
-	if m.Fragment {
-		dAtA[i] = 0x40
-		i++
-		if m.Fragment {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *WatchCancelRequest) 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 *WatchCancelRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.WatchId != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.WatchId))
-	}
-	return i, nil
-}
-
-func (m *WatchProgressRequest) 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 *WatchProgressRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *WatchResponse) 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 *WatchResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n27, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n27
-	}
-	if m.WatchId != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.WatchId))
-	}
-	if m.Created {
-		dAtA[i] = 0x18
-		i++
-		if m.Created {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.Canceled {
-		dAtA[i] = 0x20
-		i++
-		if m.Canceled {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if m.CompactRevision != 0 {
-		dAtA[i] = 0x28
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.CompactRevision))
-	}
-	if len(m.CancelReason) > 0 {
-		dAtA[i] = 0x32
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.CancelReason)))
-		i += copy(dAtA[i:], m.CancelReason)
-	}
-	if m.Fragment {
-		dAtA[i] = 0x38
-		i++
-		if m.Fragment {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	if len(m.Events) > 0 {
-		for _, msg := range m.Events {
-			dAtA[i] = 0x5a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *LeaseGrantRequest) 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 *LeaseGrantRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.TTL != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.TTL))
-	}
-	if m.ID != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *LeaseGrantResponse) 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 *LeaseGrantResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n28, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n28
-	}
-	if m.ID != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.TTL))
-	}
-	if len(m.Error) > 0 {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Error)))
-		i += copy(dAtA[i:], m.Error)
-	}
-	return i, nil
-}
-
-func (m *LeaseRevokeRequest) 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 *LeaseRevokeRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *LeaseRevokeResponse) 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 *LeaseRevokeResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n29, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n29
-	}
-	return i, nil
-}
-
-func (m *LeaseCheckpoint) 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 *LeaseCheckpoint) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if m.Remaining_TTL != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Remaining_TTL))
-	}
-	return i, nil
-}
-
-func (m *LeaseCheckpointRequest) 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 *LeaseCheckpointRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Checkpoints) > 0 {
-		for _, msg := range m.Checkpoints {
-			dAtA[i] = 0xa
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *LeaseCheckpointResponse) 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 *LeaseCheckpointResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n30, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n30
-	}
-	return i, nil
-}
-
-func (m *LeaseKeepAliveRequest) 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 *LeaseKeepAliveRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *LeaseKeepAliveResponse) 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 *LeaseKeepAliveResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n31, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n31
-	}
-	if m.ID != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.TTL))
-	}
-	return i, nil
-}
-
-func (m *LeaseTimeToLiveRequest) 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 *LeaseTimeToLiveRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if m.Keys {
-		dAtA[i] = 0x10
-		i++
-		if m.Keys {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *LeaseTimeToLiveResponse) 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 *LeaseTimeToLiveResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n32, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n32
-	}
-	if m.ID != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.TTL))
-	}
-	if m.GrantedTTL != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.GrantedTTL))
-	}
-	if len(m.Keys) > 0 {
-		for _, b := range m.Keys {
-			dAtA[i] = 0x2a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(len(b)))
-			i += copy(dAtA[i:], b)
-		}
-	}
-	return i, nil
-}
-
-func (m *LeaseLeasesRequest) 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 *LeaseLeasesRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *LeaseStatus) 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 *LeaseStatus) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *LeaseLeasesResponse) 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 *LeaseLeasesResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n33, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n33
-	}
-	if len(m.Leases) > 0 {
-		for _, msg := range m.Leases {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *Member) 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 *Member) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if len(m.Name) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			dAtA[i] = 0x1a
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	if len(m.ClientURLs) > 0 {
-		for _, s := range m.ClientURLs {
-			dAtA[i] = 0x22
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	if m.IsLearner {
-		dAtA[i] = 0x28
-		i++
-		if m.IsLearner {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *MemberAddRequest) 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 *MemberAddRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			dAtA[i] = 0xa
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	if m.IsLearner {
-		dAtA[i] = 0x10
-		i++
-		if m.IsLearner {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *MemberAddResponse) 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 *MemberAddResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n34, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n34
-	}
-	if m.Member != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Member.Size()))
-		n35, err := m.Member.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n35
-	}
-	if len(m.Members) > 0 {
-		for _, msg := range m.Members {
-			dAtA[i] = 0x1a
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *MemberRemoveRequest) 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 *MemberRemoveRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *MemberRemoveResponse) 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 *MemberRemoveResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n36, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n36
-	}
-	if len(m.Members) > 0 {
-		for _, msg := range m.Members {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *MemberUpdateRequest) 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 *MemberUpdateRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			dAtA[i] = 0x12
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	return i, nil
-}
-
-func (m *MemberUpdateResponse) 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 *MemberUpdateResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n37, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n37
-	}
-	if len(m.Members) > 0 {
-		for _, msg := range m.Members {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *MemberListRequest) 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 *MemberListRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *MemberListResponse) 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 *MemberListResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n38, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n38
-	}
-	if len(m.Members) > 0 {
-		for _, msg := range m.Members {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *MemberPromoteRequest) 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 *MemberPromoteRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.ID))
-	}
-	return i, nil
-}
-
-func (m *MemberPromoteResponse) 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 *MemberPromoteResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n39, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n39
-	}
-	if len(m.Members) > 0 {
-		for _, msg := range m.Members {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *DefragmentRequest) 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 *DefragmentRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *DefragmentResponse) 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 *DefragmentResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n40, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n40
-	}
-	return i, nil
-}
-
-func (m *MoveLeaderRequest) 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 *MoveLeaderRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.TargetID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.TargetID))
-	}
-	return i, nil
-}
-
-func (m *MoveLeaderResponse) 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 *MoveLeaderResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n41, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n41
-	}
-	return i, nil
-}
-
-func (m *AlarmRequest) 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 *AlarmRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Action != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Action))
-	}
-	if m.MemberID != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MemberID))
-	}
-	if m.Alarm != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Alarm))
-	}
-	return i, nil
-}
-
-func (m *AlarmMember) 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 *AlarmMember) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.MemberID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.MemberID))
-	}
-	if m.Alarm != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Alarm))
-	}
-	return i, nil
-}
-
-func (m *AlarmResponse) 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 *AlarmResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n42, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n42
-	}
-	if len(m.Alarms) > 0 {
-		for _, msg := range m.Alarms {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *StatusRequest) 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 *StatusRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *StatusResponse) 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 *StatusResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n43, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n43
-	}
-	if len(m.Version) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Version)))
-		i += copy(dAtA[i:], m.Version)
-	}
-	if m.DbSize != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.DbSize))
-	}
-	if m.Leader != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Leader))
-	}
-	if m.RaftIndex != 0 {
-		dAtA[i] = 0x28
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RaftIndex))
-	}
-	if m.RaftTerm != 0 {
-		dAtA[i] = 0x30
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm))
-	}
-	if m.RaftAppliedIndex != 0 {
-		dAtA[i] = 0x38
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.RaftAppliedIndex))
-	}
-	if len(m.Errors) > 0 {
-		for _, s := range m.Errors {
-			dAtA[i] = 0x42
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	if m.DbSizeInUse != 0 {
-		dAtA[i] = 0x48
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.DbSizeInUse))
-	}
-	if m.IsLearner {
-		dAtA[i] = 0x50
-		i++
-		if m.IsLearner {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
-	}
-	return i, nil
-}
-
-func (m *AuthEnableRequest) 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 *AuthEnableRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *AuthDisableRequest) 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 *AuthDisableRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *AuthenticateRequest) 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 *AuthenticateRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Password) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Password)))
-		i += copy(dAtA[i:], m.Password)
-	}
-	return i, nil
-}
-
-func (m *AuthUserAddRequest) 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 *AuthUserAddRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Password) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Password)))
-		i += copy(dAtA[i:], m.Password)
-	}
-	if m.Options != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Options.Size()))
-		n44, err := m.Options.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n44
-	}
-	return i, nil
-}
-
-func (m *AuthUserGetRequest) 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 *AuthUserGetRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	return i, nil
-}
-
-func (m *AuthUserDeleteRequest) 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 *AuthUserDeleteRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	return i, nil
-}
-
-func (m *AuthUserChangePasswordRequest) 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 *AuthUserChangePasswordRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Password) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Password)))
-		i += copy(dAtA[i:], m.Password)
-	}
-	return i, nil
-}
-
-func (m *AuthUserGrantRoleRequest) 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 *AuthUserGrantRoleRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.User) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.User)))
-		i += copy(dAtA[i:], m.User)
-	}
-	if len(m.Role) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Role)))
-		i += copy(dAtA[i:], m.Role)
-	}
-	return i, nil
-}
-
-func (m *AuthUserRevokeRoleRequest) 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 *AuthUserRevokeRoleRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Role) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Role)))
-		i += copy(dAtA[i:], m.Role)
-	}
-	return i, nil
-}
-
-func (m *AuthRoleAddRequest) 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 *AuthRoleAddRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	return i, nil
-}
-
-func (m *AuthRoleGetRequest) 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 *AuthRoleGetRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Role) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Role)))
-		i += copy(dAtA[i:], m.Role)
-	}
-	return i, nil
-}
-
-func (m *AuthUserListRequest) 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 *AuthUserListRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *AuthRoleListRequest) 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 *AuthRoleListRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	return i, nil
-}
-
-func (m *AuthRoleDeleteRequest) 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 *AuthRoleDeleteRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Role) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Role)))
-		i += copy(dAtA[i:], m.Role)
-	}
-	return i, nil
-}
-
-func (m *AuthRoleGrantPermissionRequest) 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 *AuthRoleGrantPermissionRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if m.Perm != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Perm.Size()))
-		n45, err := m.Perm.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n45
-	}
-	return i, nil
-}
-
-func (m *AuthRoleRevokePermissionRequest) 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 *AuthRoleRevokePermissionRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Role) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Role)))
-		i += copy(dAtA[i:], m.Role)
-	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if len(m.RangeEnd) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.RangeEnd)))
-		i += copy(dAtA[i:], m.RangeEnd)
-	}
-	return i, nil
-}
-
-func (m *AuthEnableResponse) 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 *AuthEnableResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n46, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n46
-	}
-	return i, nil
-}
-
-func (m *AuthDisableResponse) 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 *AuthDisableResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n47, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n47
-	}
-	return i, nil
-}
-
-func (m *AuthenticateResponse) 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 *AuthenticateResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n48, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n48
-	}
-	if len(m.Token) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(len(m.Token)))
-		i += copy(dAtA[i:], m.Token)
-	}
-	return i, nil
-}
-
-func (m *AuthUserAddResponse) 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 *AuthUserAddResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n49, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n49
-	}
-	return i, nil
-}
-
-func (m *AuthUserGetResponse) 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 *AuthUserGetResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n50, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n50
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			dAtA[i] = 0x12
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	return i, nil
-}
-
-func (m *AuthUserDeleteResponse) 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 *AuthUserDeleteResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n51, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n51
-	}
-	return i, nil
-}
-
-func (m *AuthUserChangePasswordResponse) 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 *AuthUserChangePasswordResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n52, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n52
-	}
-	return i, nil
-}
-
-func (m *AuthUserGrantRoleResponse) 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 *AuthUserGrantRoleResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n53, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n53
-	}
-	return i, nil
-}
-
-func (m *AuthUserRevokeRoleResponse) 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 *AuthUserRevokeRoleResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n54, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n54
-	}
-	return i, nil
-}
-
-func (m *AuthRoleAddResponse) 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 *AuthRoleAddResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n55, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n55
-	}
-	return i, nil
-}
-
-func (m *AuthRoleGetResponse) 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 *AuthRoleGetResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n56, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n56
-	}
-	if len(m.Perm) > 0 {
-		for _, msg := range m.Perm {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRpc(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	return i, nil
-}
-
-func (m *AuthRoleListResponse) 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 *AuthRoleListResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n57, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n57
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			dAtA[i] = 0x12
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	return i, nil
-}
-
-func (m *AuthUserListResponse) 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 *AuthUserListResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n58, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n58
-	}
-	if len(m.Users) > 0 {
-		for _, s := range m.Users {
-			dAtA[i] = 0x12
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
-	}
-	return i, nil
-}
-
-func (m *AuthRoleDeleteResponse) 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 *AuthRoleDeleteResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n59, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n59
-	}
-	return i, nil
-}
-
-func (m *AuthRoleGrantPermissionResponse) 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 *AuthRoleGrantPermissionResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n60, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n60
-	}
-	return i, nil
-}
-
-func (m *AuthRoleRevokePermissionResponse) 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 *AuthRoleRevokePermissionResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Header != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRpc(dAtA, i, uint64(m.Header.Size()))
-		n61, err := m.Header.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n61
-	}
-	return i, nil
-}
-
-func encodeVarintRpc(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 *ResponseHeader) Size() (n int) {
-	var l int
-	_ = l
-	if m.ClusterId != 0 {
-		n += 1 + sovRpc(uint64(m.ClusterId))
-	}
-	if m.MemberId != 0 {
-		n += 1 + sovRpc(uint64(m.MemberId))
-	}
-	if m.Revision != 0 {
-		n += 1 + sovRpc(uint64(m.Revision))
-	}
-	if m.RaftTerm != 0 {
-		n += 1 + sovRpc(uint64(m.RaftTerm))
-	}
-	return n
-}
-
-func (m *RangeRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Limit != 0 {
-		n += 1 + sovRpc(uint64(m.Limit))
-	}
-	if m.Revision != 0 {
-		n += 1 + sovRpc(uint64(m.Revision))
-	}
-	if m.SortOrder != 0 {
-		n += 1 + sovRpc(uint64(m.SortOrder))
-	}
-	if m.SortTarget != 0 {
-		n += 1 + sovRpc(uint64(m.SortTarget))
-	}
-	if m.Serializable {
-		n += 2
-	}
-	if m.KeysOnly {
-		n += 2
-	}
-	if m.CountOnly {
-		n += 2
-	}
-	if m.MinModRevision != 0 {
-		n += 1 + sovRpc(uint64(m.MinModRevision))
-	}
-	if m.MaxModRevision != 0 {
-		n += 1 + sovRpc(uint64(m.MaxModRevision))
-	}
-	if m.MinCreateRevision != 0 {
-		n += 1 + sovRpc(uint64(m.MinCreateRevision))
-	}
-	if m.MaxCreateRevision != 0 {
-		n += 1 + sovRpc(uint64(m.MaxCreateRevision))
-	}
-	return n
-}
-
-func (m *RangeResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Kvs) > 0 {
-		for _, e := range m.Kvs {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if m.More {
-		n += 2
-	}
-	if m.Count != 0 {
-		n += 1 + sovRpc(uint64(m.Count))
-	}
-	return n
-}
-
-func (m *PutRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Value)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Lease != 0 {
-		n += 1 + sovRpc(uint64(m.Lease))
-	}
-	if m.PrevKv {
-		n += 2
-	}
-	if m.IgnoreValue {
-		n += 2
-	}
-	if m.IgnoreLease {
-		n += 2
-	}
-	return n
-}
-
-func (m *PutResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.PrevKv != nil {
-		l = m.PrevKv.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *DeleteRangeRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.PrevKv {
-		n += 2
-	}
-	return n
-}
-
-func (m *DeleteRangeResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Deleted != 0 {
-		n += 1 + sovRpc(uint64(m.Deleted))
-	}
-	if len(m.PrevKvs) > 0 {
-		for _, e := range m.PrevKvs {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *RequestOp) Size() (n int) {
-	var l int
-	_ = l
-	if m.Request != nil {
-		n += m.Request.Size()
-	}
-	return n
-}
-
-func (m *RequestOp_RequestRange) Size() (n int) {
-	var l int
-	_ = l
-	if m.RequestRange != nil {
-		l = m.RequestRange.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *RequestOp_RequestPut) Size() (n int) {
-	var l int
-	_ = l
-	if m.RequestPut != nil {
-		l = m.RequestPut.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *RequestOp_RequestDeleteRange) Size() (n int) {
-	var l int
-	_ = l
-	if m.RequestDeleteRange != nil {
-		l = m.RequestDeleteRange.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *RequestOp_RequestTxn) Size() (n int) {
-	var l int
-	_ = l
-	if m.RequestTxn != nil {
-		l = m.RequestTxn.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *ResponseOp) Size() (n int) {
-	var l int
-	_ = l
-	if m.Response != nil {
-		n += m.Response.Size()
-	}
-	return n
-}
-
-func (m *ResponseOp_ResponseRange) Size() (n int) {
-	var l int
-	_ = l
-	if m.ResponseRange != nil {
-		l = m.ResponseRange.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *ResponseOp_ResponsePut) Size() (n int) {
-	var l int
-	_ = l
-	if m.ResponsePut != nil {
-		l = m.ResponsePut.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *ResponseOp_ResponseDeleteRange) Size() (n int) {
-	var l int
-	_ = l
-	if m.ResponseDeleteRange != nil {
-		l = m.ResponseDeleteRange.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *ResponseOp_ResponseTxn) Size() (n int) {
-	var l int
-	_ = l
-	if m.ResponseTxn != nil {
-		l = m.ResponseTxn.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *Compare) Size() (n int) {
-	var l int
-	_ = l
-	if m.Result != 0 {
-		n += 1 + sovRpc(uint64(m.Result))
-	}
-	if m.Target != 0 {
-		n += 1 + sovRpc(uint64(m.Target))
-	}
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.TargetUnion != nil {
-		n += m.TargetUnion.Size()
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 2 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *Compare_Version) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRpc(uint64(m.Version))
-	return n
-}
-func (m *Compare_CreateRevision) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRpc(uint64(m.CreateRevision))
-	return n
-}
-func (m *Compare_ModRevision) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRpc(uint64(m.ModRevision))
-	return n
-}
-func (m *Compare_Value) Size() (n int) {
-	var l int
-	_ = l
-	if m.Value != nil {
-		l = len(m.Value)
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *Compare_Lease) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRpc(uint64(m.Lease))
-	return n
-}
-func (m *TxnRequest) Size() (n int) {
-	var l int
-	_ = l
-	if len(m.Compare) > 0 {
-		for _, e := range m.Compare {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if len(m.Success) > 0 {
-		for _, e := range m.Success {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if len(m.Failure) > 0 {
-		for _, e := range m.Failure {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *TxnResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Succeeded {
-		n += 2
-	}
-	if len(m.Responses) > 0 {
-		for _, e := range m.Responses {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *CompactionRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.Revision != 0 {
-		n += 1 + sovRpc(uint64(m.Revision))
-	}
-	if m.Physical {
-		n += 2
-	}
-	return n
-}
-
-func (m *CompactionResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *HashRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *HashKVRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.Revision != 0 {
-		n += 1 + sovRpc(uint64(m.Revision))
-	}
-	return n
-}
-
-func (m *HashKVResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Hash != 0 {
-		n += 1 + sovRpc(uint64(m.Hash))
-	}
-	if m.CompactRevision != 0 {
-		n += 1 + sovRpc(uint64(m.CompactRevision))
-	}
-	return n
-}
-
-func (m *HashResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Hash != 0 {
-		n += 1 + sovRpc(uint64(m.Hash))
-	}
-	return n
-}
-
-func (m *SnapshotRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *SnapshotResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.RemainingBytes != 0 {
-		n += 1 + sovRpc(uint64(m.RemainingBytes))
-	}
-	l = len(m.Blob)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *WatchRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.RequestUnion != nil {
-		n += m.RequestUnion.Size()
-	}
-	return n
-}
-
-func (m *WatchRequest_CreateRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.CreateRequest != nil {
-		l = m.CreateRequest.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *WatchRequest_CancelRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.CancelRequest != nil {
-		l = m.CancelRequest.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *WatchRequest_ProgressRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ProgressRequest != nil {
-		l = m.ProgressRequest.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-func (m *WatchCreateRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.StartRevision != 0 {
-		n += 1 + sovRpc(uint64(m.StartRevision))
-	}
-	if m.ProgressNotify {
-		n += 2
-	}
-	if len(m.Filters) > 0 {
-		l = 0
-		for _, e := range m.Filters {
-			l += sovRpc(uint64(e))
-		}
-		n += 1 + sovRpc(uint64(l)) + l
-	}
-	if m.PrevKv {
-		n += 2
-	}
-	if m.WatchId != 0 {
-		n += 1 + sovRpc(uint64(m.WatchId))
-	}
-	if m.Fragment {
-		n += 2
-	}
-	return n
-}
-
-func (m *WatchCancelRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.WatchId != 0 {
-		n += 1 + sovRpc(uint64(m.WatchId))
-	}
-	return n
-}
-
-func (m *WatchProgressRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *WatchResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.WatchId != 0 {
-		n += 1 + sovRpc(uint64(m.WatchId))
-	}
-	if m.Created {
-		n += 2
-	}
-	if m.Canceled {
-		n += 2
-	}
-	if m.CompactRevision != 0 {
-		n += 1 + sovRpc(uint64(m.CompactRevision))
-	}
-	l = len(m.CancelReason)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Fragment {
-		n += 2
-	}
-	if len(m.Events) > 0 {
-		for _, e := range m.Events {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *LeaseGrantRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.TTL != 0 {
-		n += 1 + sovRpc(uint64(m.TTL))
-	}
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *LeaseGrantResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		n += 1 + sovRpc(uint64(m.TTL))
-	}
-	l = len(m.Error)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaseRevokeRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *LeaseRevokeResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaseCheckpoint) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if m.Remaining_TTL != 0 {
-		n += 1 + sovRpc(uint64(m.Remaining_TTL))
-	}
-	return n
-}
-
-func (m *LeaseCheckpointRequest) Size() (n int) {
-	var l int
-	_ = l
-	if len(m.Checkpoints) > 0 {
-		for _, e := range m.Checkpoints {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *LeaseCheckpointResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaseKeepAliveRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *LeaseKeepAliveResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		n += 1 + sovRpc(uint64(m.TTL))
-	}
-	return n
-}
-
-func (m *LeaseTimeToLiveRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if m.Keys {
-		n += 2
-	}
-	return n
-}
-
-func (m *LeaseTimeToLiveResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		n += 1 + sovRpc(uint64(m.TTL))
-	}
-	if m.GrantedTTL != 0 {
-		n += 1 + sovRpc(uint64(m.GrantedTTL))
-	}
-	if len(m.Keys) > 0 {
-		for _, b := range m.Keys {
-			l = len(b)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *LeaseLeasesRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *LeaseStatus) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *LeaseLeasesResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Leases) > 0 {
-		for _, e := range m.Leases {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *Member) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if len(m.ClientURLs) > 0 {
-		for _, s := range m.ClientURLs {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if m.IsLearner {
-		n += 2
-	}
-	return n
-}
-
-func (m *MemberAddRequest) Size() (n int) {
-	var l int
-	_ = l
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if m.IsLearner {
-		n += 2
-	}
-	return n
-}
-
-func (m *MemberAddResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Member != nil {
-		l = m.Member.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Members) > 0 {
-		for _, e := range m.Members {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *MemberRemoveRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *MemberRemoveResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Members) > 0 {
-		for _, e := range m.Members {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *MemberUpdateRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	if len(m.PeerURLs) > 0 {
-		for _, s := range m.PeerURLs {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *MemberUpdateResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Members) > 0 {
-		for _, e := range m.Members {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *MemberListRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *MemberListResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Members) > 0 {
-		for _, e := range m.Members {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *MemberPromoteRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovRpc(uint64(m.ID))
-	}
-	return n
-}
-
-func (m *MemberPromoteResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Members) > 0 {
-		for _, e := range m.Members {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *DefragmentRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *DefragmentResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *MoveLeaderRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.TargetID != 0 {
-		n += 1 + sovRpc(uint64(m.TargetID))
-	}
-	return n
-}
-
-func (m *MoveLeaderResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AlarmRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.Action != 0 {
-		n += 1 + sovRpc(uint64(m.Action))
-	}
-	if m.MemberID != 0 {
-		n += 1 + sovRpc(uint64(m.MemberID))
-	}
-	if m.Alarm != 0 {
-		n += 1 + sovRpc(uint64(m.Alarm))
-	}
-	return n
-}
-
-func (m *AlarmMember) Size() (n int) {
-	var l int
-	_ = l
-	if m.MemberID != 0 {
-		n += 1 + sovRpc(uint64(m.MemberID))
-	}
-	if m.Alarm != 0 {
-		n += 1 + sovRpc(uint64(m.Alarm))
-	}
-	return n
-}
-
-func (m *AlarmResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Alarms) > 0 {
-		for _, e := range m.Alarms {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *StatusRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *StatusResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Version)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.DbSize != 0 {
-		n += 1 + sovRpc(uint64(m.DbSize))
-	}
-	if m.Leader != 0 {
-		n += 1 + sovRpc(uint64(m.Leader))
-	}
-	if m.RaftIndex != 0 {
-		n += 1 + sovRpc(uint64(m.RaftIndex))
-	}
-	if m.RaftTerm != 0 {
-		n += 1 + sovRpc(uint64(m.RaftTerm))
-	}
-	if m.RaftAppliedIndex != 0 {
-		n += 1 + sovRpc(uint64(m.RaftAppliedIndex))
-	}
-	if len(m.Errors) > 0 {
-		for _, s := range m.Errors {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	if m.DbSizeInUse != 0 {
-		n += 1 + sovRpc(uint64(m.DbSizeInUse))
-	}
-	if m.IsLearner {
-		n += 2
-	}
-	return n
-}
-
-func (m *AuthEnableRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *AuthDisableRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *AuthenticateRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Password)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserAddRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Password)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Options != nil {
-		l = m.Options.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserGetRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserDeleteRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserChangePasswordRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Password)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserGrantRoleRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.User)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Role)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserRevokeRoleRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Role)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleAddRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleGetRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Role)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserListRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *AuthRoleListRequest) Size() (n int) {
-	var l int
-	_ = l
-	return n
-}
-
-func (m *AuthRoleDeleteRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Role)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleGrantPermissionRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Name)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if m.Perm != nil {
-		l = m.Perm.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleRevokePermissionRequest) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Role)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.RangeEnd)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthEnableResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthDisableResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthenticateResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	l = len(m.Token)
-	if l > 0 {
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserAddResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserGetResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *AuthUserDeleteResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserChangePasswordResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserGrantRoleResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthUserRevokeRoleResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleAddResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleGetResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Perm) > 0 {
-		for _, e := range m.Perm {
-			l = e.Size()
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *AuthRoleListResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Roles) > 0 {
-		for _, s := range m.Roles {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *AuthUserListResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	if len(m.Users) > 0 {
-		for _, s := range m.Users {
-			l = len(s)
-			n += 1 + l + sovRpc(uint64(l))
-		}
-	}
-	return n
-}
-
-func (m *AuthRoleDeleteResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleGrantPermissionResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func (m *AuthRoleRevokePermissionResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.Header != nil {
-		l = m.Header.Size()
-		n += 1 + l + sovRpc(uint64(l))
-	}
-	return n
-}
-
-func sovRpc(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozRpc(x uint64) (n int) {
-	return sovRpc(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *ResponseHeader) 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 ErrIntOverflowRpc
-			}
-			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: ResponseHeader: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ResponseHeader: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ClusterId", wireType)
-			}
-			m.ClusterId = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ClusterId |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MemberId", wireType)
-			}
-			m.MemberId = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MemberId |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
-			}
-			m.Revision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Revision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RaftTerm", wireType)
-			}
-			m.RaftTerm = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RaftTerm |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *RangeRequest) 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 ErrIntOverflowRpc
-			}
-			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: RangeRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: RangeRequest: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType)
-			}
-			m.Limit = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Limit |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
-			}
-			m.Revision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Revision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SortOrder", wireType)
-			}
-			m.SortOrder = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.SortOrder |= (RangeRequest_SortOrder(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field SortTarget", wireType)
-			}
-			m.SortTarget = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.SortTarget |= (RangeRequest_SortTarget(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 7:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Serializable", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Serializable = bool(v != 0)
-		case 8:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field KeysOnly", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.KeysOnly = bool(v != 0)
-		case 9:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CountOnly", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.CountOnly = bool(v != 0)
-		case 10:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MinModRevision", wireType)
-			}
-			m.MinModRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MinModRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 11:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MaxModRevision", wireType)
-			}
-			m.MaxModRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MaxModRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 12:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MinCreateRevision", wireType)
-			}
-			m.MinCreateRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MinCreateRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 13:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MaxCreateRevision", wireType)
-			}
-			m.MaxCreateRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MaxCreateRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *RangeResponse) 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 ErrIntOverflowRpc
-			}
-			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: RangeResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: RangeResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Kvs", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Kvs = append(m.Kvs, &mvccpb.KeyValue{})
-			if err := m.Kvs[len(m.Kvs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field More", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.More = bool(v != 0)
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType)
-			}
-			m.Count = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Count |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *PutRequest) 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 ErrIntOverflowRpc
-			}
-			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: PutRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: PutRequest: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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
-		case 3:
-			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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Lease |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.PrevKv = bool(v != 0)
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IgnoreValue", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.IgnoreValue = bool(v != 0)
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IgnoreLease", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.IgnoreLease = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *PutResponse) 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 ErrIntOverflowRpc
-			}
-			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: PutResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: PutResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 PrevKv", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.PrevKv == nil {
-				m.PrevKv = &mvccpb.KeyValue{}
-			}
-			if err := m.PrevKv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *DeleteRangeRequest) 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 ErrIntOverflowRpc
-			}
-			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: DeleteRangeRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: DeleteRangeRequest: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.PrevKv = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *DeleteRangeResponse) 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 ErrIntOverflowRpc
-			}
-			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: DeleteRangeResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: DeleteRangeResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Deleted", wireType)
-			}
-			m.Deleted = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Deleted |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevKvs", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.PrevKvs = append(m.PrevKvs, &mvccpb.KeyValue{})
-			if err := m.PrevKvs[len(m.PrevKvs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *RequestOp) 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 ErrIntOverflowRpc
-			}
-			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: RequestOp: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: RequestOp: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RequestRange", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &RangeRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Request = &RequestOp_RequestRange{v}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RequestPut", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &PutRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Request = &RequestOp_RequestPut{v}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RequestDeleteRange", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &DeleteRangeRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Request = &RequestOp_RequestDeleteRange{v}
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RequestTxn", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &TxnRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Request = &RequestOp_RequestTxn{v}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *ResponseOp) 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 ErrIntOverflowRpc
-			}
-			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: ResponseOp: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ResponseOp: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ResponseRange", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &RangeResponse{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Response = &ResponseOp_ResponseRange{v}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ResponsePut", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &PutResponse{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Response = &ResponseOp_ResponsePut{v}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ResponseDeleteRange", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &DeleteRangeResponse{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Response = &ResponseOp_ResponseDeleteRange{v}
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ResponseTxn", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &TxnResponse{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.Response = &ResponseOp_ResponseTxn{v}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *Compare) 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 ErrIntOverflowRpc
-			}
-			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: Compare: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Compare: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType)
-			}
-			m.Result = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Result |= (Compare_CompareResult(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType)
-			}
-			m.Target = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Target |= (Compare_CompareTarget(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
-			}
-			var v int64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.TargetUnion = &Compare_Version{v}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CreateRevision", wireType)
-			}
-			var v int64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.TargetUnion = &Compare_CreateRevision{v}
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ModRevision", wireType)
-			}
-			var v int64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.TargetUnion = &Compare_ModRevision{v}
-		case 7:
-			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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := make([]byte, postIndex-iNdEx)
-			copy(v, dAtA[iNdEx:postIndex])
-			m.TargetUnion = &Compare_Value{v}
-			iNdEx = postIndex
-		case 8:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Lease", wireType)
-			}
-			var v int64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.TargetUnion = &Compare_Lease{v}
-		case 64:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *TxnRequest) 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 ErrIntOverflowRpc
-			}
-			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: TxnRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: TxnRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Compare", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Compare = append(m.Compare, &Compare{})
-			if err := m.Compare[len(m.Compare)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Success = append(m.Success, &RequestOp{})
-			if err := m.Success[len(m.Success)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Failure", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Failure = append(m.Failure, &RequestOp{})
-			if err := m.Failure[len(m.Failure)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *TxnResponse) 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 ErrIntOverflowRpc
-			}
-			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: TxnResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: TxnResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Succeeded", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Succeeded = bool(v != 0)
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Responses", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Responses = append(m.Responses, &ResponseOp{})
-			if err := m.Responses[len(m.Responses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *CompactionRequest) 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 ErrIntOverflowRpc
-			}
-			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: CompactionRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: CompactionRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
-			}
-			m.Revision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Revision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Physical", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Physical = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *CompactionResponse) 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 ErrIntOverflowRpc
-			}
-			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: CompactionResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: CompactionResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *HashRequest) 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 ErrIntOverflowRpc
-			}
-			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: HashRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HashRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *HashKVRequest) 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 ErrIntOverflowRpc
-			}
-			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: HashKVRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HashKVRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Revision", wireType)
-			}
-			m.Revision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Revision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *HashKVResponse) 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 ErrIntOverflowRpc
-			}
-			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: HashKVResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HashKVResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
-			}
-			m.Hash = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Hash |= (uint32(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CompactRevision", wireType)
-			}
-			m.CompactRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.CompactRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *HashResponse) 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 ErrIntOverflowRpc
-			}
-			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: HashResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HashResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
-			}
-			m.Hash = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Hash |= (uint32(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *SnapshotRequest) 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 ErrIntOverflowRpc
-			}
-			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: SnapshotRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: SnapshotRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *SnapshotResponse) 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 ErrIntOverflowRpc
-			}
-			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: SnapshotResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: SnapshotResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RemainingBytes", wireType)
-			}
-			m.RemainingBytes = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RemainingBytes |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Blob", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Blob = append(m.Blob[:0], dAtA[iNdEx:postIndex]...)
-			if m.Blob == nil {
-				m.Blob = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *WatchRequest) 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 ErrIntOverflowRpc
-			}
-			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: WatchRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: WatchRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CreateRequest", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &WatchCreateRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.RequestUnion = &WatchRequest_CreateRequest{v}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CancelRequest", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &WatchCancelRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.RequestUnion = &WatchRequest_CancelRequest{v}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ProgressRequest", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			v := &WatchProgressRequest{}
-			if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			m.RequestUnion = &WatchRequest_ProgressRequest{v}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *WatchCreateRequest) 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 ErrIntOverflowRpc
-			}
-			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: WatchCreateRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: WatchCreateRequest: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field StartRevision", wireType)
-			}
-			m.StartRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.StartRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ProgressNotify", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.ProgressNotify = bool(v != 0)
-		case 5:
-			if wireType == 0 {
-				var v WatchCreateRequest_FilterType
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRpc
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				m.Filters = append(m.Filters, v)
-			} else if wireType == 2 {
-				var packedLen int
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRpc
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					packedLen |= (int(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				if packedLen < 0 {
-					return ErrInvalidLengthRpc
-				}
-				postIndex := iNdEx + packedLen
-				if postIndex > l {
-					return io.ErrUnexpectedEOF
-				}
-				for iNdEx < postIndex {
-					var v WatchCreateRequest_FilterType
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowRpc
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						v |= (WatchCreateRequest_FilterType(b) & 0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					m.Filters = append(m.Filters, v)
-				}
-			} else {
-				return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType)
-			}
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.PrevKv = bool(v != 0)
-		case 7:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field WatchId", wireType)
-			}
-			m.WatchId = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.WatchId |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 8:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Fragment", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Fragment = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *WatchCancelRequest) 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 ErrIntOverflowRpc
-			}
-			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: WatchCancelRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: WatchCancelRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field WatchId", wireType)
-			}
-			m.WatchId = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.WatchId |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *WatchProgressRequest) 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 ErrIntOverflowRpc
-			}
-			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: WatchProgressRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: WatchProgressRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *WatchResponse) 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 ErrIntOverflowRpc
-			}
-			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: WatchResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: WatchResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field WatchId", wireType)
-			}
-			m.WatchId = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.WatchId |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Created", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Created = bool(v != 0)
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Canceled", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Canceled = bool(v != 0)
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CompactRevision", wireType)
-			}
-			m.CompactRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.CompactRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 6:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CancelReason", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.CancelReason = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 7:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Fragment", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Fragment = bool(v != 0)
-		case 11:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Events = append(m.Events, &mvccpb.Event{})
-			if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseGrantRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseGrantRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType)
-			}
-			m.TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseGrantResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseGrantResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseGrantResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType)
-			}
-			m.TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Error = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseRevokeRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseRevokeRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseRevokeResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseRevokeResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseRevokeResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseCheckpoint) 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 ErrIntOverflowRpc
-			}
-			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: LeaseCheckpoint: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseCheckpoint: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Remaining_TTL", wireType)
-			}
-			m.Remaining_TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Remaining_TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseCheckpointRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseCheckpointRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseCheckpointRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Checkpoints", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Checkpoints = append(m.Checkpoints, &LeaseCheckpoint{})
-			if err := m.Checkpoints[len(m.Checkpoints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseCheckpointResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseCheckpointResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseCheckpointResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseKeepAliveRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseKeepAliveRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseKeepAliveRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseKeepAliveResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseKeepAliveResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseKeepAliveResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType)
-			}
-			m.TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseTimeToLiveRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseTimeToLiveRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseTimeToLiveRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Keys = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseTimeToLiveResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseTimeToLiveResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseTimeToLiveResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType)
-			}
-			m.TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field GrantedTTL", wireType)
-			}
-			m.GrantedTTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.GrantedTTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 5:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Keys = append(m.Keys, make([]byte, postIndex-iNdEx))
-			copy(m.Keys[len(m.Keys)-1], dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseLeasesRequest) 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 ErrIntOverflowRpc
-			}
-			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: LeaseLeasesRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseLeasesRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseStatus) 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 ErrIntOverflowRpc
-			}
-			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: LeaseStatus: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseStatus: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseLeasesResponse) 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 ErrIntOverflowRpc
-			}
-			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: LeaseLeasesResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseLeasesResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Leases", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Leases = append(m.Leases, &LeaseStatus{})
-			if err := m.Leases[len(m.Leases)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *Member) 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 ErrIntOverflowRpc
-			}
-			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: Member: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Member: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PeerURLs", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ClientURLs", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.ClientURLs = append(m.ClientURLs, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IsLearner", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.IsLearner = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberAddRequest) 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 ErrIntOverflowRpc
-			}
-			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: MemberAddRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberAddRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PeerURLs", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IsLearner", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.IsLearner = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberAddResponse) 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 ErrIntOverflowRpc
-			}
-			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: MemberAddResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberAddResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Member", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Member == nil {
-				m.Member = &Member{}
-			}
-			if err := m.Member.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Members", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Members = append(m.Members, &Member{})
-			if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberRemoveRequest) 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 ErrIntOverflowRpc
-			}
-			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: MemberRemoveRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberRemoveRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberRemoveResponse) 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 ErrIntOverflowRpc
-			}
-			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: MemberRemoveResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberRemoveResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Members", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Members = append(m.Members, &Member{})
-			if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberUpdateRequest) 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 ErrIntOverflowRpc
-			}
-			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: MemberUpdateRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberUpdateRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PeerURLs", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.PeerURLs = append(m.PeerURLs, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberUpdateResponse) 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 ErrIntOverflowRpc
-			}
-			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: MemberUpdateResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberUpdateResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Members", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Members = append(m.Members, &Member{})
-			if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberListRequest) 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 ErrIntOverflowRpc
-			}
-			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: MemberListRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberListRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberListResponse) 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 ErrIntOverflowRpc
-			}
-			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: MemberListResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberListResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Members", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Members = append(m.Members, &Member{})
-			if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberPromoteRequest) 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 ErrIntOverflowRpc
-			}
-			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: MemberPromoteRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberPromoteRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MemberPromoteResponse) 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 ErrIntOverflowRpc
-			}
-			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: MemberPromoteResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MemberPromoteResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Members", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Members = append(m.Members, &Member{})
-			if err := m.Members[len(m.Members)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *DefragmentRequest) 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 ErrIntOverflowRpc
-			}
-			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: DefragmentRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: DefragmentRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *DefragmentResponse) 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 ErrIntOverflowRpc
-			}
-			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: DefragmentResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: DefragmentResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MoveLeaderRequest) 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 ErrIntOverflowRpc
-			}
-			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: MoveLeaderRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MoveLeaderRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TargetID", wireType)
-			}
-			m.TargetID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TargetID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *MoveLeaderResponse) 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 ErrIntOverflowRpc
-			}
-			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: MoveLeaderResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: MoveLeaderResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AlarmRequest) 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 ErrIntOverflowRpc
-			}
-			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: AlarmRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AlarmRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType)
-			}
-			m.Action = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Action |= (AlarmRequest_AlarmAction(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MemberID", wireType)
-			}
-			m.MemberID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MemberID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
-			}
-			m.Alarm = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Alarm |= (AlarmType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AlarmMember) 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 ErrIntOverflowRpc
-			}
-			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: AlarmMember: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AlarmMember: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field MemberID", wireType)
-			}
-			m.MemberID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.MemberID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType)
-			}
-			m.Alarm = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Alarm |= (AlarmType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AlarmResponse) 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 ErrIntOverflowRpc
-			}
-			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: AlarmResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AlarmResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Alarms", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Alarms = append(m.Alarms, &AlarmMember{})
-			if err := m.Alarms[len(m.Alarms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *StatusRequest) 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 ErrIntOverflowRpc
-			}
-			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: StatusRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: StatusRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *StatusResponse) 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 ErrIntOverflowRpc
-			}
-			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: StatusResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: StatusResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Version", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Version = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DbSize", wireType)
-			}
-			m.DbSize = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.DbSize |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType)
-			}
-			m.Leader = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Leader |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RaftIndex", wireType)
-			}
-			m.RaftIndex = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RaftIndex |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RaftTerm", wireType)
-			}
-			m.RaftTerm = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RaftTerm |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 7:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RaftAppliedIndex", wireType)
-			}
-			m.RaftAppliedIndex = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RaftAppliedIndex |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 8:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Errors", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Errors = append(m.Errors, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		case 9:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field DbSizeInUse", wireType)
-			}
-			m.DbSizeInUse = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.DbSizeInUse |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 10:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field IsLearner", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.IsLearner = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthEnableRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthEnableRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthEnableRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthDisableRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthDisableRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthDisableRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthenticateRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthenticateRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthenticateRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Password = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserAddRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserAddRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserAddRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Password = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Options == nil {
-				m.Options = &authpb.UserAddOptions{}
-			}
-			if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserGetRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserGetRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserGetRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserDeleteRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserDeleteRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserDeleteRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserChangePasswordRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserChangePasswordRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserChangePasswordRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Password = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserGrantRoleRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserGrantRoleRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserGrantRoleRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field User", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.User = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Role = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserRevokeRoleRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserRevokeRoleRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserRevokeRoleRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Role = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleAddRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleAddRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleAddRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleGetRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleGetRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleGetRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Role = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserListRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserListRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserListRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleListRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleListRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleListRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleDeleteRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleDeleteRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Role = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleGrantPermissionRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleGrantPermissionRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleGrantPermissionRequest: 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 stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Name = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Perm", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Perm == nil {
-				m.Perm = &authpb.Permission{}
-			}
-			if err := m.Perm.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleRevokePermissionRequest) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleRevokePermissionRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleRevokePermissionRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Role = string(dAtA[iNdEx:postIndex])
-			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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			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 != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RangeEnd", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.RangeEnd = append(m.RangeEnd[:0], dAtA[iNdEx:postIndex]...)
-			if m.RangeEnd == nil {
-				m.RangeEnd = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthEnableResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthEnableResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthEnableResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthDisableResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthDisableResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthDisableResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthenticateResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthenticateResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthenticateResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Token", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Token = string(dAtA[iNdEx:postIndex])
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserAddResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserAddResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserAddResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserGetResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserGetResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserGetResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Roles", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserDeleteResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserDeleteResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserDeleteResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserChangePasswordResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserChangePasswordResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserChangePasswordResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserGrantRoleResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserGrantRoleResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserGrantRoleResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserRevokeRoleResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserRevokeRoleResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserRevokeRoleResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleAddResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleAddResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleAddResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleGetResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleGetResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleGetResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Perm", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Perm = append(m.Perm, &authpb.Permission{})
-			if err := m.Perm[len(m.Perm)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleListResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleListResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleListResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Roles", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthUserListResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthUserListResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthUserListResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &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 Users", wireType)
-			}
-			var stringLen uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLen := int(stringLen)
-			if intStringLen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + intStringLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Users = append(m.Users, string(dAtA[iNdEx:postIndex]))
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleDeleteResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleDeleteResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleDeleteResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleGrantPermissionResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleGrantPermissionResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleGrantPermissionResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *AuthRoleRevokePermissionResponse) 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 ErrIntOverflowRpc
-			}
-			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: AuthRoleRevokePermissionResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: AuthRoleRevokePermissionResponse: 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 ErrIntOverflowRpc
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRpc
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Header == nil {
-				m.Header = &ResponseHeader{}
-			}
-			if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRpc(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRpc
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipRpc(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, ErrIntOverflowRpc
-			}
-			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, ErrIntOverflowRpc
-				}
-				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, ErrIntOverflowRpc
-				}
-				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, ErrInvalidLengthRpc
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowRpc
-					}
-					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 := skipRpc(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 (
-	ErrInvalidLengthRpc = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowRpc   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) }
-
-var fileDescriptorRpc = []byte{
-	// 3928 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0x5b, 0x6f, 0x23, 0xc9,
-	0x75, 0x56, 0x93, 0xe2, 0xed, 0xf0, 0x22, 0xaa, 0x74, 0x19, 0x0e, 0x67, 0x46, 0xa3, 0xad, 0xd9,
-	0xd9, 0xd5, 0xce, 0xec, 0x8a, 0x6b, 0xd9, 0x4e, 0x80, 0x49, 0xe2, 0x58, 0x23, 0x71, 0x67, 0xb4,
-	0xd2, 0x88, 0xda, 0x16, 0x67, 0xf6, 0x02, 0x23, 0x42, 0x8b, 0x2c, 0x49, 0x1d, 0x91, 0xdd, 0x74,
-	0x77, 0x93, 0x23, 0x6d, 0x2e, 0x0e, 0x0c, 0xc7, 0x40, 0xf2, 0x68, 0x03, 0x41, 0xf2, 0x90, 0xa7,
-	0x20, 0x08, 0xfc, 0x90, 0xe7, 0x00, 0xf9, 0x05, 0x79, 0xca, 0x05, 0xf9, 0x03, 0xc1, 0xc6, 0x2f,
-	0xc9, 0xaf, 0x30, 0xea, 0xd6, 0x5d, 0x7d, 0xa3, 0xc6, 0xa6, 0x77, 0x5f, 0xa4, 0xae, 0x53, 0xa7,
-	0xce, 0x39, 0x75, 0xaa, 0xea, 0x9c, 0xd3, 0x5f, 0x17, 0xa1, 0xe4, 0x8c, 0x7a, 0x9b, 0x23, 0xc7,
-	0xf6, 0x6c, 0x54, 0x21, 0x5e, 0xaf, 0xef, 0x12, 0x67, 0x42, 0x9c, 0xd1, 0x69, 0x73, 0xf9, 0xdc,
-	0x3e, 0xb7, 0x59, 0x47, 0x8b, 0x3e, 0x71, 0x9e, 0xe6, 0x6d, 0xca, 0xd3, 0x1a, 0x4e, 0x7a, 0x3d,
-	0xf6, 0x67, 0x74, 0xda, 0xba, 0x9c, 0x88, 0xae, 0x3b, 0xac, 0xcb, 0x18, 0x7b, 0x17, 0xec, 0xcf,
-	0xe8, 0x94, 0xfd, 0x13, 0x9d, 0x77, 0xcf, 0x6d, 0xfb, 0x7c, 0x40, 0x5a, 0xc6, 0xc8, 0x6c, 0x19,
-	0x96, 0x65, 0x7b, 0x86, 0x67, 0xda, 0x96, 0xcb, 0x7b, 0xf1, 0x5f, 0x6a, 0x50, 0xd3, 0x89, 0x3b,
-	0xb2, 0x2d, 0x97, 0x3c, 0x27, 0x46, 0x9f, 0x38, 0xe8, 0x1e, 0x40, 0x6f, 0x30, 0x76, 0x3d, 0xe2,
-	0x9c, 0x98, 0xfd, 0x86, 0xb6, 0xae, 0x6d, 0xcc, 0xeb, 0x25, 0x41, 0xd9, 0xeb, 0xa3, 0x3b, 0x50,
-	0x1a, 0x92, 0xe1, 0x29, 0xef, 0xcd, 0xb0, 0xde, 0x22, 0x27, 0xec, 0xf5, 0x51, 0x13, 0x8a, 0x0e,
-	0x99, 0x98, 0xae, 0x69, 0x5b, 0x8d, 0xec, 0xba, 0xb6, 0x91, 0xd5, 0xfd, 0x36, 0x1d, 0xe8, 0x18,
-	0x67, 0xde, 0x89, 0x47, 0x9c, 0x61, 0x63, 0x9e, 0x0f, 0xa4, 0x84, 0x2e, 0x71, 0x86, 0xf8, 0x27,
-	0x39, 0xa8, 0xe8, 0x86, 0x75, 0x4e, 0x74, 0xf2, 0xc3, 0x31, 0x71, 0x3d, 0x54, 0x87, 0xec, 0x25,
-	0xb9, 0x66, 0xea, 0x2b, 0x3a, 0x7d, 0xe4, 0xe3, 0xad, 0x73, 0x72, 0x42, 0x2c, 0xae, 0xb8, 0x42,
-	0xc7, 0x5b, 0xe7, 0xa4, 0x6d, 0xf5, 0xd1, 0x32, 0xe4, 0x06, 0xe6, 0xd0, 0xf4, 0x84, 0x56, 0xde,
-	0x08, 0x99, 0x33, 0x1f, 0x31, 0x67, 0x07, 0xc0, 0xb5, 0x1d, 0xef, 0xc4, 0x76, 0xfa, 0xc4, 0x69,
-	0xe4, 0xd6, 0xb5, 0x8d, 0xda, 0xd6, 0xdb, 0x9b, 0xea, 0x42, 0x6c, 0xaa, 0x06, 0x6d, 0x1e, 0xdb,
-	0x8e, 0xd7, 0xa1, 0xbc, 0x7a, 0xc9, 0x95, 0x8f, 0xe8, 0x23, 0x28, 0x33, 0x21, 0x9e, 0xe1, 0x9c,
-	0x13, 0xaf, 0x91, 0x67, 0x52, 0x1e, 0xde, 0x20, 0xa5, 0xcb, 0x98, 0x75, 0xa6, 0x9e, 0x3f, 0x23,
-	0x0c, 0x15, 0x97, 0x38, 0xa6, 0x31, 0x30, 0xbf, 0x34, 0x4e, 0x07, 0xa4, 0x51, 0x58, 0xd7, 0x36,
-	0x8a, 0x7a, 0x88, 0x46, 0xe7, 0x7f, 0x49, 0xae, 0xdd, 0x13, 0xdb, 0x1a, 0x5c, 0x37, 0x8a, 0x8c,
-	0xa1, 0x48, 0x09, 0x1d, 0x6b, 0x70, 0xcd, 0x16, 0xcd, 0x1e, 0x5b, 0x1e, 0xef, 0x2d, 0xb1, 0xde,
-	0x12, 0xa3, 0xb0, 0xee, 0x0d, 0xa8, 0x0f, 0x4d, 0xeb, 0x64, 0x68, 0xf7, 0x4f, 0x7c, 0x87, 0x00,
-	0x73, 0x48, 0x6d, 0x68, 0x5a, 0x2f, 0xec, 0xbe, 0x2e, 0xdd, 0x42, 0x39, 0x8d, 0xab, 0x30, 0x67,
-	0x59, 0x70, 0x1a, 0x57, 0x2a, 0xe7, 0x26, 0x2c, 0x51, 0x99, 0x3d, 0x87, 0x18, 0x1e, 0x09, 0x98,
-	0x2b, 0x8c, 0x79, 0x71, 0x68, 0x5a, 0x3b, 0xac, 0x27, 0xc4, 0x6f, 0x5c, 0xc5, 0xf8, 0xab, 0x82,
-	0xdf, 0xb8, 0x0a, 0xf3, 0xe3, 0x4d, 0x28, 0xf9, 0x3e, 0x47, 0x45, 0x98, 0x3f, 0xec, 0x1c, 0xb6,
-	0xeb, 0x73, 0x08, 0x20, 0xbf, 0x7d, 0xbc, 0xd3, 0x3e, 0xdc, 0xad, 0x6b, 0xa8, 0x0c, 0x85, 0xdd,
-	0x36, 0x6f, 0x64, 0xf0, 0x53, 0x80, 0xc0, 0xbb, 0xa8, 0x00, 0xd9, 0xfd, 0xf6, 0xe7, 0xf5, 0x39,
-	0xca, 0xf3, 0xaa, 0xad, 0x1f, 0xef, 0x75, 0x0e, 0xeb, 0x1a, 0x1d, 0xbc, 0xa3, 0xb7, 0xb7, 0xbb,
-	0xed, 0x7a, 0x86, 0x72, 0xbc, 0xe8, 0xec, 0xd6, 0xb3, 0xa8, 0x04, 0xb9, 0x57, 0xdb, 0x07, 0x2f,
-	0xdb, 0xf5, 0x79, 0xfc, 0x73, 0x0d, 0xaa, 0x62, 0xbd, 0xf8, 0x99, 0x40, 0xdf, 0x81, 0xfc, 0x05,
-	0x3b, 0x17, 0x6c, 0x2b, 0x96, 0xb7, 0xee, 0x46, 0x16, 0x37, 0x74, 0x76, 0x74, 0xc1, 0x8b, 0x30,
-	0x64, 0x2f, 0x27, 0x6e, 0x23, 0xb3, 0x9e, 0xdd, 0x28, 0x6f, 0xd5, 0x37, 0xf9, 0x81, 0xdd, 0xdc,
-	0x27, 0xd7, 0xaf, 0x8c, 0xc1, 0x98, 0xe8, 0xb4, 0x13, 0x21, 0x98, 0x1f, 0xda, 0x0e, 0x61, 0x3b,
-	0xb6, 0xa8, 0xb3, 0x67, 0xba, 0x8d, 0xd9, 0xa2, 0x89, 0xdd, 0xca, 0x1b, 0xf8, 0x17, 0x1a, 0xc0,
-	0xd1, 0xd8, 0x4b, 0x3f, 0x1a, 0xcb, 0x90, 0x9b, 0x50, 0xc1, 0xe2, 0x58, 0xf0, 0x06, 0x3b, 0x13,
-	0xc4, 0x70, 0x89, 0x7f, 0x26, 0x68, 0x03, 0xdd, 0x82, 0xc2, 0xc8, 0x21, 0x93, 0x93, 0xcb, 0x09,
-	0x53, 0x52, 0xd4, 0xf3, 0xb4, 0xb9, 0x3f, 0x41, 0x6f, 0x41, 0xc5, 0x3c, 0xb7, 0x6c, 0x87, 0x9c,
-	0x70, 0x59, 0x39, 0xd6, 0x5b, 0xe6, 0x34, 0x66, 0xb7, 0xc2, 0xc2, 0x05, 0xe7, 0x55, 0x96, 0x03,
-	0x4a, 0xc2, 0x16, 0x94, 0x99, 0xa9, 0x33, 0xb9, 0xef, 0xbd, 0xc0, 0xc6, 0x0c, 0x1b, 0x16, 0x77,
-	0xa1, 0xb0, 0x1a, 0xff, 0x00, 0xd0, 0x2e, 0x19, 0x10, 0x8f, 0xcc, 0x12, 0x3d, 0x14, 0x9f, 0x64,
-	0x55, 0x9f, 0xe0, 0x9f, 0x69, 0xb0, 0x14, 0x12, 0x3f, 0xd3, 0xb4, 0x1a, 0x50, 0xe8, 0x33, 0x61,
-	0xdc, 0x82, 0xac, 0x2e, 0x9b, 0xe8, 0x31, 0x14, 0x85, 0x01, 0x6e, 0x23, 0x9b, 0xb2, 0x69, 0x0a,
-	0xdc, 0x26, 0x17, 0xff, 0x22, 0x03, 0x25, 0x31, 0xd1, 0xce, 0x08, 0x6d, 0x43, 0xd5, 0xe1, 0x8d,
-	0x13, 0x36, 0x1f, 0x61, 0x51, 0x33, 0x3d, 0x08, 0x3d, 0x9f, 0xd3, 0x2b, 0x62, 0x08, 0x23, 0xa3,
-	0xdf, 0x83, 0xb2, 0x14, 0x31, 0x1a, 0x7b, 0xc2, 0xe5, 0x8d, 0xb0, 0x80, 0x60, 0xff, 0x3d, 0x9f,
-	0xd3, 0x41, 0xb0, 0x1f, 0x8d, 0x3d, 0xd4, 0x85, 0x65, 0x39, 0x98, 0xcf, 0x46, 0x98, 0x91, 0x65,
-	0x52, 0xd6, 0xc3, 0x52, 0xe2, 0x4b, 0xf5, 0x7c, 0x4e, 0x47, 0x62, 0xbc, 0xd2, 0xa9, 0x9a, 0xe4,
-	0x5d, 0xf1, 0xe0, 0x1d, 0x33, 0xa9, 0x7b, 0x65, 0xc5, 0x4d, 0xea, 0x5e, 0x59, 0x4f, 0x4b, 0x50,
-	0x10, 0x2d, 0xfc, 0x2f, 0x19, 0x00, 0xb9, 0x1a, 0x9d, 0x11, 0xda, 0x85, 0x9a, 0x23, 0x5a, 0x21,
-	0x6f, 0xdd, 0x49, 0xf4, 0x96, 0x58, 0xc4, 0x39, 0xbd, 0x2a, 0x07, 0x71, 0xe3, 0xbe, 0x07, 0x15,
-	0x5f, 0x4a, 0xe0, 0xb0, 0xdb, 0x09, 0x0e, 0xf3, 0x25, 0x94, 0xe5, 0x00, 0xea, 0xb2, 0x4f, 0x61,
-	0xc5, 0x1f, 0x9f, 0xe0, 0xb3, 0xb7, 0xa6, 0xf8, 0xcc, 0x17, 0xb8, 0x24, 0x25, 0xa8, 0x5e, 0x53,
-	0x0d, 0x0b, 0xdc, 0x76, 0x3b, 0xc1, 0x6d, 0x71, 0xc3, 0xa8, 0xe3, 0x80, 0xe6, 0x4b, 0xde, 0xc4,
-	0xff, 0x97, 0x85, 0xc2, 0x8e, 0x3d, 0x1c, 0x19, 0x0e, 0x5d, 0x8d, 0xbc, 0x43, 0xdc, 0xf1, 0xc0,
-	0x63, 0xee, 0xaa, 0x6d, 0x3d, 0x08, 0x4b, 0x14, 0x6c, 0xf2, 0xbf, 0xce, 0x58, 0x75, 0x31, 0x84,
-	0x0e, 0x16, 0xe9, 0x31, 0xf3, 0x06, 0x83, 0x45, 0x72, 0x14, 0x43, 0xe4, 0x41, 0xce, 0x06, 0x07,
-	0xb9, 0x09, 0x85, 0x09, 0x71, 0x82, 0x94, 0xfe, 0x7c, 0x4e, 0x97, 0x04, 0xf4, 0x1e, 0x2c, 0x44,
-	0xd3, 0x4b, 0x4e, 0xf0, 0xd4, 0x7a, 0xe1, 0x6c, 0xf4, 0x00, 0x2a, 0xa1, 0x1c, 0x97, 0x17, 0x7c,
-	0xe5, 0xa1, 0x92, 0xe2, 0x56, 0x65, 0x5c, 0xa5, 0xf9, 0xb8, 0xf2, 0x7c, 0x4e, 0x46, 0xd6, 0x55,
-	0x19, 0x59, 0x8b, 0x62, 0x94, 0x88, 0xad, 0xa1, 0x20, 0xf3, 0xfd, 0x70, 0x90, 0xc1, 0xdf, 0x87,
-	0x6a, 0xc8, 0x41, 0x34, 0xef, 0xb4, 0x3f, 0x79, 0xb9, 0x7d, 0xc0, 0x93, 0xd4, 0x33, 0x96, 0x97,
-	0xf4, 0xba, 0x46, 0x73, 0xdd, 0x41, 0xfb, 0xf8, 0xb8, 0x9e, 0x41, 0x55, 0x28, 0x1d, 0x76, 0xba,
-	0x27, 0x9c, 0x2b, 0x8b, 0x9f, 0xf9, 0x12, 0x44, 0x92, 0x53, 0x72, 0xdb, 0x9c, 0x92, 0xdb, 0x34,
-	0x99, 0xdb, 0x32, 0x41, 0x6e, 0x63, 0x69, 0xee, 0xa0, 0xbd, 0x7d, 0xdc, 0xae, 0xcf, 0x3f, 0xad,
-	0x41, 0x85, 0xfb, 0xf7, 0x64, 0x6c, 0xd1, 0x54, 0xfb, 0x0f, 0x1a, 0x40, 0x70, 0x9a, 0x50, 0x0b,
-	0x0a, 0x3d, 0xae, 0xa7, 0xa1, 0xb1, 0x60, 0xb4, 0x92, 0xb8, 0x64, 0xba, 0xe4, 0x42, 0xdf, 0x82,
-	0x82, 0x3b, 0xee, 0xf5, 0x88, 0x2b, 0x53, 0xde, 0xad, 0x68, 0x3c, 0x14, 0xd1, 0x4a, 0x97, 0x7c,
-	0x74, 0xc8, 0x99, 0x61, 0x0e, 0xc6, 0x2c, 0x01, 0x4e, 0x1f, 0x22, 0xf8, 0xf0, 0xdf, 0x69, 0x50,
-	0x56, 0x36, 0xef, 0x6f, 0x18, 0x84, 0xef, 0x42, 0x89, 0xd9, 0x40, 0xfa, 0x22, 0x0c, 0x17, 0xf5,
-	0x80, 0x80, 0x7e, 0x07, 0x4a, 0xf2, 0x04, 0xc8, 0x48, 0xdc, 0x48, 0x16, 0xdb, 0x19, 0xe9, 0x01,
-	0x2b, 0xde, 0x87, 0x45, 0xe6, 0x95, 0x1e, 0x2d, 0xae, 0xa5, 0x1f, 0xd5, 0xf2, 0x53, 0x8b, 0x94,
-	0x9f, 0x4d, 0x28, 0x8e, 0x2e, 0xae, 0x5d, 0xb3, 0x67, 0x0c, 0x84, 0x15, 0x7e, 0x1b, 0x7f, 0x0c,
-	0x48, 0x15, 0x36, 0xcb, 0x74, 0x71, 0x15, 0xca, 0xcf, 0x0d, 0xf7, 0x42, 0x98, 0x84, 0x1f, 0x43,
-	0x95, 0x36, 0xf7, 0x5f, 0xbd, 0x81, 0x8d, 0xec, 0xe5, 0x40, 0x72, 0xcf, 0xe4, 0x73, 0x04, 0xf3,
-	0x17, 0x86, 0x7b, 0xc1, 0x26, 0x5a, 0xd5, 0xd9, 0x33, 0x7a, 0x0f, 0xea, 0x3d, 0x3e, 0xc9, 0x93,
-	0xc8, 0x2b, 0xc3, 0x82, 0xa0, 0xfb, 0x95, 0xe0, 0x67, 0x50, 0xe1, 0x73, 0xf8, 0x6d, 0x1b, 0x81,
-	0x17, 0x61, 0xe1, 0xd8, 0x32, 0x46, 0xee, 0x85, 0x2d, 0xb3, 0x1b, 0x9d, 0x74, 0x3d, 0xa0, 0xcd,
-	0xa4, 0xf1, 0x5d, 0x58, 0x70, 0xc8, 0xd0, 0x30, 0x2d, 0xd3, 0x3a, 0x3f, 0x39, 0xbd, 0xf6, 0x88,
-	0x2b, 0x5e, 0x98, 0x6a, 0x3e, 0xf9, 0x29, 0xa5, 0x52, 0xd3, 0x4e, 0x07, 0xf6, 0xa9, 0x08, 0x73,
-	0xec, 0x19, 0xff, 0x34, 0x03, 0x95, 0x4f, 0x0d, 0xaf, 0x27, 0x97, 0x0e, 0xed, 0x41, 0xcd, 0x0f,
-	0x6e, 0x8c, 0x22, 0x6c, 0x89, 0xa4, 0x58, 0x36, 0x46, 0x96, 0xd2, 0x32, 0x3b, 0x56, 0x7b, 0x2a,
-	0x81, 0x89, 0x32, 0xac, 0x1e, 0x19, 0xf8, 0xa2, 0x32, 0xe9, 0xa2, 0x18, 0xa3, 0x2a, 0x4a, 0x25,
-	0xa0, 0x0e, 0xd4, 0x47, 0x8e, 0x7d, 0xee, 0x10, 0xd7, 0xf5, 0x85, 0xf1, 0x34, 0x86, 0x13, 0x84,
-	0x1d, 0x09, 0xd6, 0x40, 0xdc, 0xc2, 0x28, 0x4c, 0x7a, 0xba, 0x10, 0xd4, 0x33, 0x3c, 0x38, 0xfd,
-	0x57, 0x06, 0x50, 0x7c, 0x52, 0xbf, 0x6e, 0x89, 0xf7, 0x10, 0x6a, 0xae, 0x67, 0x38, 0xb1, 0xcd,
-	0x56, 0x65, 0x54, 0x3f, 0xe2, 0xbf, 0x0b, 0xbe, 0x41, 0x27, 0x96, 0xed, 0x99, 0x67, 0xd7, 0xa2,
-	0x4a, 0xae, 0x49, 0xf2, 0x21, 0xa3, 0xa2, 0x36, 0x14, 0xce, 0xcc, 0x81, 0x47, 0x1c, 0xb7, 0x91,
-	0x5b, 0xcf, 0x6e, 0xd4, 0xb6, 0x1e, 0xdf, 0xb4, 0x0c, 0x9b, 0x1f, 0x31, 0xfe, 0xee, 0xf5, 0x88,
-	0xe8, 0x72, 0xac, 0x5a, 0x79, 0xe6, 0x43, 0xd5, 0xf8, 0x6d, 0x28, 0xbe, 0xa6, 0x22, 0xe8, 0x5b,
-	0x76, 0x81, 0x17, 0x8b, 0xac, 0xcd, 0x5f, 0xb2, 0xcf, 0x1c, 0xe3, 0x7c, 0x48, 0x2c, 0x4f, 0xbe,
-	0x07, 0xca, 0x36, 0x7e, 0x08, 0x10, 0xa8, 0xa1, 0x21, 0xff, 0xb0, 0x73, 0xf4, 0xb2, 0x5b, 0x9f,
-	0x43, 0x15, 0x28, 0x1e, 0x76, 0x76, 0xdb, 0x07, 0x6d, 0x9a, 0x1f, 0x70, 0x4b, 0xba, 0x34, 0xb4,
-	0x96, 0xaa, 0x4e, 0x2d, 0xa4, 0x13, 0xaf, 0xc2, 0x72, 0xd2, 0x02, 0xd2, 0x5a, 0xb4, 0x2a, 0x76,
-	0xe9, 0x4c, 0x47, 0x45, 0x55, 0x9d, 0x09, 0x4f, 0xb7, 0x01, 0x05, 0xbe, 0x7b, 0xfb, 0xa2, 0x38,
-	0x97, 0x4d, 0xea, 0x08, 0xbe, 0x19, 0x49, 0x5f, 0xac, 0x92, 0xdf, 0x4e, 0x0c, 0x2f, 0xb9, 0xc4,
-	0xf0, 0x82, 0x1e, 0x40, 0xd5, 0x3f, 0x0d, 0x86, 0x2b, 0x6a, 0x81, 0x92, 0x5e, 0x91, 0x1b, 0x9d,
-	0xd2, 0x42, 0x4e, 0x2f, 0x84, 0x9d, 0x8e, 0x1e, 0x42, 0x9e, 0x4c, 0x88, 0xe5, 0xb9, 0x8d, 0x32,
-	0xcb, 0x18, 0x55, 0x59, 0xbb, 0xb7, 0x29, 0x55, 0x17, 0x9d, 0xf8, 0xbb, 0xb0, 0xc8, 0xde, 0x91,
-	0x9e, 0x39, 0x86, 0xa5, 0xbe, 0xcc, 0x75, 0xbb, 0x07, 0xc2, 0xdd, 0xf4, 0x11, 0xd5, 0x20, 0xb3,
-	0xb7, 0x2b, 0x9c, 0x90, 0xd9, 0xdb, 0xc5, 0x3f, 0xd6, 0x00, 0xa9, 0xe3, 0x66, 0xf2, 0x73, 0x44,
-	0xb8, 0x54, 0x9f, 0x0d, 0xd4, 0x2f, 0x43, 0x8e, 0x38, 0x8e, 0xed, 0x30, 0x8f, 0x96, 0x74, 0xde,
-	0xc0, 0x6f, 0x0b, 0x1b, 0x74, 0x32, 0xb1, 0x2f, 0xfd, 0x33, 0xc8, 0xa5, 0x69, 0xbe, 0xa9, 0xfb,
-	0xb0, 0x14, 0xe2, 0x9a, 0x29, 0x73, 0x7d, 0x04, 0x0b, 0x4c, 0xd8, 0xce, 0x05, 0xe9, 0x5d, 0x8e,
-	0x6c, 0xd3, 0x8a, 0xe9, 0xa3, 0x2b, 0x17, 0x04, 0x58, 0x3a, 0x0f, 0x3e, 0xb1, 0x8a, 0x4f, 0xec,
-	0x76, 0x0f, 0xf0, 0xe7, 0xb0, 0x1a, 0x91, 0x23, 0xcd, 0xff, 0x43, 0x28, 0xf7, 0x7c, 0xa2, 0x2b,
-	0x6a, 0x9d, 0x7b, 0x61, 0xe3, 0xa2, 0x43, 0xd5, 0x11, 0xb8, 0x03, 0xb7, 0x62, 0xa2, 0x67, 0x9a,
-	0xf3, 0xbb, 0xb0, 0xc2, 0x04, 0xee, 0x13, 0x32, 0xda, 0x1e, 0x98, 0x93, 0x54, 0x4f, 0x8f, 0xc4,
-	0xa4, 0x14, 0xc6, 0xaf, 0x77, 0x5f, 0xe0, 0xdf, 0x17, 0x1a, 0xbb, 0xe6, 0x90, 0x74, 0xed, 0x83,
-	0x74, 0xdb, 0x68, 0x36, 0xbb, 0x24, 0xd7, 0xae, 0x28, 0x6b, 0xd8, 0x33, 0xfe, 0x47, 0x4d, 0xb8,
-	0x4a, 0x1d, 0xfe, 0x35, 0xef, 0xe4, 0x35, 0x80, 0x73, 0x7a, 0x64, 0x48, 0x9f, 0x76, 0x70, 0x44,
-	0x45, 0xa1, 0xf8, 0x76, 0xd2, 0xf8, 0x5d, 0x11, 0x76, 0x2e, 0x8b, 0x7d, 0xce, 0xfe, 0xf8, 0x51,
-	0xee, 0x1e, 0x94, 0x19, 0xe1, 0xd8, 0x33, 0xbc, 0xb1, 0x1b, 0x5b, 0x8c, 0x3f, 0x17, 0xdb, 0x5e,
-	0x0e, 0x9a, 0x69, 0x5e, 0xdf, 0x82, 0x3c, 0x7b, 0x99, 0x90, 0xa5, 0xf4, 0xed, 0x84, 0xfd, 0xc8,
-	0xed, 0xd0, 0x05, 0x23, 0xfe, 0xa9, 0x06, 0xf9, 0x17, 0x0c, 0x82, 0x55, 0x4c, 0x9b, 0x97, 0x6b,
-	0x61, 0x19, 0x43, 0x0e, 0x0c, 0x95, 0x74, 0xf6, 0xcc, 0x4a, 0x4f, 0x42, 0x9c, 0x97, 0xfa, 0x01,
-	0x2f, 0x71, 0x4b, 0xba, 0xdf, 0xa6, 0x3e, 0xeb, 0x0d, 0x4c, 0x62, 0x79, 0xac, 0x77, 0x9e, 0xf5,
-	0x2a, 0x14, 0x5a, 0x3d, 0x9b, 0xee, 0x01, 0x31, 0x1c, 0x4b, 0x80, 0xa6, 0x45, 0x3d, 0x20, 0xe0,
-	0x03, 0xa8, 0x73, 0x3b, 0xb6, 0xfb, 0x7d, 0xa5, 0xc0, 0xf4, 0xb5, 0x69, 0x11, 0x6d, 0x21, 0x69,
-	0x99, 0xa8, 0xb4, 0x7f, 0xd2, 0x60, 0x51, 0x11, 0x37, 0x93, 0x57, 0xdf, 0x87, 0x3c, 0x07, 0xa9,
-	0x45, 0xa5, 0xb3, 0x1c, 0x1e, 0xc5, 0xd5, 0xe8, 0x82, 0x07, 0x6d, 0x42, 0x81, 0x3f, 0xc9, 0x77,
-	0x80, 0x64, 0x76, 0xc9, 0x84, 0x1f, 0xc2, 0x92, 0x20, 0x91, 0xa1, 0x9d, 0x74, 0x30, 0xd8, 0x62,
-	0xe0, 0x3f, 0x85, 0xe5, 0x30, 0xdb, 0x4c, 0x53, 0x52, 0x8c, 0xcc, 0xbc, 0x89, 0x91, 0xdb, 0xd2,
-	0xc8, 0x97, 0xa3, 0xbe, 0x52, 0x47, 0x45, 0x77, 0x8c, 0xba, 0x5e, 0x99, 0xf0, 0x7a, 0x05, 0x13,
-	0x90, 0x22, 0xbe, 0xd1, 0x09, 0x2c, 0xc9, 0xed, 0x70, 0x60, 0xba, 0x7e, 0xb9, 0xfe, 0x25, 0x20,
-	0x95, 0xf8, 0x8d, 0x1a, 0xf4, 0x8e, 0x74, 0xc7, 0x91, 0x63, 0x0f, 0xed, 0x54, 0x97, 0xe2, 0x3f,
-	0x83, 0x95, 0x08, 0xdf, 0x37, 0xed, 0xb7, 0x5d, 0x22, 0x8b, 0x15, 0xe9, 0xb7, 0x8f, 0x01, 0xa9,
-	0xc4, 0x99, 0xb2, 0x56, 0x0b, 0x16, 0x5f, 0xd8, 0x13, 0x1a, 0xfe, 0x28, 0x35, 0x38, 0xf7, 0x1c,
-	0x63, 0xf0, 0x5d, 0xe1, 0xb7, 0xa9, 0x72, 0x75, 0xc0, 0x4c, 0xca, 0xff, 0x43, 0x83, 0xca, 0xf6,
-	0xc0, 0x70, 0x86, 0x52, 0xf1, 0xf7, 0x20, 0xcf, 0xdf, 0x9c, 0x05, 0x58, 0xf5, 0x4e, 0x58, 0x8c,
-	0xca, 0xcb, 0x1b, 0xdb, 0xfc, 0x3d, 0x5b, 0x8c, 0xa2, 0x86, 0x8b, 0xef, 0x59, 0xbb, 0x91, 0xef,
-	0x5b, 0xbb, 0xe8, 0x03, 0xc8, 0x19, 0x74, 0x08, 0x4b, 0x33, 0xb5, 0x28, 0x66, 0xc1, 0xa4, 0xb1,
-	0xfa, 0x9e, 0x73, 0xe1, 0xef, 0x40, 0x59, 0xd1, 0x80, 0x0a, 0x90, 0x7d, 0xd6, 0x16, 0xc5, 0xf8,
-	0xf6, 0x4e, 0x77, 0xef, 0x15, 0x07, 0x6b, 0x6a, 0x00, 0xbb, 0x6d, 0xbf, 0x9d, 0xc1, 0x9f, 0x89,
-	0x51, 0x22, 0xa4, 0xab, 0xf6, 0x68, 0x69, 0xf6, 0x64, 0xde, 0xc8, 0x9e, 0x2b, 0xa8, 0x8a, 0xe9,
-	0xcf, 0x9a, 0xa2, 0x98, 0xbc, 0x94, 0x14, 0xa5, 0x18, 0xaf, 0x0b, 0x46, 0xbc, 0x00, 0x55, 0x91,
-	0xb4, 0xc4, 0xfe, 0xfb, 0xf7, 0x0c, 0xd4, 0x24, 0x65, 0x56, 0x50, 0x5d, 0xe2, 0x81, 0x3c, 0xc9,
-	0xf9, 0x68, 0xe0, 0x2a, 0xe4, 0xfb, 0xa7, 0xc7, 0xe6, 0x97, 0xf2, 0x03, 0x88, 0x68, 0x51, 0xfa,
-	0x80, 0xeb, 0xe1, 0x5f, 0x21, 0x45, 0x8b, 0x66, 0x23, 0xc7, 0x38, 0xf3, 0xf6, 0xac, 0x3e, 0xb9,
-	0x62, 0xb9, 0x6d, 0x5e, 0x0f, 0x08, 0x0c, 0x28, 0x11, 0x5f, 0x2b, 0xd9, 0x0b, 0x82, 0xf2, 0xf5,
-	0x12, 0x3d, 0x82, 0x3a, 0x7d, 0xde, 0x1e, 0x8d, 0x06, 0x26, 0xe9, 0x73, 0x01, 0x05, 0xc6, 0x13,
-	0xa3, 0x53, 0xed, 0xac, 0xa4, 0x76, 0x1b, 0x45, 0x16, 0x5d, 0x45, 0x0b, 0xad, 0x43, 0x99, 0xdb,
-	0xb7, 0x67, 0xbd, 0x74, 0x09, 0xfb, 0x84, 0x97, 0xd5, 0x55, 0x52, 0x38, 0x5b, 0x42, 0x34, 0x5b,
-	0x2e, 0xc1, 0xe2, 0xf6, 0xd8, 0xbb, 0x68, 0x5b, 0xc6, 0xe9, 0x40, 0x46, 0x22, 0x5a, 0xce, 0x50,
-	0xe2, 0xae, 0xe9, 0xaa, 0xd4, 0x36, 0x2c, 0x51, 0x2a, 0xb1, 0x3c, 0xb3, 0xa7, 0x64, 0x02, 0x59,
-	0x2b, 0x68, 0x91, 0x5a, 0xc1, 0x70, 0xdd, 0xd7, 0xb6, 0xd3, 0x17, 0xee, 0xf5, 0xdb, 0x78, 0xc2,
-	0x85, 0xbf, 0x74, 0x43, 0xf9, 0xfe, 0xd7, 0x94, 0x82, 0x3e, 0x84, 0x82, 0x3d, 0x62, 0x9f, 0xa4,
-	0x05, 0x6e, 0xb0, 0xba, 0xc9, 0x3f, 0x62, 0x6f, 0x0a, 0xc1, 0x1d, 0xde, 0xab, 0x4b, 0x36, 0xbc,
-	0x11, 0xe8, 0x7d, 0x46, 0xbc, 0x29, 0x7a, 0xf1, 0x63, 0x58, 0x91, 0x9c, 0x02, 0x26, 0x9f, 0xc2,
-	0xdc, 0x81, 0x7b, 0x92, 0x79, 0xe7, 0xc2, 0xb0, 0xce, 0xc9, 0x91, 0x30, 0xf1, 0x37, 0xf5, 0xcf,
-	0x53, 0x68, 0xf8, 0x76, 0xb2, 0x57, 0x37, 0x7b, 0xa0, 0x1a, 0x30, 0x76, 0xc5, 0x4e, 0x2f, 0xe9,
-	0xec, 0x99, 0xd2, 0x1c, 0x7b, 0xe0, 0xd7, 0x6a, 0xf4, 0x19, 0xef, 0xc0, 0x6d, 0x29, 0x43, 0xbc,
-	0x54, 0x85, 0x85, 0xc4, 0x0c, 0x4a, 0x12, 0x22, 0x1c, 0x46, 0x87, 0x4e, 0x5f, 0x28, 0x95, 0x33,
-	0xec, 0x5a, 0x26, 0x53, 0x53, 0x64, 0xae, 0xf0, 0x3d, 0x44, 0x0d, 0x53, 0xd3, 0xb1, 0x20, 0x53,
-	0x01, 0x2a, 0x59, 0x2c, 0x04, 0x25, 0xc7, 0x16, 0x22, 0x26, 0xfa, 0x07, 0xb0, 0xe6, 0x1b, 0x41,
-	0xfd, 0x76, 0x44, 0x9c, 0xa1, 0xe9, 0xba, 0x0a, 0xb0, 0x9a, 0x34, 0xf1, 0x77, 0x60, 0x7e, 0x44,
-	0x44, 0x24, 0x2c, 0x6f, 0x21, 0xb9, 0x89, 0x94, 0xc1, 0xac, 0x1f, 0xf7, 0xe1, 0xbe, 0x94, 0xce,
-	0x3d, 0x9a, 0x28, 0x3e, 0x6a, 0x94, 0x84, 0x9b, 0x32, 0x29, 0x70, 0x53, 0x36, 0x02, 0xf6, 0x7f,
-	0xcc, 0x1d, 0x29, 0x4f, 0xe3, 0x4c, 0x19, 0x6e, 0x9f, 0xfb, 0xd4, 0x3f, 0xc4, 0x33, 0x09, 0x3b,
-	0x85, 0xe5, 0xf0, 0xd9, 0x9f, 0x29, 0xf8, 0x2e, 0x43, 0xce, 0xb3, 0x2f, 0x89, 0x0c, 0xbd, 0xbc,
-	0x21, 0x0d, 0xf6, 0x03, 0xc3, 0x4c, 0x06, 0x1b, 0x81, 0x30, 0xb6, 0x25, 0x67, 0xb5, 0x97, 0xae,
-	0xa6, 0xac, 0x6c, 0x79, 0x03, 0x1f, 0xc2, 0x6a, 0x34, 0x4c, 0xcc, 0x64, 0xf2, 0x2b, 0xbe, 0x81,
-	0x93, 0x22, 0xc9, 0x4c, 0x72, 0x3f, 0x09, 0x82, 0x81, 0x12, 0x50, 0x66, 0x12, 0xa9, 0x43, 0x33,
-	0x29, 0xbe, 0xfc, 0x36, 0xf6, 0xab, 0x1f, 0x6e, 0x66, 0x12, 0xe6, 0x06, 0xc2, 0x66, 0x5f, 0xfe,
-	0x20, 0x46, 0x64, 0xa7, 0xc6, 0x08, 0x71, 0x48, 0x82, 0x28, 0xf6, 0x35, 0x6c, 0x3a, 0xa1, 0x23,
-	0x08, 0xa0, 0xb3, 0xea, 0xa0, 0x39, 0xc4, 0xd7, 0xc1, 0x1a, 0x72, 0x63, 0xab, 0x61, 0x77, 0xa6,
-	0xc5, 0xf8, 0x34, 0x88, 0x9d, 0xb1, 0xc8, 0x3c, 0x93, 0xe0, 0xcf, 0x60, 0x3d, 0x3d, 0x28, 0xcf,
-	0x22, 0xf9, 0x51, 0x0b, 0x4a, 0x7e, 0x19, 0xac, 0xdc, 0x22, 0x2a, 0x43, 0xe1, 0xb0, 0x73, 0x7c,
-	0xb4, 0xbd, 0xd3, 0xe6, 0xd7, 0x88, 0x76, 0x3a, 0xba, 0xfe, 0xf2, 0xa8, 0x5b, 0xcf, 0x6c, 0xfd,
-	0x32, 0x0b, 0x99, 0xfd, 0x57, 0xe8, 0x73, 0xc8, 0xf1, 0x6f, 0xea, 0x53, 0x2e, 0x52, 0x34, 0xa7,
-	0x5d, 0x1b, 0xc0, 0xb7, 0x7e, 0xfc, 0xdf, 0xbf, 0xfc, 0x79, 0x66, 0x11, 0x57, 0x5a, 0x93, 0x6f,
-	0xb7, 0x2e, 0x27, 0x2d, 0x96, 0x1b, 0x9e, 0x68, 0x8f, 0xd0, 0x27, 0x90, 0x3d, 0x1a, 0x7b, 0x28,
-	0xf5, 0x82, 0x45, 0x33, 0xfd, 0x26, 0x01, 0x5e, 0x61, 0x42, 0x17, 0x30, 0x08, 0xa1, 0xa3, 0xb1,
-	0x47, 0x45, 0xfe, 0x10, 0xca, 0xea, 0x3d, 0x80, 0x1b, 0x6f, 0x5d, 0x34, 0x6f, 0xbe, 0x63, 0x80,
-	0xef, 0x31, 0x55, 0xb7, 0x30, 0x12, 0xaa, 0xf8, 0x4d, 0x05, 0x75, 0x16, 0xdd, 0x2b, 0x0b, 0xa5,
-	0xde, 0xc9, 0x68, 0xa6, 0x5f, 0x3b, 0x88, 0xcd, 0xc2, 0xbb, 0xb2, 0xa8, 0xc8, 0x3f, 0x16, 0x37,
-	0x0e, 0x7a, 0x1e, 0xba, 0x9f, 0xf0, 0xc5, 0x59, 0xfd, 0xb6, 0xda, 0x5c, 0x4f, 0x67, 0x10, 0x4a,
-	0xee, 0x32, 0x25, 0xab, 0x78, 0x51, 0x28, 0xe9, 0xf9, 0x2c, 0x4f, 0xb4, 0x47, 0x5b, 0x3d, 0xc8,
-	0xb1, 0xef, 0x16, 0xe8, 0x0b, 0xf9, 0xd0, 0x4c, 0xf8, 0x80, 0x93, 0xb2, 0xd0, 0xa1, 0x2f, 0x1e,
-	0x78, 0x99, 0x29, 0xaa, 0xe1, 0x12, 0x55, 0xc4, 0xbe, 0x5a, 0x3c, 0xd1, 0x1e, 0x6d, 0x68, 0x1f,
-	0x6a, 0x5b, 0xff, 0x9c, 0x83, 0x1c, 0x03, 0xec, 0xd0, 0x25, 0x40, 0x80, 0xe1, 0x47, 0x67, 0x17,
-	0xfb, 0x2a, 0x10, 0x9d, 0x5d, 0x1c, 0xfe, 0xc7, 0x4d, 0xa6, 0x74, 0x19, 0x2f, 0x50, 0xa5, 0x0c,
-	0x07, 0x6c, 0x31, 0x68, 0x93, 0xfa, 0xf1, 0xaf, 0x34, 0x81, 0x57, 0xf2, 0xb3, 0x84, 0x92, 0xa4,
-	0x85, 0x80, 0xfc, 0xe8, 0x76, 0x48, 0x00, 0xf1, 0xf1, 0x77, 0x99, 0xc2, 0x16, 0xae, 0x07, 0x0a,
-	0x1d, 0xc6, 0xf1, 0x44, 0x7b, 0xf4, 0x45, 0x03, 0x2f, 0x09, 0x2f, 0x47, 0x7a, 0xd0, 0x8f, 0xa0,
-	0x16, 0x06, 0xaa, 0xd1, 0x83, 0x04, 0x5d, 0x51, 0xbc, 0xbb, 0xf9, 0xf6, 0x74, 0x26, 0x61, 0xd3,
-	0x1a, 0xb3, 0x49, 0x28, 0xe7, 0x9a, 0x2f, 0x09, 0x19, 0x19, 0x94, 0x49, 0xac, 0x01, 0xfa, 0x7b,
-	0x4d, 0x7c, 0x47, 0x08, 0x90, 0x67, 0x94, 0x24, 0x3d, 0x86, 0x6b, 0x37, 0x1f, 0xde, 0xc0, 0x25,
-	0x8c, 0xf8, 0x03, 0x66, 0xc4, 0xef, 0xe2, 0xe5, 0xc0, 0x08, 0xcf, 0x1c, 0x12, 0xcf, 0x16, 0x56,
-	0x7c, 0x71, 0x17, 0xdf, 0x0a, 0x39, 0x27, 0xd4, 0x1b, 0x2c, 0x16, 0x47, 0x8f, 0x13, 0x17, 0x2b,
-	0x84, 0x46, 0x27, 0x2e, 0x56, 0x18, 0x7a, 0x4e, 0x5a, 0x2c, 0x8e, 0x15, 0x27, 0x2d, 0x96, 0xdf,
-	0xb3, 0xf5, 0xff, 0xf3, 0x50, 0xd8, 0xe1, 0x37, 0x7d, 0x91, 0x0d, 0x25, 0x1f, 0x7c, 0x45, 0x6b,
-	0x49, 0x08, 0x53, 0xf0, 0x2e, 0xd1, 0xbc, 0x9f, 0xda, 0x2f, 0x0c, 0x7a, 0x8b, 0x19, 0x74, 0x07,
-	0xaf, 0x52, 0xcd, 0xe2, 0x32, 0x71, 0x8b, 0xc3, 0x18, 0x2d, 0xa3, 0xdf, 0xa7, 0x8e, 0xf8, 0x13,
-	0xa8, 0xa8, 0xe8, 0x28, 0x7a, 0x2b, 0x11, 0xd5, 0x52, 0x01, 0xd6, 0x26, 0x9e, 0xc6, 0x22, 0x34,
-	0xbf, 0xcd, 0x34, 0xaf, 0xe1, 0xdb, 0x09, 0x9a, 0x1d, 0xc6, 0x1a, 0x52, 0xce, 0x91, 0xcd, 0x64,
-	0xe5, 0x21, 0xe0, 0x34, 0x59, 0x79, 0x18, 0x18, 0x9d, 0xaa, 0x7c, 0xcc, 0x58, 0xa9, 0x72, 0x17,
-	0x20, 0xc0, 0x30, 0x51, 0xa2, 0x2f, 0x95, 0x97, 0xa9, 0x68, 0x70, 0x88, 0xc3, 0x9f, 0x18, 0x33,
-	0xb5, 0x62, 0xdf, 0x45, 0xd4, 0x0e, 0x4c, 0xd7, 0xe3, 0x07, 0xb3, 0x1a, 0x02, 0x25, 0x51, 0xe2,
-	0x7c, 0xc2, 0xc8, 0x66, 0xf3, 0xc1, 0x54, 0x1e, 0xa1, 0xfd, 0x21, 0xd3, 0x7e, 0x1f, 0x37, 0x13,
-	0xb4, 0x8f, 0x38, 0x2f, 0xdd, 0x6c, 0x7f, 0x9d, 0x87, 0xf2, 0x0b, 0xc3, 0xb4, 0x3c, 0x62, 0x19,
-	0x56, 0x8f, 0xa0, 0x53, 0xc8, 0xb1, 0x4c, 0x1d, 0x0d, 0xc4, 0x2a, 0x60, 0x17, 0x0d, 0xc4, 0x21,
-	0x34, 0x0b, 0xaf, 0x33, 0xc5, 0x4d, 0xbc, 0x42, 0x15, 0x0f, 0x03, 0xd1, 0x2d, 0x06, 0x42, 0xd1,
-	0x49, 0x9f, 0x41, 0x5e, 0x7c, 0xc3, 0x89, 0x08, 0x0a, 0x81, 0x53, 0xcd, 0xbb, 0xc9, 0x9d, 0x49,
-	0x7b, 0x59, 0x55, 0xe3, 0x32, 0x3e, 0xaa, 0x67, 0x02, 0x10, 0xa0, 0xab, 0xd1, 0x15, 0x8d, 0x81,
-	0xb1, 0xcd, 0xf5, 0x74, 0x86, 0x24, 0x9f, 0xaa, 0x3a, 0xfb, 0x3e, 0x2f, 0xd5, 0xfb, 0x47, 0x30,
-	0xff, 0xdc, 0x70, 0x2f, 0x50, 0x24, 0xf7, 0x2a, 0x37, 0x80, 0x9a, 0xcd, 0xa4, 0x2e, 0xa1, 0xe5,
-	0x3e, 0xd3, 0x72, 0x9b, 0x87, 0x32, 0x55, 0xcb, 0x85, 0xe1, 0xd2, 0xa4, 0x86, 0xfa, 0x90, 0xe7,
-	0x17, 0x82, 0xa2, 0xfe, 0x0b, 0x5d, 0x2a, 0x8a, 0xfa, 0x2f, 0x7c, 0x87, 0xe8, 0x66, 0x2d, 0x23,
-	0x28, 0xca, 0x1b, 0x38, 0x28, 0xf2, 0x39, 0x36, 0x72, 0x5b, 0xa7, 0xb9, 0x96, 0xd6, 0x2d, 0x74,
-	0x3d, 0x60, 0xba, 0xee, 0xe1, 0x46, 0x6c, 0xad, 0x04, 0xe7, 0x13, 0xed, 0xd1, 0x87, 0x1a, 0xfa,
-	0x11, 0x40, 0x00, 0x48, 0xc7, 0x4e, 0x60, 0x14, 0xdb, 0x8e, 0x9d, 0xc0, 0x18, 0x96, 0x8d, 0x37,
-	0x99, 0xde, 0x0d, 0xfc, 0x20, 0xaa, 0xd7, 0x73, 0x0c, 0xcb, 0x3d, 0x23, 0xce, 0x07, 0x1c, 0x74,
-	0x74, 0x2f, 0xcc, 0x11, 0x3d, 0x0c, 0xff, 0xba, 0x00, 0xf3, 0xb4, 0x02, 0xa6, 0x85, 0x42, 0x00,
-	0x1c, 0x44, 0x2d, 0x89, 0x01, 0x7c, 0x51, 0x4b, 0xe2, 0x98, 0x43, 0xb8, 0x50, 0x60, 0xbf, 0x11,
-	0x21, 0x8c, 0x81, 0x3a, 0xda, 0x86, 0xb2, 0x82, 0x2c, 0xa0, 0x04, 0x61, 0x61, 0xe4, 0x30, 0x9a,
-	0x7a, 0x12, 0x60, 0x09, 0x7c, 0x87, 0xe9, 0x5b, 0xe1, 0xa9, 0x87, 0xe9, 0xeb, 0x73, 0x0e, 0xaa,
-	0xf0, 0x35, 0x54, 0x54, 0xf4, 0x01, 0x25, 0xc8, 0x8b, 0xa0, 0x92, 0xd1, 0x30, 0x9b, 0x04, 0x5e,
-	0x84, 0x0f, 0xbe, 0xff, 0x3b, 0x18, 0xc9, 0x46, 0x15, 0x0f, 0xa0, 0x20, 0xe0, 0x88, 0xa4, 0x59,
-	0x86, 0x21, 0xcc, 0xa4, 0x59, 0x46, 0xb0, 0x8c, 0x70, 0x71, 0xc9, 0x34, 0xd2, 0x37, 0x2e, 0x99,
-	0xca, 0x84, 0xb6, 0x67, 0xc4, 0x4b, 0xd3, 0x16, 0xa0, 0x6b, 0x69, 0xda, 0x94, 0xb7, 0xdd, 0x34,
-	0x6d, 0xe7, 0xc4, 0x13, 0xc7, 0x45, 0xbe, 0x45, 0xa2, 0x14, 0x61, 0x6a, 0xfa, 0xc0, 0xd3, 0x58,
-	0x92, 0x6a, 0xff, 0x40, 0xa1, 0xcc, 0x1d, 0x57, 0x00, 0x01, 0x58, 0x12, 0x2d, 0xe8, 0x12, 0x11,
-	0xd7, 0x68, 0x41, 0x97, 0x8c, 0xb7, 0x84, 0x43, 0x43, 0xa0, 0x97, 0xbf, 0x7a, 0x50, 0xcd, 0x3f,
-	0xd3, 0x00, 0xc5, 0x71, 0x15, 0xf4, 0x38, 0x59, 0x7a, 0x22, 0x8e, 0xdb, 0x7c, 0xff, 0xcd, 0x98,
-	0x93, 0xa2, 0x7d, 0x60, 0x52, 0x8f, 0x71, 0x8f, 0x5e, 0x53, 0xa3, 0xfe, 0x42, 0x83, 0x6a, 0x08,
-	0x94, 0x41, 0xef, 0xa4, 0xac, 0x69, 0x04, 0x06, 0x6e, 0xbe, 0x7b, 0x23, 0x5f, 0x52, 0xa5, 0xab,
-	0xec, 0x00, 0x59, 0xf2, 0xff, 0x44, 0x83, 0x5a, 0x18, 0xc4, 0x41, 0x29, 0xb2, 0x63, 0x30, 0x72,
-	0x73, 0xe3, 0x66, 0xc6, 0xe9, 0xcb, 0x13, 0x54, 0xfb, 0x03, 0x28, 0x08, 0xd8, 0x27, 0x69, 0xe3,
-	0x87, 0x01, 0xe8, 0xa4, 0x8d, 0x1f, 0xc1, 0x8c, 0x12, 0x36, 0xbe, 0x63, 0x0f, 0x88, 0x72, 0xcc,
-	0x04, 0x2e, 0x94, 0xa6, 0x6d, 0xfa, 0x31, 0x8b, 0x80, 0x4a, 0x69, 0xda, 0x82, 0x63, 0x26, 0x01,
-	0x21, 0x94, 0x22, 0xec, 0x86, 0x63, 0x16, 0xc5, 0x93, 0x12, 0x8e, 0x19, 0x53, 0xa8, 0x1c, 0xb3,
-	0x00, 0xba, 0x49, 0x3a, 0x66, 0x31, 0x3c, 0x3d, 0xe9, 0x98, 0xc5, 0xd1, 0x9f, 0x84, 0x75, 0x64,
-	0x7a, 0x43, 0xc7, 0x6c, 0x29, 0x01, 0xe5, 0x41, 0xef, 0xa7, 0x38, 0x31, 0x11, 0xa6, 0x6f, 0x7e,
-	0xf0, 0x86, 0xdc, 0xa9, 0x7b, 0x9c, 0xbb, 0x5f, 0xee, 0xf1, 0xbf, 0xd1, 0x60, 0x39, 0x09, 0x21,
-	0x42, 0x29, 0x7a, 0x52, 0xe0, 0xfd, 0xe6, 0xe6, 0x9b, 0xb2, 0x4f, 0xf7, 0x96, 0xbf, 0xeb, 0x9f,
-	0xd6, 0xff, 0xed, 0xab, 0x35, 0xed, 0x3f, 0xbf, 0x5a, 0xd3, 0xfe, 0xe7, 0xab, 0x35, 0xed, 0x6f,
-	0xff, 0x77, 0x6d, 0xee, 0x34, 0xcf, 0x7e, 0x5d, 0xf9, 0xed, 0x5f, 0x05, 0x00, 0x00, 0xff, 0xff,
-	0x52, 0x4e, 0xd7, 0x33, 0xe4, 0x39, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.proto b/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.proto
deleted file mode 100644
index 423eaba..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/etcdserverpb/rpc.proto
+++ /dev/null
@@ -1,1146 +0,0 @@
-syntax = "proto3";
-package etcdserverpb;
-
-import "gogoproto/gogo.proto";
-import "etcd/mvcc/mvccpb/kv.proto";
-import "etcd/auth/authpb/auth.proto";
-
-// for grpc-gateway
-import "google/api/annotations.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-
-service KV {
-  // Range gets the keys in the range from the key-value store.
-  rpc Range(RangeRequest) returns (RangeResponse) {
-      option (google.api.http) = {
-        post: "/v3/kv/range"
-        body: "*"
-    };
-  }
-
-  // Put puts the given key into the key-value store.
-  // A put request increments the revision of the key-value store
-  // and generates one event in the event history.
-  rpc Put(PutRequest) returns (PutResponse) {
-      option (google.api.http) = {
-        post: "/v3/kv/put"
-        body: "*"
-    };
-  }
-
-  // DeleteRange deletes the given range from the key-value store.
-  // A delete request increments the revision of the key-value store
-  // and generates a delete event in the event history for every deleted key.
-  rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse) {
-      option (google.api.http) = {
-        post: "/v3/kv/deleterange"
-        body: "*"
-    };
-  }
-
-  // Txn processes multiple requests in a single transaction.
-  // A txn request increments the revision of the key-value store
-  // and generates events with the same revision for every completed request.
-  // It is not allowed to modify the same key several times within one txn.
-  rpc Txn(TxnRequest) returns (TxnResponse) {
-      option (google.api.http) = {
-        post: "/v3/kv/txn"
-        body: "*"
-    };
-  }
-
-  // Compact compacts the event history in the etcd key-value store. The key-value
-  // store should be periodically compacted or the event history will continue to grow
-  // indefinitely.
-  rpc Compact(CompactionRequest) returns (CompactionResponse) {
-      option (google.api.http) = {
-        post: "/v3/kv/compaction"
-        body: "*"
-    };
-  }
-}
-
-service Watch {
-  // Watch watches for events happening or that have happened. Both input and output
-  // are streams; the input stream is for creating and canceling watchers and the output
-  // stream sends events. One watch RPC can watch on multiple key ranges, streaming events
-  // for several watches at once. The entire event history can be watched starting from the
-  // last compaction revision.
-  rpc Watch(stream WatchRequest) returns (stream WatchResponse) {
-      option (google.api.http) = {
-        post: "/v3/watch"
-        body: "*"
-    };
-  }
-}
-
-service Lease {
-  // LeaseGrant creates a lease which expires if the server does not receive a keepAlive
-  // within a given time to live period. All keys attached to the lease will be expired and
-  // deleted if the lease expires. Each expired key generates a delete event in the event history.
-  rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) {
-      option (google.api.http) = {
-        post: "/v3/lease/grant"
-        body: "*"
-    };
-  }
-
-  // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.
-  rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {
-      option (google.api.http) = {
-        post: "/v3/lease/revoke"
-        body: "*"
-        additional_bindings {
-            post: "/v3/kv/lease/revoke"
-            body: "*"
-        }
-    };
-  }
-
-  // LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client
-  // to the server and streaming keep alive responses from the server to the client.
-  rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) {
-      option (google.api.http) = {
-        post: "/v3/lease/keepalive"
-        body: "*"
-    };
-  }
-
-  // LeaseTimeToLive retrieves lease information.
-  rpc LeaseTimeToLive(LeaseTimeToLiveRequest) returns (LeaseTimeToLiveResponse) {
-      option (google.api.http) = {
-        post: "/v3/lease/timetolive"
-        body: "*"
-        additional_bindings {
-            post: "/v3/kv/lease/timetolive"
-            body: "*"
-        }
-    };
-  }
-
-  // LeaseLeases lists all existing leases.
-  rpc LeaseLeases(LeaseLeasesRequest) returns (LeaseLeasesResponse) {
-      option (google.api.http) = {
-        post: "/v3/lease/leases"
-        body: "*"
-        additional_bindings {
-            post: "/v3/kv/lease/leases"
-            body: "*"
-        }
-    };
-  }
-}
-
-service Cluster {
-  // MemberAdd adds a member into the cluster.
-  rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {
-      option (google.api.http) = {
-        post: "/v3/cluster/member/add"
-        body: "*"
-    };
-  }
-
-  // MemberRemove removes an existing member from the cluster.
-  rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {
-      option (google.api.http) = {
-        post: "/v3/cluster/member/remove"
-        body: "*"
-    };
-  }
-
-  // MemberUpdate updates the member configuration.
-  rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {
-      option (google.api.http) = {
-        post: "/v3/cluster/member/update"
-        body: "*"
-    };
-  }
-
-  // MemberList lists all the members in the cluster.
-  rpc MemberList(MemberListRequest) returns (MemberListResponse) {
-      option (google.api.http) = {
-        post: "/v3/cluster/member/list"
-        body: "*"
-    };
-  }
-
-  // MemberPromote promotes a member from raft learner (non-voting) to raft voting member.
-  rpc MemberPromote(MemberPromoteRequest) returns (MemberPromoteResponse) {
-      option (google.api.http) = {
-        post: "/v3/cluster/member/promote"
-        body: "*"
-    };
-  }
-}
-
-service Maintenance {
-  // Alarm activates, deactivates, and queries alarms regarding cluster health.
-  rpc Alarm(AlarmRequest) returns (AlarmResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/alarm"
-        body: "*"
-    };
-  }
-
-  // Status gets the status of the member.
-  rpc Status(StatusRequest) returns (StatusResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/status"
-        body: "*"
-    };
-  }
-
-  // Defragment defragments a member's backend database to recover storage space.
-  rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/defragment"
-        body: "*"
-    };
-  }
-
-  // Hash computes the hash of whole backend keyspace,
-  // including key, lease, and other buckets in storage.
-  // This is designed for testing ONLY!
-  // Do not rely on this in production with ongoing transactions,
-  // since Hash operation does not hold MVCC locks.
-  // Use "HashKV" API instead for "key" bucket consistency checks.
-  rpc Hash(HashRequest) returns (HashResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/hash"
-        body: "*"
-    };
-  }
-
-  // HashKV computes the hash of all MVCC keys up to a given revision.
-  // It only iterates "key" bucket in backend storage.
-  rpc HashKV(HashKVRequest) returns (HashKVResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/hash"
-        body: "*"
-    };
-  }
-
-  // Snapshot sends a snapshot of the entire backend from a member over a stream to a client.
-  rpc Snapshot(SnapshotRequest) returns (stream SnapshotResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/snapshot"
-        body: "*"
-    };
-  }
-
-  // MoveLeader requests current leader node to transfer its leadership to transferee.
-  rpc MoveLeader(MoveLeaderRequest) returns (MoveLeaderResponse) {
-      option (google.api.http) = {
-        post: "/v3/maintenance/transfer-leadership"
-        body: "*"
-    };
-  }
-}
-
-service Auth {
-  // AuthEnable enables authentication.
-  rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/enable"
-        body: "*"
-    };
-  }
-
-  // AuthDisable disables authentication.
-  rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/disable"
-        body: "*"
-    };
-  }
-
-  // Authenticate processes an authenticate request.
-  rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/authenticate"
-        body: "*"
-    };
-  }
-
-  // UserAdd adds a new user. User name cannot be empty.
-  rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/add"
-        body: "*"
-    };
-  }
-
-  // UserGet gets detailed user information.
-  rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/get"
-        body: "*"
-    };
-  }
-
-  // UserList gets a list of all users.
-  rpc UserList(AuthUserListRequest) returns (AuthUserListResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/list"
-        body: "*"
-    };
-  }
-
-  // UserDelete deletes a specified user.
-  rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/delete"
-        body: "*"
-    };
-  }
-
-  // UserChangePassword changes the password of a specified user.
-  rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/changepw"
-        body: "*"
-    };
-  }
-
-  // UserGrant grants a role to a specified user.
-  rpc UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/grant"
-        body: "*"
-    };
-  }
-
-  // UserRevokeRole revokes a role of specified user.
-  rpc UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/user/revoke"
-        body: "*"
-    };
-  }
-
-  // RoleAdd adds a new role. Role name cannot be empty.
-  rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/add"
-        body: "*"
-    };
-  }
-
-  // RoleGet gets detailed role information.
-  rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/get"
-        body: "*"
-    };
-  }
-
-  // RoleList gets lists of all roles.
-  rpc RoleList(AuthRoleListRequest) returns (AuthRoleListResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/list"
-        body: "*"
-    };
-  }
-
-  // RoleDelete deletes a specified role.
-  rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/delete"
-        body: "*"
-    };
-  }
-
-  // RoleGrantPermission grants a permission of a specified key or range to a specified role.
-  rpc RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/grant"
-        body: "*"
-    };
-  }
-
-  // RoleRevokePermission revokes a key or range permission of a specified role.
-  rpc RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse) {
-      option (google.api.http) = {
-        post: "/v3/auth/role/revoke"
-        body: "*"
-    };
-  }
-}
-
-message ResponseHeader {
-  // cluster_id is the ID of the cluster which sent the response.
-  uint64 cluster_id = 1;
-  // member_id is the ID of the member which sent the response.
-  uint64 member_id = 2;
-  // revision is the key-value store revision when the request was applied.
-  // For watch progress responses, the header.revision indicates progress. All future events
-  // recieved in this stream are guaranteed to have a higher revision number than the
-  // header.revision number.
-  int64 revision = 3;
-  // raft_term is the raft term when the request was applied.
-  uint64 raft_term = 4;
-}
-
-message RangeRequest {
-  enum SortOrder {
-	NONE = 0; // default, no sorting
-	ASCEND = 1; // lowest target value first
-	DESCEND = 2; // highest target value first
-  }
-  enum SortTarget {
-	KEY = 0;
-	VERSION = 1;
-	CREATE = 2;
-	MOD = 3;
-	VALUE = 4;
-  }
-
-  // key is the first key for the range. If range_end is not given, the request only looks up key.
-  bytes key = 1;
-  // range_end is the upper bound on the requested range [key, range_end).
-  // If range_end is '\0', the range is all keys >= key.
-  // If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"),
-  // then the range request gets all keys prefixed with key.
-  // If both key and range_end are '\0', then the range request returns all keys.
-  bytes range_end = 2;
-  // limit is a limit on the number of keys returned for the request. When limit is set to 0,
-  // it is treated as no limit.
-  int64 limit = 3;
-  // revision is the point-in-time of the key-value store to use for the range.
-  // If revision is less or equal to zero, the range is over the newest key-value store.
-  // If the revision has been compacted, ErrCompacted is returned as a response.
-  int64 revision = 4;
-
-  // sort_order is the order for returned sorted results.
-  SortOrder sort_order = 5;
-
-  // sort_target is the key-value field to use for sorting.
-  SortTarget sort_target = 6;
-
-  // serializable sets the range request to use serializable member-local reads.
-  // Range requests are linearizable by default; linearizable requests have higher
-  // latency and lower throughput than serializable requests but reflect the current
-  // consensus of the cluster. For better performance, in exchange for possible stale reads,
-  // a serializable range request is served locally without needing to reach consensus
-  // with other nodes in the cluster.
-  bool serializable = 7;
-
-  // keys_only when set returns only the keys and not the values.
-  bool keys_only = 8;
-
-  // count_only when set returns only the count of the keys in the range.
-  bool count_only = 9;
-
-  // min_mod_revision is the lower bound for returned key mod revisions; all keys with
-  // lesser mod revisions will be filtered away.
-  int64 min_mod_revision = 10;
-
-  // max_mod_revision is the upper bound for returned key mod revisions; all keys with
-  // greater mod revisions will be filtered away.
-  int64 max_mod_revision = 11;
-
-  // min_create_revision is the lower bound for returned key create revisions; all keys with
-  // lesser create revisions will be filtered away.
-  int64 min_create_revision = 12;
-
-  // max_create_revision is the upper bound for returned key create revisions; all keys with
-  // greater create revisions will be filtered away.
-  int64 max_create_revision = 13;
-}
-
-message RangeResponse {
-  ResponseHeader header = 1;
-  // kvs is the list of key-value pairs matched by the range request.
-  // kvs is empty when count is requested.
-  repeated mvccpb.KeyValue kvs = 2;
-  // more indicates if there are more keys to return in the requested range.
-  bool more = 3;
-  // count is set to the number of keys within the range when requested.
-  int64 count = 4;
-}
-
-message PutRequest {
-  // key is the key, in bytes, to put into the key-value store.
-  bytes key = 1;
-  // value is the value, in bytes, to associate with the key in the key-value store.
-  bytes value = 2;
-  // lease is the lease ID to associate with the key in the key-value store. A lease
-  // value of 0 indicates no lease.
-  int64 lease = 3;
-
-  // If prev_kv is set, etcd gets the previous key-value pair before changing it.
-  // The previous key-value pair will be returned in the put response.
-  bool prev_kv = 4;
-
-  // If ignore_value is set, etcd updates the key using its current value.
-  // Returns an error if the key does not exist.
-  bool ignore_value = 5;
-
-  // If ignore_lease is set, etcd updates the key using its current lease.
-  // Returns an error if the key does not exist.
-  bool ignore_lease = 6;
-}
-
-message PutResponse {
-  ResponseHeader header = 1;
-  // if prev_kv is set in the request, the previous key-value pair will be returned.
-  mvccpb.KeyValue prev_kv = 2;
-}
-
-message DeleteRangeRequest {
-  // key is the first key to delete in the range.
-  bytes key = 1;
-  // range_end is the key following the last key to delete for the range [key, range_end).
-  // If range_end is not given, the range is defined to contain only the key argument.
-  // If range_end is one bit larger than the given key, then the range is all the keys
-  // with the prefix (the given key).
-  // If range_end is '\0', the range is all keys greater than or equal to the key argument.
-  bytes range_end = 2;
-
-  // If prev_kv is set, etcd gets the previous key-value pairs before deleting it.
-  // The previous key-value pairs will be returned in the delete response.
-  bool prev_kv = 3;
-}
-
-message DeleteRangeResponse {
-  ResponseHeader header = 1;
-  // deleted is the number of keys deleted by the delete range request.
-  int64 deleted = 2;
-  // if prev_kv is set in the request, the previous key-value pairs will be returned.
-  repeated mvccpb.KeyValue prev_kvs = 3;
-}
-
-message RequestOp {
-  // request is a union of request types accepted by a transaction.
-  oneof request {
-    RangeRequest request_range = 1;
-    PutRequest request_put = 2;
-    DeleteRangeRequest request_delete_range = 3;
-    TxnRequest request_txn = 4;
-  }
-}
-
-message ResponseOp {
-  // response is a union of response types returned by a transaction.
-  oneof response {
-    RangeResponse response_range = 1;
-    PutResponse response_put = 2;
-    DeleteRangeResponse response_delete_range = 3;
-    TxnResponse response_txn = 4;
-  }
-}
-
-message Compare {
-  enum CompareResult {
-    EQUAL = 0;
-    GREATER = 1;
-    LESS = 2;
-    NOT_EQUAL = 3;
-  }
-  enum CompareTarget {
-    VERSION = 0;
-    CREATE = 1;
-    MOD = 2;
-    VALUE = 3;
-    LEASE = 4;
-  }
-  // result is logical comparison operation for this comparison.
-  CompareResult result = 1;
-  // target is the key-value field to inspect for the comparison.
-  CompareTarget target = 2;
-  // key is the subject key for the comparison operation.
-  bytes key = 3;
-  oneof target_union {
-    // version is the version of the given key
-    int64 version = 4;
-    // create_revision is the creation revision of the given key
-    int64 create_revision = 5;
-    // mod_revision is the last modified revision of the given key.
-    int64 mod_revision = 6;
-    // value is the value of the given key, in bytes.
-    bytes value = 7;
-    // lease is the lease id of the given key.
-    int64 lease = 8;
-    // leave room for more target_union field tags, jump to 64
-  }
-
-  // range_end compares the given target to all keys in the range [key, range_end).
-  // See RangeRequest for more details on key ranges.
-  bytes range_end = 64;
-  // TODO: fill out with most of the rest of RangeRequest fields when needed.
-}
-
-// From google paxosdb paper:
-// Our implementation hinges around a powerful primitive which we call MultiOp. All other database
-// operations except for iteration are implemented as a single call to MultiOp. A MultiOp is applied atomically
-// and consists of three components:
-// 1. A list of tests called guard. Each test in guard checks a single entry in the database. It may check
-// for the absence or presence of a value, or compare with a given value. Two different tests in the guard
-// may apply to the same or different entries in the database. All tests in the guard are applied and
-// MultiOp returns the results. If all tests are true, MultiOp executes t op (see item 2 below), otherwise
-// it executes f op (see item 3 below).
-// 2. A list of database operations called t op. Each operation in the list is either an insert, delete, or
-// lookup operation, and applies to a single database entry. Two different operations in the list may apply
-// to the same or different entries in the database. These operations are executed
-// if guard evaluates to
-// true.
-// 3. A list of database operations called f op. Like t op, but executed if guard evaluates to false.
-message TxnRequest {
-  // compare is a list of predicates representing a conjunction of terms.
-  // If the comparisons succeed, then the success requests will be processed in order,
-  // and the response will contain their respective responses in order.
-  // If the comparisons fail, then the failure requests will be processed in order,
-  // and the response will contain their respective responses in order.
-  repeated Compare compare = 1;
-  // success is a list of requests which will be applied when compare evaluates to true.
-  repeated RequestOp success = 2;
-  // failure is a list of requests which will be applied when compare evaluates to false.
-  repeated RequestOp failure = 3;
-}
-
-message TxnResponse {
-  ResponseHeader header = 1;
-  // succeeded is set to true if the compare evaluated to true or false otherwise.
-  bool succeeded = 2;
-  // responses is a list of responses corresponding to the results from applying
-  // success if succeeded is true or failure if succeeded is false.
-  repeated ResponseOp responses = 3;
-}
-
-// CompactionRequest compacts the key-value store up to a given revision. All superseded keys
-// with a revision less than the compaction revision will be removed.
-message CompactionRequest {
-  // revision is the key-value store revision for the compaction operation.
-  int64 revision = 1;
-  // physical is set so the RPC will wait until the compaction is physically
-  // applied to the local database such that compacted entries are totally
-  // removed from the backend database.
-  bool physical = 2;
-}
-
-message CompactionResponse {
-  ResponseHeader header = 1;
-}
-
-message HashRequest {
-}
-
-message HashKVRequest {
-  // revision is the key-value store revision for the hash operation.
-  int64 revision = 1;
-}
-
-message HashKVResponse {
-  ResponseHeader header = 1;
-  // hash is the hash value computed from the responding member's MVCC keys up to a given revision.
-  uint32 hash = 2;
-  // compact_revision is the compacted revision of key-value store when hash begins.
-  int64 compact_revision = 3;
-}
-
-message HashResponse {
-  ResponseHeader header = 1;
-  // hash is the hash value computed from the responding member's KV's backend.
-  uint32 hash = 2;
-}
-
-message SnapshotRequest {
-}
-
-message SnapshotResponse {
-  // header has the current key-value store information. The first header in the snapshot
-  // stream indicates the point in time of the snapshot.
-  ResponseHeader header = 1;
-
-  // remaining_bytes is the number of blob bytes to be sent after this message
-  uint64 remaining_bytes = 2;
-
-  // blob contains the next chunk of the snapshot in the snapshot stream.
-  bytes blob = 3;
-}
-
-message WatchRequest {
-  // request_union is a request to either create a new watcher or cancel an existing watcher.
-  oneof request_union {
-    WatchCreateRequest create_request = 1;
-    WatchCancelRequest cancel_request = 2;
-    WatchProgressRequest progress_request = 3;
-  }
-}
-
-message WatchCreateRequest {
-  // key is the key to register for watching.
-  bytes key = 1;
-
-  // range_end is the end of the range [key, range_end) to watch. If range_end is not given,
-  // only the key argument is watched. If range_end is equal to '\0', all keys greater than
-  // or equal to the key argument are watched.
-  // If the range_end is one bit larger than the given key,
-  // then all keys with the prefix (the given key) will be watched.
-  bytes range_end = 2;
-
-  // start_revision is an optional revision to watch from (inclusive). No start_revision is "now".
-  int64 start_revision = 3;
-
-  // progress_notify is set so that the etcd server will periodically send a WatchResponse with
-  // no events to the new watcher if there are no recent events. It is useful when clients
-  // wish to recover a disconnected watcher starting from a recent known revision.
-  // The etcd server may decide how often it will send notifications based on current load.
-  bool progress_notify = 4;
-
-  enum FilterType {
-    // filter out put event.
-    NOPUT = 0;
-    // filter out delete event.
-    NODELETE = 1;
-  }
-
-  // filters filter the events at server side before it sends back to the watcher.
-  repeated FilterType filters = 5;
-
-  // If prev_kv is set, created watcher gets the previous KV before the event happens.
-  // If the previous KV is already compacted, nothing will be returned.
-  bool prev_kv = 6;
-
-  // If watch_id is provided and non-zero, it will be assigned to this watcher.
-  // Since creating a watcher in etcd is not a synchronous operation,
-  // this can be used ensure that ordering is correct when creating multiple
-  // watchers on the same stream. Creating a watcher with an ID already in
-  // use on the stream will cause an error to be returned.
-  int64 watch_id = 7;
-
-  // fragment enables splitting large revisions into multiple watch responses.
-  bool fragment = 8;
-}
-
-message WatchCancelRequest {
-  // watch_id is the watcher id to cancel so that no more events are transmitted.
-  int64 watch_id = 1;
-}
-
-// Requests the a watch stream progress status be sent in the watch response stream as soon as
-// possible.
-message WatchProgressRequest {
-}
-
-message WatchResponse {
-  ResponseHeader header = 1;
-  // watch_id is the ID of the watcher that corresponds to the response.
-  int64 watch_id = 2;
-
-  // created is set to true if the response is for a create watch request.
-  // The client should record the watch_id and expect to receive events for
-  // the created watcher from the same stream.
-  // All events sent to the created watcher will attach with the same watch_id.
-  bool created = 3;
-
-  // canceled is set to true if the response is for a cancel watch request.
-  // No further events will be sent to the canceled watcher.
-  bool canceled = 4;
-
-  // compact_revision is set to the minimum index if a watcher tries to watch
-  // at a compacted index.
-  //
-  // This happens when creating a watcher at a compacted revision or the watcher cannot
-  // catch up with the progress of the key-value store.
-  //
-  // The client should treat the watcher as canceled and should not try to create any
-  // watcher with the same start_revision again.
-  int64 compact_revision = 5;
-
-  // cancel_reason indicates the reason for canceling the watcher.
-  string cancel_reason = 6;
-
-  // framgment is true if large watch response was split over multiple responses.
-  bool fragment = 7;
-
-  repeated mvccpb.Event events = 11;
-}
-
-message LeaseGrantRequest {
-  // TTL is the advisory time-to-live in seconds. Expired lease will return -1.
-  int64 TTL = 1;
-  // ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID.
-  int64 ID = 2;
-}
-
-message LeaseGrantResponse {
-  ResponseHeader header = 1;
-  // ID is the lease ID for the granted lease.
-  int64 ID = 2;
-  // TTL is the server chosen lease time-to-live in seconds.
-  int64 TTL = 3;
-  string error = 4;
-}
-
-message LeaseRevokeRequest {
-  // ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted.
-  int64 ID = 1;
-}
-
-message LeaseRevokeResponse {
-  ResponseHeader header = 1;
-}
-
-message LeaseCheckpoint {
-    // ID is the lease ID to checkpoint.
-  int64 ID = 1;
-
-  // Remaining_TTL is the remaining time until expiry of the lease.
-  int64 remaining_TTL = 2;
-}
-
-message LeaseCheckpointRequest {
-  repeated LeaseCheckpoint checkpoints = 1;
-}
-
-message LeaseCheckpointResponse {
-  ResponseHeader header = 1;
-}
-
-message LeaseKeepAliveRequest {
-  // ID is the lease ID for the lease to keep alive.
-  int64 ID = 1;
-}
-
-message LeaseKeepAliveResponse {
-  ResponseHeader header = 1;
-  // ID is the lease ID from the keep alive request.
-  int64 ID = 2;
-  // TTL is the new time-to-live for the lease.
-  int64 TTL = 3;
-}
-
-message LeaseTimeToLiveRequest {
-  // ID is the lease ID for the lease.
-  int64 ID = 1;
-  // keys is true to query all the keys attached to this lease.
-  bool keys = 2;
-}
-
-message LeaseTimeToLiveResponse {
-  ResponseHeader header = 1;
-  // ID is the lease ID from the keep alive request.
-  int64 ID = 2;
-  // TTL is the remaining TTL in seconds for the lease; the lease will expire in under TTL+1 seconds.
-  int64 TTL = 3;
-  // GrantedTTL is the initial granted time in seconds upon lease creation/renewal.
-  int64 grantedTTL = 4;
-  // Keys is the list of keys attached to this lease.
-  repeated bytes keys = 5;
-}
-
-message LeaseLeasesRequest {
-}
-
-message LeaseStatus {
-  int64 ID = 1;
-  // TODO: int64 TTL = 2;
-}
-
-message LeaseLeasesResponse {
-  ResponseHeader header = 1;
-  repeated LeaseStatus leases = 2;
-}
-
-message Member {
-  // ID is the member ID for this member.
-  uint64 ID = 1;
-  // name is the human-readable name of the member. If the member is not started, the name will be an empty string.
-  string name = 2;
-  // peerURLs is the list of URLs the member exposes to the cluster for communication.
-  repeated string peerURLs = 3;
-  // clientURLs is the list of URLs the member exposes to clients for communication. If the member is not started, clientURLs will be empty.
-  repeated string clientURLs = 4;
-  // isLearner indicates if the member is raft learner.
-  bool isLearner = 5;
-}
-
-message MemberAddRequest {
-  // peerURLs is the list of URLs the added member will use to communicate with the cluster.
-  repeated string peerURLs = 1;
-  // isLearner indicates if the added member is raft learner.
-  bool isLearner = 2;
-}
-
-message MemberAddResponse {
-  ResponseHeader header = 1;
-  // member is the member information for the added member.
-  Member member = 2;
-  // members is a list of all members after adding the new member.
-  repeated Member members = 3;
-}
-
-message MemberRemoveRequest {
-  // ID is the member ID of the member to remove.
-  uint64 ID = 1;
-}
-
-message MemberRemoveResponse {
-  ResponseHeader header = 1;
-  // members is a list of all members after removing the member.
-  repeated Member members = 2;
-}
-
-message MemberUpdateRequest {
-  // ID is the member ID of the member to update.
-  uint64 ID = 1;
-  // peerURLs is the new list of URLs the member will use to communicate with the cluster.
-  repeated string peerURLs = 2;
-}
-
-message MemberUpdateResponse{
-  ResponseHeader header = 1;
-  // members is a list of all members after updating the member.
-  repeated Member members = 2;
-}
-
-message MemberListRequest {
-}
-
-message MemberListResponse {
-  ResponseHeader header = 1;
-  // members is a list of all members associated with the cluster.
-  repeated Member members = 2;
-}
-
-message MemberPromoteRequest {
-  // ID is the member ID of the member to promote.
-  uint64 ID = 1;
-}
-
-message MemberPromoteResponse {
-  ResponseHeader header = 1;
-  // members is a list of all members after promoting the member.
-  repeated Member members = 2;
-}
-
-message DefragmentRequest {
-}
-
-message DefragmentResponse {
-  ResponseHeader header = 1;
-}
-
-message MoveLeaderRequest {
-  // targetID is the node ID for the new leader.
-  uint64 targetID = 1;
-}
-
-message MoveLeaderResponse {
-  ResponseHeader header = 1;
-}
-
-enum AlarmType {
-	NONE = 0; // default, used to query if any alarm is active
-	NOSPACE = 1; // space quota is exhausted
-	CORRUPT = 2; // kv store corruption detected
-}
-
-message AlarmRequest {
-  enum AlarmAction {
-	GET = 0;
-	ACTIVATE = 1;
-	DEACTIVATE = 2;
-  }
-  // action is the kind of alarm request to issue. The action
-  // may GET alarm statuses, ACTIVATE an alarm, or DEACTIVATE a
-  // raised alarm.
-  AlarmAction action = 1;
-  // memberID is the ID of the member associated with the alarm. If memberID is 0, the
-  // alarm request covers all members.
-  uint64 memberID = 2;
-  // alarm is the type of alarm to consider for this request.
-  AlarmType alarm = 3;
-}
-
-message AlarmMember {
-  // memberID is the ID of the member associated with the raised alarm.
-  uint64 memberID = 1;
-  // alarm is the type of alarm which has been raised.
-  AlarmType alarm = 2;
-}
-
-message AlarmResponse {
-  ResponseHeader header = 1;
-  // alarms is a list of alarms associated with the alarm request.
-  repeated AlarmMember alarms = 2;
-}
-
-message StatusRequest {
-}
-
-message StatusResponse {
-  ResponseHeader header = 1;
-  // version is the cluster protocol version used by the responding member.
-  string version = 2;
-  // dbSize is the size of the backend database physically allocated, in bytes, of the responding member.
-  int64 dbSize = 3;
-  // leader is the member ID which the responding member believes is the current leader.
-  uint64 leader = 4;
-  // raftIndex is the current raft committed index of the responding member.
-  uint64 raftIndex = 5;
-  // raftTerm is the current raft term of the responding member.
-  uint64 raftTerm = 6;
-  // raftAppliedIndex is the current raft applied index of the responding member.
-  uint64 raftAppliedIndex = 7;
-  // errors contains alarm/health information and status.
-  repeated string errors = 8;
-  // dbSizeInUse is the size of the backend database logically in use, in bytes, of the responding member.
-  int64 dbSizeInUse = 9;
-  // isLearner indicates if the member is raft learner.
-  bool isLearner = 10;
-}
-
-message AuthEnableRequest {
-}
-
-message AuthDisableRequest {
-}
-
-message AuthenticateRequest {
-  string name = 1;
-  string password = 2;
-}
-
-message AuthUserAddRequest {
-  string name = 1;
-  string password = 2;
-  authpb.UserAddOptions options = 3;
-}
-
-message AuthUserGetRequest {
-  string name = 1;
-}
-
-message AuthUserDeleteRequest {
-  // name is the name of the user to delete.
-  string name = 1;
-}
-
-message AuthUserChangePasswordRequest {
-  // name is the name of the user whose password is being changed.
-  string name = 1;
-  // password is the new password for the user.
-  string password = 2;
-}
-
-message AuthUserGrantRoleRequest {
-  // user is the name of the user which should be granted a given role.
-  string user = 1;
-  // role is the name of the role to grant to the user.
-  string role = 2;
-}
-
-message AuthUserRevokeRoleRequest {
-  string name = 1;
-  string role = 2;
-}
-
-message AuthRoleAddRequest {
-  // name is the name of the role to add to the authentication system.
-  string name = 1;
-}
-
-message AuthRoleGetRequest {
-  string role = 1;
-}
-
-message AuthUserListRequest {
-}
-
-message AuthRoleListRequest {
-}
-
-message AuthRoleDeleteRequest {
-  string role = 1;
-}
-
-message AuthRoleGrantPermissionRequest {
-  // name is the name of the role which will be granted the permission.
-  string name = 1;
-  // perm is the permission to grant to the role.
-  authpb.Permission perm = 2;
-}
-
-message AuthRoleRevokePermissionRequest {
-  string role = 1;
-  bytes key = 2;
-  bytes range_end = 3;
-}
-
-message AuthEnableResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthDisableResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthenticateResponse {
-  ResponseHeader header = 1;
-  // token is an authorized token that can be used in succeeding RPCs
-  string token = 2;
-}
-
-message AuthUserAddResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthUserGetResponse {
-  ResponseHeader header = 1;
-
-  repeated string roles = 2;
-}
-
-message AuthUserDeleteResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthUserChangePasswordResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthUserGrantRoleResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthUserRevokeRoleResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthRoleAddResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthRoleGetResponse {
-  ResponseHeader header = 1;
-
-  repeated authpb.Permission perm = 2;
-}
-
-message AuthRoleListResponse {
-  ResponseHeader header = 1;
-
-  repeated string roles = 2;
-}
-
-message AuthUserListResponse {
-  ResponseHeader header = 1;
-
-  repeated string users = 2;
-}
-
-message AuthRoleDeleteResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthRoleGrantPermissionResponse {
-  ResponseHeader header = 1;
-}
-
-message AuthRoleRevokePermissionResponse {
-  ResponseHeader header = 1;
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/metrics.go b/vendor/go.etcd.io/etcd/etcdserver/metrics.go
deleted file mode 100644
index e0c0cde..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/metrics.go
+++ /dev/null
@@ -1,221 +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 etcdserver
-
-import (
-	goruntime "runtime"
-	"time"
-
-	"go.etcd.io/etcd/pkg/runtime"
-	"go.etcd.io/etcd/version"
-
-	"github.com/prometheus/client_golang/prometheus"
-	"go.uber.org/zap"
-)
-
-var (
-	hasLeader = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "has_leader",
-		Help:      "Whether or not a leader exists. 1 is existence, 0 is not.",
-	})
-	isLeader = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "is_leader",
-		Help:      "Whether or not this member is a leader. 1 if is, 0 otherwise.",
-	})
-	leaderChanges = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "leader_changes_seen_total",
-		Help:      "The number of leader changes seen.",
-	})
-	isLearner = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "is_learner",
-		Help:      "Whether or not this member is a learner. 1 if is, 0 otherwise.",
-	})
-	learnerPromoteFailed = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "learner_promote_failures",
-		Help:      "The total number of failed learner promotions (likely learner not ready) while this member is leader.",
-	},
-		[]string{"Reason"},
-	)
-	learnerPromoteSucceed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "learner_promote_successes",
-		Help:      "The total number of successful learner promotions while this member is leader.",
-	})
-	heartbeatSendFailures = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "heartbeat_send_failures_total",
-		Help:      "The total number of leader heartbeat send failures (likely overloaded from slow disk).",
-	})
-	slowApplies = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "slow_apply_total",
-		Help:      "The total number of slow apply requests (likely overloaded from slow disk).",
-	})
-	applySnapshotInProgress = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "snapshot_apply_in_progress_total",
-		Help:      "1 if the server is applying the incoming snapshot. 0 if none.",
-	})
-	proposalsCommitted = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_committed_total",
-		Help:      "The total number of consensus proposals committed.",
-	})
-	proposalsApplied = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_applied_total",
-		Help:      "The total number of consensus proposals applied.",
-	})
-	proposalsPending = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_pending",
-		Help:      "The current number of pending proposals to commit.",
-	})
-	proposalsFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "proposals_failed_total",
-		Help:      "The total number of failed proposals seen.",
-	})
-	slowReadIndex = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "slow_read_indexes_total",
-		Help:      "The total number of pending read indexes not in sync with leader's or timed out read index requests.",
-	})
-	readIndexFailed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "read_indexes_failed_total",
-		Help:      "The total number of failed read indexes seen.",
-	})
-	leaseExpired = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "server",
-		Name:      "lease_expired_total",
-		Help:      "The total number of expired leases.",
-	})
-	quotaBackendBytes = prometheus.NewGauge(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "quota_backend_bytes",
-		Help:      "Current backend storage quota size in bytes.",
-	})
-	currentVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "version",
-		Help:      "Which version is running. 1 for 'server_version' label with current version.",
-	},
-		[]string{"server_version"})
-	currentGoVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "go_version",
-		Help:      "Which Go version server is running with. 1 for 'server_go_version' label with current version.",
-	},
-		[]string{"server_go_version"})
-	serverID = prometheus.NewGaugeVec(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "server",
-		Name:      "id",
-		Help:      "Server or member ID in hexadecimal format. 1 for 'server_id' label with current ID.",
-	},
-		[]string{"server_id"})
-)
-
-func init() {
-	prometheus.MustRegister(hasLeader)
-	prometheus.MustRegister(isLeader)
-	prometheus.MustRegister(leaderChanges)
-	prometheus.MustRegister(heartbeatSendFailures)
-	prometheus.MustRegister(slowApplies)
-	prometheus.MustRegister(applySnapshotInProgress)
-	prometheus.MustRegister(proposalsCommitted)
-	prometheus.MustRegister(proposalsApplied)
-	prometheus.MustRegister(proposalsPending)
-	prometheus.MustRegister(proposalsFailed)
-	prometheus.MustRegister(slowReadIndex)
-	prometheus.MustRegister(readIndexFailed)
-	prometheus.MustRegister(leaseExpired)
-	prometheus.MustRegister(quotaBackendBytes)
-	prometheus.MustRegister(currentVersion)
-	prometheus.MustRegister(currentGoVersion)
-	prometheus.MustRegister(serverID)
-	prometheus.MustRegister(isLearner)
-	prometheus.MustRegister(learnerPromoteSucceed)
-	prometheus.MustRegister(learnerPromoteFailed)
-
-	currentVersion.With(prometheus.Labels{
-		"server_version": version.Version,
-	}).Set(1)
-	currentGoVersion.With(prometheus.Labels{
-		"server_go_version": goruntime.Version(),
-	}).Set(1)
-}
-
-func monitorFileDescriptor(lg *zap.Logger, done <-chan struct{}) {
-	ticker := time.NewTicker(5 * time.Second)
-	defer ticker.Stop()
-	for {
-		used, err := runtime.FDUsage()
-		if err != nil {
-			if lg != nil {
-				lg.Warn("failed to get file descriptor usage", zap.Error(err))
-			} else {
-				plog.Errorf("cannot monitor file descriptor usage (%v)", err)
-			}
-			return
-		}
-		limit, err := runtime.FDLimit()
-		if err != nil {
-			if lg != nil {
-				lg.Warn("failed to get file descriptor limit", zap.Error(err))
-			} else {
-				plog.Errorf("cannot monitor file descriptor usage (%v)", err)
-			}
-			return
-		}
-		if used >= limit/5*4 {
-			if lg != nil {
-				lg.Warn("80% of file descriptors are used", zap.Uint64("used", used), zap.Uint64("limit", limit))
-			} else {
-				plog.Warningf("80%% of the file descriptor limit is used [used = %d, limit = %d]", used, limit)
-			}
-		}
-		select {
-		case <-ticker.C:
-		case <-done:
-			return
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/quota.go b/vendor/go.etcd.io/etcd/etcdserver/quota.go
deleted file mode 100644
index 6d70430..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/quota.go
+++ /dev/null
@@ -1,182 +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 etcdserver
-
-import (
-	"sync"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	humanize "github.com/dustin/go-humanize"
-	"go.uber.org/zap"
-)
-
-const (
-	// DefaultQuotaBytes is the number of bytes the backend Size may
-	// consume before exceeding the space quota.
-	DefaultQuotaBytes = int64(2 * 1024 * 1024 * 1024) // 2GB
-	// MaxQuotaBytes is the maximum number of bytes suggested for a backend
-	// quota. A larger quota may lead to degraded performance.
-	MaxQuotaBytes = int64(8 * 1024 * 1024 * 1024) // 8GB
-)
-
-// Quota represents an arbitrary quota against arbitrary requests. Each request
-// costs some charge; if there is not enough remaining charge, then there are
-// too few resources available within the quota to apply the request.
-type Quota interface {
-	// Available judges whether the given request fits within the quota.
-	Available(req interface{}) bool
-	// Cost computes the charge against the quota for a given request.
-	Cost(req interface{}) int
-	// Remaining is the amount of charge left for the quota.
-	Remaining() int64
-}
-
-type passthroughQuota struct{}
-
-func (*passthroughQuota) Available(interface{}) bool { return true }
-func (*passthroughQuota) Cost(interface{}) int       { return 0 }
-func (*passthroughQuota) Remaining() int64           { return 1 }
-
-type backendQuota struct {
-	s               *EtcdServer
-	maxBackendBytes int64
-}
-
-const (
-	// leaseOverhead is an estimate for the cost of storing a lease
-	leaseOverhead = 64
-	// kvOverhead is an estimate for the cost of storing a key's metadata
-	kvOverhead = 256
-)
-
-var (
-	// only log once
-	quotaLogOnce sync.Once
-
-	DefaultQuotaSize = humanize.Bytes(uint64(DefaultQuotaBytes))
-	maxQuotaSize     = humanize.Bytes(uint64(MaxQuotaBytes))
-)
-
-// NewBackendQuota creates a quota layer with the given storage limit.
-func NewBackendQuota(s *EtcdServer, name string) Quota {
-	lg := s.getLogger()
-	quotaBackendBytes.Set(float64(s.Cfg.QuotaBackendBytes))
-
-	if s.Cfg.QuotaBackendBytes < 0 {
-		// disable quotas if negative
-		quotaLogOnce.Do(func() {
-			if lg != nil {
-				lg.Info(
-					"disabled backend quota",
-					zap.String("quota-name", name),
-					zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
-				)
-			} else {
-				plog.Warningf("disabling backend quota")
-			}
-		})
-		return &passthroughQuota{}
-	}
-
-	if s.Cfg.QuotaBackendBytes == 0 {
-		// use default size if no quota size given
-		quotaLogOnce.Do(func() {
-			if lg != nil {
-				lg.Info(
-					"enabled backend quota with default value",
-					zap.String("quota-name", name),
-					zap.Int64("quota-size-bytes", DefaultQuotaBytes),
-					zap.String("quota-size", DefaultQuotaSize),
-				)
-			}
-		})
-		quotaBackendBytes.Set(float64(DefaultQuotaBytes))
-		return &backendQuota{s, DefaultQuotaBytes}
-	}
-
-	quotaLogOnce.Do(func() {
-		if s.Cfg.QuotaBackendBytes > MaxQuotaBytes {
-			if lg != nil {
-				lg.Warn(
-					"quota exceeds the maximum value",
-					zap.String("quota-name", name),
-					zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
-					zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
-					zap.Int64("quota-maximum-size-bytes", MaxQuotaBytes),
-					zap.String("quota-maximum-size", maxQuotaSize),
-				)
-			} else {
-				plog.Warningf("backend quota %v exceeds maximum recommended quota %v", s.Cfg.QuotaBackendBytes, MaxQuotaBytes)
-			}
-		}
-		if lg != nil {
-			lg.Info(
-				"enabled backend quota",
-				zap.String("quota-name", name),
-				zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
-				zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
-			)
-		}
-	})
-	return &backendQuota{s, s.Cfg.QuotaBackendBytes}
-}
-
-func (b *backendQuota) Available(v interface{}) bool {
-	// TODO: maybe optimize backend.Size()
-	return b.s.Backend().Size()+int64(b.Cost(v)) < b.maxBackendBytes
-}
-
-func (b *backendQuota) Cost(v interface{}) int {
-	switch r := v.(type) {
-	case *pb.PutRequest:
-		return costPut(r)
-	case *pb.TxnRequest:
-		return costTxn(r)
-	case *pb.LeaseGrantRequest:
-		return leaseOverhead
-	default:
-		panic("unexpected cost")
-	}
-}
-
-func costPut(r *pb.PutRequest) int { return kvOverhead + len(r.Key) + len(r.Value) }
-
-func costTxnReq(u *pb.RequestOp) int {
-	r := u.GetRequestPut()
-	if r == nil {
-		return 0
-	}
-	return costPut(r)
-}
-
-func costTxn(r *pb.TxnRequest) int {
-	sizeSuccess := 0
-	for _, u := range r.Success {
-		sizeSuccess += costTxnReq(u)
-	}
-	sizeFailure := 0
-	for _, u := range r.Failure {
-		sizeFailure += costTxnReq(u)
-	}
-	if sizeFailure > sizeSuccess {
-		return sizeFailure
-	}
-	return sizeSuccess
-}
-
-func (b *backendQuota) Remaining() int64 {
-	return b.maxBackendBytes - b.s.Backend().Size()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/raft.go b/vendor/go.etcd.io/etcd/etcdserver/raft.go
deleted file mode 100644
index c0fe979..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/raft.go
+++ /dev/null
@@ -1,753 +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 etcdserver
-
-import (
-	"encoding/json"
-	"expvar"
-	"fmt"
-	"log"
-	"sort"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/rafthttp"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/contention"
-	"go.etcd.io/etcd/pkg/logutil"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/wal"
-	"go.etcd.io/etcd/wal/walpb"
-	"go.uber.org/zap"
-)
-
-const (
-	// The max throughput of etcd will not exceed 100MB/s (100K * 1KB value).
-	// Assuming the RTT is around 10ms, 1MB max size is large enough.
-	maxSizePerMsg = 1 * 1024 * 1024
-	// Never overflow the rafthttp buffer, which is 4096.
-	// TODO: a better const?
-	maxInflightMsgs = 4096 / 8
-)
-
-var (
-	// protects raftStatus
-	raftStatusMu sync.Mutex
-	// indirection for expvar func interface
-	// expvar panics when publishing duplicate name
-	// expvar does not support remove a registered name
-	// so only register a func that calls raftStatus
-	// and change raftStatus as we need.
-	raftStatus func() raft.Status
-)
-
-func init() {
-	expvar.Publish("raft.status", expvar.Func(func() interface{} {
-		raftStatusMu.Lock()
-		defer raftStatusMu.Unlock()
-		return raftStatus()
-	}))
-}
-
-// apply contains entries, snapshot to be applied. Once
-// an apply is consumed, the entries will be persisted to
-// to raft storage concurrently; the application must read
-// raftDone before assuming the raft messages are stable.
-type apply struct {
-	entries  []raftpb.Entry
-	snapshot raftpb.Snapshot
-	// notifyc synchronizes etcd server applies with the raft node
-	notifyc chan struct{}
-}
-
-type raftNode struct {
-	lg *zap.Logger
-
-	tickMu *sync.Mutex
-	raftNodeConfig
-
-	// a chan to send/receive snapshot
-	msgSnapC chan raftpb.Message
-
-	// a chan to send out apply
-	applyc chan apply
-
-	// a chan to send out readState
-	readStateC chan raft.ReadState
-
-	// utility
-	ticker *time.Ticker
-	// contention detectors for raft heartbeat message
-	td *contention.TimeoutDetector
-
-	stopped chan struct{}
-	done    chan struct{}
-}
-
-type raftNodeConfig struct {
-	lg *zap.Logger
-
-	// to check if msg receiver is removed from cluster
-	isIDRemoved func(id uint64) bool
-	raft.Node
-	raftStorage *raft.MemoryStorage
-	storage     Storage
-	heartbeat   time.Duration // for logging
-	// transport specifies the transport to send and receive msgs to members.
-	// Sending messages MUST NOT block. It is okay to drop messages, since
-	// clients should timeout and reissue their messages.
-	// If transport is nil, server will panic.
-	transport rafthttp.Transporter
-}
-
-func newRaftNode(cfg raftNodeConfig) *raftNode {
-	var lg raft.Logger
-	if cfg.lg != nil {
-		lg = logutil.NewRaftLoggerZap(cfg.lg)
-	} else {
-		lcfg := logutil.DefaultZapLoggerConfig
-		var err error
-		lg, err = logutil.NewRaftLogger(&lcfg)
-		if err != nil {
-			log.Fatalf("cannot create raft logger %v", err)
-		}
-	}
-	raft.SetLogger(lg)
-	r := &raftNode{
-		lg:             cfg.lg,
-		tickMu:         new(sync.Mutex),
-		raftNodeConfig: cfg,
-		// set up contention detectors for raft heartbeat message.
-		// expect to send a heartbeat within 2 heartbeat intervals.
-		td:         contention.NewTimeoutDetector(2 * cfg.heartbeat),
-		readStateC: make(chan raft.ReadState, 1),
-		msgSnapC:   make(chan raftpb.Message, maxInFlightMsgSnap),
-		applyc:     make(chan apply),
-		stopped:    make(chan struct{}),
-		done:       make(chan struct{}),
-	}
-	if r.heartbeat == 0 {
-		r.ticker = &time.Ticker{}
-	} else {
-		r.ticker = time.NewTicker(r.heartbeat)
-	}
-	return r
-}
-
-// raft.Node does not have locks in Raft package
-func (r *raftNode) tick() {
-	r.tickMu.Lock()
-	r.Tick()
-	r.tickMu.Unlock()
-}
-
-// start prepares and starts raftNode in a new goroutine. It is no longer safe
-// to modify the fields after it has been started.
-func (r *raftNode) start(rh *raftReadyHandler) {
-	internalTimeout := time.Second
-
-	go func() {
-		defer r.onStop()
-		islead := false
-
-		for {
-			select {
-			case <-r.ticker.C:
-				r.tick()
-			case rd := <-r.Ready():
-				if rd.SoftState != nil {
-					newLeader := rd.SoftState.Lead != raft.None && rh.getLead() != rd.SoftState.Lead
-					if newLeader {
-						leaderChanges.Inc()
-					}
-
-					if rd.SoftState.Lead == raft.None {
-						hasLeader.Set(0)
-					} else {
-						hasLeader.Set(1)
-					}
-
-					rh.updateLead(rd.SoftState.Lead)
-					islead = rd.RaftState == raft.StateLeader
-					if islead {
-						isLeader.Set(1)
-					} else {
-						isLeader.Set(0)
-					}
-					rh.updateLeadership(newLeader)
-					r.td.Reset()
-				}
-
-				if len(rd.ReadStates) != 0 {
-					select {
-					case r.readStateC <- rd.ReadStates[len(rd.ReadStates)-1]:
-					case <-time.After(internalTimeout):
-						if r.lg != nil {
-							r.lg.Warn("timed out sending read state", zap.Duration("timeout", internalTimeout))
-						} else {
-							plog.Warningf("timed out sending read state")
-						}
-					case <-r.stopped:
-						return
-					}
-				}
-
-				notifyc := make(chan struct{}, 1)
-				ap := apply{
-					entries:  rd.CommittedEntries,
-					snapshot: rd.Snapshot,
-					notifyc:  notifyc,
-				}
-
-				updateCommittedIndex(&ap, rh)
-
-				select {
-				case r.applyc <- ap:
-				case <-r.stopped:
-					return
-				}
-
-				// the leader can write to its disk in parallel with replicating to the followers and them
-				// writing to their disks.
-				// For more details, check raft thesis 10.2.1
-				if islead {
-					// gofail: var raftBeforeLeaderSend struct{}
-					r.transport.Send(r.processMessages(rd.Messages))
-				}
-
-				// gofail: var raftBeforeSave struct{}
-				if err := r.storage.Save(rd.HardState, rd.Entries); err != nil {
-					if r.lg != nil {
-						r.lg.Fatal("failed to save Raft hard state and entries", zap.Error(err))
-					} else {
-						plog.Fatalf("raft save state and entries error: %v", err)
-					}
-				}
-				if !raft.IsEmptyHardState(rd.HardState) {
-					proposalsCommitted.Set(float64(rd.HardState.Commit))
-				}
-				// gofail: var raftAfterSave struct{}
-
-				if !raft.IsEmptySnap(rd.Snapshot) {
-					// gofail: var raftBeforeSaveSnap struct{}
-					if err := r.storage.SaveSnap(rd.Snapshot); err != nil {
-						if r.lg != nil {
-							r.lg.Fatal("failed to save Raft snapshot", zap.Error(err))
-						} else {
-							plog.Fatalf("raft save snapshot error: %v", err)
-						}
-					}
-					// etcdserver now claim the snapshot has been persisted onto the disk
-					notifyc <- struct{}{}
-
-					// gofail: var raftAfterSaveSnap struct{}
-					r.raftStorage.ApplySnapshot(rd.Snapshot)
-					if r.lg != nil {
-						r.lg.Info("applied incoming Raft snapshot", zap.Uint64("snapshot-index", rd.Snapshot.Metadata.Index))
-					} else {
-						plog.Infof("raft applied incoming snapshot at index %d", rd.Snapshot.Metadata.Index)
-					}
-					// gofail: var raftAfterApplySnap struct{}
-				}
-
-				r.raftStorage.Append(rd.Entries)
-
-				if !islead {
-					// finish processing incoming messages before we signal raftdone chan
-					msgs := r.processMessages(rd.Messages)
-
-					// now unblocks 'applyAll' that waits on Raft log disk writes before triggering snapshots
-					notifyc <- struct{}{}
-
-					// Candidate or follower needs to wait for all pending configuration
-					// changes to be applied before sending messages.
-					// Otherwise we might incorrectly count votes (e.g. votes from removed members).
-					// Also slow machine's follower raft-layer could proceed to become the leader
-					// on its own single-node cluster, before apply-layer applies the config change.
-					// We simply wait for ALL pending entries to be applied for now.
-					// We might improve this later on if it causes unnecessary long blocking issues.
-					waitApply := false
-					for _, ent := range rd.CommittedEntries {
-						if ent.Type == raftpb.EntryConfChange {
-							waitApply = true
-							break
-						}
-					}
-					if waitApply {
-						// blocks until 'applyAll' calls 'applyWait.Trigger'
-						// to be in sync with scheduled config-change job
-						// (assume notifyc has cap of 1)
-						select {
-						case notifyc <- struct{}{}:
-						case <-r.stopped:
-							return
-						}
-					}
-
-					// gofail: var raftBeforeFollowerSend struct{}
-					r.transport.Send(msgs)
-				} else {
-					// leader already processed 'MsgSnap' and signaled
-					notifyc <- struct{}{}
-				}
-
-				r.Advance()
-			case <-r.stopped:
-				return
-			}
-		}
-	}()
-}
-
-func updateCommittedIndex(ap *apply, rh *raftReadyHandler) {
-	var ci uint64
-	if len(ap.entries) != 0 {
-		ci = ap.entries[len(ap.entries)-1].Index
-	}
-	if ap.snapshot.Metadata.Index > ci {
-		ci = ap.snapshot.Metadata.Index
-	}
-	if ci != 0 {
-		rh.updateCommittedIndex(ci)
-	}
-}
-
-func (r *raftNode) processMessages(ms []raftpb.Message) []raftpb.Message {
-	sentAppResp := false
-	for i := len(ms) - 1; i >= 0; i-- {
-		if r.isIDRemoved(ms[i].To) {
-			ms[i].To = 0
-		}
-
-		if ms[i].Type == raftpb.MsgAppResp {
-			if sentAppResp {
-				ms[i].To = 0
-			} else {
-				sentAppResp = true
-			}
-		}
-
-		if ms[i].Type == raftpb.MsgSnap {
-			// There are two separate data store: the store for v2, and the KV for v3.
-			// The msgSnap only contains the most recent snapshot of store without KV.
-			// So we need to redirect the msgSnap to etcd server main loop for merging in the
-			// current store snapshot and KV snapshot.
-			select {
-			case r.msgSnapC <- ms[i]:
-			default:
-				// drop msgSnap if the inflight chan if full.
-			}
-			ms[i].To = 0
-		}
-		if ms[i].Type == raftpb.MsgHeartbeat {
-			ok, exceed := r.td.Observe(ms[i].To)
-			if !ok {
-				// TODO: limit request rate.
-				if r.lg != nil {
-					r.lg.Warn(
-						"leader failed to send out heartbeat on time; took too long, leader is overloaded likely from slow disk",
-						zap.String("to", fmt.Sprintf("%x", ms[i].To)),
-						zap.Duration("heartbeat-interval", r.heartbeat),
-						zap.Duration("expected-duration", 2*r.heartbeat),
-						zap.Duration("exceeded-duration", exceed),
-					)
-				} else {
-					plog.Warningf("failed to send out heartbeat on time (exceeded the %v timeout for %v, to %x)", r.heartbeat, exceed, ms[i].To)
-					plog.Warningf("server is likely overloaded")
-				}
-				heartbeatSendFailures.Inc()
-			}
-		}
-	}
-	return ms
-}
-
-func (r *raftNode) apply() chan apply {
-	return r.applyc
-}
-
-func (r *raftNode) stop() {
-	r.stopped <- struct{}{}
-	<-r.done
-}
-
-func (r *raftNode) onStop() {
-	r.Stop()
-	r.ticker.Stop()
-	r.transport.Stop()
-	if err := r.storage.Close(); err != nil {
-		if r.lg != nil {
-			r.lg.Panic("failed to close Raft storage", zap.Error(err))
-		} else {
-			plog.Panicf("raft close storage error: %v", err)
-		}
-	}
-	close(r.done)
-}
-
-// for testing
-func (r *raftNode) pauseSending() {
-	p := r.transport.(rafthttp.Pausable)
-	p.Pause()
-}
-
-func (r *raftNode) resumeSending() {
-	p := r.transport.(rafthttp.Pausable)
-	p.Resume()
-}
-
-// advanceTicks advances ticks of Raft node.
-// This can be used for fast-forwarding election
-// ticks in multi data-center deployments, thus
-// speeding up election process.
-func (r *raftNode) advanceTicks(ticks int) {
-	for i := 0; i < ticks; i++ {
-		r.tick()
-	}
-}
-
-func startNode(cfg ServerConfig, cl *membership.RaftCluster, ids []types.ID) (id types.ID, n raft.Node, s *raft.MemoryStorage, w *wal.WAL) {
-	var err error
-	member := cl.MemberByName(cfg.Name)
-	metadata := pbutil.MustMarshal(
-		&pb.Metadata{
-			NodeID:    uint64(member.ID),
-			ClusterID: uint64(cl.ID()),
-		},
-	)
-	if w, err = wal.Create(cfg.Logger, cfg.WALDir(), metadata); err != nil {
-		if cfg.Logger != nil {
-			cfg.Logger.Panic("failed to create WAL", zap.Error(err))
-		} else {
-			plog.Panicf("create wal error: %v", err)
-		}
-	}
-	peers := make([]raft.Peer, len(ids))
-	for i, id := range ids {
-		var ctx []byte
-		ctx, err = json.Marshal((*cl).Member(id))
-		if err != nil {
-			if cfg.Logger != nil {
-				cfg.Logger.Panic("failed to marshal member", zap.Error(err))
-			} else {
-				plog.Panicf("marshal member should never fail: %v", err)
-			}
-		}
-		peers[i] = raft.Peer{ID: uint64(id), Context: ctx}
-	}
-	id = member.ID
-	if cfg.Logger != nil {
-		cfg.Logger.Info(
-			"starting local member",
-			zap.String("local-member-id", id.String()),
-			zap.String("cluster-id", cl.ID().String()),
-		)
-	} else {
-		plog.Infof("starting member %s in cluster %s", id, cl.ID())
-	}
-	s = raft.NewMemoryStorage()
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-		PreVote:         cfg.PreVote,
-	}
-	if cfg.Logger != nil {
-		// called after capnslog setting in "init" function
-		if cfg.LoggerConfig != nil {
-			c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig)
-			if err != nil {
-				log.Fatalf("cannot create raft logger %v", err)
-			}
-		} else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil {
-			c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer)
-		}
-	}
-
-	if len(peers) == 0 {
-		n = raft.RestartNode(c)
-	} else {
-		n = raft.StartNode(c, peers)
-	}
-	raftStatusMu.Lock()
-	raftStatus = n.Status
-	raftStatusMu.Unlock()
-	return id, n, s, w
-}
-
-func restartNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
-	var walsnap walpb.Snapshot
-	if snapshot != nil {
-		walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
-	}
-	w, id, cid, st, ents := readWAL(cfg.Logger, cfg.WALDir(), walsnap)
-
-	if cfg.Logger != nil {
-		cfg.Logger.Info(
-			"restarting local member",
-			zap.String("cluster-id", cid.String()),
-			zap.String("local-member-id", id.String()),
-			zap.Uint64("commit-index", st.Commit),
-		)
-	} else {
-		plog.Infof("restarting member %s in cluster %s at commit index %d", id, cid, st.Commit)
-	}
-	cl := membership.NewCluster(cfg.Logger, "")
-	cl.SetID(id, cid)
-	s := raft.NewMemoryStorage()
-	if snapshot != nil {
-		s.ApplySnapshot(*snapshot)
-	}
-	s.SetHardState(st)
-	s.Append(ents)
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-		PreVote:         cfg.PreVote,
-	}
-	if cfg.Logger != nil {
-		// called after capnslog setting in "init" function
-		var err error
-		if cfg.LoggerConfig != nil {
-			c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig)
-			if err != nil {
-				log.Fatalf("cannot create raft logger %v", err)
-			}
-		} else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil {
-			c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer)
-		}
-	}
-
-	n := raft.RestartNode(c)
-	raftStatusMu.Lock()
-	raftStatus = n.Status
-	raftStatusMu.Unlock()
-	return id, cl, n, s, w
-}
-
-func restartAsStandaloneNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) {
-	var walsnap walpb.Snapshot
-	if snapshot != nil {
-		walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
-	}
-	w, id, cid, st, ents := readWAL(cfg.Logger, cfg.WALDir(), walsnap)
-
-	// discard the previously uncommitted entries
-	for i, ent := range ents {
-		if ent.Index > st.Commit {
-			if cfg.Logger != nil {
-				cfg.Logger.Info(
-					"discarding uncommitted WAL entries",
-					zap.Uint64("entry-index", ent.Index),
-					zap.Uint64("commit-index-from-wal", st.Commit),
-					zap.Int("number-of-discarded-entries", len(ents)-i),
-				)
-			} else {
-				plog.Infof("discarding %d uncommitted WAL entries ", len(ents)-i)
-			}
-			ents = ents[:i]
-			break
-		}
-	}
-
-	// force append the configuration change entries
-	toAppEnts := createConfigChangeEnts(
-		cfg.Logger,
-		getIDs(cfg.Logger, snapshot, ents),
-		uint64(id),
-		st.Term,
-		st.Commit,
-	)
-	ents = append(ents, toAppEnts...)
-
-	// force commit newly appended entries
-	err := w.Save(raftpb.HardState{}, toAppEnts)
-	if err != nil {
-		if cfg.Logger != nil {
-			cfg.Logger.Fatal("failed to save hard state and entries", zap.Error(err))
-		} else {
-			plog.Fatalf("%v", err)
-		}
-	}
-	if len(ents) != 0 {
-		st.Commit = ents[len(ents)-1].Index
-	}
-
-	if cfg.Logger != nil {
-		cfg.Logger.Info(
-			"forcing restart member",
-			zap.String("cluster-id", cid.String()),
-			zap.String("local-member-id", id.String()),
-			zap.Uint64("commit-index", st.Commit),
-		)
-	} else {
-		plog.Printf("forcing restart of member %s in cluster %s at commit index %d", id, cid, st.Commit)
-	}
-
-	cl := membership.NewCluster(cfg.Logger, "")
-	cl.SetID(id, cid)
-	s := raft.NewMemoryStorage()
-	if snapshot != nil {
-		s.ApplySnapshot(*snapshot)
-	}
-	s.SetHardState(st)
-	s.Append(ents)
-	c := &raft.Config{
-		ID:              uint64(id),
-		ElectionTick:    cfg.ElectionTicks,
-		HeartbeatTick:   1,
-		Storage:         s,
-		MaxSizePerMsg:   maxSizePerMsg,
-		MaxInflightMsgs: maxInflightMsgs,
-		CheckQuorum:     true,
-		PreVote:         cfg.PreVote,
-	}
-	if cfg.Logger != nil {
-		// called after capnslog setting in "init" function
-		if cfg.LoggerConfig != nil {
-			c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig)
-			if err != nil {
-				log.Fatalf("cannot create raft logger %v", err)
-			}
-		} else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil {
-			c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer)
-		}
-	}
-
-	n := raft.RestartNode(c)
-	raftStatus = n.Status
-	return id, cl, n, s, w
-}
-
-// getIDs returns an ordered set of IDs included in the given snapshot and
-// the entries. The given snapshot/entries can contain two kinds of
-// ID-related entry:
-// - ConfChangeAddNode, in which case the contained ID will be added into the set.
-// - ConfChangeRemoveNode, in which case the contained ID will be removed from the set.
-func getIDs(lg *zap.Logger, snap *raftpb.Snapshot, ents []raftpb.Entry) []uint64 {
-	ids := make(map[uint64]bool)
-	if snap != nil {
-		for _, id := range snap.Metadata.ConfState.Voters {
-			ids[id] = true
-		}
-	}
-	for _, e := range ents {
-		if e.Type != raftpb.EntryConfChange {
-			continue
-		}
-		var cc raftpb.ConfChange
-		pbutil.MustUnmarshal(&cc, e.Data)
-		switch cc.Type {
-		case raftpb.ConfChangeAddNode:
-			ids[cc.NodeID] = true
-		case raftpb.ConfChangeRemoveNode:
-			delete(ids, cc.NodeID)
-		case raftpb.ConfChangeUpdateNode:
-			// do nothing
-		default:
-			if lg != nil {
-				lg.Panic("unknown ConfChange Type", zap.String("type", cc.Type.String()))
-			} else {
-				plog.Panicf("ConfChange Type should be either ConfChangeAddNode or ConfChangeRemoveNode!")
-			}
-		}
-	}
-	sids := make(types.Uint64Slice, 0, len(ids))
-	for id := range ids {
-		sids = append(sids, id)
-	}
-	sort.Sort(sids)
-	return []uint64(sids)
-}
-
-// createConfigChangeEnts creates a series of Raft entries (i.e.
-// EntryConfChange) to remove the set of given IDs from the cluster. The ID
-// `self` is _not_ removed, even if present in the set.
-// If `self` is not inside the given ids, it creates a Raft entry to add a
-// default member with the given `self`.
-func createConfigChangeEnts(lg *zap.Logger, ids []uint64, self uint64, term, index uint64) []raftpb.Entry {
-	found := false
-	for _, id := range ids {
-		if id == self {
-			found = true
-		}
-	}
-
-	var ents []raftpb.Entry
-	next := index + 1
-
-	// NB: always add self first, then remove other nodes. Raft will panic if the
-	// set of voters ever becomes empty.
-	if !found {
-		m := membership.Member{
-			ID:             types.ID(self),
-			RaftAttributes: membership.RaftAttributes{PeerURLs: []string{"http://localhost:2380"}},
-		}
-		ctx, err := json.Marshal(m)
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to marshal member", zap.Error(err))
-			} else {
-				plog.Panicf("marshal member should never fail: %v", err)
-			}
-		}
-		cc := &raftpb.ConfChange{
-			Type:    raftpb.ConfChangeAddNode,
-			NodeID:  self,
-			Context: ctx,
-		}
-		e := raftpb.Entry{
-			Type:  raftpb.EntryConfChange,
-			Data:  pbutil.MustMarshal(cc),
-			Term:  term,
-			Index: next,
-		}
-		ents = append(ents, e)
-		next++
-	}
-
-	for _, id := range ids {
-		if id == self {
-			continue
-		}
-		cc := &raftpb.ConfChange{
-			Type:   raftpb.ConfChangeRemoveNode,
-			NodeID: id,
-		}
-		e := raftpb.Entry{
-			Type:  raftpb.EntryConfChange,
-			Data:  pbutil.MustMarshal(cc),
-			Term:  term,
-			Index: next,
-		}
-		ents = append(ents, e)
-		next++
-	}
-
-	return ents
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/server.go b/vendor/go.etcd.io/etcd/etcdserver/server.go
deleted file mode 100644
index 78daa0e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/server.go
+++ /dev/null
@@ -1,2656 +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 etcdserver
-
-import (
-	"context"
-	"encoding/json"
-	"expvar"
-	"fmt"
-	"math"
-	"math/rand"
-	"net/http"
-	"os"
-	"path"
-	"regexp"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"go.etcd.io/etcd/auth"
-	"go.etcd.io/etcd/etcdserver/api"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/rafthttp"
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	"go.etcd.io/etcd/etcdserver/api/v2discovery"
-	"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/api/v3alarm"
-	"go.etcd.io/etcd/etcdserver/api/v3compactor"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/lease/leasehttp"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/pkg/fileutil"
-	"go.etcd.io/etcd/pkg/idutil"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/pkg/runtime"
-	"go.etcd.io/etcd/pkg/schedule"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/pkg/wait"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/version"
-	"go.etcd.io/etcd/wal"
-
-	"github.com/coreos/go-semver/semver"
-	"github.com/coreos/pkg/capnslog"
-	humanize "github.com/dustin/go-humanize"
-	"github.com/prometheus/client_golang/prometheus"
-	"go.uber.org/zap"
-)
-
-const (
-	DefaultSnapshotCount = 100000
-
-	// DefaultSnapshotCatchUpEntries is the number of entries for a slow follower
-	// to catch-up after compacting the raft storage entries.
-	// We expect the follower has a millisecond level latency with the leader.
-	// The max throughput is around 10K. Keep a 5K entries is enough for helping
-	// follower to catch up.
-	DefaultSnapshotCatchUpEntries uint64 = 5000
-
-	StoreClusterPrefix = "/0"
-	StoreKeysPrefix    = "/1"
-
-	// HealthInterval is the minimum time the cluster should be healthy
-	// before accepting add member requests.
-	HealthInterval = 5 * time.Second
-
-	purgeFileInterval = 30 * time.Second
-	// monitorVersionInterval should be smaller than the timeout
-	// on the connection. Or we will not be able to reuse the connection
-	// (since it will timeout).
-	monitorVersionInterval = rafthttp.ConnWriteTimeout - time.Second
-
-	// max number of in-flight snapshot messages etcdserver allows to have
-	// This number is more than enough for most clusters with 5 machines.
-	maxInFlightMsgSnap = 16
-
-	releaseDelayAfterSnapshot = 30 * time.Second
-
-	// maxPendingRevokes is the maximum number of outstanding expired lease revocations.
-	maxPendingRevokes = 16
-
-	recommendedMaxRequestBytes = 10 * 1024 * 1024
-
-	readyPercent = 0.9
-)
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "etcdserver")
-
-	storeMemberAttributeRegexp = regexp.MustCompile(path.Join(membership.StoreMembersPrefix, "[[:xdigit:]]{1,16}", "attributes"))
-)
-
-func init() {
-	rand.Seed(time.Now().UnixNano())
-
-	expvar.Publish(
-		"file_descriptor_limit",
-		expvar.Func(
-			func() interface{} {
-				n, _ := runtime.FDLimit()
-				return n
-			},
-		),
-	)
-}
-
-type Response struct {
-	Term    uint64
-	Index   uint64
-	Event   *v2store.Event
-	Watcher v2store.Watcher
-	Err     error
-}
-
-type ServerV2 interface {
-	Server
-	Leader() types.ID
-
-	// Do takes a V2 request and attempts to fulfill it, returning a Response.
-	Do(ctx context.Context, r pb.Request) (Response, error)
-	stats.Stats
-	ClientCertAuthEnabled() bool
-}
-
-type ServerV3 interface {
-	Server
-	RaftStatusGetter
-}
-
-func (s *EtcdServer) ClientCertAuthEnabled() bool { return s.Cfg.ClientCertAuthEnabled }
-
-type Server interface {
-	// AddMember attempts to add a member into the cluster. It will return
-	// ErrIDRemoved if member ID is removed from the cluster, or return
-	// ErrIDExists if member ID exists in the cluster.
-	AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error)
-	// RemoveMember attempts to remove a member from the cluster. It will
-	// return ErrIDRemoved if member ID is removed from the cluster, or return
-	// ErrIDNotFound if member ID is not in the cluster.
-	RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error)
-	// UpdateMember attempts to update an existing member in the cluster. It will
-	// return ErrIDNotFound if the member ID does not exist.
-	UpdateMember(ctx context.Context, updateMemb membership.Member) ([]*membership.Member, error)
-	// PromoteMember attempts to promote a non-voting node to a voting node. It will
-	// return ErrIDNotFound if the member ID does not exist.
-	// return ErrLearnerNotReady if the member are not ready.
-	// return ErrMemberNotLearner if the member is not a learner.
-	PromoteMember(ctx context.Context, id uint64) ([]*membership.Member, error)
-
-	// ClusterVersion is the cluster-wide minimum major.minor version.
-	// Cluster version is set to the min version that an etcd member is
-	// compatible with when first bootstrap.
-	//
-	// ClusterVersion is nil until the cluster is bootstrapped (has a quorum).
-	//
-	// During a rolling upgrades, the ClusterVersion will be updated
-	// automatically after a sync. (5 second by default)
-	//
-	// The API/raft component can utilize ClusterVersion to determine if
-	// it can accept a client request or a raft RPC.
-	// NOTE: ClusterVersion might be nil when etcd 2.1 works with etcd 2.0 and
-	// the leader is etcd 2.0. etcd 2.0 leader will not update clusterVersion since
-	// this feature is introduced post 2.0.
-	ClusterVersion() *semver.Version
-	Cluster() api.Cluster
-	Alarms() []*pb.AlarmMember
-}
-
-// EtcdServer is the production implementation of the Server interface
-type EtcdServer struct {
-	// inflightSnapshots holds count the number of snapshots currently inflight.
-	inflightSnapshots int64  // must use atomic operations to access; keep 64-bit aligned.
-	appliedIndex      uint64 // must use atomic operations to access; keep 64-bit aligned.
-	committedIndex    uint64 // must use atomic operations to access; keep 64-bit aligned.
-	term              uint64 // must use atomic operations to access; keep 64-bit aligned.
-	lead              uint64 // must use atomic operations to access; keep 64-bit aligned.
-
-	// consistIndex used to hold the offset of current executing entry
-	// It is initialized to 0 before executing any entry.
-	consistIndex consistentIndex // must use atomic operations to access; keep 64-bit aligned.
-	r            raftNode        // uses 64-bit atomics; keep 64-bit aligned.
-
-	readych chan struct{}
-	Cfg     ServerConfig
-
-	lgMu *sync.RWMutex
-	lg   *zap.Logger
-
-	w wait.Wait
-
-	readMu sync.RWMutex
-	// read routine notifies etcd server that it waits for reading by sending an empty struct to
-	// readwaitC
-	readwaitc chan struct{}
-	// readNotifier is used to notify the read routine that it can process the request
-	// when there is no error
-	readNotifier *notifier
-
-	// stop signals the run goroutine should shutdown.
-	stop chan struct{}
-	// stopping is closed by run goroutine on shutdown.
-	stopping chan struct{}
-	// done is closed when all goroutines from start() complete.
-	done chan struct{}
-	// leaderChanged is used to notify the linearizable read loop to drop the old read requests.
-	leaderChanged   chan struct{}
-	leaderChangedMu sync.RWMutex
-
-	errorc     chan error
-	id         types.ID
-	attributes membership.Attributes
-
-	cluster *membership.RaftCluster
-
-	v2store     v2store.Store
-	snapshotter *snap.Snapshotter
-
-	applyV2 ApplierV2
-
-	// applyV3 is the applier with auth and quotas
-	applyV3 applierV3
-	// applyV3Base is the core applier without auth or quotas
-	applyV3Base applierV3
-	applyWait   wait.WaitTime
-
-	kv         mvcc.ConsistentWatchableKV
-	lessor     lease.Lessor
-	bemu       sync.Mutex
-	be         backend.Backend
-	authStore  auth.AuthStore
-	alarmStore *v3alarm.AlarmStore
-
-	stats  *stats.ServerStats
-	lstats *stats.LeaderStats
-
-	SyncTicker *time.Ticker
-	// compactor is used to auto-compact the KV.
-	compactor v3compactor.Compactor
-
-	// peerRt used to send requests (version, lease) to peers.
-	peerRt   http.RoundTripper
-	reqIDGen *idutil.Generator
-
-	// forceVersionC is used to force the version monitor loop
-	// to detect the cluster version immediately.
-	forceVersionC chan struct{}
-
-	// wgMu blocks concurrent waitgroup mutation while server stopping
-	wgMu sync.RWMutex
-	// wg is used to wait for the go routines that depends on the server state
-	// to exit when stopping the server.
-	wg sync.WaitGroup
-
-	// ctx is used for etcd-initiated requests that may need to be canceled
-	// on etcd server shutdown.
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	leadTimeMu      sync.RWMutex
-	leadElectedTime time.Time
-
-	*AccessController
-}
-
-// NewServer creates a new EtcdServer from the supplied configuration. The
-// configuration is considered static for the lifetime of the EtcdServer.
-func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) {
-	st := v2store.New(StoreClusterPrefix, StoreKeysPrefix)
-
-	var (
-		w  *wal.WAL
-		n  raft.Node
-		s  *raft.MemoryStorage
-		id types.ID
-		cl *membership.RaftCluster
-	)
-
-	if cfg.MaxRequestBytes > recommendedMaxRequestBytes {
-		if cfg.Logger != nil {
-			cfg.Logger.Warn(
-				"exceeded recommended request limit",
-				zap.Uint("max-request-bytes", cfg.MaxRequestBytes),
-				zap.String("max-request-size", humanize.Bytes(uint64(cfg.MaxRequestBytes))),
-				zap.Int("recommended-request-bytes", recommendedMaxRequestBytes),
-				zap.String("recommended-request-size", humanize.Bytes(uint64(recommendedMaxRequestBytes))),
-			)
-		} else {
-			plog.Warningf("MaxRequestBytes %v exceeds maximum recommended size %v", cfg.MaxRequestBytes, recommendedMaxRequestBytes)
-		}
-	}
-
-	if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil {
-		return nil, fmt.Errorf("cannot access data directory: %v", terr)
-	}
-
-	haveWAL := wal.Exist(cfg.WALDir())
-
-	if err = fileutil.TouchDirAll(cfg.SnapDir()); err != nil {
-		if cfg.Logger != nil {
-			cfg.Logger.Fatal(
-				"failed to create snapshot directory",
-				zap.String("path", cfg.SnapDir()),
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("create snapshot directory error: %v", err)
-		}
-	}
-	ss := snap.New(cfg.Logger, cfg.SnapDir())
-
-	bepath := cfg.backendPath()
-	beExist := fileutil.Exist(bepath)
-	be := openBackend(cfg)
-
-	defer func() {
-		if err != nil {
-			be.Close()
-		}
-	}()
-
-	prt, err := rafthttp.NewRoundTripper(cfg.PeerTLSInfo, cfg.peerDialTimeout())
-	if err != nil {
-		return nil, err
-	}
-	var (
-		remotes  []*membership.Member
-		snapshot *raftpb.Snapshot
-	)
-
-	switch {
-	case !haveWAL && !cfg.NewCluster:
-		if err = cfg.VerifyJoinExisting(); err != nil {
-			return nil, err
-		}
-		cl, err = membership.NewClusterFromURLsMap(cfg.Logger, cfg.InitialClusterToken, cfg.InitialPeerURLsMap)
-		if err != nil {
-			return nil, err
-		}
-		existingCluster, gerr := GetClusterFromRemotePeers(cfg.Logger, getRemotePeerURLs(cl, cfg.Name), prt)
-		if gerr != nil {
-			return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", gerr)
-		}
-		if err = membership.ValidateClusterAndAssignIDs(cfg.Logger, cl, existingCluster); err != nil {
-			return nil, fmt.Errorf("error validating peerURLs %s: %v", existingCluster, err)
-		}
-		if !isCompatibleWithCluster(cfg.Logger, cl, cl.MemberByName(cfg.Name).ID, prt) {
-			return nil, fmt.Errorf("incompatible with current running cluster")
-		}
-
-		remotes = existingCluster.Members()
-		cl.SetID(types.ID(0), existingCluster.ID())
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		id, n, s, w = startNode(cfg, cl, nil)
-		cl.SetID(id, existingCluster.ID())
-
-	case !haveWAL && cfg.NewCluster:
-		if err = cfg.VerifyBootstrap(); err != nil {
-			return nil, err
-		}
-		cl, err = membership.NewClusterFromURLsMap(cfg.Logger, cfg.InitialClusterToken, cfg.InitialPeerURLsMap)
-		if err != nil {
-			return nil, err
-		}
-		m := cl.MemberByName(cfg.Name)
-		if isMemberBootstrapped(cfg.Logger, cl, cfg.Name, prt, cfg.bootstrapTimeout()) {
-			return nil, fmt.Errorf("member %s has already been bootstrapped", m.ID)
-		}
-		if cfg.ShouldDiscover() {
-			var str string
-			str, err = v2discovery.JoinCluster(cfg.Logger, cfg.DiscoveryURL, cfg.DiscoveryProxy, m.ID, cfg.InitialPeerURLsMap.String())
-			if err != nil {
-				return nil, &DiscoveryError{Op: "join", Err: err}
-			}
-			var urlsmap types.URLsMap
-			urlsmap, err = types.NewURLsMap(str)
-			if err != nil {
-				return nil, err
-			}
-			if checkDuplicateURL(urlsmap) {
-				return nil, fmt.Errorf("discovery cluster %s has duplicate url", urlsmap)
-			}
-			if cl, err = membership.NewClusterFromURLsMap(cfg.Logger, cfg.InitialClusterToken, urlsmap); err != nil {
-				return nil, err
-			}
-		}
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		id, n, s, w = startNode(cfg, cl, cl.MemberIDs())
-		cl.SetID(id, cl.ID())
-
-	case haveWAL:
-		if err = fileutil.IsDirWriteable(cfg.MemberDir()); err != nil {
-			return nil, fmt.Errorf("cannot write to member directory: %v", err)
-		}
-
-		if err = fileutil.IsDirWriteable(cfg.WALDir()); err != nil {
-			return nil, fmt.Errorf("cannot write to WAL directory: %v", err)
-		}
-
-		if cfg.ShouldDiscover() {
-			if cfg.Logger != nil {
-				cfg.Logger.Warn(
-					"discovery token is ignored since cluster already initialized; valid logs are found",
-					zap.String("wal-dir", cfg.WALDir()),
-				)
-			} else {
-				plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir())
-			}
-		}
-		snapshot, err = ss.Load()
-		if err != nil && err != snap.ErrNoSnapshot {
-			return nil, err
-		}
-		if snapshot != nil {
-			if err = st.Recovery(snapshot.Data); err != nil {
-				if cfg.Logger != nil {
-					cfg.Logger.Panic("failed to recover from snapshot")
-				} else {
-					plog.Panicf("recovered store from snapshot error: %v", err)
-				}
-			}
-
-			if cfg.Logger != nil {
-				cfg.Logger.Info(
-					"recovered v2 store from snapshot",
-					zap.Uint64("snapshot-index", snapshot.Metadata.Index),
-					zap.String("snapshot-size", humanize.Bytes(uint64(snapshot.Size()))),
-				)
-			} else {
-				plog.Infof("recovered store from snapshot at index %d", snapshot.Metadata.Index)
-			}
-
-			if be, err = recoverSnapshotBackend(cfg, be, *snapshot); err != nil {
-				if cfg.Logger != nil {
-					cfg.Logger.Panic("failed to recover v3 backend from snapshot", zap.Error(err))
-				} else {
-					plog.Panicf("recovering backend from snapshot error: %v", err)
-				}
-			}
-			if cfg.Logger != nil {
-				s1, s2 := be.Size(), be.SizeInUse()
-				cfg.Logger.Info(
-					"recovered v3 backend from snapshot",
-					zap.Int64("backend-size-bytes", s1),
-					zap.String("backend-size", humanize.Bytes(uint64(s1))),
-					zap.Int64("backend-size-in-use-bytes", s2),
-					zap.String("backend-size-in-use", humanize.Bytes(uint64(s2))),
-				)
-			}
-		}
-
-		if !cfg.ForceNewCluster {
-			id, cl, n, s, w = restartNode(cfg, snapshot)
-		} else {
-			id, cl, n, s, w = restartAsStandaloneNode(cfg, snapshot)
-		}
-
-		cl.SetStore(st)
-		cl.SetBackend(be)
-		cl.Recover(api.UpdateCapability)
-		if cl.Version() != nil && !cl.Version().LessThan(semver.Version{Major: 3}) && !beExist {
-			os.RemoveAll(bepath)
-			return nil, fmt.Errorf("database file (%v) of the backend is missing", bepath)
-		}
-
-	default:
-		return nil, fmt.Errorf("unsupported bootstrap config")
-	}
-
-	if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil {
-		return nil, fmt.Errorf("cannot access member directory: %v", terr)
-	}
-
-	sstats := stats.NewServerStats(cfg.Name, id.String())
-	lstats := stats.NewLeaderStats(id.String())
-
-	heartbeat := time.Duration(cfg.TickMs) * time.Millisecond
-	srv = &EtcdServer{
-		readych:     make(chan struct{}),
-		Cfg:         cfg,
-		lgMu:        new(sync.RWMutex),
-		lg:          cfg.Logger,
-		errorc:      make(chan error, 1),
-		v2store:     st,
-		snapshotter: ss,
-		r: *newRaftNode(
-			raftNodeConfig{
-				lg:          cfg.Logger,
-				isIDRemoved: func(id uint64) bool { return cl.IsIDRemoved(types.ID(id)) },
-				Node:        n,
-				heartbeat:   heartbeat,
-				raftStorage: s,
-				storage:     NewStorage(w, ss),
-			},
-		),
-		id:               id,
-		attributes:       membership.Attributes{Name: cfg.Name, ClientURLs: cfg.ClientURLs.StringSlice()},
-		cluster:          cl,
-		stats:            sstats,
-		lstats:           lstats,
-		SyncTicker:       time.NewTicker(500 * time.Millisecond),
-		peerRt:           prt,
-		reqIDGen:         idutil.NewGenerator(uint16(id), time.Now()),
-		forceVersionC:    make(chan struct{}),
-		AccessController: &AccessController{CORS: cfg.CORS, HostWhitelist: cfg.HostWhitelist},
-	}
-	serverID.With(prometheus.Labels{"server_id": id.String()}).Set(1)
-
-	srv.applyV2 = &applierV2store{store: srv.v2store, cluster: srv.cluster}
-
-	srv.be = be
-	minTTL := time.Duration((3*cfg.ElectionTicks)/2) * heartbeat
-
-	// always recover lessor before kv. When we recover the mvcc.KV it will reattach keys to its leases.
-	// If we recover mvcc.KV first, it will attach the keys to the wrong lessor before it recovers.
-	srv.lessor = lease.NewLessor(
-		srv.getLogger(),
-		srv.be,
-		lease.LessorConfig{
-			MinLeaseTTL:                int64(math.Ceil(minTTL.Seconds())),
-			CheckpointInterval:         cfg.LeaseCheckpointInterval,
-			ExpiredLeasesRetryInterval: srv.Cfg.ReqTimeout(),
-		})
-	srv.kv = mvcc.New(srv.getLogger(), srv.be, srv.lessor, &srv.consistIndex, mvcc.StoreConfig{CompactionBatchLimit: cfg.CompactionBatchLimit})
-	if beExist {
-		kvindex := srv.kv.ConsistentIndex()
-		// TODO: remove kvindex != 0 checking when we do not expect users to upgrade
-		// etcd from pre-3.0 release.
-		if snapshot != nil && kvindex < snapshot.Metadata.Index {
-			if kvindex != 0 {
-				return nil, fmt.Errorf("database file (%v index %d) does not match with snapshot (index %d)", bepath, kvindex, snapshot.Metadata.Index)
-			}
-			if cfg.Logger != nil {
-				cfg.Logger.Warn(
-					"consistent index was never saved",
-					zap.Uint64("snapshot-index", snapshot.Metadata.Index),
-				)
-			} else {
-				plog.Warningf("consistent index never saved (snapshot index=%d)", snapshot.Metadata.Index)
-			}
-		}
-	}
-	newSrv := srv // since srv == nil in defer if srv is returned as nil
-	defer func() {
-		// closing backend without first closing kv can cause
-		// resumed compactions to fail with closed tx errors
-		if err != nil {
-			newSrv.kv.Close()
-		}
-	}()
-
-	srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex())
-	tp, err := auth.NewTokenProvider(cfg.Logger, cfg.AuthToken,
-		func(index uint64) <-chan struct{} {
-			return srv.applyWait.Wait(index)
-		},
-	)
-	if err != nil {
-		if cfg.Logger != nil {
-			cfg.Logger.Warn("failed to create token provider", zap.Error(err))
-		} else {
-			plog.Errorf("failed to create token provider: %s", err)
-		}
-		return nil, err
-	}
-	srv.authStore = auth.NewAuthStore(srv.getLogger(), srv.be, tp, int(cfg.BcryptCost))
-	if num := cfg.AutoCompactionRetention; num != 0 {
-		srv.compactor, err = v3compactor.New(cfg.Logger, cfg.AutoCompactionMode, num, srv.kv, srv)
-		if err != nil {
-			return nil, err
-		}
-		srv.compactor.Run()
-	}
-
-	srv.applyV3Base = srv.newApplierV3Backend()
-	if err = srv.restoreAlarms(); err != nil {
-		return nil, err
-	}
-
-	if srv.Cfg.EnableLeaseCheckpoint {
-		// setting checkpointer enables lease checkpoint feature.
-		srv.lessor.SetCheckpointer(func(ctx context.Context, cp *pb.LeaseCheckpointRequest) {
-			srv.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseCheckpoint: cp})
-		})
-	}
-
-	// TODO: move transport initialization near the definition of remote
-	tr := &rafthttp.Transport{
-		Logger:      cfg.Logger,
-		TLSInfo:     cfg.PeerTLSInfo,
-		DialTimeout: cfg.peerDialTimeout(),
-		ID:          id,
-		URLs:        cfg.PeerURLs,
-		ClusterID:   cl.ID(),
-		Raft:        srv,
-		Snapshotter: ss,
-		ServerStats: sstats,
-		LeaderStats: lstats,
-		ErrorC:      srv.errorc,
-	}
-	if err = tr.Start(); err != nil {
-		return nil, err
-	}
-	// add all remotes into transport
-	for _, m := range remotes {
-		if m.ID != id {
-			tr.AddRemote(m.ID, m.PeerURLs)
-		}
-	}
-	for _, m := range cl.Members() {
-		if m.ID != id {
-			tr.AddPeer(m.ID, m.PeerURLs)
-		}
-	}
-	srv.r.transport = tr
-
-	return srv, nil
-}
-
-func (s *EtcdServer) getLogger() *zap.Logger {
-	s.lgMu.RLock()
-	l := s.lg
-	s.lgMu.RUnlock()
-	return l
-}
-
-func tickToDur(ticks int, tickMs uint) string {
-	return fmt.Sprintf("%v", time.Duration(ticks)*time.Duration(tickMs)*time.Millisecond)
-}
-
-func (s *EtcdServer) adjustTicks() {
-	lg := s.getLogger()
-	clusterN := len(s.cluster.Members())
-
-	// single-node fresh start, or single-node recovers from snapshot
-	if clusterN == 1 {
-		ticks := s.Cfg.ElectionTicks - 1
-		if lg != nil {
-			lg.Info(
-				"started as single-node; fast-forwarding election ticks",
-				zap.String("local-member-id", s.ID().String()),
-				zap.Int("forward-ticks", ticks),
-				zap.String("forward-duration", tickToDur(ticks, s.Cfg.TickMs)),
-				zap.Int("election-ticks", s.Cfg.ElectionTicks),
-				zap.String("election-timeout", tickToDur(s.Cfg.ElectionTicks, s.Cfg.TickMs)),
-			)
-		} else {
-			plog.Infof("%s as single-node; fast-forwarding %d ticks (election ticks %d)", s.ID(), ticks, s.Cfg.ElectionTicks)
-		}
-		s.r.advanceTicks(ticks)
-		return
-	}
-
-	if !s.Cfg.InitialElectionTickAdvance {
-		if lg != nil {
-			lg.Info("skipping initial election tick advance", zap.Int("election-ticks", s.Cfg.ElectionTicks))
-		}
-		return
-	}
-	if lg != nil {
-		lg.Info("starting initial election tick advance", zap.Int("election-ticks", s.Cfg.ElectionTicks))
-	}
-
-	// retry up to "rafthttp.ConnReadTimeout", which is 5-sec
-	// until peer connection reports; otherwise:
-	// 1. all connections failed, or
-	// 2. no active peers, or
-	// 3. restarted single-node with no snapshot
-	// then, do nothing, because advancing ticks would have no effect
-	waitTime := rafthttp.ConnReadTimeout
-	itv := 50 * time.Millisecond
-	for i := int64(0); i < int64(waitTime/itv); i++ {
-		select {
-		case <-time.After(itv):
-		case <-s.stopping:
-			return
-		}
-
-		peerN := s.r.transport.ActivePeers()
-		if peerN > 1 {
-			// multi-node received peer connection reports
-			// adjust ticks, in case slow leader message receive
-			ticks := s.Cfg.ElectionTicks - 2
-
-			if lg != nil {
-				lg.Info(
-					"initialized peer connections; fast-forwarding election ticks",
-					zap.String("local-member-id", s.ID().String()),
-					zap.Int("forward-ticks", ticks),
-					zap.String("forward-duration", tickToDur(ticks, s.Cfg.TickMs)),
-					zap.Int("election-ticks", s.Cfg.ElectionTicks),
-					zap.String("election-timeout", tickToDur(s.Cfg.ElectionTicks, s.Cfg.TickMs)),
-					zap.Int("active-remote-members", peerN),
-				)
-			} else {
-				plog.Infof("%s initialized peer connection; fast-forwarding %d ticks (election ticks %d) with %d active peer(s)", s.ID(), ticks, s.Cfg.ElectionTicks, peerN)
-			}
-
-			s.r.advanceTicks(ticks)
-			return
-		}
-	}
-}
-
-// Start performs any initialization of the Server necessary for it to
-// begin serving requests. It must be called before Do or Process.
-// Start must be non-blocking; any long-running server functionality
-// should be implemented in goroutines.
-func (s *EtcdServer) Start() {
-	s.start()
-	s.goAttach(func() { s.adjustTicks() })
-	s.goAttach(func() { s.publish(s.Cfg.ReqTimeout()) })
-	s.goAttach(s.purgeFile)
-	s.goAttach(func() { monitorFileDescriptor(s.getLogger(), s.stopping) })
-	s.goAttach(s.monitorVersions)
-	s.goAttach(s.linearizableReadLoop)
-	s.goAttach(s.monitorKVHash)
-}
-
-// start prepares and starts server in a new goroutine. It is no longer safe to
-// modify a server's fields after it has been sent to Start.
-// This function is just used for testing.
-func (s *EtcdServer) start() {
-	lg := s.getLogger()
-
-	if s.Cfg.SnapshotCount == 0 {
-		if lg != nil {
-			lg.Info(
-				"updating snapshot-count to default",
-				zap.Uint64("given-snapshot-count", s.Cfg.SnapshotCount),
-				zap.Uint64("updated-snapshot-count", DefaultSnapshotCount),
-			)
-		} else {
-			plog.Infof("set snapshot count to default %d", DefaultSnapshotCount)
-		}
-		s.Cfg.SnapshotCount = DefaultSnapshotCount
-	}
-	if s.Cfg.SnapshotCatchUpEntries == 0 {
-		if lg != nil {
-			lg.Info(
-				"updating snapshot catch-up entries to default",
-				zap.Uint64("given-snapshot-catchup-entries", s.Cfg.SnapshotCatchUpEntries),
-				zap.Uint64("updated-snapshot-catchup-entries", DefaultSnapshotCatchUpEntries),
-			)
-		}
-		s.Cfg.SnapshotCatchUpEntries = DefaultSnapshotCatchUpEntries
-	}
-
-	s.w = wait.New()
-	s.applyWait = wait.NewTimeList()
-	s.done = make(chan struct{})
-	s.stop = make(chan struct{})
-	s.stopping = make(chan struct{})
-	s.ctx, s.cancel = context.WithCancel(context.Background())
-	s.readwaitc = make(chan struct{}, 1)
-	s.readNotifier = newNotifier()
-	s.leaderChanged = make(chan struct{})
-	if s.ClusterVersion() != nil {
-		if lg != nil {
-			lg.Info(
-				"starting etcd server",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("local-server-version", version.Version),
-				zap.String("cluster-id", s.Cluster().ID().String()),
-				zap.String("cluster-version", version.Cluster(s.ClusterVersion().String())),
-			)
-		} else {
-			plog.Infof("starting server... [version: %v, cluster version: %v]", version.Version, version.Cluster(s.ClusterVersion().String()))
-		}
-		membership.ClusterVersionMetrics.With(prometheus.Labels{"cluster_version": s.ClusterVersion().String()}).Set(1)
-	} else {
-		if lg != nil {
-			lg.Info(
-				"starting etcd server",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("local-server-version", version.Version),
-				zap.String("cluster-version", "to_be_decided"),
-			)
-		} else {
-			plog.Infof("starting server... [version: %v, cluster version: to_be_decided]", version.Version)
-		}
-	}
-
-	// TODO: if this is an empty log, writes all peer infos
-	// into the first entry
-	go s.run()
-}
-
-func (s *EtcdServer) purgeFile() {
-	var dberrc, serrc, werrc <-chan error
-	if s.Cfg.MaxSnapFiles > 0 {
-		dberrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.SnapDir(), "snap.db", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
-		serrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.SnapDir(), "snap", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
-	}
-	if s.Cfg.MaxWALFiles > 0 {
-		werrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.WALDir(), "wal", s.Cfg.MaxWALFiles, purgeFileInterval, s.done)
-	}
-
-	lg := s.getLogger()
-	select {
-	case e := <-dberrc:
-		if lg != nil {
-			lg.Fatal("failed to purge snap db file", zap.Error(e))
-		} else {
-			plog.Fatalf("failed to purge snap db file %v", e)
-		}
-	case e := <-serrc:
-		if lg != nil {
-			lg.Fatal("failed to purge snap file", zap.Error(e))
-		} else {
-			plog.Fatalf("failed to purge snap file %v", e)
-		}
-	case e := <-werrc:
-		if lg != nil {
-			lg.Fatal("failed to purge wal file", zap.Error(e))
-		} else {
-			plog.Fatalf("failed to purge wal file %v", e)
-		}
-	case <-s.stopping:
-		return
-	}
-}
-
-func (s *EtcdServer) Cluster() api.Cluster { return s.cluster }
-
-func (s *EtcdServer) ApplyWait() <-chan struct{} { return s.applyWait.Wait(s.getCommittedIndex()) }
-
-type ServerPeer interface {
-	ServerV2
-	RaftHandler() http.Handler
-	LeaseHandler() http.Handler
-}
-
-func (s *EtcdServer) LeaseHandler() http.Handler {
-	if s.lessor == nil {
-		return nil
-	}
-	return leasehttp.NewHandler(s.lessor, s.ApplyWait)
-}
-
-func (s *EtcdServer) RaftHandler() http.Handler { return s.r.transport.Handler() }
-
-// Process takes a raft message and applies it to the server's raft state
-// machine, respecting any timeout of the given context.
-func (s *EtcdServer) Process(ctx context.Context, m raftpb.Message) error {
-	if s.cluster.IsIDRemoved(types.ID(m.From)) {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejected Raft message from removed member",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("removed-member-id", types.ID(m.From).String()),
-			)
-		} else {
-			plog.Warningf("reject message from removed member %s", types.ID(m.From).String())
-		}
-		return httptypes.NewHTTPError(http.StatusForbidden, "cannot process message from removed member")
-	}
-	if m.Type == raftpb.MsgApp {
-		s.stats.RecvAppendReq(types.ID(m.From).String(), m.Size())
-	}
-	return s.r.Step(ctx, m)
-}
-
-func (s *EtcdServer) IsIDRemoved(id uint64) bool { return s.cluster.IsIDRemoved(types.ID(id)) }
-
-func (s *EtcdServer) ReportUnreachable(id uint64) { s.r.ReportUnreachable(id) }
-
-// ReportSnapshot reports snapshot sent status to the raft state machine,
-// and clears the used snapshot from the snapshot store.
-func (s *EtcdServer) ReportSnapshot(id uint64, status raft.SnapshotStatus) {
-	s.r.ReportSnapshot(id, status)
-}
-
-type etcdProgress struct {
-	confState raftpb.ConfState
-	snapi     uint64
-	appliedt  uint64
-	appliedi  uint64
-}
-
-// raftReadyHandler contains a set of EtcdServer operations to be called by raftNode,
-// and helps decouple state machine logic from Raft algorithms.
-// TODO: add a state machine interface to apply the commit entries and do snapshot/recover
-type raftReadyHandler struct {
-	getLead              func() (lead uint64)
-	updateLead           func(lead uint64)
-	updateLeadership     func(newLeader bool)
-	updateCommittedIndex func(uint64)
-}
-
-func (s *EtcdServer) run() {
-	lg := s.getLogger()
-
-	sn, err := s.r.raftStorage.Snapshot()
-	if err != nil {
-		if lg != nil {
-			lg.Panic("failed to get snapshot from Raft storage", zap.Error(err))
-		} else {
-			plog.Panicf("get snapshot from raft storage error: %v", err)
-		}
-	}
-
-	// asynchronously accept apply packets, dispatch progress in-order
-	sched := schedule.NewFIFOScheduler()
-
-	var (
-		smu   sync.RWMutex
-		syncC <-chan time.Time
-	)
-	setSyncC := func(ch <-chan time.Time) {
-		smu.Lock()
-		syncC = ch
-		smu.Unlock()
-	}
-	getSyncC := func() (ch <-chan time.Time) {
-		smu.RLock()
-		ch = syncC
-		smu.RUnlock()
-		return
-	}
-	rh := &raftReadyHandler{
-		getLead:    func() (lead uint64) { return s.getLead() },
-		updateLead: func(lead uint64) { s.setLead(lead) },
-		updateLeadership: func(newLeader bool) {
-			if !s.isLeader() {
-				if s.lessor != nil {
-					s.lessor.Demote()
-				}
-				if s.compactor != nil {
-					s.compactor.Pause()
-				}
-				setSyncC(nil)
-			} else {
-				if newLeader {
-					t := time.Now()
-					s.leadTimeMu.Lock()
-					s.leadElectedTime = t
-					s.leadTimeMu.Unlock()
-				}
-				setSyncC(s.SyncTicker.C)
-				if s.compactor != nil {
-					s.compactor.Resume()
-				}
-			}
-			if newLeader {
-				s.leaderChangedMu.Lock()
-				lc := s.leaderChanged
-				s.leaderChanged = make(chan struct{})
-				close(lc)
-				s.leaderChangedMu.Unlock()
-			}
-			// TODO: remove the nil checking
-			// current test utility does not provide the stats
-			if s.stats != nil {
-				s.stats.BecomeLeader()
-			}
-		},
-		updateCommittedIndex: func(ci uint64) {
-			cci := s.getCommittedIndex()
-			if ci > cci {
-				s.setCommittedIndex(ci)
-			}
-		},
-	}
-	s.r.start(rh)
-
-	ep := etcdProgress{
-		confState: sn.Metadata.ConfState,
-		snapi:     sn.Metadata.Index,
-		appliedt:  sn.Metadata.Term,
-		appliedi:  sn.Metadata.Index,
-	}
-
-	defer func() {
-		s.wgMu.Lock() // block concurrent waitgroup adds in goAttach while stopping
-		close(s.stopping)
-		s.wgMu.Unlock()
-		s.cancel()
-
-		sched.Stop()
-
-		// wait for gouroutines before closing raft so wal stays open
-		s.wg.Wait()
-
-		s.SyncTicker.Stop()
-
-		// must stop raft after scheduler-- etcdserver can leak rafthttp pipelines
-		// by adding a peer after raft stops the transport
-		s.r.stop()
-
-		// kv, lessor and backend can be nil if running without v3 enabled
-		// or running unit tests.
-		if s.lessor != nil {
-			s.lessor.Stop()
-		}
-		if s.kv != nil {
-			s.kv.Close()
-		}
-		if s.authStore != nil {
-			s.authStore.Close()
-		}
-		if s.be != nil {
-			s.be.Close()
-		}
-		if s.compactor != nil {
-			s.compactor.Stop()
-		}
-		close(s.done)
-	}()
-
-	var expiredLeaseC <-chan []*lease.Lease
-	if s.lessor != nil {
-		expiredLeaseC = s.lessor.ExpiredLeasesC()
-	}
-
-	for {
-		select {
-		case ap := <-s.r.apply():
-			f := func(context.Context) { s.applyAll(&ep, &ap) }
-			sched.Schedule(f)
-		case leases := <-expiredLeaseC:
-			s.goAttach(func() {
-				// Increases throughput of expired leases deletion process through parallelization
-				c := make(chan struct{}, maxPendingRevokes)
-				for _, lease := range leases {
-					select {
-					case c <- struct{}{}:
-					case <-s.stopping:
-						return
-					}
-					lid := lease.ID
-					s.goAttach(func() {
-						ctx := s.authStore.WithRoot(s.ctx)
-						_, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)})
-						if lerr == nil {
-							leaseExpired.Inc()
-						} else {
-							if lg != nil {
-								lg.Warn(
-									"failed to revoke lease",
-									zap.String("lease-id", fmt.Sprintf("%016x", lid)),
-									zap.Error(lerr),
-								)
-							} else {
-								plog.Warningf("failed to revoke %016x (%q)", lid, lerr.Error())
-							}
-						}
-
-						<-c
-					})
-				}
-			})
-		case err := <-s.errorc:
-			if lg != nil {
-				lg.Warn("server error", zap.Error(err))
-				lg.Warn("data-dir used by this member must be removed")
-			} else {
-				plog.Errorf("%s", err)
-				plog.Infof("the data-dir used by this member must be removed.")
-			}
-			return
-		case <-getSyncC():
-			if s.v2store.HasTTLKeys() {
-				s.sync(s.Cfg.ReqTimeout())
-			}
-		case <-s.stop:
-			return
-		}
-	}
-}
-
-func (s *EtcdServer) applyAll(ep *etcdProgress, apply *apply) {
-	s.applySnapshot(ep, apply)
-	s.applyEntries(ep, apply)
-
-	proposalsApplied.Set(float64(ep.appliedi))
-	s.applyWait.Trigger(ep.appliedi)
-
-	// wait for the raft routine to finish the disk writes before triggering a
-	// snapshot. or applied index might be greater than the last index in raft
-	// storage, since the raft routine might be slower than apply routine.
-	<-apply.notifyc
-
-	s.triggerSnapshot(ep)
-	select {
-	// snapshot requested via send()
-	case m := <-s.r.msgSnapC:
-		merged := s.createMergedSnapshotMessage(m, ep.appliedt, ep.appliedi, ep.confState)
-		s.sendMergedSnap(merged)
-	default:
-	}
-}
-
-func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) {
-	if raft.IsEmptySnap(apply.snapshot) {
-		return
-	}
-	applySnapshotInProgress.Inc()
-
-	lg := s.getLogger()
-	if lg != nil {
-		lg.Info(
-			"applying snapshot",
-			zap.Uint64("current-snapshot-index", ep.snapi),
-			zap.Uint64("current-applied-index", ep.appliedi),
-			zap.Uint64("incoming-leader-snapshot-index", apply.snapshot.Metadata.Index),
-			zap.Uint64("incoming-leader-snapshot-term", apply.snapshot.Metadata.Term),
-		)
-	} else {
-		plog.Infof("applying snapshot at index %d...", ep.snapi)
-	}
-	defer func() {
-		if lg != nil {
-			lg.Info(
-				"applied snapshot",
-				zap.Uint64("current-snapshot-index", ep.snapi),
-				zap.Uint64("current-applied-index", ep.appliedi),
-				zap.Uint64("incoming-leader-snapshot-index", apply.snapshot.Metadata.Index),
-				zap.Uint64("incoming-leader-snapshot-term", apply.snapshot.Metadata.Term),
-			)
-		} else {
-			plog.Infof("finished applying incoming snapshot at index %d", ep.snapi)
-		}
-		applySnapshotInProgress.Dec()
-	}()
-
-	if apply.snapshot.Metadata.Index <= ep.appliedi {
-		if lg != nil {
-			lg.Panic(
-				"unexpected leader snapshot from outdated index",
-				zap.Uint64("current-snapshot-index", ep.snapi),
-				zap.Uint64("current-applied-index", ep.appliedi),
-				zap.Uint64("incoming-leader-snapshot-index", apply.snapshot.Metadata.Index),
-				zap.Uint64("incoming-leader-snapshot-term", apply.snapshot.Metadata.Term),
-			)
-		} else {
-			plog.Panicf("snapshot index [%d] should > appliedi[%d] + 1",
-				apply.snapshot.Metadata.Index, ep.appliedi)
-		}
-	}
-
-	// wait for raftNode to persist snapshot onto the disk
-	<-apply.notifyc
-
-	newbe, err := openSnapshotBackend(s.Cfg, s.snapshotter, apply.snapshot)
-	if err != nil {
-		if lg != nil {
-			lg.Panic("failed to open snapshot backend", zap.Error(err))
-		} else {
-			plog.Panic(err)
-		}
-	}
-
-	// always recover lessor before kv. When we recover the mvcc.KV it will reattach keys to its leases.
-	// If we recover mvcc.KV first, it will attach the keys to the wrong lessor before it recovers.
-	if s.lessor != nil {
-		if lg != nil {
-			lg.Info("restoring lease store")
-		} else {
-			plog.Info("recovering lessor...")
-		}
-
-		s.lessor.Recover(newbe, func() lease.TxnDelete { return s.kv.Write() })
-
-		if lg != nil {
-			lg.Info("restored lease store")
-		} else {
-			plog.Info("finished recovering lessor")
-		}
-	}
-
-	if lg != nil {
-		lg.Info("restoring mvcc store")
-	} else {
-		plog.Info("restoring mvcc store...")
-	}
-
-	if err := s.kv.Restore(newbe); err != nil {
-		if lg != nil {
-			lg.Panic("failed to restore mvcc store", zap.Error(err))
-		} else {
-			plog.Panicf("restore KV error: %v", err)
-		}
-	}
-
-	s.consistIndex.setConsistentIndex(s.kv.ConsistentIndex())
-	if lg != nil {
-		lg.Info("restored mvcc store")
-	} else {
-		plog.Info("finished restoring mvcc store")
-	}
-
-	// Closing old backend might block until all the txns
-	// on the backend are finished.
-	// We do not want to wait on closing the old backend.
-	s.bemu.Lock()
-	oldbe := s.be
-	go func() {
-		if lg != nil {
-			lg.Info("closing old backend file")
-		} else {
-			plog.Info("closing old backend...")
-		}
-		defer func() {
-			if lg != nil {
-				lg.Info("closed old backend file")
-			} else {
-				plog.Info("finished closing old backend")
-			}
-		}()
-		if err := oldbe.Close(); err != nil {
-			if lg != nil {
-				lg.Panic("failed to close old backend", zap.Error(err))
-			} else {
-				plog.Panicf("close backend error: %v", err)
-			}
-		}
-	}()
-
-	s.be = newbe
-	s.bemu.Unlock()
-
-	if lg != nil {
-		lg.Info("restoring alarm store")
-	} else {
-		plog.Info("recovering alarms...")
-	}
-
-	if err := s.restoreAlarms(); err != nil {
-		if lg != nil {
-			lg.Panic("failed to restore alarm store", zap.Error(err))
-		} else {
-			plog.Panicf("restore alarms error: %v", err)
-		}
-	}
-
-	if lg != nil {
-		lg.Info("restored alarm store")
-	} else {
-		plog.Info("finished recovering alarms")
-	}
-
-	if s.authStore != nil {
-		if lg != nil {
-			lg.Info("restoring auth store")
-		} else {
-			plog.Info("recovering auth store...")
-		}
-
-		s.authStore.Recover(newbe)
-
-		if lg != nil {
-			lg.Info("restored auth store")
-		} else {
-			plog.Info("finished recovering auth store")
-		}
-	}
-
-	if lg != nil {
-		lg.Info("restoring v2 store")
-	} else {
-		plog.Info("recovering store v2...")
-	}
-	if err := s.v2store.Recovery(apply.snapshot.Data); err != nil {
-		if lg != nil {
-			lg.Panic("failed to restore v2 store", zap.Error(err))
-		} else {
-			plog.Panicf("recovery store error: %v", err)
-		}
-	}
-
-	if lg != nil {
-		lg.Info("restored v2 store")
-	} else {
-		plog.Info("finished recovering store v2")
-	}
-
-	s.cluster.SetBackend(newbe)
-
-	if lg != nil {
-		lg.Info("restoring cluster configuration")
-	} else {
-		plog.Info("recovering cluster configuration...")
-	}
-
-	s.cluster.Recover(api.UpdateCapability)
-
-	if lg != nil {
-		lg.Info("restored cluster configuration")
-		lg.Info("removing old peers from network")
-	} else {
-		plog.Info("finished recovering cluster configuration")
-		plog.Info("removing old peers from network...")
-	}
-
-	// recover raft transport
-	s.r.transport.RemoveAllPeers()
-
-	if lg != nil {
-		lg.Info("removed old peers from network")
-		lg.Info("adding peers from new cluster configuration")
-	} else {
-		plog.Info("finished removing old peers from network")
-		plog.Info("adding peers from new cluster configuration into network...")
-	}
-
-	for _, m := range s.cluster.Members() {
-		if m.ID == s.ID() {
-			continue
-		}
-		s.r.transport.AddPeer(m.ID, m.PeerURLs)
-	}
-
-	if lg != nil {
-		lg.Info("added peers from new cluster configuration")
-	} else {
-		plog.Info("finished adding peers from new cluster configuration into network...")
-	}
-
-	ep.appliedt = apply.snapshot.Metadata.Term
-	ep.appliedi = apply.snapshot.Metadata.Index
-	ep.snapi = ep.appliedi
-	ep.confState = apply.snapshot.Metadata.ConfState
-}
-
-func (s *EtcdServer) applyEntries(ep *etcdProgress, apply *apply) {
-	if len(apply.entries) == 0 {
-		return
-	}
-	firsti := apply.entries[0].Index
-	if firsti > ep.appliedi+1 {
-		if lg := s.getLogger(); lg != nil {
-			lg.Panic(
-				"unexpected committed entry index",
-				zap.Uint64("current-applied-index", ep.appliedi),
-				zap.Uint64("first-committed-entry-index", firsti),
-			)
-		} else {
-			plog.Panicf("first index of committed entry[%d] should <= appliedi[%d] + 1", firsti, ep.appliedi)
-		}
-	}
-	var ents []raftpb.Entry
-	if ep.appliedi+1-firsti < uint64(len(apply.entries)) {
-		ents = apply.entries[ep.appliedi+1-firsti:]
-	}
-	if len(ents) == 0 {
-		return
-	}
-	var shouldstop bool
-	if ep.appliedt, ep.appliedi, shouldstop = s.apply(ents, &ep.confState); shouldstop {
-		go s.stopWithDelay(10*100*time.Millisecond, fmt.Errorf("the member has been permanently removed from the cluster"))
-	}
-}
-
-func (s *EtcdServer) triggerSnapshot(ep *etcdProgress) {
-	if ep.appliedi-ep.snapi <= s.Cfg.SnapshotCount {
-		return
-	}
-
-	if lg := s.getLogger(); lg != nil {
-		lg.Info(
-			"triggering snapshot",
-			zap.String("local-member-id", s.ID().String()),
-			zap.Uint64("local-member-applied-index", ep.appliedi),
-			zap.Uint64("local-member-snapshot-index", ep.snapi),
-			zap.Uint64("local-member-snapshot-count", s.Cfg.SnapshotCount),
-		)
-	} else {
-		plog.Infof("start to snapshot (applied: %d, lastsnap: %d)", ep.appliedi, ep.snapi)
-	}
-
-	s.snapshot(ep.appliedi, ep.confState)
-	ep.snapi = ep.appliedi
-}
-
-func (s *EtcdServer) hasMultipleVotingMembers() bool {
-	return s.cluster != nil && len(s.cluster.VotingMemberIDs()) > 1
-}
-
-func (s *EtcdServer) isLeader() bool {
-	return uint64(s.ID()) == s.Lead()
-}
-
-// MoveLeader transfers the leader to the given transferee.
-func (s *EtcdServer) MoveLeader(ctx context.Context, lead, transferee uint64) error {
-	if !s.cluster.IsMemberExist(types.ID(transferee)) || s.cluster.Member(types.ID(transferee)).IsLearner {
-		return ErrBadLeaderTransferee
-	}
-
-	now := time.Now()
-	interval := time.Duration(s.Cfg.TickMs) * time.Millisecond
-
-	if lg := s.getLogger(); lg != nil {
-		lg.Info(
-			"leadership transfer starting",
-			zap.String("local-member-id", s.ID().String()),
-			zap.String("current-leader-member-id", types.ID(lead).String()),
-			zap.String("transferee-member-id", types.ID(transferee).String()),
-		)
-	} else {
-		plog.Infof("%s starts leadership transfer from %s to %s", s.ID(), types.ID(lead), types.ID(transferee))
-	}
-
-	s.r.TransferLeadership(ctx, lead, transferee)
-	for s.Lead() != transferee {
-		select {
-		case <-ctx.Done(): // time out
-			return ErrTimeoutLeaderTransfer
-		case <-time.After(interval):
-		}
-	}
-
-	// TODO: drain all requests, or drop all messages to the old leader
-	if lg := s.getLogger(); lg != nil {
-		lg.Info(
-			"leadership transfer finished",
-			zap.String("local-member-id", s.ID().String()),
-			zap.String("old-leader-member-id", types.ID(lead).String()),
-			zap.String("new-leader-member-id", types.ID(transferee).String()),
-			zap.Duration("took", time.Since(now)),
-		)
-	} else {
-		plog.Infof("%s finished leadership transfer from %s to %s (took %v)", s.ID(), types.ID(lead), types.ID(transferee), time.Since(now))
-	}
-	return nil
-}
-
-// TransferLeadership transfers the leader to the chosen transferee.
-func (s *EtcdServer) TransferLeadership() error {
-	if !s.isLeader() {
-		if lg := s.getLogger(); lg != nil {
-			lg.Info(
-				"skipped leadership transfer; local server is not leader",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("current-leader-member-id", types.ID(s.Lead()).String()),
-			)
-		} else {
-			plog.Printf("skipped leadership transfer for stopping non-leader member")
-		}
-		return nil
-	}
-
-	if !s.hasMultipleVotingMembers() {
-		if lg := s.getLogger(); lg != nil {
-			lg.Info(
-				"skipped leadership transfer for single voting member cluster",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("current-leader-member-id", types.ID(s.Lead()).String()),
-			)
-		} else {
-			plog.Printf("skipped leadership transfer for single voting member cluster")
-		}
-		return nil
-	}
-
-	transferee, ok := longestConnected(s.r.transport, s.cluster.VotingMemberIDs())
-	if !ok {
-		return ErrUnhealthy
-	}
-
-	tm := s.Cfg.ReqTimeout()
-	ctx, cancel := context.WithTimeout(s.ctx, tm)
-	err := s.MoveLeader(ctx, s.Lead(), uint64(transferee))
-	cancel()
-	return err
-}
-
-// HardStop stops the server without coordination with other members in the cluster.
-func (s *EtcdServer) HardStop() {
-	select {
-	case s.stop <- struct{}{}:
-	case <-s.done:
-		return
-	}
-	<-s.done
-}
-
-// Stop stops the server gracefully, and shuts down the running goroutine.
-// Stop should be called after a Start(s), otherwise it will block forever.
-// When stopping leader, Stop transfers its leadership to one of its peers
-// before stopping the server.
-// Stop terminates the Server and performs any necessary finalization.
-// Do and Process cannot be called after Stop has been invoked.
-func (s *EtcdServer) Stop() {
-	if err := s.TransferLeadership(); err != nil {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn("leadership transfer failed", zap.String("local-member-id", s.ID().String()), zap.Error(err))
-		} else {
-			plog.Warningf("%s failed to transfer leadership (%v)", s.ID(), err)
-		}
-	}
-	s.HardStop()
-}
-
-// ReadyNotify returns a channel that will be closed when the server
-// is ready to serve client requests
-func (s *EtcdServer) ReadyNotify() <-chan struct{} { return s.readych }
-
-func (s *EtcdServer) stopWithDelay(d time.Duration, err error) {
-	select {
-	case <-time.After(d):
-	case <-s.done:
-	}
-	select {
-	case s.errorc <- err:
-	default:
-	}
-}
-
-// StopNotify returns a channel that receives a empty struct
-// when the server is stopped.
-func (s *EtcdServer) StopNotify() <-chan struct{} { return s.done }
-
-func (s *EtcdServer) SelfStats() []byte { return s.stats.JSON() }
-
-func (s *EtcdServer) LeaderStats() []byte {
-	lead := s.getLead()
-	if lead != uint64(s.id) {
-		return nil
-	}
-	return s.lstats.JSON()
-}
-
-func (s *EtcdServer) StoreStats() []byte { return s.v2store.JsonStats() }
-
-func (s *EtcdServer) checkMembershipOperationPermission(ctx context.Context) error {
-	if s.authStore == nil {
-		// In the context of ordinary etcd process, s.authStore will never be nil.
-		// This branch is for handling cases in server_test.go
-		return nil
-	}
-
-	// Note that this permission check is done in the API layer,
-	// so TOCTOU problem can be caused potentially in a schedule like this:
-	// update membership with user A -> revoke root role of A -> apply membership change
-	// in the state machine layer
-	// However, both of membership change and role management requires the root privilege.
-	// So careful operation by admins can prevent the problem.
-	authInfo, err := s.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return err
-	}
-
-	return s.AuthStore().IsAdminPermitted(authInfo)
-}
-
-func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-
-	// TODO: move Member to protobuf type
-	b, err := json.Marshal(memb)
-	if err != nil {
-		return nil, err
-	}
-
-	// by default StrictReconfigCheck is enabled; reject new members if unhealthy.
-	if err := s.mayAddMember(memb); err != nil {
-		return nil, err
-	}
-
-	cc := raftpb.ConfChange{
-		Type:    raftpb.ConfChangeAddNode,
-		NodeID:  uint64(memb.ID),
-		Context: b,
-	}
-
-	if memb.IsLearner {
-		cc.Type = raftpb.ConfChangeAddLearnerNode
-	}
-
-	return s.configure(ctx, cc)
-}
-
-func (s *EtcdServer) mayAddMember(memb membership.Member) error {
-	if !s.Cfg.StrictReconfigCheck {
-		return nil
-	}
-
-	// protect quorum when adding voting member
-	if !memb.IsLearner && !s.cluster.IsReadyToAddVotingMember() {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejecting member add request; not enough healthy members",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("requested-member-add", fmt.Sprintf("%+v", memb)),
-				zap.Error(ErrNotEnoughStartedMembers),
-			)
-		} else {
-			plog.Warningf("not enough started members, rejecting member add %+v", memb)
-		}
-		return ErrNotEnoughStartedMembers
-	}
-
-	if !isConnectedFullySince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), s.cluster.VotingMembers()) {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejecting member add request; local member has not been connected to all peers, reconfigure breaks active quorum",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("requested-member-add", fmt.Sprintf("%+v", memb)),
-				zap.Error(ErrUnhealthy),
-			)
-		} else {
-			plog.Warningf("not healthy for reconfigure, rejecting member add %+v", memb)
-		}
-		return ErrUnhealthy
-	}
-
-	return nil
-}
-
-func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-
-	// by default StrictReconfigCheck is enabled; reject removal if leads to quorum loss
-	if err := s.mayRemoveMember(types.ID(id)); err != nil {
-		return nil, err
-	}
-
-	cc := raftpb.ConfChange{
-		Type:   raftpb.ConfChangeRemoveNode,
-		NodeID: id,
-	}
-	return s.configure(ctx, cc)
-}
-
-// PromoteMember promotes a learner node to a voting node.
-func (s *EtcdServer) PromoteMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	// only raft leader has information on whether the to-be-promoted learner node is ready. If promoteMember call
-	// fails with ErrNotLeader, forward the request to leader node via HTTP. If promoteMember call fails with error
-	// other than ErrNotLeader, return the error.
-	resp, err := s.promoteMember(ctx, id)
-	if err == nil {
-		learnerPromoteSucceed.Inc()
-		return resp, nil
-	}
-	if err != ErrNotLeader {
-		learnerPromoteFailed.WithLabelValues(err.Error()).Inc()
-		return resp, err
-	}
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-	// forward to leader
-	for cctx.Err() == nil {
-		leader, err := s.waitLeader(cctx)
-		if err != nil {
-			return nil, err
-		}
-		for _, url := range leader.PeerURLs {
-			resp, err := promoteMemberHTTP(cctx, url, id, s.peerRt)
-			if err == nil {
-				return resp, nil
-			}
-			// If member promotion failed, return early. Otherwise keep retry.
-			if err == ErrLearnerNotReady || err == membership.ErrIDNotFound || err == membership.ErrMemberNotLearner {
-				return nil, err
-			}
-		}
-	}
-
-	if cctx.Err() == context.DeadlineExceeded {
-		return nil, ErrTimeout
-	}
-	return nil, ErrCanceled
-}
-
-// promoteMember checks whether the to-be-promoted learner node is ready before sending the promote
-// request to raft.
-// The function returns ErrNotLeader if the local node is not raft leader (therefore does not have
-// enough information to determine if the learner node is ready), returns ErrLearnerNotReady if the
-// local node is leader (therefore has enough information) but decided the learner node is not ready
-// to be promoted.
-func (s *EtcdServer) promoteMember(ctx context.Context, id uint64) ([]*membership.Member, error) {
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-
-	// check if we can promote this learner.
-	if err := s.mayPromoteMember(types.ID(id)); err != nil {
-		return nil, err
-	}
-
-	// build the context for the promote confChange. mark IsLearner to false and IsPromote to true.
-	promoteChangeContext := membership.ConfigChangeContext{
-		Member: membership.Member{
-			ID: types.ID(id),
-		},
-		IsPromote: true,
-	}
-
-	b, err := json.Marshal(promoteChangeContext)
-	if err != nil {
-		return nil, err
-	}
-
-	cc := raftpb.ConfChange{
-		Type:    raftpb.ConfChangeAddNode,
-		NodeID:  id,
-		Context: b,
-	}
-
-	return s.configure(ctx, cc)
-}
-
-func (s *EtcdServer) mayPromoteMember(id types.ID) error {
-	err := s.isLearnerReady(uint64(id))
-	if err != nil {
-		return err
-	}
-
-	if !s.Cfg.StrictReconfigCheck {
-		return nil
-	}
-	if !s.cluster.IsReadyToPromoteMember(uint64(id)) {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejecting member promote request; not enough healthy members",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("requested-member-remove-id", id.String()),
-				zap.Error(ErrNotEnoughStartedMembers),
-			)
-		} else {
-			plog.Warningf("not enough started members, rejecting promote member %s", id)
-		}
-		return ErrNotEnoughStartedMembers
-	}
-
-	return nil
-}
-
-// check whether the learner catches up with leader or not.
-// Note: it will return nil if member is not found in cluster or if member is not learner.
-// These two conditions will be checked before apply phase later.
-func (s *EtcdServer) isLearnerReady(id uint64) error {
-	rs := s.raftStatus()
-
-	// leader's raftStatus.Progress is not nil
-	if rs.Progress == nil {
-		return ErrNotLeader
-	}
-
-	var learnerMatch uint64
-	isFound := false
-	leaderID := rs.ID
-	for memberID, progress := range rs.Progress {
-		if id == memberID {
-			// check its status
-			learnerMatch = progress.Match
-			isFound = true
-			break
-		}
-	}
-
-	if isFound {
-		leaderMatch := rs.Progress[leaderID].Match
-		// the learner's Match not caught up with leader yet
-		if float64(learnerMatch) < float64(leaderMatch)*readyPercent {
-			return ErrLearnerNotReady
-		}
-	}
-
-	return nil
-}
-
-func (s *EtcdServer) mayRemoveMember(id types.ID) error {
-	if !s.Cfg.StrictReconfigCheck {
-		return nil
-	}
-
-	isLearner := s.cluster.IsMemberExist(id) && s.cluster.Member(id).IsLearner
-	// no need to check quorum when removing non-voting member
-	if isLearner {
-		return nil
-	}
-
-	if !s.cluster.IsReadyToRemoveVotingMember(uint64(id)) {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejecting member remove request; not enough healthy members",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("requested-member-remove-id", id.String()),
-				zap.Error(ErrNotEnoughStartedMembers),
-			)
-		} else {
-			plog.Warningf("not enough started members, rejecting remove member %s", id)
-		}
-		return ErrNotEnoughStartedMembers
-	}
-
-	// downed member is safe to remove since it's not part of the active quorum
-	if t := s.r.transport.ActiveSince(id); id != s.ID() && t.IsZero() {
-		return nil
-	}
-
-	// protect quorum if some members are down
-	m := s.cluster.VotingMembers()
-	active := numConnectedSince(s.r.transport, time.Now().Add(-HealthInterval), s.ID(), m)
-	if (active - 1) < 1+((len(m)-1)/2) {
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn(
-				"rejecting member remove request; local member has not been connected to all peers, reconfigure breaks active quorum",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("requested-member-remove", id.String()),
-				zap.Int("active-peers", active),
-				zap.Error(ErrUnhealthy),
-			)
-		} else {
-			plog.Warningf("reconfigure breaks active quorum, rejecting remove member %s", id)
-		}
-		return ErrUnhealthy
-	}
-
-	return nil
-}
-
-func (s *EtcdServer) UpdateMember(ctx context.Context, memb membership.Member) ([]*membership.Member, error) {
-	b, merr := json.Marshal(memb)
-	if merr != nil {
-		return nil, merr
-	}
-
-	if err := s.checkMembershipOperationPermission(ctx); err != nil {
-		return nil, err
-	}
-	cc := raftpb.ConfChange{
-		Type:    raftpb.ConfChangeUpdateNode,
-		NodeID:  uint64(memb.ID),
-		Context: b,
-	}
-	return s.configure(ctx, cc)
-}
-
-func (s *EtcdServer) setCommittedIndex(v uint64) {
-	atomic.StoreUint64(&s.committedIndex, v)
-}
-
-func (s *EtcdServer) getCommittedIndex() uint64 {
-	return atomic.LoadUint64(&s.committedIndex)
-}
-
-func (s *EtcdServer) setAppliedIndex(v uint64) {
-	atomic.StoreUint64(&s.appliedIndex, v)
-}
-
-func (s *EtcdServer) getAppliedIndex() uint64 {
-	return atomic.LoadUint64(&s.appliedIndex)
-}
-
-func (s *EtcdServer) setTerm(v uint64) {
-	atomic.StoreUint64(&s.term, v)
-}
-
-func (s *EtcdServer) getTerm() uint64 {
-	return atomic.LoadUint64(&s.term)
-}
-
-func (s *EtcdServer) setLead(v uint64) {
-	atomic.StoreUint64(&s.lead, v)
-}
-
-func (s *EtcdServer) getLead() uint64 {
-	return atomic.LoadUint64(&s.lead)
-}
-
-func (s *EtcdServer) leaderChangedNotify() <-chan struct{} {
-	s.leaderChangedMu.RLock()
-	defer s.leaderChangedMu.RUnlock()
-	return s.leaderChanged
-}
-
-// RaftStatusGetter represents etcd server and Raft progress.
-type RaftStatusGetter interface {
-	ID() types.ID
-	Leader() types.ID
-	CommittedIndex() uint64
-	AppliedIndex() uint64
-	Term() uint64
-}
-
-func (s *EtcdServer) ID() types.ID { return s.id }
-
-func (s *EtcdServer) Leader() types.ID { return types.ID(s.getLead()) }
-
-func (s *EtcdServer) Lead() uint64 { return s.getLead() }
-
-func (s *EtcdServer) CommittedIndex() uint64 { return s.getCommittedIndex() }
-
-func (s *EtcdServer) AppliedIndex() uint64 { return s.getAppliedIndex() }
-
-func (s *EtcdServer) Term() uint64 { return s.getTerm() }
-
-type confChangeResponse struct {
-	membs []*membership.Member
-	err   error
-}
-
-// configure sends a configuration change through consensus and
-// then waits for it to be applied to the server. It
-// will block until the change is performed or there is an error.
-func (s *EtcdServer) configure(ctx context.Context, cc raftpb.ConfChange) ([]*membership.Member, error) {
-	cc.ID = s.reqIDGen.Next()
-	ch := s.w.Register(cc.ID)
-
-	start := time.Now()
-	if err := s.r.ProposeConfChange(ctx, cc); err != nil {
-		s.w.Trigger(cc.ID, nil)
-		return nil, err
-	}
-
-	select {
-	case x := <-ch:
-		if x == nil {
-			if lg := s.getLogger(); lg != nil {
-				lg.Panic("failed to configure")
-			} else {
-				plog.Panicf("configure trigger value should never be nil")
-			}
-		}
-		resp := x.(*confChangeResponse)
-		if lg := s.getLogger(); lg != nil {
-			lg.Info(
-				"applied a configuration change through raft",
-				zap.String("local-member-id", s.ID().String()),
-				zap.String("raft-conf-change", cc.Type.String()),
-				zap.String("raft-conf-change-node-id", types.ID(cc.NodeID).String()),
-			)
-		}
-		return resp.membs, resp.err
-
-	case <-ctx.Done():
-		s.w.Trigger(cc.ID, nil) // GC wait
-		return nil, s.parseProposeCtxErr(ctx.Err(), start)
-
-	case <-s.stopping:
-		return nil, ErrStopped
-	}
-}
-
-// sync proposes a SYNC request and is non-blocking.
-// This makes no guarantee that the request will be proposed or performed.
-// The request will be canceled after the given timeout.
-func (s *EtcdServer) sync(timeout time.Duration) {
-	req := pb.Request{
-		Method: "SYNC",
-		ID:     s.reqIDGen.Next(),
-		Time:   time.Now().UnixNano(),
-	}
-	data := pbutil.MustMarshal(&req)
-	// There is no promise that node has leader when do SYNC request,
-	// so it uses goroutine to propose.
-	ctx, cancel := context.WithTimeout(s.ctx, timeout)
-	s.goAttach(func() {
-		s.r.Propose(ctx, data)
-		cancel()
-	})
-}
-
-// publish registers server information into the cluster. The information
-// is the JSON representation of this server's member struct, updated with the
-// static clientURLs of the server.
-// The function keeps attempting to register until it succeeds,
-// or its server is stopped.
-//
-// Use v2 store to encode member attributes, and apply through Raft
-// but does not go through v2 API endpoint, which means even with v2
-// client handler disabled (e.g. --enable-v2=false), cluster can still
-// process publish requests through rafthttp
-// TODO: Deprecate v2 store
-func (s *EtcdServer) publish(timeout time.Duration) {
-	b, err := json.Marshal(s.attributes)
-	if err != nil {
-		if lg := s.getLogger(); lg != nil {
-			lg.Panic("failed to marshal JSON", zap.Error(err))
-		} else {
-			plog.Panicf("json marshal error: %v", err)
-		}
-		return
-	}
-	req := pb.Request{
-		Method: "PUT",
-		Path:   membership.MemberAttributesStorePath(s.id),
-		Val:    string(b),
-	}
-
-	for {
-		ctx, cancel := context.WithTimeout(s.ctx, timeout)
-		_, err := s.Do(ctx, req)
-		cancel()
-		switch err {
-		case nil:
-			close(s.readych)
-			if lg := s.getLogger(); lg != nil {
-				lg.Info(
-					"published local member to cluster through raft",
-					zap.String("local-member-id", s.ID().String()),
-					zap.String("local-member-attributes", fmt.Sprintf("%+v", s.attributes)),
-					zap.String("request-path", req.Path),
-					zap.String("cluster-id", s.cluster.ID().String()),
-					zap.Duration("publish-timeout", timeout),
-				)
-			} else {
-				plog.Infof("published %+v to cluster %s", s.attributes, s.cluster.ID())
-			}
-			return
-
-		case ErrStopped:
-			if lg := s.getLogger(); lg != nil {
-				lg.Warn(
-					"stopped publish because server is stopped",
-					zap.String("local-member-id", s.ID().String()),
-					zap.String("local-member-attributes", fmt.Sprintf("%+v", s.attributes)),
-					zap.Duration("publish-timeout", timeout),
-					zap.Error(err),
-				)
-			} else {
-				plog.Infof("aborting publish because server is stopped")
-			}
-			return
-
-		default:
-			if lg := s.getLogger(); lg != nil {
-				lg.Warn(
-					"failed to publish local member to cluster through raft",
-					zap.String("local-member-id", s.ID().String()),
-					zap.String("local-member-attributes", fmt.Sprintf("%+v", s.attributes)),
-					zap.String("request-path", req.Path),
-					zap.Duration("publish-timeout", timeout),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("publish error: %v", err)
-			}
-		}
-	}
-}
-
-func (s *EtcdServer) sendMergedSnap(merged snap.Message) {
-	atomic.AddInt64(&s.inflightSnapshots, 1)
-
-	lg := s.getLogger()
-	fields := []zap.Field{
-		zap.String("from", s.ID().String()),
-		zap.String("to", types.ID(merged.To).String()),
-		zap.Int64("bytes", merged.TotalSize),
-		zap.String("size", humanize.Bytes(uint64(merged.TotalSize))),
-	}
-
-	now := time.Now()
-	s.r.transport.SendSnapshot(merged)
-	if lg != nil {
-		lg.Info("sending merged snapshot", fields...)
-	}
-
-	s.goAttach(func() {
-		select {
-		case ok := <-merged.CloseNotify():
-			// delay releasing inflight snapshot for another 30 seconds to
-			// block log compaction.
-			// If the follower still fails to catch up, it is probably just too slow
-			// to catch up. We cannot avoid the snapshot cycle anyway.
-			if ok {
-				select {
-				case <-time.After(releaseDelayAfterSnapshot):
-				case <-s.stopping:
-				}
-			}
-
-			atomic.AddInt64(&s.inflightSnapshots, -1)
-
-			if lg != nil {
-				lg.Info("sent merged snapshot", append(fields, zap.Duration("took", time.Since(now)))...)
-			}
-
-		case <-s.stopping:
-			if lg != nil {
-				lg.Warn("canceled sending merged snapshot; server stopping", fields...)
-			}
-			return
-		}
-	})
-}
-
-// apply takes entries received from Raft (after it has been committed) and
-// applies them to the current state of the EtcdServer.
-// The given entries should not be empty.
-func (s *EtcdServer) apply(
-	es []raftpb.Entry,
-	confState *raftpb.ConfState,
-) (appliedt uint64, appliedi uint64, shouldStop bool) {
-	for i := range es {
-		e := es[i]
-		switch e.Type {
-		case raftpb.EntryNormal:
-			s.applyEntryNormal(&e)
-			s.setAppliedIndex(e.Index)
-			s.setTerm(e.Term)
-
-		case raftpb.EntryConfChange:
-			// set the consistent index of current executing entry
-			if e.Index > s.consistIndex.ConsistentIndex() {
-				s.consistIndex.setConsistentIndex(e.Index)
-			}
-			var cc raftpb.ConfChange
-			pbutil.MustUnmarshal(&cc, e.Data)
-			removedSelf, err := s.applyConfChange(cc, confState)
-			s.setAppliedIndex(e.Index)
-			s.setTerm(e.Term)
-			shouldStop = shouldStop || removedSelf
-			s.w.Trigger(cc.ID, &confChangeResponse{s.cluster.Members(), err})
-
-		default:
-			if lg := s.getLogger(); lg != nil {
-				lg.Panic(
-					"unknown entry type; must be either EntryNormal or EntryConfChange",
-					zap.String("type", e.Type.String()),
-				)
-			} else {
-				plog.Panicf("entry type should be either EntryNormal or EntryConfChange")
-			}
-		}
-		appliedi, appliedt = e.Index, e.Term
-	}
-	return appliedt, appliedi, shouldStop
-}
-
-// applyEntryNormal apples an EntryNormal type raftpb request to the EtcdServer
-func (s *EtcdServer) applyEntryNormal(e *raftpb.Entry) {
-	shouldApplyV3 := false
-	if e.Index > s.consistIndex.ConsistentIndex() {
-		// set the consistent index of current executing entry
-		s.consistIndex.setConsistentIndex(e.Index)
-		shouldApplyV3 = true
-	}
-
-	// raft state machine may generate noop entry when leader confirmation.
-	// skip it in advance to avoid some potential bug in the future
-	if len(e.Data) == 0 {
-		select {
-		case s.forceVersionC <- struct{}{}:
-		default:
-		}
-		// promote lessor when the local member is leader and finished
-		// applying all entries from the last term.
-		if s.isLeader() {
-			s.lessor.Promote(s.Cfg.electionTimeout())
-		}
-		return
-	}
-
-	var raftReq pb.InternalRaftRequest
-	if !pbutil.MaybeUnmarshal(&raftReq, e.Data) { // backward compatible
-		var r pb.Request
-		rp := &r
-		pbutil.MustUnmarshal(rp, e.Data)
-		s.w.Trigger(r.ID, s.applyV2Request((*RequestV2)(rp)))
-		return
-	}
-	if raftReq.V2 != nil {
-		req := (*RequestV2)(raftReq.V2)
-		s.w.Trigger(req.ID, s.applyV2Request(req))
-		return
-	}
-
-	// do not re-apply applied entries.
-	if !shouldApplyV3 {
-		return
-	}
-
-	id := raftReq.ID
-	if id == 0 {
-		id = raftReq.Header.ID
-	}
-
-	var ar *applyResult
-	needResult := s.w.IsRegistered(id)
-	if needResult || !noSideEffect(&raftReq) {
-		if !needResult && raftReq.Txn != nil {
-			removeNeedlessRangeReqs(raftReq.Txn)
-		}
-		ar = s.applyV3.Apply(&raftReq)
-	}
-
-	if ar == nil {
-		return
-	}
-
-	if ar.err != ErrNoSpace || len(s.alarmStore.Get(pb.AlarmType_NOSPACE)) > 0 {
-		s.w.Trigger(id, ar)
-		return
-	}
-
-	if lg := s.getLogger(); lg != nil {
-		lg.Warn(
-			"message exceeded backend quota; raising alarm",
-			zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
-			zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
-			zap.Error(ar.err),
-		)
-	} else {
-		plog.Errorf("applying raft message exceeded backend quota")
-	}
-
-	s.goAttach(func() {
-		a := &pb.AlarmRequest{
-			MemberID: uint64(s.ID()),
-			Action:   pb.AlarmRequest_ACTIVATE,
-			Alarm:    pb.AlarmType_NOSPACE,
-		}
-		s.raftRequest(s.ctx, pb.InternalRaftRequest{Alarm: a})
-		s.w.Trigger(id, ar)
-	})
-}
-
-// applyConfChange applies a ConfChange to the server. It is only
-// invoked with a ConfChange that has already passed through Raft
-func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.ConfState) (bool, error) {
-	if err := s.cluster.ValidateConfigurationChange(cc); err != nil {
-		cc.NodeID = raft.None
-		s.r.ApplyConfChange(cc)
-		return false, err
-	}
-
-	lg := s.getLogger()
-	*confState = *s.r.ApplyConfChange(cc)
-	switch cc.Type {
-	case raftpb.ConfChangeAddNode, raftpb.ConfChangeAddLearnerNode:
-		confChangeContext := new(membership.ConfigChangeContext)
-		if err := json.Unmarshal(cc.Context, confChangeContext); err != nil {
-			if lg != nil {
-				lg.Panic("failed to unmarshal member", zap.Error(err))
-			} else {
-				plog.Panicf("unmarshal member should never fail: %v", err)
-			}
-		}
-		if cc.NodeID != uint64(confChangeContext.Member.ID) {
-			if lg != nil {
-				lg.Panic(
-					"got different member ID",
-					zap.String("member-id-from-config-change-entry", types.ID(cc.NodeID).String()),
-					zap.String("member-id-from-message", confChangeContext.Member.ID.String()),
-				)
-			} else {
-				plog.Panicf("nodeID should always be equal to member ID")
-			}
-		}
-		if confChangeContext.IsPromote {
-			s.cluster.PromoteMember(confChangeContext.Member.ID)
-		} else {
-			s.cluster.AddMember(&confChangeContext.Member)
-
-			if confChangeContext.Member.ID != s.id {
-				s.r.transport.AddPeer(confChangeContext.Member.ID, confChangeContext.PeerURLs)
-			}
-		}
-
-		// update the isLearner metric when this server id is equal to the id in raft member confChange
-		if confChangeContext.Member.ID == s.id {
-			if cc.Type == raftpb.ConfChangeAddLearnerNode {
-				isLearner.Set(1)
-			} else {
-				isLearner.Set(0)
-			}
-		}
-
-	case raftpb.ConfChangeRemoveNode:
-		id := types.ID(cc.NodeID)
-		s.cluster.RemoveMember(id)
-		if id == s.id {
-			return true, nil
-		}
-		s.r.transport.RemovePeer(id)
-
-	case raftpb.ConfChangeUpdateNode:
-		m := new(membership.Member)
-		if err := json.Unmarshal(cc.Context, m); err != nil {
-			if lg != nil {
-				lg.Panic("failed to unmarshal member", zap.Error(err))
-			} else {
-				plog.Panicf("unmarshal member should never fail: %v", err)
-			}
-		}
-		if cc.NodeID != uint64(m.ID) {
-			if lg != nil {
-				lg.Panic(
-					"got different member ID",
-					zap.String("member-id-from-config-change-entry", types.ID(cc.NodeID).String()),
-					zap.String("member-id-from-message", m.ID.String()),
-				)
-			} else {
-				plog.Panicf("nodeID should always be equal to member ID")
-			}
-		}
-		s.cluster.UpdateRaftAttributes(m.ID, m.RaftAttributes)
-		if m.ID != s.id {
-			s.r.transport.UpdatePeer(m.ID, m.PeerURLs)
-		}
-	}
-	return false, nil
-}
-
-// TODO: non-blocking snapshot
-func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) {
-	clone := s.v2store.Clone()
-	// commit kv to write metadata (for example: consistent index) to disk.
-	// KV().commit() updates the consistent index in backend.
-	// All operations that update consistent index must be called sequentially
-	// from applyAll function.
-	// So KV().Commit() cannot run in parallel with apply. It has to be called outside
-	// the go routine created below.
-	s.KV().Commit()
-
-	s.goAttach(func() {
-		lg := s.getLogger()
-
-		d, err := clone.SaveNoCopy()
-		// TODO: current store will never fail to do a snapshot
-		// what should we do if the store might fail?
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to save v2 store", zap.Error(err))
-			} else {
-				plog.Panicf("store save should never fail: %v", err)
-			}
-		}
-		snap, err := s.r.raftStorage.CreateSnapshot(snapi, &confState, d)
-		if err != nil {
-			// the snapshot was done asynchronously with the progress of raft.
-			// raft might have already got a newer snapshot.
-			if err == raft.ErrSnapOutOfDate {
-				return
-			}
-			if lg != nil {
-				lg.Panic("failed to create snapshot", zap.Error(err))
-			} else {
-				plog.Panicf("unexpected create snapshot error %v", err)
-			}
-		}
-		// SaveSnap saves the snapshot and releases the locked wal files
-		// to the snapshot index.
-		if err = s.r.storage.SaveSnap(snap); err != nil {
-			if lg != nil {
-				lg.Panic("failed to save snapshot", zap.Error(err))
-			} else {
-				plog.Fatalf("save snapshot error: %v", err)
-			}
-		}
-		if lg != nil {
-			lg.Info(
-				"saved snapshot",
-				zap.Uint64("snapshot-index", snap.Metadata.Index),
-			)
-		} else {
-			plog.Infof("saved snapshot at index %d", snap.Metadata.Index)
-		}
-
-		// When sending a snapshot, etcd will pause compaction.
-		// After receives a snapshot, the slow follower needs to get all the entries right after
-		// the snapshot sent to catch up. If we do not pause compaction, the log entries right after
-		// the snapshot sent might already be compacted. It happens when the snapshot takes long time
-		// to send and save. Pausing compaction avoids triggering a snapshot sending cycle.
-		if atomic.LoadInt64(&s.inflightSnapshots) != 0 {
-			if lg != nil {
-				lg.Info("skip compaction since there is an inflight snapshot")
-			} else {
-				plog.Infof("skip compaction since there is an inflight snapshot")
-			}
-			return
-		}
-
-		// keep some in memory log entries for slow followers.
-		compacti := uint64(1)
-		if snapi > s.Cfg.SnapshotCatchUpEntries {
-			compacti = snapi - s.Cfg.SnapshotCatchUpEntries
-		}
-
-		err = s.r.raftStorage.Compact(compacti)
-		if err != nil {
-			// the compaction was done asynchronously with the progress of raft.
-			// raft log might already been compact.
-			if err == raft.ErrCompacted {
-				return
-			}
-			if lg != nil {
-				lg.Panic("failed to compact", zap.Error(err))
-			} else {
-				plog.Panicf("unexpected compaction error %v", err)
-			}
-		}
-		if lg != nil {
-			lg.Info(
-				"compacted Raft logs",
-				zap.Uint64("compact-index", compacti),
-			)
-		} else {
-			plog.Infof("compacted raft log at %d", compacti)
-		}
-	})
-}
-
-// CutPeer drops messages to the specified peer.
-func (s *EtcdServer) CutPeer(id types.ID) {
-	tr, ok := s.r.transport.(*rafthttp.Transport)
-	if ok {
-		tr.CutPeer(id)
-	}
-}
-
-// MendPeer recovers the message dropping behavior of the given peer.
-func (s *EtcdServer) MendPeer(id types.ID) {
-	tr, ok := s.r.transport.(*rafthttp.Transport)
-	if ok {
-		tr.MendPeer(id)
-	}
-}
-
-func (s *EtcdServer) PauseSending() { s.r.pauseSending() }
-
-func (s *EtcdServer) ResumeSending() { s.r.resumeSending() }
-
-func (s *EtcdServer) ClusterVersion() *semver.Version {
-	if s.cluster == nil {
-		return nil
-	}
-	return s.cluster.Version()
-}
-
-// monitorVersions checks the member's version every monitorVersionInterval.
-// It updates the cluster version if all members agrees on a higher one.
-// It prints out log if there is a member with a higher version than the
-// local version.
-func (s *EtcdServer) monitorVersions() {
-	for {
-		select {
-		case <-s.forceVersionC:
-		case <-time.After(monitorVersionInterval):
-		case <-s.stopping:
-			return
-		}
-
-		if s.Leader() != s.ID() {
-			continue
-		}
-
-		v := decideClusterVersion(s.getLogger(), getVersions(s.getLogger(), s.cluster, s.id, s.peerRt))
-		if v != nil {
-			// only keep major.minor version for comparison
-			v = &semver.Version{
-				Major: v.Major,
-				Minor: v.Minor,
-			}
-		}
-
-		// if the current version is nil:
-		// 1. use the decided version if possible
-		// 2. or use the min cluster version
-		if s.cluster.Version() == nil {
-			verStr := version.MinClusterVersion
-			if v != nil {
-				verStr = v.String()
-			}
-			s.goAttach(func() { s.updateClusterVersion(verStr) })
-			continue
-		}
-
-		// update cluster version only if the decided version is greater than
-		// the current cluster version
-		if v != nil && s.cluster.Version().LessThan(*v) {
-			s.goAttach(func() { s.updateClusterVersion(v.String()) })
-		}
-	}
-}
-
-func (s *EtcdServer) updateClusterVersion(ver string) {
-	lg := s.getLogger()
-
-	if s.cluster.Version() == nil {
-		if lg != nil {
-			lg.Info(
-				"setting up initial cluster version",
-				zap.String("cluster-version", version.Cluster(ver)),
-			)
-		} else {
-			plog.Infof("setting up the initial cluster version to %s", version.Cluster(ver))
-		}
-	} else {
-		if lg != nil {
-			lg.Info(
-				"updating cluster version",
-				zap.String("from", version.Cluster(s.cluster.Version().String())),
-				zap.String("to", version.Cluster(ver)),
-			)
-		} else {
-			plog.Infof("updating the cluster version from %s to %s", version.Cluster(s.cluster.Version().String()), version.Cluster(ver))
-		}
-	}
-
-	req := pb.Request{
-		Method: "PUT",
-		Path:   membership.StoreClusterVersionKey(),
-		Val:    ver,
-	}
-
-	ctx, cancel := context.WithTimeout(s.ctx, s.Cfg.ReqTimeout())
-	_, err := s.Do(ctx, req)
-	cancel()
-
-	switch err {
-	case nil:
-		if lg != nil {
-			lg.Info("cluster version is updated", zap.String("cluster-version", version.Cluster(ver)))
-		}
-		return
-
-	case ErrStopped:
-		if lg != nil {
-			lg.Warn("aborting cluster version update; server is stopped", zap.Error(err))
-		} else {
-			plog.Infof("aborting update cluster version because server is stopped")
-		}
-		return
-
-	default:
-		if lg != nil {
-			lg.Warn("failed to update cluster version", zap.Error(err))
-		} else {
-			plog.Errorf("error updating cluster version (%v)", err)
-		}
-	}
-}
-
-func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error {
-	switch err {
-	case context.Canceled:
-		return ErrCanceled
-
-	case context.DeadlineExceeded:
-		s.leadTimeMu.RLock()
-		curLeadElected := s.leadElectedTime
-		s.leadTimeMu.RUnlock()
-		prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond)
-		if start.After(prevLeadLost) && start.Before(curLeadElected) {
-			return ErrTimeoutDueToLeaderFail
-		}
-		lead := types.ID(s.getLead())
-		switch lead {
-		case types.ID(raft.None):
-			// TODO: return error to specify it happens because the cluster does not have leader now
-		case s.ID():
-			if !isConnectedToQuorumSince(s.r.transport, start, s.ID(), s.cluster.Members()) {
-				return ErrTimeoutDueToConnectionLost
-			}
-		default:
-			if !isConnectedSince(s.r.transport, start, lead) {
-				return ErrTimeoutDueToConnectionLost
-			}
-		}
-		return ErrTimeout
-
-	default:
-		return err
-	}
-}
-
-func (s *EtcdServer) KV() mvcc.ConsistentWatchableKV { return s.kv }
-func (s *EtcdServer) Backend() backend.Backend {
-	s.bemu.Lock()
-	defer s.bemu.Unlock()
-	return s.be
-}
-
-func (s *EtcdServer) AuthStore() auth.AuthStore { return s.authStore }
-
-func (s *EtcdServer) restoreAlarms() error {
-	s.applyV3 = s.newApplierV3()
-	as, err := v3alarm.NewAlarmStore(s)
-	if err != nil {
-		return err
-	}
-	s.alarmStore = as
-	if len(as.Get(pb.AlarmType_NOSPACE)) > 0 {
-		s.applyV3 = newApplierV3Capped(s.applyV3)
-	}
-	if len(as.Get(pb.AlarmType_CORRUPT)) > 0 {
-		s.applyV3 = newApplierV3Corrupt(s.applyV3)
-	}
-	return nil
-}
-
-// goAttach creates a goroutine on a given function and tracks it using
-// the etcdserver waitgroup.
-func (s *EtcdServer) goAttach(f func()) {
-	s.wgMu.RLock() // this blocks with ongoing close(s.stopping)
-	defer s.wgMu.RUnlock()
-	select {
-	case <-s.stopping:
-		if lg := s.getLogger(); lg != nil {
-			lg.Warn("server has stopped; skipping goAttach")
-		} else {
-			plog.Warning("server has stopped (skipping goAttach)")
-		}
-		return
-	default:
-	}
-
-	// now safe to add since waitgroup wait has not started yet
-	s.wg.Add(1)
-	go func() {
-		defer s.wg.Done()
-		f()
-	}()
-}
-
-func (s *EtcdServer) Alarms() []*pb.AlarmMember {
-	return s.alarmStore.Get(pb.AlarmType_NONE)
-}
-
-func (s *EtcdServer) Logger() *zap.Logger {
-	return s.lg
-}
-
-// IsLearner returns if the local member is raft learner
-func (s *EtcdServer) IsLearner() bool {
-	return s.cluster.IsLocalMemberLearner()
-}
-
-// IsMemberExist returns if the member with the given id exists in cluster.
-func (s *EtcdServer) IsMemberExist(id types.ID) bool {
-	return s.cluster.IsMemberExist(id)
-}
-
-// raftStatus returns the raft status of this etcd node.
-func (s *EtcdServer) raftStatus() raft.Status {
-	return s.r.Node.Status()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/server_access_control.go b/vendor/go.etcd.io/etcd/etcdserver/server_access_control.go
deleted file mode 100644
index 09e2255..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/server_access_control.go
+++ /dev/null
@@ -1,65 +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 etcdserver
-
-import "sync"
-
-// AccessController controls etcd server HTTP request access.
-type AccessController struct {
-	corsMu          sync.RWMutex
-	CORS            map[string]struct{}
-	hostWhitelistMu sync.RWMutex
-	HostWhitelist   map[string]struct{}
-}
-
-// NewAccessController returns a new "AccessController" with default "*" values.
-func NewAccessController() *AccessController {
-	return &AccessController{
-		CORS:          map[string]struct{}{"*": {}},
-		HostWhitelist: map[string]struct{}{"*": {}},
-	}
-}
-
-// OriginAllowed determines whether the server will allow a given CORS origin.
-// If CORS is empty, allow all.
-func (ac *AccessController) OriginAllowed(origin string) bool {
-	ac.corsMu.RLock()
-	defer ac.corsMu.RUnlock()
-	if len(ac.CORS) == 0 { // allow all
-		return true
-	}
-	_, ok := ac.CORS["*"]
-	if ok {
-		return true
-	}
-	_, ok = ac.CORS[origin]
-	return ok
-}
-
-// IsHostWhitelisted returns true if the host is whitelisted.
-// If whitelist is empty, allow all.
-func (ac *AccessController) IsHostWhitelisted(host string) bool {
-	ac.hostWhitelistMu.RLock()
-	defer ac.hostWhitelistMu.RUnlock()
-	if len(ac.HostWhitelist) == 0 { // allow all
-		return true
-	}
-	_, ok := ac.HostWhitelist["*"]
-	if ok {
-		return true
-	}
-	_, ok = ac.HostWhitelist[host]
-	return ok
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/snapshot_merge.go b/vendor/go.etcd.io/etcd/etcdserver/snapshot_merge.go
deleted file mode 100644
index 4177768..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/snapshot_merge.go
+++ /dev/null
@@ -1,100 +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 etcdserver
-
-import (
-	"io"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/raft/raftpb"
-
-	humanize "github.com/dustin/go-humanize"
-	"go.uber.org/zap"
-)
-
-// createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf),
-// a snapshot of v2 store inside raft.Snapshot as []byte, a snapshot of v3 KV in the top level message
-// as ReadCloser.
-func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi uint64, confState raftpb.ConfState) snap.Message {
-	// get a snapshot of v2 store as []byte
-	clone := s.v2store.Clone()
-	d, err := clone.SaveNoCopy()
-	if err != nil {
-		if lg := s.getLogger(); lg != nil {
-			lg.Panic("failed to save v2 store data", zap.Error(err))
-		} else {
-			plog.Panicf("store save should never fail: %v", err)
-		}
-	}
-
-	// commit kv to write metadata(for example: consistent index).
-	s.KV().Commit()
-	dbsnap := s.be.Snapshot()
-	// get a snapshot of v3 KV as readCloser
-	rc := newSnapshotReaderCloser(s.getLogger(), dbsnap)
-
-	// put the []byte snapshot of store into raft snapshot and return the merged snapshot with
-	// KV readCloser snapshot.
-	snapshot := raftpb.Snapshot{
-		Metadata: raftpb.SnapshotMetadata{
-			Index:     snapi,
-			Term:      snapt,
-			ConfState: confState,
-		},
-		Data: d,
-	}
-	m.Snapshot = snapshot
-
-	return *snap.NewMessage(m, rc, dbsnap.Size())
-}
-
-func newSnapshotReaderCloser(lg *zap.Logger, snapshot backend.Snapshot) io.ReadCloser {
-	pr, pw := io.Pipe()
-	go func() {
-		n, err := snapshot.WriteTo(pw)
-		if err == nil {
-			if lg != nil {
-				lg.Info(
-					"sent database snapshot to writer",
-					zap.Int64("bytes", n),
-					zap.String("size", humanize.Bytes(uint64(n))),
-				)
-			} else {
-				plog.Infof("wrote database snapshot out [total bytes: %d]", n)
-			}
-		} else {
-			if lg != nil {
-				lg.Warn(
-					"failed to send database snapshot to writer",
-					zap.String("size", humanize.Bytes(uint64(n))),
-					zap.Error(err),
-				)
-			} else {
-				plog.Warningf("failed to write database snapshot out [written bytes: %d]: %v", n, err)
-			}
-		}
-		pw.CloseWithError(err)
-		err = snapshot.Close()
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to close database snapshot", zap.Error(err))
-			} else {
-				plog.Panicf("failed to close database snapshot: %v", err)
-			}
-		}
-	}()
-	return pr
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/storage.go b/vendor/go.etcd.io/etcd/etcdserver/storage.go
deleted file mode 100644
index d57b6f9..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/storage.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 etcdserver
-
-import (
-	"io"
-
-	"go.etcd.io/etcd/etcdserver/api/snap"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/pkg/types"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/wal"
-	"go.etcd.io/etcd/wal/walpb"
-
-	"go.uber.org/zap"
-)
-
-type Storage interface {
-	// Save function saves ents and state to the underlying stable storage.
-	// Save MUST block until st and ents are on stable storage.
-	Save(st raftpb.HardState, ents []raftpb.Entry) error
-	// SaveSnap function saves snapshot to the underlying stable storage.
-	SaveSnap(snap raftpb.Snapshot) error
-	// Close closes the Storage and performs finalization.
-	Close() error
-}
-
-type storage struct {
-	*wal.WAL
-	*snap.Snapshotter
-}
-
-func NewStorage(w *wal.WAL, s *snap.Snapshotter) Storage {
-	return &storage{w, s}
-}
-
-// SaveSnap saves the snapshot to disk and release the locked
-// wal files since they will not be used.
-func (st *storage) SaveSnap(snap raftpb.Snapshot) error {
-	walsnap := walpb.Snapshot{
-		Index: snap.Metadata.Index,
-		Term:  snap.Metadata.Term,
-	}
-	err := st.WAL.SaveSnapshot(walsnap)
-	if err != nil {
-		return err
-	}
-	err = st.Snapshotter.SaveSnap(snap)
-	if err != nil {
-		return err
-	}
-	return st.WAL.ReleaseLockTo(snap.Metadata.Index)
-}
-
-func readWAL(lg *zap.Logger, waldir string, snap walpb.Snapshot) (w *wal.WAL, id, cid types.ID, st raftpb.HardState, ents []raftpb.Entry) {
-	var (
-		err       error
-		wmetadata []byte
-	)
-
-	repaired := false
-	for {
-		if w, err = wal.Open(lg, waldir, snap); err != nil {
-			if lg != nil {
-				lg.Fatal("failed to open WAL", zap.Error(err))
-			} else {
-				plog.Fatalf("open wal error: %v", err)
-			}
-		}
-		if wmetadata, st, ents, err = w.ReadAll(); err != nil {
-			w.Close()
-			// we can only repair ErrUnexpectedEOF and we never repair twice.
-			if repaired || err != io.ErrUnexpectedEOF {
-				if lg != nil {
-					lg.Fatal("failed to read WAL, cannot be repaired", zap.Error(err))
-				} else {
-					plog.Fatalf("read wal error (%v) and cannot be repaired", err)
-				}
-			}
-			if !wal.Repair(lg, waldir) {
-				if lg != nil {
-					lg.Fatal("failed to repair WAL", zap.Error(err))
-				} else {
-					plog.Fatalf("WAL error (%v) cannot be repaired", err)
-				}
-			} else {
-				if lg != nil {
-					lg.Info("repaired WAL", zap.Error(err))
-				} else {
-					plog.Infof("repaired WAL error (%v)", err)
-				}
-				repaired = true
-			}
-			continue
-		}
-		break
-	}
-	var metadata pb.Metadata
-	pbutil.MustUnmarshal(&metadata, wmetadata)
-	id = types.ID(metadata.NodeID)
-	cid = types.ID(metadata.ClusterID)
-	return w, id, cid, st, ents
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/util.go b/vendor/go.etcd.io/etcd/etcdserver/util.go
deleted file mode 100644
index fe5024e..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/util.go
+++ /dev/null
@@ -1,168 +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 etcdserver
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"time"
-
-	"github.com/golang/protobuf/proto"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	"go.etcd.io/etcd/etcdserver/api/rafthttp"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/pkg/types"
-
-	"go.uber.org/zap"
-)
-
-// isConnectedToQuorumSince checks whether the local member is connected to the
-// quorum of the cluster since the given time.
-func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
-	return numConnectedSince(transport, since, self, members) >= (len(members)/2)+1
-}
-
-// isConnectedSince checks whether the local member is connected to the
-// remote member since the given time.
-func isConnectedSince(transport rafthttp.Transporter, since time.Time, remote types.ID) bool {
-	t := transport.ActiveSince(remote)
-	return !t.IsZero() && t.Before(since)
-}
-
-// isConnectedFullySince checks whether the local member is connected to all
-// members in the cluster since the given time.
-func isConnectedFullySince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
-	return numConnectedSince(transport, since, self, members) == len(members)
-}
-
-// numConnectedSince counts how many members are connected to the local member
-// since the given time.
-func numConnectedSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) int {
-	connectedNum := 0
-	for _, m := range members {
-		if m.ID == self || isConnectedSince(transport, since, m.ID) {
-			connectedNum++
-		}
-	}
-	return connectedNum
-}
-
-// longestConnected chooses the member with longest active-since-time.
-// It returns false, if nothing is active.
-func longestConnected(tp rafthttp.Transporter, membs []types.ID) (types.ID, bool) {
-	var longest types.ID
-	var oldest time.Time
-	for _, id := range membs {
-		tm := tp.ActiveSince(id)
-		if tm.IsZero() { // inactive
-			continue
-		}
-
-		if oldest.IsZero() { // first longest candidate
-			oldest = tm
-			longest = id
-		}
-
-		if tm.Before(oldest) {
-			oldest = tm
-			longest = id
-		}
-	}
-	if uint64(longest) == 0 {
-		return longest, false
-	}
-	return longest, true
-}
-
-type notifier struct {
-	c   chan struct{}
-	err error
-}
-
-func newNotifier() *notifier {
-	return &notifier{
-		c: make(chan struct{}),
-	}
-}
-
-func (nc *notifier) notify(err error) {
-	nc.err = err
-	close(nc.c)
-}
-
-func warnOfExpensiveRequest(lg *zap.Logger, now time.Time, reqStringer fmt.Stringer, respMsg proto.Message, err error) {
-	var resp string
-	if !isNil(respMsg) {
-		resp = fmt.Sprintf("size:%d", proto.Size(respMsg))
-	}
-	warnOfExpensiveGenericRequest(lg, now, reqStringer, "", resp, err)
-}
-
-func warnOfExpensiveReadOnlyTxnRequest(lg *zap.Logger, now time.Time, r *pb.TxnRequest, txnResponse *pb.TxnResponse, err error) {
-	reqStringer := pb.NewLoggableTxnRequest(r)
-	var resp string
-	if !isNil(txnResponse) {
-		var resps []string
-		for _, r := range txnResponse.Responses {
-			switch op := r.Response.(type) {
-			case *pb.ResponseOp_ResponseRange:
-				resps = append(resps, fmt.Sprintf("range_response_count:%d", len(op.ResponseRange.Kvs)))
-			default:
-				// only range responses should be in a read only txn request
-			}
-		}
-		resp = fmt.Sprintf("responses:<%s> size:%d", strings.Join(resps, " "), proto.Size(txnResponse))
-	}
-	warnOfExpensiveGenericRequest(lg, now, reqStringer, "read-only range ", resp, err)
-}
-
-func warnOfExpensiveReadOnlyRangeRequest(lg *zap.Logger, now time.Time, reqStringer fmt.Stringer, rangeResponse *pb.RangeResponse, err error) {
-	var resp string
-	if !isNil(rangeResponse) {
-		resp = fmt.Sprintf("range_response_count:%d size:%d", len(rangeResponse.Kvs), proto.Size(rangeResponse))
-	}
-	warnOfExpensiveGenericRequest(lg, now, reqStringer, "read-only range ", resp, err)
-}
-
-func warnOfExpensiveGenericRequest(lg *zap.Logger, now time.Time, reqStringer fmt.Stringer, prefix string, resp string, err error) {
-	d := time.Since(now)
-	if d > warnApplyDuration {
-		if lg != nil {
-			lg.Warn(
-				"apply request took too long",
-				zap.Duration("took", d),
-				zap.Duration("expected-duration", warnApplyDuration),
-				zap.String("prefix", prefix),
-				zap.String("request", reqStringer.String()),
-				zap.String("response", resp),
-				zap.Error(err),
-			)
-		} else {
-			var result string
-			if err != nil {
-				result = fmt.Sprintf("error:%v", err)
-			} else {
-				result = resp
-			}
-			plog.Warningf("%srequest %q with result %q took too long (%v) to execute", prefix, reqStringer.String(), result, d)
-		}
-		slowApplies.Inc()
-	}
-}
-
-func isNil(msg proto.Message) bool {
-	return msg == nil || reflect.ValueOf(msg).IsNil()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/v2_server.go b/vendor/go.etcd.io/etcd/etcdserver/v2_server.go
deleted file mode 100644
index 9238b2d..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/v2_server.go
+++ /dev/null
@@ -1,165 +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 etcdserver
-
-import (
-	"context"
-	"time"
-
-	"go.etcd.io/etcd/etcdserver/api/v2store"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-)
-
-type RequestV2 pb.Request
-
-type RequestV2Handler interface {
-	Post(ctx context.Context, r *RequestV2) (Response, error)
-	Put(ctx context.Context, r *RequestV2) (Response, error)
-	Delete(ctx context.Context, r *RequestV2) (Response, error)
-	QGet(ctx context.Context, r *RequestV2) (Response, error)
-	Get(ctx context.Context, r *RequestV2) (Response, error)
-	Head(ctx context.Context, r *RequestV2) (Response, error)
-}
-
-type reqV2HandlerEtcdServer struct {
-	reqV2HandlerStore
-	s *EtcdServer
-}
-
-type reqV2HandlerStore struct {
-	store   v2store.Store
-	applier ApplierV2
-}
-
-func NewStoreRequestV2Handler(s v2store.Store, applier ApplierV2) RequestV2Handler {
-	return &reqV2HandlerStore{s, applier}
-}
-
-func (a *reqV2HandlerStore) Post(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Post(r), nil
-}
-
-func (a *reqV2HandlerStore) Put(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Put(r), nil
-}
-
-func (a *reqV2HandlerStore) Delete(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.Delete(r), nil
-}
-
-func (a *reqV2HandlerStore) QGet(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.applier.QGet(r), nil
-}
-
-func (a *reqV2HandlerStore) Get(ctx context.Context, r *RequestV2) (Response, error) {
-	if r.Wait {
-		wc, err := a.store.Watch(r.Path, r.Recursive, r.Stream, r.Since)
-		return Response{Watcher: wc}, err
-	}
-	ev, err := a.store.Get(r.Path, r.Recursive, r.Sorted)
-	return Response{Event: ev}, err
-}
-
-func (a *reqV2HandlerStore) Head(ctx context.Context, r *RequestV2) (Response, error) {
-	ev, err := a.store.Get(r.Path, r.Recursive, r.Sorted)
-	return Response{Event: ev}, err
-}
-
-func (a *reqV2HandlerEtcdServer) Post(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) Put(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) Delete(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) QGet(ctx context.Context, r *RequestV2) (Response, error) {
-	return a.processRaftRequest(ctx, r)
-}
-
-func (a *reqV2HandlerEtcdServer) processRaftRequest(ctx context.Context, r *RequestV2) (Response, error) {
-	data, err := ((*pb.Request)(r)).Marshal()
-	if err != nil {
-		return Response{}, err
-	}
-	ch := a.s.w.Register(r.ID)
-
-	start := time.Now()
-	a.s.r.Propose(ctx, data)
-	proposalsPending.Inc()
-	defer proposalsPending.Dec()
-
-	select {
-	case x := <-ch:
-		resp := x.(Response)
-		return resp, resp.Err
-	case <-ctx.Done():
-		proposalsFailed.Inc()
-		a.s.w.Trigger(r.ID, nil) // GC wait
-		return Response{}, a.s.parseProposeCtxErr(ctx.Err(), start)
-	case <-a.s.stopping:
-	}
-	return Response{}, ErrStopped
-}
-
-func (s *EtcdServer) Do(ctx context.Context, r pb.Request) (Response, error) {
-	r.ID = s.reqIDGen.Next()
-	h := &reqV2HandlerEtcdServer{
-		reqV2HandlerStore: reqV2HandlerStore{
-			store:   s.v2store,
-			applier: s.applyV2,
-		},
-		s: s,
-	}
-	rp := &r
-	resp, err := ((*RequestV2)(rp)).Handle(ctx, h)
-	resp.Term, resp.Index = s.Term(), s.CommittedIndex()
-	return resp, err
-}
-
-// Handle interprets r and performs an operation on s.store according to r.Method
-// and other fields. If r.Method is "POST", "PUT", "DELETE", or a "GET" with
-// Quorum == true, r will be sent through consensus before performing its
-// respective operation. Do will block until an action is performed or there is
-// an error.
-func (r *RequestV2) Handle(ctx context.Context, v2api RequestV2Handler) (Response, error) {
-	if r.Method == "GET" && r.Quorum {
-		r.Method = "QGET"
-	}
-	switch r.Method {
-	case "POST":
-		return v2api.Post(ctx, r)
-	case "PUT":
-		return v2api.Put(ctx, r)
-	case "DELETE":
-		return v2api.Delete(ctx, r)
-	case "QGET":
-		return v2api.QGet(ctx, r)
-	case "GET":
-		return v2api.Get(ctx, r)
-	case "HEAD":
-		return v2api.Head(ctx, r)
-	}
-	return Response{}, ErrUnknownMethod
-}
-
-func (r *RequestV2) String() string {
-	rpb := pb.Request(*r)
-	return rpb.String()
-}
diff --git a/vendor/go.etcd.io/etcd/etcdserver/v3_server.go b/vendor/go.etcd.io/etcd/etcdserver/v3_server.go
deleted file mode 100644
index b208461..0000000
--- a/vendor/go.etcd.io/etcd/etcdserver/v3_server.go
+++ /dev/null
@@ -1,768 +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 etcdserver
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"time"
-
-	"go.etcd.io/etcd/auth"
-	"go.etcd.io/etcd/etcdserver/api/membership"
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/lease/leasehttp"
-	"go.etcd.io/etcd/mvcc"
-	"go.etcd.io/etcd/raft"
-
-	"github.com/gogo/protobuf/proto"
-	"go.uber.org/zap"
-)
-
-const (
-	// In the health case, there might be a small gap (10s of entries) between
-	// the applied index and committed index.
-	// However, if the committed entries are very heavy to apply, the gap might grow.
-	// We should stop accepting new proposals if the gap growing to a certain point.
-	maxGapBetweenApplyAndCommitIndex = 5000
-)
-
-type RaftKV interface {
-	Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error)
-	Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error)
-	DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error)
-	Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error)
-	Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error)
-}
-
-type Lessor interface {
-	// LeaseGrant sends LeaseGrant request to raft and apply it after committed.
-	LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error)
-	// LeaseRevoke sends LeaseRevoke request to raft and apply it after committed.
-	LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error)
-
-	// LeaseRenew renews the lease with given ID. The renewed TTL is returned. Or an error
-	// is returned.
-	LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error)
-
-	// LeaseTimeToLive retrieves lease information.
-	LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error)
-
-	// LeaseLeases lists all leases.
-	LeaseLeases(ctx context.Context, r *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error)
-}
-
-type Authenticator interface {
-	AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error)
-	AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error)
-	Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error)
-	UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error)
-	UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error)
-	UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error)
-	UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error)
-	UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error)
-	UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error)
-	RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error)
-	RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error)
-	RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error)
-	RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error)
-	RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error)
-	UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error)
-	RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error)
-}
-
-func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) {
-	var resp *pb.RangeResponse
-	var err error
-	defer func(start time.Time) {
-		warnOfExpensiveReadOnlyRangeRequest(s.getLogger(), start, r, resp, err)
-	}(time.Now())
-
-	if !r.Serializable {
-		err = s.linearizableReadNotify(ctx)
-		if err != nil {
-			return nil, err
-		}
-	}
-	chk := func(ai *auth.AuthInfo) error {
-		return s.authStore.IsRangePermitted(ai, r.Key, r.RangeEnd)
-	}
-
-	get := func() { resp, err = s.applyV3Base.Range(nil, r) }
-	if serr := s.doSerialize(ctx, chk, get); serr != nil {
-		err = serr
-		return nil, err
-	}
-	return resp, err
-}
-
-func (s *EtcdServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{Put: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.PutResponse), nil
-}
-
-func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{DeleteRange: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.DeleteRangeResponse), nil
-}
-
-func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) {
-	if isTxnReadonly(r) {
-		if !isTxnSerializable(r) {
-			err := s.linearizableReadNotify(ctx)
-			if err != nil {
-				return nil, err
-			}
-		}
-		var resp *pb.TxnResponse
-		var err error
-		chk := func(ai *auth.AuthInfo) error {
-			return checkTxnAuth(s.authStore, ai, r)
-		}
-
-		defer func(start time.Time) {
-			warnOfExpensiveReadOnlyTxnRequest(s.getLogger(), start, r, resp, err)
-		}(time.Now())
-
-		get := func() { resp, err = s.applyV3Base.Txn(r) }
-		if serr := s.doSerialize(ctx, chk, get); serr != nil {
-			return nil, serr
-		}
-		return resp, err
-	}
-
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{Txn: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.TxnResponse), nil
-}
-
-func isTxnSerializable(r *pb.TxnRequest) bool {
-	for _, u := range r.Success {
-		if r := u.GetRequestRange(); r == nil || !r.Serializable {
-			return false
-		}
-	}
-	for _, u := range r.Failure {
-		if r := u.GetRequestRange(); r == nil || !r.Serializable {
-			return false
-		}
-	}
-	return true
-}
-
-func isTxnReadonly(r *pb.TxnRequest) bool {
-	for _, u := range r.Success {
-		if r := u.GetRequestRange(); r == nil {
-			return false
-		}
-	}
-	for _, u := range r.Failure {
-		if r := u.GetRequestRange(); r == nil {
-			return false
-		}
-	}
-	return true
-}
-
-func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) {
-	result, err := s.processInternalRaftRequestOnce(ctx, pb.InternalRaftRequest{Compaction: r})
-	if r.Physical && result != nil && result.physc != nil {
-		<-result.physc
-		// The compaction is done deleting keys; the hash is now settled
-		// but the data is not necessarily committed. If there's a crash,
-		// the hash may revert to a hash prior to compaction completing
-		// if the compaction resumes. Force the finished compaction to
-		// commit so it won't resume following a crash.
-		s.be.ForceCommit()
-	}
-	if err != nil {
-		return nil, err
-	}
-	if result.err != nil {
-		return nil, result.err
-	}
-	resp := result.resp.(*pb.CompactionResponse)
-	if resp == nil {
-		resp = &pb.CompactionResponse{}
-	}
-	if resp.Header == nil {
-		resp.Header = &pb.ResponseHeader{}
-	}
-	resp.Header.Revision = s.kv.Rev()
-	return resp, nil
-}
-
-func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) {
-	// no id given? choose one
-	for r.ID == int64(lease.NoLease) {
-		// only use positive int64 id's
-		r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1))
-	}
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseGrant: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.LeaseGrantResponse), nil
-}
-
-func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{LeaseRevoke: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.LeaseRevokeResponse), nil
-}
-
-func (s *EtcdServer) LeaseRenew(ctx context.Context, id lease.LeaseID) (int64, error) {
-	ttl, err := s.lessor.Renew(id)
-	if err == nil { // already requested to primary lessor(leader)
-		return ttl, nil
-	}
-	if err != lease.ErrNotPrimary {
-		return -1, err
-	}
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	// renewals don't go through raft; forward to leader manually
-	for cctx.Err() == nil && err != nil {
-		leader, lerr := s.waitLeader(cctx)
-		if lerr != nil {
-			return -1, lerr
-		}
-		for _, url := range leader.PeerURLs {
-			lurl := url + leasehttp.LeasePrefix
-			ttl, err = leasehttp.RenewHTTP(cctx, id, lurl, s.peerRt)
-			if err == nil || err == lease.ErrLeaseNotFound {
-				return ttl, err
-			}
-		}
-	}
-
-	if cctx.Err() == context.DeadlineExceeded {
-		return -1, ErrTimeout
-	}
-	return -1, ErrCanceled
-}
-
-func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveRequest) (*pb.LeaseTimeToLiveResponse, error) {
-	if s.Leader() == s.ID() {
-		// primary; timetolive directly from leader
-		le := s.lessor.Lookup(lease.LeaseID(r.ID))
-		if le == nil {
-			return nil, lease.ErrLeaseNotFound
-		}
-		// TODO: fill out ResponseHeader
-		resp := &pb.LeaseTimeToLiveResponse{Header: &pb.ResponseHeader{}, ID: r.ID, TTL: int64(le.Remaining().Seconds()), GrantedTTL: le.TTL()}
-		if r.Keys {
-			ks := le.Keys()
-			kbs := make([][]byte, len(ks))
-			for i := range ks {
-				kbs[i] = []byte(ks[i])
-			}
-			resp.Keys = kbs
-		}
-		return resp, nil
-	}
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	// forward to leader
-	for cctx.Err() == nil {
-		leader, err := s.waitLeader(cctx)
-		if err != nil {
-			return nil, err
-		}
-		for _, url := range leader.PeerURLs {
-			lurl := url + leasehttp.LeaseInternalPrefix
-			resp, err := leasehttp.TimeToLiveHTTP(cctx, lease.LeaseID(r.ID), r.Keys, lurl, s.peerRt)
-			if err == nil {
-				return resp.LeaseTimeToLiveResponse, nil
-			}
-			if err == lease.ErrLeaseNotFound {
-				return nil, err
-			}
-		}
-	}
-
-	if cctx.Err() == context.DeadlineExceeded {
-		return nil, ErrTimeout
-	}
-	return nil, ErrCanceled
-}
-
-func (s *EtcdServer) LeaseLeases(ctx context.Context, r *pb.LeaseLeasesRequest) (*pb.LeaseLeasesResponse, error) {
-	ls := s.lessor.Leases()
-	lss := make([]*pb.LeaseStatus, len(ls))
-	for i := range ls {
-		lss[i] = &pb.LeaseStatus{ID: int64(ls[i].ID)}
-	}
-	return &pb.LeaseLeasesResponse{Header: newHeader(s), Leases: lss}, nil
-}
-
-func (s *EtcdServer) waitLeader(ctx context.Context) (*membership.Member, error) {
-	leader := s.cluster.Member(s.Leader())
-	for leader == nil {
-		// wait an election
-		dur := time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond
-		select {
-		case <-time.After(dur):
-			leader = s.cluster.Member(s.Leader())
-		case <-s.stopping:
-			return nil, ErrStopped
-		case <-ctx.Done():
-			return nil, ErrNoLeader
-		}
-	}
-	if leader == nil || len(leader.PeerURLs) == 0 {
-		return nil, ErrNoLeader
-	}
-	return leader, nil
-}
-
-func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{Alarm: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AlarmResponse), nil
-}
-
-func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) {
-	resp, err := s.raftRequestOnce(ctx, pb.InternalRaftRequest{AuthEnable: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthEnableResponse), nil
-}
-
-func (s *EtcdServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthDisable: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthDisableResponse), nil
-}
-
-func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
-	if err := s.linearizableReadNotify(ctx); err != nil {
-		return nil, err
-	}
-
-	lg := s.getLogger()
-
-	var resp proto.Message
-	for {
-		checkedRevision, err := s.AuthStore().CheckPassword(r.Name, r.Password)
-		if err != nil {
-			if err != auth.ErrAuthNotEnabled {
-				if lg != nil {
-					lg.Warn(
-						"invalid authentication was requested",
-						zap.String("user", r.Name),
-						zap.Error(err),
-					)
-				} else {
-					plog.Errorf("invalid authentication request to user %s was issued", r.Name)
-				}
-			}
-			return nil, err
-		}
-
-		st, err := s.AuthStore().GenTokenPrefix()
-		if err != nil {
-			return nil, err
-		}
-
-		internalReq := &pb.InternalAuthenticateRequest{
-			Name:        r.Name,
-			Password:    r.Password,
-			SimpleToken: st,
-		}
-
-		resp, err = s.raftRequestOnce(ctx, pb.InternalRaftRequest{Authenticate: internalReq})
-		if err != nil {
-			return nil, err
-		}
-		if checkedRevision == s.AuthStore().Revision() {
-			break
-		}
-
-		if lg != nil {
-			lg.Info("revision when password checked became stale; retrying")
-		} else {
-			plog.Infof("revision when password checked is obsolete, retrying")
-		}
-	}
-
-	return resp.(*pb.AuthenticateResponse), nil
-}
-
-func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserAddResponse), nil
-}
-
-func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserDeleteResponse), nil
-}
-
-func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserChangePasswordResponse), nil
-}
-
-func (s *EtcdServer) UserGrantRole(ctx context.Context, r *pb.AuthUserGrantRoleRequest) (*pb.AuthUserGrantRoleResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserGrantRole: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserGrantRoleResponse), nil
-}
-
-func (s *EtcdServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserGet: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserGetResponse), nil
-}
-
-func (s *EtcdServer) UserList(ctx context.Context, r *pb.AuthUserListRequest) (*pb.AuthUserListResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserList: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserListResponse), nil
-}
-
-func (s *EtcdServer) UserRevokeRole(ctx context.Context, r *pb.AuthUserRevokeRoleRequest) (*pb.AuthUserRevokeRoleResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserRevokeRole: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthUserRevokeRoleResponse), nil
-}
-
-func (s *EtcdServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleAdd: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleAddResponse), nil
-}
-
-func (s *EtcdServer) RoleGrantPermission(ctx context.Context, r *pb.AuthRoleGrantPermissionRequest) (*pb.AuthRoleGrantPermissionResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleGrantPermission: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleGrantPermissionResponse), nil
-}
-
-func (s *EtcdServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleGet: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleGetResponse), nil
-}
-
-func (s *EtcdServer) RoleList(ctx context.Context, r *pb.AuthRoleListRequest) (*pb.AuthRoleListResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleList: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleListResponse), nil
-}
-
-func (s *EtcdServer) RoleRevokePermission(ctx context.Context, r *pb.AuthRoleRevokePermissionRequest) (*pb.AuthRoleRevokePermissionResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleRevokePermission: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleRevokePermissionResponse), nil
-}
-
-func (s *EtcdServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) {
-	resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthRoleDelete: r})
-	if err != nil {
-		return nil, err
-	}
-	return resp.(*pb.AuthRoleDeleteResponse), nil
-}
-
-func (s *EtcdServer) raftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (proto.Message, error) {
-	result, err := s.processInternalRaftRequestOnce(ctx, r)
-	if err != nil {
-		return nil, err
-	}
-	if result.err != nil {
-		return nil, result.err
-	}
-	return result.resp, nil
-}
-
-func (s *EtcdServer) raftRequest(ctx context.Context, r pb.InternalRaftRequest) (proto.Message, error) {
-	for {
-		resp, err := s.raftRequestOnce(ctx, r)
-		if err != auth.ErrAuthOldRevision {
-			return resp, err
-		}
-	}
-}
-
-// doSerialize handles the auth logic, with permissions checked by "chk", for a serialized request "get". Returns a non-nil error on authentication failure.
-func (s *EtcdServer) doSerialize(ctx context.Context, chk func(*auth.AuthInfo) error, get func()) error {
-	ai, err := s.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return err
-	}
-	if ai == nil {
-		// chk expects non-nil AuthInfo; use empty credentials
-		ai = &auth.AuthInfo{}
-	}
-	if err = chk(ai); err != nil {
-		return err
-	}
-	// fetch response for serialized request
-	get()
-	// check for stale token revision in case the auth store was updated while
-	// the request has been handled.
-	if ai.Revision != 0 && ai.Revision != s.authStore.Revision() {
-		return auth.ErrAuthOldRevision
-	}
-	return nil
-}
-
-func (s *EtcdServer) processInternalRaftRequestOnce(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) {
-	ai := s.getAppliedIndex()
-	ci := s.getCommittedIndex()
-	if ci > ai+maxGapBetweenApplyAndCommitIndex {
-		return nil, ErrTooManyRequests
-	}
-
-	r.Header = &pb.RequestHeader{
-		ID: s.reqIDGen.Next(),
-	}
-
-	authInfo, err := s.AuthInfoFromCtx(ctx)
-	if err != nil {
-		return nil, err
-	}
-	if authInfo != nil {
-		r.Header.Username = authInfo.Username
-		r.Header.AuthRevision = authInfo.Revision
-	}
-
-	data, err := r.Marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	if len(data) > int(s.Cfg.MaxRequestBytes) {
-		return nil, ErrRequestTooLarge
-	}
-
-	id := r.ID
-	if id == 0 {
-		id = r.Header.ID
-	}
-	ch := s.w.Register(id)
-
-	cctx, cancel := context.WithTimeout(ctx, s.Cfg.ReqTimeout())
-	defer cancel()
-
-	start := time.Now()
-	err = s.r.Propose(cctx, data)
-	if err != nil {
-		proposalsFailed.Inc()
-		s.w.Trigger(id, nil) // GC wait
-		return nil, err
-	}
-	proposalsPending.Inc()
-	defer proposalsPending.Dec()
-
-	select {
-	case x := <-ch:
-		return x.(*applyResult), nil
-	case <-cctx.Done():
-		proposalsFailed.Inc()
-		s.w.Trigger(id, nil) // GC wait
-		return nil, s.parseProposeCtxErr(cctx.Err(), start)
-	case <-s.done:
-		return nil, ErrStopped
-	}
-}
-
-// Watchable returns a watchable interface attached to the etcdserver.
-func (s *EtcdServer) Watchable() mvcc.WatchableKV { return s.KV() }
-
-func (s *EtcdServer) linearizableReadLoop() {
-	var rs raft.ReadState
-
-	for {
-		ctxToSend := make([]byte, 8)
-		id1 := s.reqIDGen.Next()
-		binary.BigEndian.PutUint64(ctxToSend, id1)
-		leaderChangedNotifier := s.leaderChangedNotify()
-		select {
-		case <-leaderChangedNotifier:
-			continue
-		case <-s.readwaitc:
-		case <-s.stopping:
-			return
-		}
-
-		nextnr := newNotifier()
-
-		s.readMu.Lock()
-		nr := s.readNotifier
-		s.readNotifier = nextnr
-		s.readMu.Unlock()
-
-		lg := s.getLogger()
-		cctx, cancel := context.WithTimeout(context.Background(), s.Cfg.ReqTimeout())
-		if err := s.r.ReadIndex(cctx, ctxToSend); err != nil {
-			cancel()
-			if err == raft.ErrStopped {
-				return
-			}
-			if lg != nil {
-				lg.Warn("failed to get read index from Raft", zap.Error(err))
-			} else {
-				plog.Errorf("failed to get read index from raft: %v", err)
-			}
-			readIndexFailed.Inc()
-			nr.notify(err)
-			continue
-		}
-		cancel()
-
-		var (
-			timeout bool
-			done    bool
-		)
-		for !timeout && !done {
-			select {
-			case rs = <-s.r.readStateC:
-				done = bytes.Equal(rs.RequestCtx, ctxToSend)
-				if !done {
-					// a previous request might time out. now we should ignore the response of it and
-					// continue waiting for the response of the current requests.
-					id2 := uint64(0)
-					if len(rs.RequestCtx) == 8 {
-						id2 = binary.BigEndian.Uint64(rs.RequestCtx)
-					}
-					if lg != nil {
-						lg.Warn(
-							"ignored out-of-date read index response; local node read indexes queueing up and waiting to be in sync with leader",
-							zap.Uint64("sent-request-id", id1),
-							zap.Uint64("received-request-id", id2),
-						)
-					} else {
-						plog.Warningf("ignored out-of-date read index response; local node read indexes queueing up and waiting to be in sync with leader (request ID want %d, got %d)", id1, id2)
-					}
-					slowReadIndex.Inc()
-				}
-			case <-leaderChangedNotifier:
-				timeout = true
-				readIndexFailed.Inc()
-				// return a retryable error.
-				nr.notify(ErrLeaderChanged)
-			case <-time.After(s.Cfg.ReqTimeout()):
-				if lg != nil {
-					lg.Warn("timed out waiting for read index response (local node might have slow network)", zap.Duration("timeout", s.Cfg.ReqTimeout()))
-				} else {
-					plog.Warningf("timed out waiting for read index response (local node might have slow network)")
-				}
-				nr.notify(ErrTimeout)
-				timeout = true
-				slowReadIndex.Inc()
-			case <-s.stopping:
-				return
-			}
-		}
-		if !done {
-			continue
-		}
-
-		if ai := s.getAppliedIndex(); ai < rs.Index {
-			select {
-			case <-s.applyWait.Wait(rs.Index):
-			case <-s.stopping:
-				return
-			}
-		}
-		// unblock all l-reads requested at indices before rs.Index
-		nr.notify(nil)
-	}
-}
-
-func (s *EtcdServer) linearizableReadNotify(ctx context.Context) error {
-	s.readMu.RLock()
-	nc := s.readNotifier
-	s.readMu.RUnlock()
-
-	// signal linearizable loop for current notify if it hasn't been already
-	select {
-	case s.readwaitc <- struct{}{}:
-	default:
-	}
-
-	// wait for read state notification
-	select {
-	case <-nc.c:
-		return nc.err
-	case <-ctx.Done():
-		return ctx.Err()
-	case <-s.done:
-		return ErrStopped
-	}
-}
-
-func (s *EtcdServer) AuthInfoFromCtx(ctx context.Context) (*auth.AuthInfo, error) {
-	authInfo, err := s.AuthStore().AuthInfoFromCtx(ctx)
-	if authInfo != nil || err != nil {
-		return authInfo, err
-	}
-	if !s.Cfg.ClientCertAuthEnabled {
-		return nil, nil
-	}
-	authInfo = s.AuthStore().AuthInfoFromTLS(ctx)
-	return authInfo, nil
-
-}
diff --git a/vendor/go.etcd.io/etcd/lease/doc.go b/vendor/go.etcd.io/etcd/lease/doc.go
deleted file mode 100644
index a74eaf7..0000000
--- a/vendor/go.etcd.io/etcd/lease/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 lease provides an interface and implementation for time-limited leases over arbitrary resources.
-package lease
diff --git a/vendor/go.etcd.io/etcd/lease/lease_queue.go b/vendor/go.etcd.io/etcd/lease/lease_queue.go
deleted file mode 100644
index 17ddb35..0000000
--- a/vendor/go.etcd.io/etcd/lease/lease_queue.go
+++ /dev/null
@@ -1,106 +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 lease
-
-import "container/heap"
-
-// LeaseWithTime contains lease object with a time.
-// For the lessor's lease heap, time identifies the lease expiration time.
-// For the lessor's lease checkpoint heap, the time identifies the next lease checkpoint time.
-type LeaseWithTime struct {
-	id LeaseID
-	// Unix nanos timestamp.
-	time  int64
-	index int
-}
-
-type LeaseQueue []*LeaseWithTime
-
-func (pq LeaseQueue) Len() int { return len(pq) }
-
-func (pq LeaseQueue) Less(i, j int) bool {
-	return pq[i].time < pq[j].time
-}
-
-func (pq LeaseQueue) Swap(i, j int) {
-	pq[i], pq[j] = pq[j], pq[i]
-	pq[i].index = i
-	pq[j].index = j
-}
-
-func (pq *LeaseQueue) Push(x interface{}) {
-	n := len(*pq)
-	item := x.(*LeaseWithTime)
-	item.index = n
-	*pq = append(*pq, item)
-}
-
-func (pq *LeaseQueue) Pop() interface{} {
-	old := *pq
-	n := len(old)
-	item := old[n-1]
-	item.index = -1 // for safety
-	*pq = old[0 : n-1]
-	return item
-}
-
-// LeaseExpiredNotifier is a queue used to notify lessor to revoke expired lease.
-// Only save one item for a lease, `Register` will update time of the corresponding lease.
-type LeaseExpiredNotifier struct {
-	m     map[LeaseID]*LeaseWithTime
-	queue LeaseQueue
-}
-
-func newLeaseExpiredNotifier() *LeaseExpiredNotifier {
-	return &LeaseExpiredNotifier{
-		m:     make(map[LeaseID]*LeaseWithTime),
-		queue: make(LeaseQueue, 0),
-	}
-}
-
-func (mq *LeaseExpiredNotifier) Init() {
-	heap.Init(&mq.queue)
-	mq.m = make(map[LeaseID]*LeaseWithTime)
-	for _, item := range mq.queue {
-		mq.m[item.id] = item
-	}
-}
-
-func (mq *LeaseExpiredNotifier) RegisterOrUpdate(item *LeaseWithTime) {
-	if old, ok := mq.m[item.id]; ok {
-		old.time = item.time
-		heap.Fix(&mq.queue, old.index)
-	} else {
-		heap.Push(&mq.queue, item)
-		mq.m[item.id] = item
-	}
-}
-
-func (mq *LeaseExpiredNotifier) Unregister() *LeaseWithTime {
-	item := heap.Pop(&mq.queue).(*LeaseWithTime)
-	delete(mq.m, item.id)
-	return item
-}
-
-func (mq *LeaseExpiredNotifier) Poll() *LeaseWithTime {
-	if mq.Len() == 0 {
-		return nil
-	}
-	return mq.queue[0]
-}
-
-func (mq *LeaseExpiredNotifier) Len() int {
-	return len(mq.m)
-}
diff --git a/vendor/go.etcd.io/etcd/lease/leasehttp/doc.go b/vendor/go.etcd.io/etcd/lease/leasehttp/doc.go
deleted file mode 100644
index 8177a37..0000000
--- a/vendor/go.etcd.io/etcd/lease/leasehttp/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 leasehttp serves lease renewals made through HTTP requests.
-package leasehttp
diff --git a/vendor/go.etcd.io/etcd/lease/leasehttp/http.go b/vendor/go.etcd.io/etcd/lease/leasehttp/http.go
deleted file mode 100644
index 67e916d..0000000
--- a/vendor/go.etcd.io/etcd/lease/leasehttp/http.go
+++ /dev/null
@@ -1,248 +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 leasehttp
-
-import (
-	"bytes"
-	"context"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"time"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/lease/leasepb"
-	"go.etcd.io/etcd/pkg/httputil"
-)
-
-var (
-	LeasePrefix         = "/leases"
-	LeaseInternalPrefix = "/leases/internal"
-	applyTimeout        = time.Second
-	ErrLeaseHTTPTimeout = errors.New("waiting for node to catch up its applied index has timed out")
-)
-
-// NewHandler returns an http Handler for lease renewals
-func NewHandler(l lease.Lessor, waitch func() <-chan struct{}) http.Handler {
-	return &leaseHandler{l, waitch}
-}
-
-type leaseHandler struct {
-	l      lease.Lessor
-	waitch func() <-chan struct{}
-}
-
-func (h *leaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
-		return
-	}
-
-	defer r.Body.Close()
-	b, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		http.Error(w, "error reading body", http.StatusBadRequest)
-		return
-	}
-
-	var v []byte
-	switch r.URL.Path {
-	case LeasePrefix:
-		lreq := pb.LeaseKeepAliveRequest{}
-		if uerr := lreq.Unmarshal(b); uerr != nil {
-			http.Error(w, "error unmarshalling request", http.StatusBadRequest)
-			return
-		}
-		select {
-		case <-h.waitch():
-		case <-time.After(applyTimeout):
-			http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout)
-			return
-		}
-		ttl, rerr := h.l.Renew(lease.LeaseID(lreq.ID))
-		if rerr != nil {
-			if rerr == lease.ErrLeaseNotFound {
-				http.Error(w, rerr.Error(), http.StatusNotFound)
-				return
-			}
-
-			http.Error(w, rerr.Error(), http.StatusBadRequest)
-			return
-		}
-		// TODO: fill out ResponseHeader
-		resp := &pb.LeaseKeepAliveResponse{ID: lreq.ID, TTL: ttl}
-		v, err = resp.Marshal()
-		if err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-	case LeaseInternalPrefix:
-		lreq := leasepb.LeaseInternalRequest{}
-		if lerr := lreq.Unmarshal(b); lerr != nil {
-			http.Error(w, "error unmarshalling request", http.StatusBadRequest)
-			return
-		}
-		select {
-		case <-h.waitch():
-		case <-time.After(applyTimeout):
-			http.Error(w, ErrLeaseHTTPTimeout.Error(), http.StatusRequestTimeout)
-			return
-		}
-		l := h.l.Lookup(lease.LeaseID(lreq.LeaseTimeToLiveRequest.ID))
-		if l == nil {
-			http.Error(w, lease.ErrLeaseNotFound.Error(), http.StatusNotFound)
-			return
-		}
-		// TODO: fill out ResponseHeader
-		resp := &leasepb.LeaseInternalResponse{
-			LeaseTimeToLiveResponse: &pb.LeaseTimeToLiveResponse{
-				Header:     &pb.ResponseHeader{},
-				ID:         lreq.LeaseTimeToLiveRequest.ID,
-				TTL:        int64(l.Remaining().Seconds()),
-				GrantedTTL: l.TTL(),
-			},
-		}
-		if lreq.LeaseTimeToLiveRequest.Keys {
-			ks := l.Keys()
-			kbs := make([][]byte, len(ks))
-			for i := range ks {
-				kbs[i] = []byte(ks[i])
-			}
-			resp.LeaseTimeToLiveResponse.Keys = kbs
-		}
-
-		v, err = resp.Marshal()
-		if err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
-			return
-		}
-
-	default:
-		http.Error(w, fmt.Sprintf("unknown request path %q", r.URL.Path), http.StatusBadRequest)
-		return
-	}
-
-	w.Header().Set("Content-Type", "application/protobuf")
-	w.Write(v)
-}
-
-// RenewHTTP renews a lease at a given primary server.
-// TODO: Batch request in future?
-func RenewHTTP(ctx context.Context, id lease.LeaseID, url string, rt http.RoundTripper) (int64, error) {
-	// will post lreq protobuf to leader
-	lreq, err := (&pb.LeaseKeepAliveRequest{ID: int64(id)}).Marshal()
-	if err != nil {
-		return -1, err
-	}
-
-	cc := &http.Client{Transport: rt}
-	req, err := http.NewRequest("POST", url, bytes.NewReader(lreq))
-	if err != nil {
-		return -1, err
-	}
-	req.Header.Set("Content-Type", "application/protobuf")
-	req.Cancel = ctx.Done()
-
-	resp, err := cc.Do(req)
-	if err != nil {
-		return -1, err
-	}
-	b, err := readResponse(resp)
-	if err != nil {
-		return -1, err
-	}
-
-	if resp.StatusCode == http.StatusRequestTimeout {
-		return -1, ErrLeaseHTTPTimeout
-	}
-
-	if resp.StatusCode == http.StatusNotFound {
-		return -1, lease.ErrLeaseNotFound
-	}
-
-	if resp.StatusCode != http.StatusOK {
-		return -1, fmt.Errorf("lease: unknown error(%s)", string(b))
-	}
-
-	lresp := &pb.LeaseKeepAliveResponse{}
-	if err := lresp.Unmarshal(b); err != nil {
-		return -1, fmt.Errorf(`lease: %v. data = "%s"`, err, string(b))
-	}
-	if lresp.ID != int64(id) {
-		return -1, fmt.Errorf("lease: renew id mismatch")
-	}
-	return lresp.TTL, nil
-}
-
-// TimeToLiveHTTP retrieves lease information of the given lease ID.
-func TimeToLiveHTTP(ctx context.Context, id lease.LeaseID, keys bool, url string, rt http.RoundTripper) (*leasepb.LeaseInternalResponse, error) {
-	// will post lreq protobuf to leader
-	lreq, err := (&leasepb.LeaseInternalRequest{
-		LeaseTimeToLiveRequest: &pb.LeaseTimeToLiveRequest{
-			ID:   int64(id),
-			Keys: keys,
-		},
-	}).Marshal()
-	if err != nil {
-		return nil, err
-	}
-
-	req, err := http.NewRequest("POST", url, bytes.NewReader(lreq))
-	if err != nil {
-		return nil, err
-	}
-	req.Header.Set("Content-Type", "application/protobuf")
-
-	req = req.WithContext(ctx)
-
-	cc := &http.Client{Transport: rt}
-	var b []byte
-	// buffer errc channel so that errc don't block inside the go routinue
-	resp, err := cc.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	b, err = readResponse(resp)
-	if err != nil {
-		return nil, err
-	}
-	if resp.StatusCode == http.StatusRequestTimeout {
-		return nil, ErrLeaseHTTPTimeout
-	}
-	if resp.StatusCode == http.StatusNotFound {
-		return nil, lease.ErrLeaseNotFound
-	}
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("lease: unknown error(%s)", string(b))
-	}
-
-	lresp := &leasepb.LeaseInternalResponse{}
-	if err := lresp.Unmarshal(b); err != nil {
-		return nil, fmt.Errorf(`lease: %v. data = "%s"`, err, string(b))
-	}
-	if lresp.LeaseTimeToLiveResponse.ID != int64(id) {
-		return nil, fmt.Errorf("lease: renew id mismatch")
-	}
-	return lresp, nil
-}
-
-func readResponse(resp *http.Response) (b []byte, err error) {
-	b, err = ioutil.ReadAll(resp.Body)
-	httputil.GracefulClose(resp)
-	return
-}
diff --git a/vendor/go.etcd.io/etcd/lease/leasepb/lease.pb.go b/vendor/go.etcd.io/etcd/lease/leasepb/lease.pb.go
deleted file mode 100644
index 16637ee..0000000
--- a/vendor/go.etcd.io/etcd/lease/leasepb/lease.pb.go
+++ /dev/null
@@ -1,620 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: lease.proto
-
-/*
-	Package leasepb is a generated protocol buffer package.
-
-	It is generated from these files:
-		lease.proto
-
-	It has these top-level messages:
-		Lease
-		LeaseInternalRequest
-		LeaseInternalResponse
-*/
-package leasepb
-
-import (
-	"fmt"
-
-	proto "github.com/golang/protobuf/proto"
-
-	math "math"
-
-	_ "github.com/gogo/protobuf/gogoproto"
-
-	etcdserverpb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	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 Lease struct {
-	ID           int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
-	TTL          int64 `protobuf:"varint,2,opt,name=TTL,proto3" json:"TTL,omitempty"`
-	RemainingTTL int64 `protobuf:"varint,3,opt,name=RemainingTTL,proto3" json:"RemainingTTL,omitempty"`
-}
-
-func (m *Lease) Reset()                    { *m = Lease{} }
-func (m *Lease) String() string            { return proto.CompactTextString(m) }
-func (*Lease) ProtoMessage()               {}
-func (*Lease) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{0} }
-
-type LeaseInternalRequest struct {
-	LeaseTimeToLiveRequest *etcdserverpb.LeaseTimeToLiveRequest `protobuf:"bytes,1,opt,name=LeaseTimeToLiveRequest" json:"LeaseTimeToLiveRequest,omitempty"`
-}
-
-func (m *LeaseInternalRequest) Reset()                    { *m = LeaseInternalRequest{} }
-func (m *LeaseInternalRequest) String() string            { return proto.CompactTextString(m) }
-func (*LeaseInternalRequest) ProtoMessage()               {}
-func (*LeaseInternalRequest) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{1} }
-
-type LeaseInternalResponse struct {
-	LeaseTimeToLiveResponse *etcdserverpb.LeaseTimeToLiveResponse `protobuf:"bytes,1,opt,name=LeaseTimeToLiveResponse" json:"LeaseTimeToLiveResponse,omitempty"`
-}
-
-func (m *LeaseInternalResponse) Reset()                    { *m = LeaseInternalResponse{} }
-func (m *LeaseInternalResponse) String() string            { return proto.CompactTextString(m) }
-func (*LeaseInternalResponse) ProtoMessage()               {}
-func (*LeaseInternalResponse) Descriptor() ([]byte, []int) { return fileDescriptorLease, []int{2} }
-
-func init() {
-	proto.RegisterType((*Lease)(nil), "leasepb.Lease")
-	proto.RegisterType((*LeaseInternalRequest)(nil), "leasepb.LeaseInternalRequest")
-	proto.RegisterType((*LeaseInternalResponse)(nil), "leasepb.LeaseInternalResponse")
-}
-func (m *Lease) 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 *Lease) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.ID != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintLease(dAtA, i, uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintLease(dAtA, i, uint64(m.TTL))
-	}
-	if m.RemainingTTL != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintLease(dAtA, i, uint64(m.RemainingTTL))
-	}
-	return i, nil
-}
-
-func (m *LeaseInternalRequest) 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 *LeaseInternalRequest) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.LeaseTimeToLiveRequest != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintLease(dAtA, i, uint64(m.LeaseTimeToLiveRequest.Size()))
-		n1, err := m.LeaseTimeToLiveRequest.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	return i, nil
-}
-
-func (m *LeaseInternalResponse) 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 *LeaseInternalResponse) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.LeaseTimeToLiveResponse != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintLease(dAtA, i, uint64(m.LeaseTimeToLiveResponse.Size()))
-		n2, err := m.LeaseTimeToLiveResponse.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	return i, nil
-}
-
-func encodeVarintLease(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 *Lease) Size() (n int) {
-	var l int
-	_ = l
-	if m.ID != 0 {
-		n += 1 + sovLease(uint64(m.ID))
-	}
-	if m.TTL != 0 {
-		n += 1 + sovLease(uint64(m.TTL))
-	}
-	if m.RemainingTTL != 0 {
-		n += 1 + sovLease(uint64(m.RemainingTTL))
-	}
-	return n
-}
-
-func (m *LeaseInternalRequest) Size() (n int) {
-	var l int
-	_ = l
-	if m.LeaseTimeToLiveRequest != nil {
-		l = m.LeaseTimeToLiveRequest.Size()
-		n += 1 + l + sovLease(uint64(l))
-	}
-	return n
-}
-
-func (m *LeaseInternalResponse) Size() (n int) {
-	var l int
-	_ = l
-	if m.LeaseTimeToLiveResponse != nil {
-		l = m.LeaseTimeToLiveResponse.Size()
-		n += 1 + l + sovLease(uint64(l))
-	}
-	return n
-}
-
-func sovLease(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozLease(x uint64) (n int) {
-	return sovLease(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *Lease) 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 ErrIntOverflowLease
-			}
-			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: Lease: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Lease: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowLease
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field TTL", wireType)
-			}
-			m.TTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowLease
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.TTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RemainingTTL", wireType)
-			}
-			m.RemainingTTL = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowLease
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RemainingTTL |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipLease(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthLease
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseInternalRequest) 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 ErrIntOverflowLease
-			}
-			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: LeaseInternalRequest: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseInternalRequest: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LeaseTimeToLiveRequest", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowLease
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthLease
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.LeaseTimeToLiveRequest == nil {
-				m.LeaseTimeToLiveRequest = &etcdserverpb.LeaseTimeToLiveRequest{}
-			}
-			if err := m.LeaseTimeToLiveRequest.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipLease(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthLease
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *LeaseInternalResponse) 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 ErrIntOverflowLease
-			}
-			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: LeaseInternalResponse: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: LeaseInternalResponse: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LeaseTimeToLiveResponse", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowLease
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthLease
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.LeaseTimeToLiveResponse == nil {
-				m.LeaseTimeToLiveResponse = &etcdserverpb.LeaseTimeToLiveResponse{}
-			}
-			if err := m.LeaseTimeToLiveResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipLease(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthLease
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipLease(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, ErrIntOverflowLease
-			}
-			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, ErrIntOverflowLease
-				}
-				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, ErrIntOverflowLease
-				}
-				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, ErrInvalidLengthLease
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowLease
-					}
-					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 := skipLease(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 (
-	ErrInvalidLengthLease = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowLease   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("lease.proto", fileDescriptorLease) }
-
-var fileDescriptorLease = []byte{
-	// 253 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x49, 0x4d, 0x2c,
-	0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x07, 0x73, 0x0a, 0x92, 0xa4, 0x44, 0xd2,
-	0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x4a, 0x2d, 0xb5, 0x24, 0x39, 0x45,
-	0x1f, 0x44, 0x14, 0xa7, 0x16, 0x95, 0xa5, 0x16, 0x21, 0x31, 0x0b, 0x92, 0xf4, 0x8b, 0x0a, 0x92,
-	0x21, 0xea, 0x94, 0x7c, 0xb9, 0x58, 0x7d, 0x40, 0x06, 0x09, 0xf1, 0x71, 0x31, 0x79, 0xba, 0x48,
-	0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0x31, 0x79, 0xba, 0x08, 0x09, 0x70, 0x31, 0x87, 0x84, 0xf8,
-	0x48, 0x30, 0x81, 0x05, 0x40, 0x4c, 0x21, 0x25, 0x2e, 0x9e, 0xa0, 0xd4, 0xdc, 0xc4, 0xcc, 0xbc,
-	0xcc, 0xbc, 0x74, 0x90, 0x14, 0x33, 0x58, 0x0a, 0x45, 0x4c, 0xa9, 0x84, 0x4b, 0x04, 0x6c, 0x9c,
-	0x67, 0x5e, 0x49, 0x6a, 0x51, 0x5e, 0x62, 0x4e, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x50,
-	0x0c, 0x97, 0x18, 0x58, 0x3c, 0x24, 0x33, 0x37, 0x35, 0x24, 0xdf, 0x27, 0xb3, 0x2c, 0x15, 0x2a,
-	0x03, 0xb6, 0x91, 0xdb, 0x48, 0x45, 0x0f, 0xd9, 0x7d, 0x7a, 0xd8, 0xd5, 0x06, 0xe1, 0x30, 0x43,
-	0xa9, 0x82, 0x4b, 0x14, 0xcd, 0xd6, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0xa1, 0x78, 0x2e, 0x71,
-	0x0c, 0x2d, 0x10, 0x29, 0xa8, 0xbd, 0xaa, 0x04, 0xec, 0x85, 0x28, 0x0e, 0xc2, 0x65, 0x8a, 0x93,
-	0xc4, 0x89, 0x87, 0x72, 0x0c, 0x17, 0x1e, 0xca, 0x31, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91,
-	0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81, 0xc3, 0xd7, 0x18,
-	0x10, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x9f, 0x8b, 0x6c, 0xb5, 0x01, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/lease/leasepb/lease.proto b/vendor/go.etcd.io/etcd/lease/leasepb/lease.proto
deleted file mode 100644
index 1169d9f..0000000
--- a/vendor/go.etcd.io/etcd/lease/leasepb/lease.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-syntax = "proto3";
-package leasepb;
-
-import "gogoproto/gogo.proto";
-import "etcd/etcdserver/etcdserverpb/rpc.proto";
-
-option (gogoproto.marshaler_all) = true;
-option (gogoproto.sizer_all) = true;
-option (gogoproto.unmarshaler_all) = true;
-option (gogoproto.goproto_getters_all) = false;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-message Lease {
-  int64 ID = 1;
-  int64 TTL = 2;
-  int64 RemainingTTL = 3;
-}
-
-message LeaseInternalRequest {
-  etcdserverpb.LeaseTimeToLiveRequest LeaseTimeToLiveRequest = 1;
-}
-
-message LeaseInternalResponse {
-  etcdserverpb.LeaseTimeToLiveResponse LeaseTimeToLiveResponse = 1;
-}
diff --git a/vendor/go.etcd.io/etcd/lease/lessor.go b/vendor/go.etcd.io/etcd/lease/lessor.go
deleted file mode 100644
index cc20283..0000000
--- a/vendor/go.etcd.io/etcd/lease/lessor.go
+++ /dev/null
@@ -1,933 +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 lease
-
-import (
-	"container/heap"
-	"context"
-	"encoding/binary"
-	"errors"
-	"math"
-	"sort"
-	"sync"
-	"time"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"go.etcd.io/etcd/lease/leasepb"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.uber.org/zap"
-)
-
-// NoLease is a special LeaseID representing the absence of a lease.
-const NoLease = LeaseID(0)
-
-// MaxLeaseTTL is the maximum lease TTL value
-const MaxLeaseTTL = 9000000000
-
-var (
-	forever = time.Time{}
-
-	leaseBucketName = []byte("lease")
-
-	// maximum number of leases to revoke per second; configurable for tests
-	leaseRevokeRate = 1000
-
-	// maximum number of lease checkpoints recorded to the consensus log per second; configurable for tests
-	leaseCheckpointRate = 1000
-
-	// the default interval of lease checkpoint
-	defaultLeaseCheckpointInterval = 5 * time.Minute
-
-	// maximum number of lease checkpoints to batch into a single consensus log entry
-	maxLeaseCheckpointBatchSize = 1000
-
-	// the default interval to check if the expired lease is revoked
-	defaultExpiredleaseRetryInterval = 3 * time.Second
-
-	ErrNotPrimary       = errors.New("not a primary lessor")
-	ErrLeaseNotFound    = errors.New("lease not found")
-	ErrLeaseExists      = errors.New("lease already exists")
-	ErrLeaseTTLTooLarge = errors.New("too large lease TTL")
-)
-
-// TxnDelete is a TxnWrite that only permits deletes. Defined here
-// to avoid circular dependency with mvcc.
-type TxnDelete interface {
-	DeleteRange(key, end []byte) (n, rev int64)
-	End()
-}
-
-// RangeDeleter is a TxnDelete constructor.
-type RangeDeleter func() TxnDelete
-
-// Checkpointer permits checkpointing of lease remaining TTLs to the consensus log. Defined here to
-// avoid circular dependency with mvcc.
-type Checkpointer func(ctx context.Context, lc *pb.LeaseCheckpointRequest)
-
-type LeaseID int64
-
-// Lessor owns leases. It can grant, revoke, renew and modify leases for lessee.
-type Lessor interface {
-	// SetRangeDeleter lets the lessor create TxnDeletes to the store.
-	// Lessor deletes the items in the revoked or expired lease by creating
-	// new TxnDeletes.
-	SetRangeDeleter(rd RangeDeleter)
-
-	SetCheckpointer(cp Checkpointer)
-
-	// Grant grants a lease that expires at least after TTL seconds.
-	Grant(id LeaseID, ttl int64) (*Lease, error)
-	// Revoke revokes a lease with given ID. The item attached to the
-	// given lease will be removed. If the ID does not exist, an error
-	// will be returned.
-	Revoke(id LeaseID) error
-
-	// Checkpoint applies the remainingTTL of a lease. The remainingTTL is used in Promote to set
-	// the expiry of leases to less than the full TTL when possible.
-	Checkpoint(id LeaseID, remainingTTL int64) error
-
-	// Attach attaches given leaseItem to the lease with given LeaseID.
-	// If the lease does not exist, an error will be returned.
-	Attach(id LeaseID, items []LeaseItem) error
-
-	// GetLease returns LeaseID for given item.
-	// If no lease found, NoLease value will be returned.
-	GetLease(item LeaseItem) LeaseID
-
-	// Detach detaches given leaseItem from the lease with given LeaseID.
-	// If the lease does not exist, an error will be returned.
-	Detach(id LeaseID, items []LeaseItem) error
-
-	// Promote promotes the lessor to be the primary lessor. Primary lessor manages
-	// the expiration and renew of leases.
-	// Newly promoted lessor renew the TTL of all lease to extend + previous TTL.
-	Promote(extend time.Duration)
-
-	// Demote demotes the lessor from being the primary lessor.
-	Demote()
-
-	// Renew renews a lease with given ID. It returns the renewed TTL. If the ID does not exist,
-	// an error will be returned.
-	Renew(id LeaseID) (int64, error)
-
-	// Lookup gives the lease at a given lease id, if any
-	Lookup(id LeaseID) *Lease
-
-	// Leases lists all leases.
-	Leases() []*Lease
-
-	// ExpiredLeasesC returns a chan that is used to receive expired leases.
-	ExpiredLeasesC() <-chan []*Lease
-
-	// Recover recovers the lessor state from the given backend and RangeDeleter.
-	Recover(b backend.Backend, rd RangeDeleter)
-
-	// Stop stops the lessor for managing leases. The behavior of calling Stop multiple
-	// times is undefined.
-	Stop()
-}
-
-// lessor implements Lessor interface.
-// TODO: use clockwork for testability.
-type lessor struct {
-	mu sync.RWMutex
-
-	// demotec is set when the lessor is the primary.
-	// demotec will be closed if the lessor is demoted.
-	demotec chan struct{}
-
-	leaseMap             map[LeaseID]*Lease
-	leaseExpiredNotifier *LeaseExpiredNotifier
-	leaseCheckpointHeap  LeaseQueue
-	itemMap              map[LeaseItem]LeaseID
-
-	// When a lease expires, the lessor will delete the
-	// leased range (or key) by the RangeDeleter.
-	rd RangeDeleter
-
-	// When a lease's deadline should be persisted to preserve the remaining TTL across leader
-	// elections and restarts, the lessor will checkpoint the lease by the Checkpointer.
-	cp Checkpointer
-
-	// backend to persist leases. We only persist lease ID and expiry for now.
-	// The leased items can be recovered by iterating all the keys in kv.
-	b backend.Backend
-
-	// minLeaseTTL is the minimum lease TTL that can be granted for a lease. Any
-	// requests for shorter TTLs are extended to the minimum TTL.
-	minLeaseTTL int64
-
-	expiredC chan []*Lease
-	// stopC is a channel whose closure indicates that the lessor should be stopped.
-	stopC chan struct{}
-	// doneC is a channel whose closure indicates that the lessor is stopped.
-	doneC chan struct{}
-
-	lg *zap.Logger
-
-	// Wait duration between lease checkpoints.
-	checkpointInterval time.Duration
-	// the interval to check if the expired lease is revoked
-	expiredLeaseRetryInterval time.Duration
-}
-
-type LessorConfig struct {
-	MinLeaseTTL                int64
-	CheckpointInterval         time.Duration
-	ExpiredLeasesRetryInterval time.Duration
-}
-
-func NewLessor(lg *zap.Logger, b backend.Backend, cfg LessorConfig) Lessor {
-	return newLessor(lg, b, cfg)
-}
-
-func newLessor(lg *zap.Logger, b backend.Backend, cfg LessorConfig) *lessor {
-	checkpointInterval := cfg.CheckpointInterval
-	expiredLeaseRetryInterval := cfg.ExpiredLeasesRetryInterval
-	if checkpointInterval == 0 {
-		checkpointInterval = defaultLeaseCheckpointInterval
-	}
-	if expiredLeaseRetryInterval == 0 {
-		expiredLeaseRetryInterval = defaultExpiredleaseRetryInterval
-	}
-	l := &lessor{
-		leaseMap:                  make(map[LeaseID]*Lease),
-		itemMap:                   make(map[LeaseItem]LeaseID),
-		leaseExpiredNotifier:      newLeaseExpiredNotifier(),
-		leaseCheckpointHeap:       make(LeaseQueue, 0),
-		b:                         b,
-		minLeaseTTL:               cfg.MinLeaseTTL,
-		checkpointInterval:        checkpointInterval,
-		expiredLeaseRetryInterval: expiredLeaseRetryInterval,
-		// expiredC is a small buffered chan to avoid unnecessary blocking.
-		expiredC: make(chan []*Lease, 16),
-		stopC:    make(chan struct{}),
-		doneC:    make(chan struct{}),
-		lg:       lg,
-	}
-	l.initAndRecover()
-
-	go l.runLoop()
-
-	return l
-}
-
-// isPrimary indicates if this lessor is the primary lessor. The primary
-// lessor manages lease expiration and renew.
-//
-// in etcd, raft leader is the primary. Thus there might be two primary
-// leaders at the same time (raft allows concurrent leader but with different term)
-// for at most a leader election timeout.
-// The old primary leader cannot affect the correctness since its proposal has a
-// smaller term and will not be committed.
-//
-// TODO: raft follower do not forward lease management proposals. There might be a
-// very small window (within second normally which depends on go scheduling) that
-// a raft follow is the primary between the raft leader demotion and lessor demotion.
-// Usually this should not be a problem. Lease should not be that sensitive to timing.
-func (le *lessor) isPrimary() bool {
-	return le.demotec != nil
-}
-
-func (le *lessor) SetRangeDeleter(rd RangeDeleter) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.rd = rd
-}
-
-func (le *lessor) SetCheckpointer(cp Checkpointer) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.cp = cp
-}
-
-func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) {
-	if id == NoLease {
-		return nil, ErrLeaseNotFound
-	}
-
-	if ttl > MaxLeaseTTL {
-		return nil, ErrLeaseTTLTooLarge
-	}
-
-	// TODO: when lessor is under high load, it should give out lease
-	// with longer TTL to reduce renew load.
-	l := &Lease{
-		ID:      id,
-		ttl:     ttl,
-		itemSet: make(map[LeaseItem]struct{}),
-		revokec: make(chan struct{}),
-	}
-
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	if _, ok := le.leaseMap[id]; ok {
-		return nil, ErrLeaseExists
-	}
-
-	if l.ttl < le.minLeaseTTL {
-		l.ttl = le.minLeaseTTL
-	}
-
-	if le.isPrimary() {
-		l.refresh(0)
-	} else {
-		l.forever()
-	}
-
-	le.leaseMap[id] = l
-	item := &LeaseWithTime{id: l.ID, time: l.expiry.UnixNano()}
-	le.leaseExpiredNotifier.RegisterOrUpdate(item)
-	l.persistTo(le.b)
-
-	leaseTotalTTLs.Observe(float64(l.ttl))
-	leaseGranted.Inc()
-
-	if le.isPrimary() {
-		le.scheduleCheckpointIfNeeded(l)
-	}
-
-	return l, nil
-}
-
-func (le *lessor) Revoke(id LeaseID) error {
-	le.mu.Lock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		le.mu.Unlock()
-		return ErrLeaseNotFound
-	}
-	defer close(l.revokec)
-	// unlock before doing external work
-	le.mu.Unlock()
-
-	if le.rd == nil {
-		return nil
-	}
-
-	txn := le.rd()
-
-	// sort keys so deletes are in same order among all members,
-	// otherwise the backend hashes will be different
-	keys := l.Keys()
-	sort.StringSlice(keys).Sort()
-	for _, key := range keys {
-		txn.DeleteRange([]byte(key), nil)
-	}
-
-	le.mu.Lock()
-	defer le.mu.Unlock()
-	delete(le.leaseMap, l.ID)
-	// lease deletion needs to be in the same backend transaction with the
-	// kv deletion. Or we might end up with not executing the revoke or not
-	// deleting the keys if etcdserver fails in between.
-	le.b.BatchTx().UnsafeDelete(leaseBucketName, int64ToBytes(int64(l.ID)))
-
-	txn.End()
-
-	leaseRevoked.Inc()
-	return nil
-}
-
-func (le *lessor) Checkpoint(id LeaseID, remainingTTL int64) error {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	if l, ok := le.leaseMap[id]; ok {
-		// when checkpointing, we only update the remainingTTL, Promote is responsible for applying this to lease expiry
-		l.remainingTTL = remainingTTL
-		if le.isPrimary() {
-			// schedule the next checkpoint as needed
-			le.scheduleCheckpointIfNeeded(l)
-		}
-	}
-	return nil
-}
-
-// Renew renews an existing lease. If the given lease does not exist or
-// has expired, an error will be returned.
-func (le *lessor) Renew(id LeaseID) (int64, error) {
-	le.mu.RLock()
-	if !le.isPrimary() {
-		// forward renew request to primary instead of returning error.
-		le.mu.RUnlock()
-		return -1, ErrNotPrimary
-	}
-
-	demotec := le.demotec
-
-	l := le.leaseMap[id]
-	if l == nil {
-		le.mu.RUnlock()
-		return -1, ErrLeaseNotFound
-	}
-	// Clear remaining TTL when we renew if it is set
-	clearRemainingTTL := le.cp != nil && l.remainingTTL > 0
-
-	le.mu.RUnlock()
-	if l.expired() {
-		select {
-		// A expired lease might be pending for revoking or going through
-		// quorum to be revoked. To be accurate, renew request must wait for the
-		// deletion to complete.
-		case <-l.revokec:
-			return -1, ErrLeaseNotFound
-		// The expired lease might fail to be revoked if the primary changes.
-		// The caller will retry on ErrNotPrimary.
-		case <-demotec:
-			return -1, ErrNotPrimary
-		case <-le.stopC:
-			return -1, ErrNotPrimary
-		}
-	}
-
-	// Clear remaining TTL when we renew if it is set
-	// By applying a RAFT entry only when the remainingTTL is already set, we limit the number
-	// of RAFT entries written per lease to a max of 2 per checkpoint interval.
-	if clearRemainingTTL {
-		le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: []*pb.LeaseCheckpoint{{ID: int64(l.ID), Remaining_TTL: 0}}})
-	}
-
-	le.mu.Lock()
-	l.refresh(0)
-	item := &LeaseWithTime{id: l.ID, time: l.expiry.UnixNano()}
-	le.leaseExpiredNotifier.RegisterOrUpdate(item)
-	le.mu.Unlock()
-
-	leaseRenewed.Inc()
-	return l.ttl, nil
-}
-
-func (le *lessor) Lookup(id LeaseID) *Lease {
-	le.mu.RLock()
-	defer le.mu.RUnlock()
-	return le.leaseMap[id]
-}
-
-func (le *lessor) unsafeLeases() []*Lease {
-	leases := make([]*Lease, 0, len(le.leaseMap))
-	for _, l := range le.leaseMap {
-		leases = append(leases, l)
-	}
-	return leases
-}
-
-func (le *lessor) Leases() []*Lease {
-	le.mu.RLock()
-	ls := le.unsafeLeases()
-	le.mu.RUnlock()
-	sort.Sort(leasesByExpiry(ls))
-	return ls
-}
-
-func (le *lessor) Promote(extend time.Duration) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.demotec = make(chan struct{})
-
-	// refresh the expiries of all leases.
-	for _, l := range le.leaseMap {
-		l.refresh(extend)
-		item := &LeaseWithTime{id: l.ID, time: l.expiry.UnixNano()}
-		le.leaseExpiredNotifier.RegisterOrUpdate(item)
-	}
-
-	if len(le.leaseMap) < leaseRevokeRate {
-		// no possibility of lease pile-up
-		return
-	}
-
-	// adjust expiries in case of overlap
-	leases := le.unsafeLeases()
-	sort.Sort(leasesByExpiry(leases))
-
-	baseWindow := leases[0].Remaining()
-	nextWindow := baseWindow + time.Second
-	expires := 0
-	// have fewer expires than the total revoke rate so piled up leases
-	// don't consume the entire revoke limit
-	targetExpiresPerSecond := (3 * leaseRevokeRate) / 4
-	for _, l := range leases {
-		remaining := l.Remaining()
-		if remaining > nextWindow {
-			baseWindow = remaining
-			nextWindow = baseWindow + time.Second
-			expires = 1
-			continue
-		}
-		expires++
-		if expires <= targetExpiresPerSecond {
-			continue
-		}
-		rateDelay := float64(time.Second) * (float64(expires) / float64(targetExpiresPerSecond))
-		// If leases are extended by n seconds, leases n seconds ahead of the
-		// base window should be extended by only one second.
-		rateDelay -= float64(remaining - baseWindow)
-		delay := time.Duration(rateDelay)
-		nextWindow = baseWindow + delay
-		l.refresh(delay + extend)
-		item := &LeaseWithTime{id: l.ID, time: l.expiry.UnixNano()}
-		le.leaseExpiredNotifier.RegisterOrUpdate(item)
-		le.scheduleCheckpointIfNeeded(l)
-	}
-}
-
-type leasesByExpiry []*Lease
-
-func (le leasesByExpiry) Len() int           { return len(le) }
-func (le leasesByExpiry) Less(i, j int) bool { return le[i].Remaining() < le[j].Remaining() }
-func (le leasesByExpiry) Swap(i, j int)      { le[i], le[j] = le[j], le[i] }
-
-func (le *lessor) Demote() {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	// set the expiries of all leases to forever
-	for _, l := range le.leaseMap {
-		l.forever()
-	}
-
-	le.clearScheduledLeasesCheckpoints()
-
-	if le.demotec != nil {
-		close(le.demotec)
-		le.demotec = nil
-	}
-}
-
-// Attach attaches items to the lease with given ID. When the lease
-// expires, the attached items will be automatically removed.
-// If the given lease does not exist, an error will be returned.
-func (le *lessor) Attach(id LeaseID, items []LeaseItem) error {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		return ErrLeaseNotFound
-	}
-
-	l.mu.Lock()
-	for _, it := range items {
-		l.itemSet[it] = struct{}{}
-		le.itemMap[it] = id
-	}
-	l.mu.Unlock()
-	return nil
-}
-
-func (le *lessor) GetLease(item LeaseItem) LeaseID {
-	le.mu.RLock()
-	id := le.itemMap[item]
-	le.mu.RUnlock()
-	return id
-}
-
-// Detach detaches items from the lease with given ID.
-// If the given lease does not exist, an error will be returned.
-func (le *lessor) Detach(id LeaseID, items []LeaseItem) error {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	l := le.leaseMap[id]
-	if l == nil {
-		return ErrLeaseNotFound
-	}
-
-	l.mu.Lock()
-	for _, it := range items {
-		delete(l.itemSet, it)
-		delete(le.itemMap, it)
-	}
-	l.mu.Unlock()
-	return nil
-}
-
-func (le *lessor) Recover(b backend.Backend, rd RangeDeleter) {
-	le.mu.Lock()
-	defer le.mu.Unlock()
-
-	le.b = b
-	le.rd = rd
-	le.leaseMap = make(map[LeaseID]*Lease)
-	le.itemMap = make(map[LeaseItem]LeaseID)
-	le.initAndRecover()
-}
-
-func (le *lessor) ExpiredLeasesC() <-chan []*Lease {
-	return le.expiredC
-}
-
-func (le *lessor) Stop() {
-	close(le.stopC)
-	<-le.doneC
-}
-
-func (le *lessor) runLoop() {
-	defer close(le.doneC)
-
-	for {
-		le.revokeExpiredLeases()
-		le.checkpointScheduledLeases()
-
-		select {
-		case <-time.After(500 * time.Millisecond):
-		case <-le.stopC:
-			return
-		}
-	}
-}
-
-// revokeExpiredLeases finds all leases past their expiry and sends them to expired channel for
-// to be revoked.
-func (le *lessor) revokeExpiredLeases() {
-	var ls []*Lease
-
-	// rate limit
-	revokeLimit := leaseRevokeRate / 2
-
-	le.mu.RLock()
-	if le.isPrimary() {
-		ls = le.findExpiredLeases(revokeLimit)
-	}
-	le.mu.RUnlock()
-
-	if len(ls) != 0 {
-		select {
-		case <-le.stopC:
-			return
-		case le.expiredC <- ls:
-		default:
-			// the receiver of expiredC is probably busy handling
-			// other stuff
-			// let's try this next time after 500ms
-		}
-	}
-}
-
-// checkpointScheduledLeases finds all scheduled lease checkpoints that are due and
-// submits them to the checkpointer to persist them to the consensus log.
-func (le *lessor) checkpointScheduledLeases() {
-	var cps []*pb.LeaseCheckpoint
-
-	// rate limit
-	for i := 0; i < leaseCheckpointRate/2; i++ {
-		le.mu.Lock()
-		if le.isPrimary() {
-			cps = le.findDueScheduledCheckpoints(maxLeaseCheckpointBatchSize)
-		}
-		le.mu.Unlock()
-
-		if len(cps) != 0 {
-			le.cp(context.Background(), &pb.LeaseCheckpointRequest{Checkpoints: cps})
-		}
-		if len(cps) < maxLeaseCheckpointBatchSize {
-			return
-		}
-	}
-}
-
-func (le *lessor) clearScheduledLeasesCheckpoints() {
-	le.leaseCheckpointHeap = make(LeaseQueue, 0)
-}
-
-// expireExists returns true if expiry items exist.
-// It pops only when expiry item exists.
-// "next" is true, to indicate that it may exist in next attempt.
-func (le *lessor) expireExists() (l *Lease, ok bool, next bool) {
-	if le.leaseExpiredNotifier.Len() == 0 {
-		return nil, false, false
-	}
-
-	item := le.leaseExpiredNotifier.Poll()
-	l = le.leaseMap[item.id]
-	if l == nil {
-		// lease has expired or been revoked
-		// no need to revoke (nothing is expiry)
-		le.leaseExpiredNotifier.Unregister() // O(log N)
-		return nil, false, true
-	}
-	now := time.Now()
-	if now.UnixNano() < item.time /* expiration time */ {
-		// Candidate expirations are caught up, reinsert this item
-		// and no need to revoke (nothing is expiry)
-		return l, false, false
-	}
-
-	// recheck if revoke is complete after retry interval
-	item.time = now.Add(le.expiredLeaseRetryInterval).UnixNano()
-	le.leaseExpiredNotifier.RegisterOrUpdate(item)
-	return l, true, false
-}
-
-// findExpiredLeases loops leases in the leaseMap until reaching expired limit
-// and returns the expired leases that needed to be revoked.
-func (le *lessor) findExpiredLeases(limit int) []*Lease {
-	leases := make([]*Lease, 0, 16)
-
-	for {
-		l, ok, next := le.expireExists()
-		if !ok && !next {
-			break
-		}
-		if !ok {
-			continue
-		}
-		if next {
-			continue
-		}
-
-		if l.expired() {
-			leases = append(leases, l)
-
-			// reach expired limit
-			if len(leases) == limit {
-				break
-			}
-		}
-	}
-
-	return leases
-}
-
-func (le *lessor) scheduleCheckpointIfNeeded(lease *Lease) {
-	if le.cp == nil {
-		return
-	}
-
-	if lease.RemainingTTL() > int64(le.checkpointInterval.Seconds()) {
-		if le.lg != nil {
-			le.lg.Debug("Scheduling lease checkpoint",
-				zap.Int64("leaseID", int64(lease.ID)),
-				zap.Duration("intervalSeconds", le.checkpointInterval),
-			)
-		}
-		heap.Push(&le.leaseCheckpointHeap, &LeaseWithTime{
-			id:   lease.ID,
-			time: time.Now().Add(le.checkpointInterval).UnixNano(),
-		})
-	}
-}
-
-func (le *lessor) findDueScheduledCheckpoints(checkpointLimit int) []*pb.LeaseCheckpoint {
-	if le.cp == nil {
-		return nil
-	}
-
-	now := time.Now()
-	cps := []*pb.LeaseCheckpoint{}
-	for le.leaseCheckpointHeap.Len() > 0 && len(cps) < checkpointLimit {
-		lt := le.leaseCheckpointHeap[0]
-		if lt.time /* next checkpoint time */ > now.UnixNano() {
-			return cps
-		}
-		heap.Pop(&le.leaseCheckpointHeap)
-		var l *Lease
-		var ok bool
-		if l, ok = le.leaseMap[lt.id]; !ok {
-			continue
-		}
-		if !now.Before(l.expiry) {
-			continue
-		}
-		remainingTTL := int64(math.Ceil(l.expiry.Sub(now).Seconds()))
-		if remainingTTL >= l.ttl {
-			continue
-		}
-		if le.lg != nil {
-			le.lg.Debug("Checkpointing lease",
-				zap.Int64("leaseID", int64(lt.id)),
-				zap.Int64("remainingTTL", remainingTTL),
-			)
-		}
-		cps = append(cps, &pb.LeaseCheckpoint{ID: int64(lt.id), Remaining_TTL: remainingTTL})
-	}
-	return cps
-}
-
-func (le *lessor) initAndRecover() {
-	tx := le.b.BatchTx()
-	tx.Lock()
-
-	tx.UnsafeCreateBucket(leaseBucketName)
-	_, vs := tx.UnsafeRange(leaseBucketName, int64ToBytes(0), int64ToBytes(math.MaxInt64), 0)
-	// TODO: copy vs and do decoding outside tx lock if lock contention becomes an issue.
-	for i := range vs {
-		var lpb leasepb.Lease
-		err := lpb.Unmarshal(vs[i])
-		if err != nil {
-			tx.Unlock()
-			panic("failed to unmarshal lease proto item")
-		}
-		ID := LeaseID(lpb.ID)
-		if lpb.TTL < le.minLeaseTTL {
-			lpb.TTL = le.minLeaseTTL
-		}
-		le.leaseMap[ID] = &Lease{
-			ID:  ID,
-			ttl: lpb.TTL,
-			// itemSet will be filled in when recover key-value pairs
-			// set expiry to forever, refresh when promoted
-			itemSet: make(map[LeaseItem]struct{}),
-			expiry:  forever,
-			revokec: make(chan struct{}),
-		}
-	}
-	le.leaseExpiredNotifier.Init()
-	heap.Init(&le.leaseCheckpointHeap)
-	tx.Unlock()
-
-	le.b.ForceCommit()
-}
-
-type Lease struct {
-	ID           LeaseID
-	ttl          int64 // time to live of the lease in seconds
-	remainingTTL int64 // remaining time to live in seconds, if zero valued it is considered unset and the full ttl should be used
-	// expiryMu protects concurrent accesses to expiry
-	expiryMu sync.RWMutex
-	// expiry is time when lease should expire. no expiration when expiry.IsZero() is true
-	expiry time.Time
-
-	// mu protects concurrent accesses to itemSet
-	mu      sync.RWMutex
-	itemSet map[LeaseItem]struct{}
-	revokec chan struct{}
-}
-
-func (l *Lease) expired() bool {
-	return l.Remaining() <= 0
-}
-
-func (l *Lease) persistTo(b backend.Backend) {
-	key := int64ToBytes(int64(l.ID))
-
-	lpb := leasepb.Lease{ID: int64(l.ID), TTL: l.ttl, RemainingTTL: l.remainingTTL}
-	val, err := lpb.Marshal()
-	if err != nil {
-		panic("failed to marshal lease proto item")
-	}
-
-	b.BatchTx().Lock()
-	b.BatchTx().UnsafePut(leaseBucketName, key, val)
-	b.BatchTx().Unlock()
-}
-
-// TTL returns the TTL of the Lease.
-func (l *Lease) TTL() int64 {
-	return l.ttl
-}
-
-// RemainingTTL returns the last checkpointed remaining TTL of the lease.
-// TODO(jpbetz): do not expose this utility method
-func (l *Lease) RemainingTTL() int64 {
-	if l.remainingTTL > 0 {
-		return l.remainingTTL
-	}
-	return l.ttl
-}
-
-// refresh refreshes the expiry of the lease.
-func (l *Lease) refresh(extend time.Duration) {
-	newExpiry := time.Now().Add(extend + time.Duration(l.RemainingTTL())*time.Second)
-	l.expiryMu.Lock()
-	defer l.expiryMu.Unlock()
-	l.expiry = newExpiry
-}
-
-// forever sets the expiry of lease to be forever.
-func (l *Lease) forever() {
-	l.expiryMu.Lock()
-	defer l.expiryMu.Unlock()
-	l.expiry = forever
-}
-
-// Keys returns all the keys attached to the lease.
-func (l *Lease) Keys() []string {
-	l.mu.RLock()
-	keys := make([]string, 0, len(l.itemSet))
-	for k := range l.itemSet {
-		keys = append(keys, k.Key)
-	}
-	l.mu.RUnlock()
-	return keys
-}
-
-// Remaining returns the remaining time of the lease.
-func (l *Lease) Remaining() time.Duration {
-	l.expiryMu.RLock()
-	defer l.expiryMu.RUnlock()
-	if l.expiry.IsZero() {
-		return time.Duration(math.MaxInt64)
-	}
-	return time.Until(l.expiry)
-}
-
-type LeaseItem struct {
-	Key string
-}
-
-func int64ToBytes(n int64) []byte {
-	bytes := make([]byte, 8)
-	binary.BigEndian.PutUint64(bytes, uint64(n))
-	return bytes
-}
-
-// FakeLessor is a fake implementation of Lessor interface.
-// Used for testing only.
-type FakeLessor struct{}
-
-func (fl *FakeLessor) SetRangeDeleter(dr RangeDeleter) {}
-
-func (fl *FakeLessor) SetCheckpointer(cp Checkpointer) {}
-
-func (fl *FakeLessor) Grant(id LeaseID, ttl int64) (*Lease, error) { return nil, nil }
-
-func (fl *FakeLessor) Revoke(id LeaseID) error { return nil }
-
-func (fl *FakeLessor) Checkpoint(id LeaseID, remainingTTL int64) error { return nil }
-
-func (fl *FakeLessor) Attach(id LeaseID, items []LeaseItem) error { return nil }
-
-func (fl *FakeLessor) GetLease(item LeaseItem) LeaseID            { return 0 }
-func (fl *FakeLessor) Detach(id LeaseID, items []LeaseItem) error { return nil }
-
-func (fl *FakeLessor) Promote(extend time.Duration) {}
-
-func (fl *FakeLessor) Demote() {}
-
-func (fl *FakeLessor) Renew(id LeaseID) (int64, error) { return 10, nil }
-
-func (fl *FakeLessor) Lookup(id LeaseID) *Lease { return nil }
-
-func (fl *FakeLessor) Leases() []*Lease { return nil }
-
-func (fl *FakeLessor) ExpiredLeasesC() <-chan []*Lease { return nil }
-
-func (fl *FakeLessor) Recover(b backend.Backend, rd RangeDeleter) {}
-
-func (fl *FakeLessor) Stop() {}
-
-type FakeTxnDelete struct {
-	backend.BatchTx
-}
-
-func (ftd *FakeTxnDelete) DeleteRange(key, end []byte) (n, rev int64) { return 0, 0 }
-func (ftd *FakeTxnDelete) End()                                       { ftd.Unlock() }
diff --git a/vendor/go.etcd.io/etcd/lease/metrics.go b/vendor/go.etcd.io/etcd/lease/metrics.go
deleted file mode 100644
index 06f8b58..0000000
--- a/vendor/go.etcd.io/etcd/lease/metrics.go
+++ /dev/null
@@ -1,59 +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 lease
-
-import (
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	leaseGranted = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "lease",
-		Name:      "granted_total",
-		Help:      "The total number of granted leases.",
-	})
-
-	leaseRevoked = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "lease",
-		Name:      "revoked_total",
-		Help:      "The total number of revoked leases.",
-	})
-
-	leaseRenewed = prometheus.NewCounter(prometheus.CounterOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "lease",
-		Name:      "renewed_total",
-		Help:      "The number of renewed leases seen by the leader.",
-	})
-
-	leaseTotalTTLs = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "lease",
-			Name:      "ttl_total",
-			Help:      "Bucketed histogram of lease TTLs.",
-			// 1 second -> 3 months
-			Buckets: prometheus.ExponentialBuckets(1, 2, 24),
-		})
-)
-
-func init() {
-	prometheus.MustRegister(leaseGranted)
-	prometheus.MustRegister(leaseRevoked)
-	prometheus.MustRegister(leaseRenewed)
-	prometheus.MustRegister(leaseTotalTTLs)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/backend.go b/vendor/go.etcd.io/etcd/mvcc/backend/backend.go
deleted file mode 100644
index bffd749..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/backend.go
+++ /dev/null
@@ -1,570 +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 backend
-
-import (
-	"fmt"
-	"hash/crc32"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"github.com/coreos/pkg/capnslog"
-	humanize "github.com/dustin/go-humanize"
-	bolt "go.etcd.io/bbolt"
-	"go.uber.org/zap"
-)
-
-var (
-	defaultBatchLimit    = 10000
-	defaultBatchInterval = 100 * time.Millisecond
-
-	defragLimit = 10000
-
-	// initialMmapSize is the initial size of the mmapped region. Setting this larger than
-	// the potential max db size can prevent writer from blocking reader.
-	// This only works for linux.
-	initialMmapSize = uint64(10 * 1024 * 1024 * 1024)
-
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "mvcc/backend")
-
-	// minSnapshotWarningTimeout is the minimum threshold to trigger a long running snapshot warning.
-	minSnapshotWarningTimeout = 30 * time.Second
-)
-
-type Backend interface {
-	// ReadTx returns a read transaction. It is replaced by ConcurrentReadTx in the main data path, see #10523.
-	ReadTx() ReadTx
-	BatchTx() BatchTx
-	// ConcurrentReadTx returns a non-blocking read transaction.
-	ConcurrentReadTx() ReadTx
-
-	Snapshot() Snapshot
-	Hash(ignores map[IgnoreKey]struct{}) (uint32, error)
-	// Size returns the current size of the backend physically allocated.
-	// The backend can hold DB space that is not utilized at the moment,
-	// since it can conduct pre-allocation or spare unused space for recycling.
-	// Use SizeInUse() instead for the actual DB size.
-	Size() int64
-	// SizeInUse returns the current size of the backend logically in use.
-	// Since the backend can manage free space in a non-byte unit such as
-	// number of pages, the returned value can be not exactly accurate in bytes.
-	SizeInUse() int64
-	// OpenReadTxN returns the number of currently open read transactions in the backend.
-	OpenReadTxN() int64
-	Defrag() error
-	ForceCommit()
-	Close() error
-}
-
-type Snapshot interface {
-	// Size gets the size of the snapshot.
-	Size() int64
-	// WriteTo writes the snapshot into the given writer.
-	WriteTo(w io.Writer) (n int64, err error)
-	// Close closes the snapshot.
-	Close() error
-}
-
-type backend struct {
-	// size and commits are used with atomic operations so they must be
-	// 64-bit aligned, otherwise 32-bit tests will crash
-
-	// size is the number of bytes allocated in the backend
-	size int64
-	// sizeInUse is the number of bytes actually used in the backend
-	sizeInUse int64
-	// commits counts number of commits since start
-	commits int64
-	// openReadTxN is the number of currently open read transactions in the backend
-	openReadTxN int64
-
-	mu sync.RWMutex
-	db *bolt.DB
-
-	batchInterval time.Duration
-	batchLimit    int
-	batchTx       *batchTxBuffered
-
-	readTx *readTx
-
-	stopc chan struct{}
-	donec chan struct{}
-
-	lg *zap.Logger
-}
-
-type BackendConfig struct {
-	// Path is the file path to the backend file.
-	Path string
-	// BatchInterval is the maximum time before flushing the BatchTx.
-	BatchInterval time.Duration
-	// BatchLimit is the maximum puts before flushing the BatchTx.
-	BatchLimit int
-	// BackendFreelistType is the backend boltdb's freelist type.
-	BackendFreelistType bolt.FreelistType
-	// MmapSize is the number of bytes to mmap for the backend.
-	MmapSize uint64
-	// Logger logs backend-side operations.
-	Logger *zap.Logger
-}
-
-func DefaultBackendConfig() BackendConfig {
-	return BackendConfig{
-		BatchInterval: defaultBatchInterval,
-		BatchLimit:    defaultBatchLimit,
-		MmapSize:      initialMmapSize,
-	}
-}
-
-func New(bcfg BackendConfig) Backend {
-	return newBackend(bcfg)
-}
-
-func NewDefaultBackend(path string) Backend {
-	bcfg := DefaultBackendConfig()
-	bcfg.Path = path
-	return newBackend(bcfg)
-}
-
-func newBackend(bcfg BackendConfig) *backend {
-	bopts := &bolt.Options{}
-	if boltOpenOptions != nil {
-		*bopts = *boltOpenOptions
-	}
-	bopts.InitialMmapSize = bcfg.mmapSize()
-	bopts.FreelistType = bcfg.BackendFreelistType
-
-	db, err := bolt.Open(bcfg.Path, 0600, bopts)
-	if err != nil {
-		if bcfg.Logger != nil {
-			bcfg.Logger.Panic("failed to open database", zap.String("path", bcfg.Path), zap.Error(err))
-		} else {
-			plog.Panicf("cannot open database at %s (%v)", bcfg.Path, err)
-		}
-	}
-
-	// In future, may want to make buffering optional for low-concurrency systems
-	// or dynamically swap between buffered/non-buffered depending on workload.
-	b := &backend{
-		db: db,
-
-		batchInterval: bcfg.BatchInterval,
-		batchLimit:    bcfg.BatchLimit,
-
-		readTx: &readTx{
-			buf: txReadBuffer{
-				txBuffer: txBuffer{make(map[string]*bucketBuffer)},
-			},
-			buckets: make(map[string]*bolt.Bucket),
-			txWg:    new(sync.WaitGroup),
-		},
-
-		stopc: make(chan struct{}),
-		donec: make(chan struct{}),
-
-		lg: bcfg.Logger,
-	}
-	b.batchTx = newBatchTxBuffered(b)
-	go b.run()
-	return b
-}
-
-// BatchTx returns the current batch tx in coalescer. The tx can be used for read and
-// write operations. The write result can be retrieved within the same tx immediately.
-// The write result is isolated with other txs until the current one get committed.
-func (b *backend) BatchTx() BatchTx {
-	return b.batchTx
-}
-
-func (b *backend) ReadTx() ReadTx { return b.readTx }
-
-// ConcurrentReadTx creates and returns a new ReadTx, which:
-// A) creates and keeps a copy of backend.readTx.txReadBuffer,
-// B) references the boltdb read Tx (and its bucket cache) of current batch interval.
-func (b *backend) ConcurrentReadTx() ReadTx {
-	b.readTx.RLock()
-	defer b.readTx.RUnlock()
-	// prevent boltdb read Tx from been rolled back until store read Tx is done. Needs to be called when holding readTx.RLock().
-	b.readTx.txWg.Add(1)
-	// TODO: might want to copy the read buffer lazily - create copy when A) end of a write transaction B) end of a batch interval.
-	return &concurrentReadTx{
-		buf:     b.readTx.buf.unsafeCopy(),
-		tx:      b.readTx.tx,
-		txMu:    &b.readTx.txMu,
-		buckets: b.readTx.buckets,
-		txWg:    b.readTx.txWg,
-	}
-}
-
-// ForceCommit forces the current batching tx to commit.
-func (b *backend) ForceCommit() {
-	b.batchTx.Commit()
-}
-
-func (b *backend) Snapshot() Snapshot {
-	b.batchTx.Commit()
-
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	tx, err := b.db.Begin(false)
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to begin tx", zap.Error(err))
-		} else {
-			plog.Fatalf("cannot begin tx (%s)", err)
-		}
-	}
-
-	stopc, donec := make(chan struct{}), make(chan struct{})
-	dbBytes := tx.Size()
-	go func() {
-		defer close(donec)
-		// sendRateBytes is based on transferring snapshot data over a 1 gigabit/s connection
-		// assuming a min tcp throughput of 100MB/s.
-		var sendRateBytes int64 = 100 * 1024 * 1014
-		warningTimeout := time.Duration(int64((float64(dbBytes) / float64(sendRateBytes)) * float64(time.Second)))
-		if warningTimeout < minSnapshotWarningTimeout {
-			warningTimeout = minSnapshotWarningTimeout
-		}
-		start := time.Now()
-		ticker := time.NewTicker(warningTimeout)
-		defer ticker.Stop()
-		for {
-			select {
-			case <-ticker.C:
-				if b.lg != nil {
-					b.lg.Warn(
-						"snapshotting taking too long to transfer",
-						zap.Duration("taking", time.Since(start)),
-						zap.Int64("bytes", dbBytes),
-						zap.String("size", humanize.Bytes(uint64(dbBytes))),
-					)
-				} else {
-					plog.Warningf("snapshotting is taking more than %v seconds to finish transferring %v MB [started at %v]", time.Since(start).Seconds(), float64(dbBytes)/float64(1024*1014), start)
-				}
-
-			case <-stopc:
-				snapshotTransferSec.Observe(time.Since(start).Seconds())
-				return
-			}
-		}
-	}()
-
-	return &snapshot{tx, stopc, donec}
-}
-
-type IgnoreKey struct {
-	Bucket string
-	Key    string
-}
-
-func (b *backend) Hash(ignores map[IgnoreKey]struct{}) (uint32, error) {
-	h := crc32.New(crc32.MakeTable(crc32.Castagnoli))
-
-	b.mu.RLock()
-	defer b.mu.RUnlock()
-	err := b.db.View(func(tx *bolt.Tx) error {
-		c := tx.Cursor()
-		for next, _ := c.First(); next != nil; next, _ = c.Next() {
-			b := tx.Bucket(next)
-			if b == nil {
-				return fmt.Errorf("cannot get hash of bucket %s", string(next))
-			}
-			h.Write(next)
-			b.ForEach(func(k, v []byte) error {
-				bk := IgnoreKey{Bucket: string(next), Key: string(k)}
-				if _, ok := ignores[bk]; !ok {
-					h.Write(k)
-					h.Write(v)
-				}
-				return nil
-			})
-		}
-		return nil
-	})
-
-	if err != nil {
-		return 0, err
-	}
-
-	return h.Sum32(), nil
-}
-
-func (b *backend) Size() int64 {
-	return atomic.LoadInt64(&b.size)
-}
-
-func (b *backend) SizeInUse() int64 {
-	return atomic.LoadInt64(&b.sizeInUse)
-}
-
-func (b *backend) run() {
-	defer close(b.donec)
-	t := time.NewTimer(b.batchInterval)
-	defer t.Stop()
-	for {
-		select {
-		case <-t.C:
-		case <-b.stopc:
-			b.batchTx.CommitAndStop()
-			return
-		}
-		if b.batchTx.safePending() != 0 {
-			b.batchTx.Commit()
-		}
-		t.Reset(b.batchInterval)
-	}
-}
-
-func (b *backend) Close() error {
-	close(b.stopc)
-	<-b.donec
-	return b.db.Close()
-}
-
-// Commits returns total number of commits since start
-func (b *backend) Commits() int64 {
-	return atomic.LoadInt64(&b.commits)
-}
-
-func (b *backend) Defrag() error {
-	return b.defrag()
-}
-
-func (b *backend) defrag() error {
-	now := time.Now()
-
-	// TODO: make this non-blocking?
-	// lock batchTx to ensure nobody is using previous tx, and then
-	// close previous ongoing tx.
-	b.batchTx.Lock()
-	defer b.batchTx.Unlock()
-
-	// lock database after lock tx to avoid deadlock.
-	b.mu.Lock()
-	defer b.mu.Unlock()
-
-	// block concurrent read requests while resetting tx
-	b.readTx.Lock()
-	defer b.readTx.Unlock()
-
-	b.batchTx.unsafeCommit(true)
-
-	b.batchTx.tx = nil
-
-	tmpdb, err := bolt.Open(b.db.Path()+".tmp", 0600, boltOpenOptions)
-	if err != nil {
-		return err
-	}
-
-	dbp := b.db.Path()
-	tdbp := tmpdb.Path()
-	size1, sizeInUse1 := b.Size(), b.SizeInUse()
-	if b.lg != nil {
-		b.lg.Info(
-			"defragmenting",
-			zap.String("path", dbp),
-			zap.Int64("current-db-size-bytes", size1),
-			zap.String("current-db-size", humanize.Bytes(uint64(size1))),
-			zap.Int64("current-db-size-in-use-bytes", sizeInUse1),
-			zap.String("current-db-size-in-use", humanize.Bytes(uint64(sizeInUse1))),
-		)
-	}
-
-	err = defragdb(b.db, tmpdb, defragLimit)
-	if err != nil {
-		tmpdb.Close()
-		os.RemoveAll(tmpdb.Path())
-		return err
-	}
-
-	err = b.db.Close()
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to close database", zap.Error(err))
-		} else {
-			plog.Fatalf("cannot close database (%s)", err)
-		}
-	}
-	err = tmpdb.Close()
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to close tmp database", zap.Error(err))
-		} else {
-			plog.Fatalf("cannot close database (%s)", err)
-		}
-	}
-	err = os.Rename(tdbp, dbp)
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to rename tmp database", zap.Error(err))
-		} else {
-			plog.Fatalf("cannot rename database (%s)", err)
-		}
-	}
-
-	b.db, err = bolt.Open(dbp, 0600, boltOpenOptions)
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to open database", zap.String("path", dbp), zap.Error(err))
-		} else {
-			plog.Panicf("cannot open database at %s (%v)", dbp, err)
-		}
-	}
-	b.batchTx.tx = b.unsafeBegin(true)
-
-	b.readTx.reset()
-	b.readTx.tx = b.unsafeBegin(false)
-
-	size := b.readTx.tx.Size()
-	db := b.readTx.tx.DB()
-	atomic.StoreInt64(&b.size, size)
-	atomic.StoreInt64(&b.sizeInUse, size-(int64(db.Stats().FreePageN)*int64(db.Info().PageSize)))
-
-	took := time.Since(now)
-	defragSec.Observe(took.Seconds())
-
-	size2, sizeInUse2 := b.Size(), b.SizeInUse()
-	if b.lg != nil {
-		b.lg.Info(
-			"defragmented",
-			zap.String("path", dbp),
-			zap.Int64("current-db-size-bytes-diff", size2-size1),
-			zap.Int64("current-db-size-bytes", size2),
-			zap.String("current-db-size", humanize.Bytes(uint64(size2))),
-			zap.Int64("current-db-size-in-use-bytes-diff", sizeInUse2-sizeInUse1),
-			zap.Int64("current-db-size-in-use-bytes", sizeInUse2),
-			zap.String("current-db-size-in-use", humanize.Bytes(uint64(sizeInUse2))),
-			zap.Duration("took", took),
-		)
-	}
-	return nil
-}
-
-func defragdb(odb, tmpdb *bolt.DB, limit int) error {
-	// open a tx on tmpdb for writes
-	tmptx, err := tmpdb.Begin(true)
-	if err != nil {
-		return err
-	}
-
-	// open a tx on old db for read
-	tx, err := odb.Begin(false)
-	if err != nil {
-		return err
-	}
-	defer tx.Rollback()
-
-	c := tx.Cursor()
-
-	count := 0
-	for next, _ := c.First(); next != nil; next, _ = c.Next() {
-		b := tx.Bucket(next)
-		if b == nil {
-			return fmt.Errorf("backend: cannot defrag bucket %s", string(next))
-		}
-
-		tmpb, berr := tmptx.CreateBucketIfNotExists(next)
-		if berr != nil {
-			return berr
-		}
-		tmpb.FillPercent = 0.9 // for seq write in for each
-
-		b.ForEach(func(k, v []byte) error {
-			count++
-			if count > limit {
-				err = tmptx.Commit()
-				if err != nil {
-					return err
-				}
-				tmptx, err = tmpdb.Begin(true)
-				if err != nil {
-					return err
-				}
-				tmpb = tmptx.Bucket(next)
-				tmpb.FillPercent = 0.9 // for seq write in for each
-
-				count = 0
-			}
-			return tmpb.Put(k, v)
-		})
-	}
-
-	return tmptx.Commit()
-}
-
-func (b *backend) begin(write bool) *bolt.Tx {
-	b.mu.RLock()
-	tx := b.unsafeBegin(write)
-	b.mu.RUnlock()
-
-	size := tx.Size()
-	db := tx.DB()
-	stats := db.Stats()
-	atomic.StoreInt64(&b.size, size)
-	atomic.StoreInt64(&b.sizeInUse, size-(int64(stats.FreePageN)*int64(db.Info().PageSize)))
-	atomic.StoreInt64(&b.openReadTxN, int64(stats.OpenTxN))
-
-	return tx
-}
-
-func (b *backend) unsafeBegin(write bool) *bolt.Tx {
-	tx, err := b.db.Begin(write)
-	if err != nil {
-		if b.lg != nil {
-			b.lg.Fatal("failed to begin tx", zap.Error(err))
-		} else {
-			plog.Fatalf("cannot begin tx (%s)", err)
-		}
-	}
-	return tx
-}
-
-func (b *backend) OpenReadTxN() int64 {
-	return atomic.LoadInt64(&b.openReadTxN)
-}
-
-// NewTmpBackend creates a backend implementation for testing.
-func NewTmpBackend(batchInterval time.Duration, batchLimit int) (*backend, string) {
-	dir, err := ioutil.TempDir(os.TempDir(), "etcd_backend_test")
-	if err != nil {
-		panic(err)
-	}
-	tmpPath := filepath.Join(dir, "database")
-	bcfg := DefaultBackendConfig()
-	bcfg.Path, bcfg.BatchInterval, bcfg.BatchLimit = tmpPath, batchInterval, batchLimit
-	return newBackend(bcfg), tmpPath
-}
-
-func NewDefaultTmpBackend() (*backend, string) {
-	return NewTmpBackend(defaultBatchInterval, defaultBatchLimit)
-}
-
-type snapshot struct {
-	*bolt.Tx
-	stopc chan struct{}
-	donec chan struct{}
-}
-
-func (s *snapshot) Close() error {
-	close(s.stopc)
-	<-s.donec
-	return s.Tx.Rollback()
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/batch_tx.go b/vendor/go.etcd.io/etcd/mvcc/backend/batch_tx.go
deleted file mode 100644
index d5c8a88..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/batch_tx.go
+++ /dev/null
@@ -1,339 +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 backend
-
-import (
-	"bytes"
-	"math"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	bolt "go.etcd.io/bbolt"
-	"go.uber.org/zap"
-)
-
-type BatchTx interface {
-	ReadTx
-	UnsafeCreateBucket(name []byte)
-	UnsafePut(bucketName []byte, key []byte, value []byte)
-	UnsafeSeqPut(bucketName []byte, key []byte, value []byte)
-	UnsafeDelete(bucketName []byte, key []byte)
-	// Commit commits a previous tx and begins a new writable one.
-	Commit()
-	// CommitAndStop commits the previous tx and does not create a new one.
-	CommitAndStop()
-}
-
-type batchTx struct {
-	sync.Mutex
-	tx      *bolt.Tx
-	backend *backend
-
-	pending int
-}
-
-func (t *batchTx) Lock() {
-	t.Mutex.Lock()
-}
-
-func (t *batchTx) Unlock() {
-	if t.pending >= t.backend.batchLimit {
-		t.commit(false)
-	}
-	t.Mutex.Unlock()
-}
-
-// BatchTx interface embeds ReadTx interface. But RLock() and RUnlock() do not
-// have appropriate semantics in BatchTx interface. Therefore should not be called.
-// TODO: might want to decouple ReadTx and BatchTx
-
-func (t *batchTx) RLock() {
-	panic("unexpected RLock")
-}
-
-func (t *batchTx) RUnlock() {
-	panic("unexpected RUnlock")
-}
-
-func (t *batchTx) UnsafeCreateBucket(name []byte) {
-	_, err := t.tx.CreateBucket(name)
-	if err != nil && err != bolt.ErrBucketExists {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to create a bucket",
-				zap.String("bucket-name", string(name)),
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot create bucket %s (%v)", name, err)
-		}
-	}
-	t.pending++
-}
-
-// UnsafePut must be called holding the lock on the tx.
-func (t *batchTx) UnsafePut(bucketName []byte, key []byte, value []byte) {
-	t.unsafePut(bucketName, key, value, false)
-}
-
-// UnsafeSeqPut must be called holding the lock on the tx.
-func (t *batchTx) UnsafeSeqPut(bucketName []byte, key []byte, value []byte) {
-	t.unsafePut(bucketName, key, value, true)
-}
-
-func (t *batchTx) unsafePut(bucketName []byte, key []byte, value []byte, seq bool) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to find a bucket",
-				zap.String("bucket-name", string(bucketName)),
-			)
-		} else {
-			plog.Fatalf("bucket %s does not exist", bucketName)
-		}
-	}
-	if seq {
-		// it is useful to increase fill percent when the workloads are mostly append-only.
-		// this can delay the page split and reduce space usage.
-		bucket.FillPercent = 0.9
-	}
-	if err := bucket.Put(key, value); err != nil {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to write to a bucket",
-				zap.String("bucket-name", string(bucketName)),
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot put key into bucket (%v)", err)
-		}
-	}
-	t.pending++
-}
-
-// UnsafeRange must be called holding the lock on the tx.
-func (t *batchTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to find a bucket",
-				zap.String("bucket-name", string(bucketName)),
-			)
-		} else {
-			plog.Fatalf("bucket %s does not exist", bucketName)
-		}
-	}
-	return unsafeRange(bucket.Cursor(), key, endKey, limit)
-}
-
-func unsafeRange(c *bolt.Cursor, key, endKey []byte, limit int64) (keys [][]byte, vs [][]byte) {
-	if limit <= 0 {
-		limit = math.MaxInt64
-	}
-	var isMatch func(b []byte) bool
-	if len(endKey) > 0 {
-		isMatch = func(b []byte) bool { return bytes.Compare(b, endKey) < 0 }
-	} else {
-		isMatch = func(b []byte) bool { return bytes.Equal(b, key) }
-		limit = 1
-	}
-
-	for ck, cv := c.Seek(key); ck != nil && isMatch(ck); ck, cv = c.Next() {
-		vs = append(vs, cv)
-		keys = append(keys, ck)
-		if limit == int64(len(keys)) {
-			break
-		}
-	}
-	return keys, vs
-}
-
-// UnsafeDelete must be called holding the lock on the tx.
-func (t *batchTx) UnsafeDelete(bucketName []byte, key []byte) {
-	bucket := t.tx.Bucket(bucketName)
-	if bucket == nil {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to find a bucket",
-				zap.String("bucket-name", string(bucketName)),
-			)
-		} else {
-			plog.Fatalf("bucket %s does not exist", bucketName)
-		}
-	}
-	err := bucket.Delete(key)
-	if err != nil {
-		if t.backend.lg != nil {
-			t.backend.lg.Fatal(
-				"failed to delete a key",
-				zap.String("bucket-name", string(bucketName)),
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot delete key from bucket (%v)", err)
-		}
-	}
-	t.pending++
-}
-
-// UnsafeForEach must be called holding the lock on the tx.
-func (t *batchTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	return unsafeForEach(t.tx, bucketName, visitor)
-}
-
-func unsafeForEach(tx *bolt.Tx, bucket []byte, visitor func(k, v []byte) error) error {
-	if b := tx.Bucket(bucket); b != nil {
-		return b.ForEach(visitor)
-	}
-	return nil
-}
-
-// Commit commits a previous tx and begins a new writable one.
-func (t *batchTx) Commit() {
-	t.Lock()
-	t.commit(false)
-	t.Unlock()
-}
-
-// CommitAndStop commits the previous tx and does not create a new one.
-func (t *batchTx) CommitAndStop() {
-	t.Lock()
-	t.commit(true)
-	t.Unlock()
-}
-
-func (t *batchTx) safePending() int {
-	t.Mutex.Lock()
-	defer t.Mutex.Unlock()
-	return t.pending
-}
-
-func (t *batchTx) commit(stop bool) {
-	// commit the last tx
-	if t.tx != nil {
-		if t.pending == 0 && !stop {
-			return
-		}
-
-		start := time.Now()
-
-		// gofail: var beforeCommit struct{}
-		err := t.tx.Commit()
-		// gofail: var afterCommit struct{}
-
-		rebalanceSec.Observe(t.tx.Stats().RebalanceTime.Seconds())
-		spillSec.Observe(t.tx.Stats().SpillTime.Seconds())
-		writeSec.Observe(t.tx.Stats().WriteTime.Seconds())
-		commitSec.Observe(time.Since(start).Seconds())
-		atomic.AddInt64(&t.backend.commits, 1)
-
-		t.pending = 0
-		if err != nil {
-			if t.backend.lg != nil {
-				t.backend.lg.Fatal("failed to commit tx", zap.Error(err))
-			} else {
-				plog.Fatalf("cannot commit tx (%s)", err)
-			}
-		}
-	}
-	if !stop {
-		t.tx = t.backend.begin(true)
-	}
-}
-
-type batchTxBuffered struct {
-	batchTx
-	buf txWriteBuffer
-}
-
-func newBatchTxBuffered(backend *backend) *batchTxBuffered {
-	tx := &batchTxBuffered{
-		batchTx: batchTx{backend: backend},
-		buf: txWriteBuffer{
-			txBuffer: txBuffer{make(map[string]*bucketBuffer)},
-			seq:      true,
-		},
-	}
-	tx.Commit()
-	return tx
-}
-
-func (t *batchTxBuffered) Unlock() {
-	if t.pending != 0 {
-		t.backend.readTx.Lock() // blocks txReadBuffer for writing.
-		t.buf.writeback(&t.backend.readTx.buf)
-		t.backend.readTx.Unlock()
-		if t.pending >= t.backend.batchLimit {
-			t.commit(false)
-		}
-	}
-	t.batchTx.Unlock()
-}
-
-func (t *batchTxBuffered) Commit() {
-	t.Lock()
-	t.commit(false)
-	t.Unlock()
-}
-
-func (t *batchTxBuffered) CommitAndStop() {
-	t.Lock()
-	t.commit(true)
-	t.Unlock()
-}
-
-func (t *batchTxBuffered) commit(stop bool) {
-	// all read txs must be closed to acquire boltdb commit rwlock
-	t.backend.readTx.Lock()
-	t.unsafeCommit(stop)
-	t.backend.readTx.Unlock()
-}
-
-func (t *batchTxBuffered) unsafeCommit(stop bool) {
-	if t.backend.readTx.tx != nil {
-		// wait all store read transactions using the current boltdb tx to finish,
-		// then close the boltdb tx
-		go func(tx *bolt.Tx, wg *sync.WaitGroup) {
-			wg.Wait()
-			if err := tx.Rollback(); err != nil {
-				if t.backend.lg != nil {
-					t.backend.lg.Fatal("failed to rollback tx", zap.Error(err))
-				} else {
-					plog.Fatalf("cannot rollback tx (%s)", err)
-				}
-			}
-		}(t.backend.readTx.tx, t.backend.readTx.txWg)
-		t.backend.readTx.reset()
-	}
-
-	t.batchTx.commit(stop)
-
-	if !stop {
-		t.backend.readTx.tx = t.backend.begin(false)
-	}
-}
-
-func (t *batchTxBuffered) UnsafePut(bucketName []byte, key []byte, value []byte) {
-	t.batchTx.UnsafePut(bucketName, key, value)
-	t.buf.put(bucketName, key, value)
-}
-
-func (t *batchTxBuffered) UnsafeSeqPut(bucketName []byte, key []byte, value []byte) {
-	t.batchTx.UnsafeSeqPut(bucketName, key, value)
-	t.buf.putSeq(bucketName, key, value)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/config_default.go b/vendor/go.etcd.io/etcd/mvcc/backend/config_default.go
deleted file mode 100644
index f15f030..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/config_default.go
+++ /dev/null
@@ -1,23 +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.
-
-// +build !linux,!windows
-
-package backend
-
-import bolt "go.etcd.io/bbolt"
-
-var boltOpenOptions *bolt.Options
-
-func (bcfg *BackendConfig) mmapSize() int { return int(bcfg.MmapSize) }
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/config_linux.go b/vendor/go.etcd.io/etcd/mvcc/backend/config_linux.go
deleted file mode 100644
index f712671..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/config_linux.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 backend
-
-import (
-	"syscall"
-
-	bolt "go.etcd.io/bbolt"
-)
-
-// syscall.MAP_POPULATE on linux 2.6.23+ does sequential read-ahead
-// which can speed up entire-database read with boltdb. We want to
-// enable MAP_POPULATE for faster key-value store recovery in storage
-// package. If your kernel version is lower than 2.6.23
-// (https://github.com/torvalds/linux/releases/tag/v2.6.23), mmap might
-// silently ignore this flag. Please update your kernel to prevent this.
-var boltOpenOptions = &bolt.Options{
-	MmapFlags:      syscall.MAP_POPULATE,
-	NoFreelistSync: true,
-}
-
-func (bcfg *BackendConfig) mmapSize() int { return int(bcfg.MmapSize) }
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/config_windows.go b/vendor/go.etcd.io/etcd/mvcc/backend/config_windows.go
deleted file mode 100644
index c650059..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/config_windows.go
+++ /dev/null
@@ -1,26 +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.
-
-// +build windows
-
-package backend
-
-import bolt "go.etcd.io/bbolt"
-
-var boltOpenOptions *bolt.Options = nil
-
-// setting mmap size != 0 on windows will allocate the entire
-// mmap size for the file, instead of growing it. So, force 0.
-
-func (bcfg *BackendConfig) mmapSize() int { return 0 }
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/doc.go b/vendor/go.etcd.io/etcd/mvcc/backend/doc.go
deleted file mode 100644
index 9cc42fa..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/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 backend defines a standard interface for etcd's backend MVCC storage.
-package backend
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/metrics.go b/vendor/go.etcd.io/etcd/mvcc/backend/metrics.go
deleted file mode 100644
index d9641af..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/metrics.go
+++ /dev/null
@@ -1,95 +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 backend
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	commitSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_commit_duration_seconds",
-		Help:      "The latency distributions of commit called by backend.",
-
-		// 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),
-	})
-
-	rebalanceSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "disk",
-		Name:      "backend_commit_rebalance_duration_seconds",
-		Help:      "The latency distributions of commit.rebalance called by bboltdb backend.",
-
-		// 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),
-	})
-
-	spillSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "disk",
-		Name:      "backend_commit_spill_duration_seconds",
-		Help:      "The latency distributions of commit.spill called by bboltdb backend.",
-
-		// 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),
-	})
-
-	writeSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "disk",
-		Name:      "backend_commit_write_duration_seconds",
-		Help:      "The latency distributions of commit.write called by bboltdb backend.",
-
-		// 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),
-	})
-
-	defragSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_defrag_duration_seconds",
-		Help:      "The latency distribution of backend defragmentation.",
-
-		// 100 MB usually takes 1 sec, so start with 10 MB of 100 ms
-		// lowest bucket start of upper bound 0.1 sec (100 ms) with factor 2
-		// highest bucket start of 0.1 sec * 2^12 == 409.6 sec
-		Buckets: prometheus.ExponentialBuckets(.1, 2, 13),
-	})
-
-	snapshotTransferSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "backend_snapshot_duration_seconds",
-		Help:      "The latency distribution of backend snapshots.",
-
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^16 == 655.36 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 17),
-	})
-)
-
-func init() {
-	prometheus.MustRegister(commitSec)
-	prometheus.MustRegister(rebalanceSec)
-	prometheus.MustRegister(spillSec)
-	prometheus.MustRegister(writeSec)
-	prometheus.MustRegister(defragSec)
-	prometheus.MustRegister(snapshotTransferSec)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/read_tx.go b/vendor/go.etcd.io/etcd/mvcc/backend/read_tx.go
deleted file mode 100644
index 91fe72e..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/read_tx.go
+++ /dev/null
@@ -1,210 +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 backend
-
-import (
-	"bytes"
-	"math"
-	"sync"
-
-	bolt "go.etcd.io/bbolt"
-)
-
-// safeRangeBucket is a hack to avoid inadvertently reading duplicate keys;
-// overwrites on a bucket should only fetch with limit=1, but safeRangeBucket
-// is known to never overwrite any key so range is safe.
-var safeRangeBucket = []byte("key")
-
-type ReadTx interface {
-	Lock()
-	Unlock()
-	RLock()
-	RUnlock()
-
-	UnsafeRange(bucketName []byte, key, endKey []byte, limit int64) (keys [][]byte, vals [][]byte)
-	UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error
-}
-
-type readTx struct {
-	// mu protects accesses to the txReadBuffer
-	mu  sync.RWMutex
-	buf txReadBuffer
-
-	// TODO: group and encapsulate {txMu, tx, buckets, txWg}, as they share the same lifecycle.
-	// txMu protects accesses to buckets and tx on Range requests.
-	txMu    sync.RWMutex
-	tx      *bolt.Tx
-	buckets map[string]*bolt.Bucket
-	// txWg protects tx from being rolled back at the end of a batch interval until all reads using this tx are done.
-	txWg *sync.WaitGroup
-}
-
-func (rt *readTx) Lock()    { rt.mu.Lock() }
-func (rt *readTx) Unlock()  { rt.mu.Unlock() }
-func (rt *readTx) RLock()   { rt.mu.RLock() }
-func (rt *readTx) RUnlock() { rt.mu.RUnlock() }
-
-func (rt *readTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	if endKey == nil {
-		// forbid duplicates for single keys
-		limit = 1
-	}
-	if limit <= 0 {
-		limit = math.MaxInt64
-	}
-	if limit > 1 && !bytes.Equal(bucketName, safeRangeBucket) {
-		panic("do not use unsafeRange on non-keys bucket")
-	}
-	keys, vals := rt.buf.Range(bucketName, key, endKey, limit)
-	if int64(len(keys)) == limit {
-		return keys, vals
-	}
-
-	// find/cache bucket
-	bn := string(bucketName)
-	rt.txMu.RLock()
-	bucket, ok := rt.buckets[bn]
-	rt.txMu.RUnlock()
-	if !ok {
-		rt.txMu.Lock()
-		bucket = rt.tx.Bucket(bucketName)
-		rt.buckets[bn] = bucket
-		rt.txMu.Unlock()
-	}
-
-	// ignore missing bucket since may have been created in this batch
-	if bucket == nil {
-		return keys, vals
-	}
-	rt.txMu.Lock()
-	c := bucket.Cursor()
-	rt.txMu.Unlock()
-
-	k2, v2 := unsafeRange(c, key, endKey, limit-int64(len(keys)))
-	return append(k2, keys...), append(v2, vals...)
-}
-
-func (rt *readTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	dups := make(map[string]struct{})
-	getDups := func(k, v []byte) error {
-		dups[string(k)] = struct{}{}
-		return nil
-	}
-	visitNoDup := func(k, v []byte) error {
-		if _, ok := dups[string(k)]; ok {
-			return nil
-		}
-		return visitor(k, v)
-	}
-	if err := rt.buf.ForEach(bucketName, getDups); err != nil {
-		return err
-	}
-	rt.txMu.Lock()
-	err := unsafeForEach(rt.tx, bucketName, visitNoDup)
-	rt.txMu.Unlock()
-	if err != nil {
-		return err
-	}
-	return rt.buf.ForEach(bucketName, visitor)
-}
-
-func (rt *readTx) reset() {
-	rt.buf.reset()
-	rt.buckets = make(map[string]*bolt.Bucket)
-	rt.tx = nil
-	rt.txWg = new(sync.WaitGroup)
-}
-
-// TODO: create a base type for readTx and concurrentReadTx to avoid duplicated function implementation?
-type concurrentReadTx struct {
-	buf     txReadBuffer
-	txMu    *sync.RWMutex
-	tx      *bolt.Tx
-	buckets map[string]*bolt.Bucket
-	txWg    *sync.WaitGroup
-}
-
-func (rt *concurrentReadTx) Lock()   {}
-func (rt *concurrentReadTx) Unlock() {}
-
-// RLock is no-op. concurrentReadTx does not need to be locked after it is created.
-func (rt *concurrentReadTx) RLock() {}
-
-// RUnlock signals the end of concurrentReadTx.
-func (rt *concurrentReadTx) RUnlock() { rt.txWg.Done() }
-
-func (rt *concurrentReadTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	dups := make(map[string]struct{})
-	getDups := func(k, v []byte) error {
-		dups[string(k)] = struct{}{}
-		return nil
-	}
-	visitNoDup := func(k, v []byte) error {
-		if _, ok := dups[string(k)]; ok {
-			return nil
-		}
-		return visitor(k, v)
-	}
-	if err := rt.buf.ForEach(bucketName, getDups); err != nil {
-		return err
-	}
-	rt.txMu.Lock()
-	err := unsafeForEach(rt.tx, bucketName, visitNoDup)
-	rt.txMu.Unlock()
-	if err != nil {
-		return err
-	}
-	return rt.buf.ForEach(bucketName, visitor)
-}
-
-func (rt *concurrentReadTx) UnsafeRange(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	if endKey == nil {
-		// forbid duplicates for single keys
-		limit = 1
-	}
-	if limit <= 0 {
-		limit = math.MaxInt64
-	}
-	if limit > 1 && !bytes.Equal(bucketName, safeRangeBucket) {
-		panic("do not use unsafeRange on non-keys bucket")
-	}
-	keys, vals := rt.buf.Range(bucketName, key, endKey, limit)
-	if int64(len(keys)) == limit {
-		return keys, vals
-	}
-
-	// find/cache bucket
-	bn := string(bucketName)
-	rt.txMu.RLock()
-	bucket, ok := rt.buckets[bn]
-	rt.txMu.RUnlock()
-	if !ok {
-		rt.txMu.Lock()
-		bucket = rt.tx.Bucket(bucketName)
-		rt.buckets[bn] = bucket
-		rt.txMu.Unlock()
-	}
-
-	// ignore missing bucket since may have been created in this batch
-	if bucket == nil {
-		return keys, vals
-	}
-	rt.txMu.Lock()
-	c := bucket.Cursor()
-	rt.txMu.Unlock()
-
-	k2, v2 := unsafeRange(c, key, endKey, limit-int64(len(keys)))
-	return append(k2, keys...), append(v2, vals...)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/backend/tx_buffer.go b/vendor/go.etcd.io/etcd/mvcc/backend/tx_buffer.go
deleted file mode 100644
index d734638..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/backend/tx_buffer.go
+++ /dev/null
@@ -1,203 +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 backend
-
-import (
-	"bytes"
-	"sort"
-)
-
-// txBuffer handles functionality shared between txWriteBuffer and txReadBuffer.
-type txBuffer struct {
-	buckets map[string]*bucketBuffer
-}
-
-func (txb *txBuffer) reset() {
-	for k, v := range txb.buckets {
-		if v.used == 0 {
-			// demote
-			delete(txb.buckets, k)
-		}
-		v.used = 0
-	}
-}
-
-// txWriteBuffer buffers writes of pending updates that have not yet committed.
-type txWriteBuffer struct {
-	txBuffer
-	seq bool
-}
-
-func (txw *txWriteBuffer) put(bucket, k, v []byte) {
-	txw.seq = false
-	txw.putSeq(bucket, k, v)
-}
-
-func (txw *txWriteBuffer) putSeq(bucket, k, v []byte) {
-	b, ok := txw.buckets[string(bucket)]
-	if !ok {
-		b = newBucketBuffer()
-		txw.buckets[string(bucket)] = b
-	}
-	b.add(k, v)
-}
-
-func (txw *txWriteBuffer) writeback(txr *txReadBuffer) {
-	for k, wb := range txw.buckets {
-		rb, ok := txr.buckets[k]
-		if !ok {
-			delete(txw.buckets, k)
-			txr.buckets[k] = wb
-			continue
-		}
-		if !txw.seq && wb.used > 1 {
-			// assume no duplicate keys
-			sort.Sort(wb)
-		}
-		rb.merge(wb)
-	}
-	txw.reset()
-}
-
-// txReadBuffer accesses buffered updates.
-type txReadBuffer struct{ txBuffer }
-
-func (txr *txReadBuffer) Range(bucketName, key, endKey []byte, limit int64) ([][]byte, [][]byte) {
-	if b := txr.buckets[string(bucketName)]; b != nil {
-		return b.Range(key, endKey, limit)
-	}
-	return nil, nil
-}
-
-func (txr *txReadBuffer) ForEach(bucketName []byte, visitor func(k, v []byte) error) error {
-	if b := txr.buckets[string(bucketName)]; b != nil {
-		return b.ForEach(visitor)
-	}
-	return nil
-}
-
-// unsafeCopy returns a copy of txReadBuffer, caller should acquire backend.readTx.RLock()
-func (txr *txReadBuffer) unsafeCopy() txReadBuffer {
-	txrCopy := txReadBuffer{
-		txBuffer: txBuffer{
-			buckets: make(map[string]*bucketBuffer, len(txr.txBuffer.buckets)),
-		},
-	}
-	for bucketName, bucket := range txr.txBuffer.buckets {
-		txrCopy.txBuffer.buckets[bucketName] = bucket.Copy()
-	}
-	return txrCopy
-}
-
-type kv struct {
-	key []byte
-	val []byte
-}
-
-// bucketBuffer buffers key-value pairs that are pending commit.
-type bucketBuffer struct {
-	buf []kv
-	// used tracks number of elements in use so buf can be reused without reallocation.
-	used int
-}
-
-func newBucketBuffer() *bucketBuffer {
-	return &bucketBuffer{buf: make([]kv, 512), used: 0}
-}
-
-func (bb *bucketBuffer) Range(key, endKey []byte, limit int64) (keys [][]byte, vals [][]byte) {
-	f := func(i int) bool { return bytes.Compare(bb.buf[i].key, key) >= 0 }
-	idx := sort.Search(bb.used, f)
-	if idx < 0 {
-		return nil, nil
-	}
-	if len(endKey) == 0 {
-		if bytes.Equal(key, bb.buf[idx].key) {
-			keys = append(keys, bb.buf[idx].key)
-			vals = append(vals, bb.buf[idx].val)
-		}
-		return keys, vals
-	}
-	if bytes.Compare(endKey, bb.buf[idx].key) <= 0 {
-		return nil, nil
-	}
-	for i := idx; i < bb.used && int64(len(keys)) < limit; i++ {
-		if bytes.Compare(endKey, bb.buf[i].key) <= 0 {
-			break
-		}
-		keys = append(keys, bb.buf[i].key)
-		vals = append(vals, bb.buf[i].val)
-	}
-	return keys, vals
-}
-
-func (bb *bucketBuffer) ForEach(visitor func(k, v []byte) error) error {
-	for i := 0; i < bb.used; i++ {
-		if err := visitor(bb.buf[i].key, bb.buf[i].val); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (bb *bucketBuffer) add(k, v []byte) {
-	bb.buf[bb.used].key, bb.buf[bb.used].val = k, v
-	bb.used++
-	if bb.used == len(bb.buf) {
-		buf := make([]kv, (3*len(bb.buf))/2)
-		copy(buf, bb.buf)
-		bb.buf = buf
-	}
-}
-
-// merge merges data from bb into bbsrc.
-func (bb *bucketBuffer) merge(bbsrc *bucketBuffer) {
-	for i := 0; i < bbsrc.used; i++ {
-		bb.add(bbsrc.buf[i].key, bbsrc.buf[i].val)
-	}
-	if bb.used == bbsrc.used {
-		return
-	}
-	if bytes.Compare(bb.buf[(bb.used-bbsrc.used)-1].key, bbsrc.buf[0].key) < 0 {
-		return
-	}
-
-	sort.Stable(bb)
-
-	// remove duplicates, using only newest update
-	widx := 0
-	for ridx := 1; ridx < bb.used; ridx++ {
-		if !bytes.Equal(bb.buf[ridx].key, bb.buf[widx].key) {
-			widx++
-		}
-		bb.buf[widx] = bb.buf[ridx]
-	}
-	bb.used = widx + 1
-}
-
-func (bb *bucketBuffer) Len() int { return bb.used }
-func (bb *bucketBuffer) Less(i, j int) bool {
-	return bytes.Compare(bb.buf[i].key, bb.buf[j].key) < 0
-}
-func (bb *bucketBuffer) Swap(i, j int) { bb.buf[i], bb.buf[j] = bb.buf[j], bb.buf[i] }
-
-func (bb *bucketBuffer) Copy() *bucketBuffer {
-	bbCopy := bucketBuffer{
-		buf:  make([]kv, len(bb.buf)),
-		used: bb.used,
-	}
-	copy(bbCopy.buf, bb.buf)
-	return &bbCopy
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/doc.go b/vendor/go.etcd.io/etcd/mvcc/doc.go
deleted file mode 100644
index ad5be03..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/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 mvcc defines etcd's stable MVCC storage.
-package mvcc
diff --git a/vendor/go.etcd.io/etcd/mvcc/index.go b/vendor/go.etcd.io/etcd/mvcc/index.go
deleted file mode 100644
index f8cc6df..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/index.go
+++ /dev/null
@@ -1,258 +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 mvcc
-
-import (
-	"sort"
-	"sync"
-
-	"github.com/google/btree"
-	"go.uber.org/zap"
-)
-
-type index interface {
-	Get(key []byte, atRev int64) (rev, created revision, ver int64, err error)
-	Range(key, end []byte, atRev int64) ([][]byte, []revision)
-	Revisions(key, end []byte, atRev int64) []revision
-	Put(key []byte, rev revision)
-	Tombstone(key []byte, rev revision) error
-	RangeSince(key, end []byte, rev int64) []revision
-	Compact(rev int64) map[revision]struct{}
-	Keep(rev int64) map[revision]struct{}
-	Equal(b index) bool
-
-	Insert(ki *keyIndex)
-	KeyIndex(ki *keyIndex) *keyIndex
-}
-
-type treeIndex struct {
-	sync.RWMutex
-	tree *btree.BTree
-	lg   *zap.Logger
-}
-
-func newTreeIndex(lg *zap.Logger) index {
-	return &treeIndex{
-		tree: btree.New(32),
-		lg:   lg,
-	}
-}
-
-func (ti *treeIndex) Put(key []byte, rev revision) {
-	keyi := &keyIndex{key: key}
-
-	ti.Lock()
-	defer ti.Unlock()
-	item := ti.tree.Get(keyi)
-	if item == nil {
-		keyi.put(ti.lg, rev.main, rev.sub)
-		ti.tree.ReplaceOrInsert(keyi)
-		return
-	}
-	okeyi := item.(*keyIndex)
-	okeyi.put(ti.lg, rev.main, rev.sub)
-}
-
-func (ti *treeIndex) Get(key []byte, atRev int64) (modified, created revision, ver int64, err error) {
-	keyi := &keyIndex{key: key}
-	ti.RLock()
-	defer ti.RUnlock()
-	if keyi = ti.keyIndex(keyi); keyi == nil {
-		return revision{}, revision{}, 0, ErrRevisionNotFound
-	}
-	return keyi.get(ti.lg, atRev)
-}
-
-func (ti *treeIndex) KeyIndex(keyi *keyIndex) *keyIndex {
-	ti.RLock()
-	defer ti.RUnlock()
-	return ti.keyIndex(keyi)
-}
-
-func (ti *treeIndex) keyIndex(keyi *keyIndex) *keyIndex {
-	if item := ti.tree.Get(keyi); item != nil {
-		return item.(*keyIndex)
-	}
-	return nil
-}
-
-func (ti *treeIndex) visit(key, end []byte, f func(ki *keyIndex)) {
-	keyi, endi := &keyIndex{key: key}, &keyIndex{key: end}
-
-	ti.RLock()
-	defer ti.RUnlock()
-
-	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if len(endi.key) > 0 && !item.Less(endi) {
-			return false
-		}
-		f(item.(*keyIndex))
-		return true
-	})
-}
-
-func (ti *treeIndex) Revisions(key, end []byte, atRev int64) (revs []revision) {
-	if end == nil {
-		rev, _, _, err := ti.Get(key, atRev)
-		if err != nil {
-			return nil
-		}
-		return []revision{rev}
-	}
-	ti.visit(key, end, func(ki *keyIndex) {
-		if rev, _, _, err := ki.get(ti.lg, atRev); err == nil {
-			revs = append(revs, rev)
-		}
-	})
-	return revs
-}
-
-func (ti *treeIndex) Range(key, end []byte, atRev int64) (keys [][]byte, revs []revision) {
-	if end == nil {
-		rev, _, _, err := ti.Get(key, atRev)
-		if err != nil {
-			return nil, nil
-		}
-		return [][]byte{key}, []revision{rev}
-	}
-	ti.visit(key, end, func(ki *keyIndex) {
-		if rev, _, _, err := ki.get(ti.lg, atRev); err == nil {
-			revs = append(revs, rev)
-			keys = append(keys, ki.key)
-		}
-	})
-	return keys, revs
-}
-
-func (ti *treeIndex) Tombstone(key []byte, rev revision) error {
-	keyi := &keyIndex{key: key}
-
-	ti.Lock()
-	defer ti.Unlock()
-	item := ti.tree.Get(keyi)
-	if item == nil {
-		return ErrRevisionNotFound
-	}
-
-	ki := item.(*keyIndex)
-	return ki.tombstone(ti.lg, rev.main, rev.sub)
-}
-
-// RangeSince returns all revisions from key(including) to end(excluding)
-// at or after the given rev. The returned slice is sorted in the order
-// of revision.
-func (ti *treeIndex) RangeSince(key, end []byte, rev int64) []revision {
-	keyi := &keyIndex{key: key}
-
-	ti.RLock()
-	defer ti.RUnlock()
-
-	if end == nil {
-		item := ti.tree.Get(keyi)
-		if item == nil {
-			return nil
-		}
-		keyi = item.(*keyIndex)
-		return keyi.since(ti.lg, rev)
-	}
-
-	endi := &keyIndex{key: end}
-	var revs []revision
-	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if len(endi.key) > 0 && !item.Less(endi) {
-			return false
-		}
-		curKeyi := item.(*keyIndex)
-		revs = append(revs, curKeyi.since(ti.lg, rev)...)
-		return true
-	})
-	sort.Sort(revisions(revs))
-
-	return revs
-}
-
-func (ti *treeIndex) Compact(rev int64) map[revision]struct{} {
-	available := make(map[revision]struct{})
-	if ti.lg != nil {
-		ti.lg.Info("compact tree index", zap.Int64("revision", rev))
-	} else {
-		plog.Printf("store.index: compact %d", rev)
-	}
-	ti.Lock()
-	clone := ti.tree.Clone()
-	ti.Unlock()
-
-	clone.Ascend(func(item btree.Item) bool {
-		keyi := item.(*keyIndex)
-		//Lock is needed here to prevent modification to the keyIndex while
-		//compaction is going on or revision added to empty before deletion
-		ti.Lock()
-		keyi.compact(ti.lg, rev, available)
-		if keyi.isEmpty() {
-			item := ti.tree.Delete(keyi)
-			if item == nil {
-				if ti.lg != nil {
-					ti.lg.Panic("failed to delete during compaction")
-				} else {
-					plog.Panic("store.index: unexpected delete failure during compaction")
-				}
-			}
-		}
-		ti.Unlock()
-		return true
-	})
-	return available
-}
-
-// Keep finds all revisions to be kept for a Compaction at the given rev.
-func (ti *treeIndex) Keep(rev int64) map[revision]struct{} {
-	available := make(map[revision]struct{})
-	ti.RLock()
-	defer ti.RUnlock()
-	ti.tree.Ascend(func(i btree.Item) bool {
-		keyi := i.(*keyIndex)
-		keyi.keep(rev, available)
-		return true
-	})
-	return available
-}
-
-func (ti *treeIndex) Equal(bi index) bool {
-	b := bi.(*treeIndex)
-
-	if ti.tree.Len() != b.tree.Len() {
-		return false
-	}
-
-	equal := true
-
-	ti.tree.Ascend(func(item btree.Item) bool {
-		aki := item.(*keyIndex)
-		bki := b.tree.Get(item).(*keyIndex)
-		if !aki.equal(bki) {
-			equal = false
-			return false
-		}
-		return true
-	})
-
-	return equal
-}
-
-func (ti *treeIndex) Insert(ki *keyIndex) {
-	ti.Lock()
-	defer ti.Unlock()
-	ti.tree.ReplaceOrInsert(ki)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/key_index.go b/vendor/go.etcd.io/etcd/mvcc/key_index.go
deleted file mode 100644
index cf77cb4..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/key_index.go
+++ /dev/null
@@ -1,402 +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 mvcc
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-
-	"github.com/google/btree"
-	"go.uber.org/zap"
-)
-
-var (
-	ErrRevisionNotFound = errors.New("mvcc: revision not found")
-)
-
-// keyIndex stores the revisions of a key in the backend.
-// Each keyIndex has at least one key generation.
-// Each generation might have several key versions.
-// Tombstone on a key appends an tombstone version at the end
-// of the current generation and creates a new empty generation.
-// Each version of a key has an index pointing to the backend.
-//
-// For example: put(1.0);put(2.0);tombstone(3.0);put(4.0);tombstone(5.0) on key "foo"
-// generate a keyIndex:
-// key:     "foo"
-// rev: 5
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//    {1.0, 2.0, 3.0(t)}
-//
-// Compact a keyIndex removes the versions with smaller or equal to
-// rev except the largest one. If the generation becomes empty
-// during compaction, it will be removed. if all the generations get
-// removed, the keyIndex should be removed.
-//
-// For example:
-// compact(2) on the previous example
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//    {2.0, 3.0(t)}
-//
-// compact(4)
-// generations:
-//    {empty}
-//    {4.0, 5.0(t)}
-//
-// compact(5):
-// generations:
-//    {empty} -> key SHOULD be removed.
-//
-// compact(6):
-// generations:
-//    {empty} -> key SHOULD be removed.
-type keyIndex struct {
-	key         []byte
-	modified    revision // the main rev of the last modification
-	generations []generation
-}
-
-// put puts a revision to the keyIndex.
-func (ki *keyIndex) put(lg *zap.Logger, main int64, sub int64) {
-	rev := revision{main: main, sub: sub}
-
-	if !rev.GreaterThan(ki.modified) {
-		if lg != nil {
-			lg.Panic(
-				"'put' with an unexpected smaller revision",
-				zap.Int64("given-revision-main", rev.main),
-				zap.Int64("given-revision-sub", rev.sub),
-				zap.Int64("modified-revision-main", ki.modified.main),
-				zap.Int64("modified-revision-sub", ki.modified.sub),
-			)
-		} else {
-			plog.Panicf("store.keyindex: put with unexpected smaller revision [%v / %v]", rev, ki.modified)
-		}
-	}
-	if len(ki.generations) == 0 {
-		ki.generations = append(ki.generations, generation{})
-	}
-	g := &ki.generations[len(ki.generations)-1]
-	if len(g.revs) == 0 { // create a new key
-		keysGauge.Inc()
-		g.created = rev
-	}
-	g.revs = append(g.revs, rev)
-	g.ver++
-	ki.modified = rev
-}
-
-func (ki *keyIndex) restore(lg *zap.Logger, created, modified revision, ver int64) {
-	if len(ki.generations) != 0 {
-		if lg != nil {
-			lg.Panic(
-				"'restore' got an unexpected non-empty generations",
-				zap.Int("generations-size", len(ki.generations)),
-			)
-		} else {
-			plog.Panicf("store.keyindex: cannot restore non-empty keyIndex")
-		}
-	}
-
-	ki.modified = modified
-	g := generation{created: created, ver: ver, revs: []revision{modified}}
-	ki.generations = append(ki.generations, g)
-	keysGauge.Inc()
-}
-
-// tombstone puts a revision, pointing to a tombstone, to the keyIndex.
-// It also creates a new empty generation in the keyIndex.
-// It returns ErrRevisionNotFound when tombstone on an empty generation.
-func (ki *keyIndex) tombstone(lg *zap.Logger, main int64, sub int64) error {
-	if ki.isEmpty() {
-		if lg != nil {
-			lg.Panic(
-				"'tombstone' got an unexpected empty keyIndex",
-				zap.String("key", string(ki.key)),
-			)
-		} else {
-			plog.Panicf("store.keyindex: unexpected tombstone on empty keyIndex %s", string(ki.key))
-		}
-	}
-	if ki.generations[len(ki.generations)-1].isEmpty() {
-		return ErrRevisionNotFound
-	}
-	ki.put(lg, main, sub)
-	ki.generations = append(ki.generations, generation{})
-	keysGauge.Dec()
-	return nil
-}
-
-// get gets the modified, created revision and version of the key that satisfies the given atRev.
-// Rev must be higher than or equal to the given atRev.
-func (ki *keyIndex) get(lg *zap.Logger, atRev int64) (modified, created revision, ver int64, err error) {
-	if ki.isEmpty() {
-		if lg != nil {
-			lg.Panic(
-				"'get' got an unexpected empty keyIndex",
-				zap.String("key", string(ki.key)),
-			)
-		} else {
-			plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key))
-		}
-	}
-	g := ki.findGeneration(atRev)
-	if g.isEmpty() {
-		return revision{}, revision{}, 0, ErrRevisionNotFound
-	}
-
-	n := g.walk(func(rev revision) bool { return rev.main > atRev })
-	if n != -1 {
-		return g.revs[n], g.created, g.ver - int64(len(g.revs)-n-1), nil
-	}
-
-	return revision{}, revision{}, 0, ErrRevisionNotFound
-}
-
-// since returns revisions since the given rev. Only the revision with the
-// largest sub revision will be returned if multiple revisions have the same
-// main revision.
-func (ki *keyIndex) since(lg *zap.Logger, rev int64) []revision {
-	if ki.isEmpty() {
-		if lg != nil {
-			lg.Panic(
-				"'since' got an unexpected empty keyIndex",
-				zap.String("key", string(ki.key)),
-			)
-		} else {
-			plog.Panicf("store.keyindex: unexpected get on empty keyIndex %s", string(ki.key))
-		}
-	}
-	since := revision{rev, 0}
-	var gi int
-	// find the generations to start checking
-	for gi = len(ki.generations) - 1; gi > 0; gi-- {
-		g := ki.generations[gi]
-		if g.isEmpty() {
-			continue
-		}
-		if since.GreaterThan(g.created) {
-			break
-		}
-	}
-
-	var revs []revision
-	var last int64
-	for ; gi < len(ki.generations); gi++ {
-		for _, r := range ki.generations[gi].revs {
-			if since.GreaterThan(r) {
-				continue
-			}
-			if r.main == last {
-				// replace the revision with a new one that has higher sub value,
-				// because the original one should not be seen by external
-				revs[len(revs)-1] = r
-				continue
-			}
-			revs = append(revs, r)
-			last = r.main
-		}
-	}
-	return revs
-}
-
-// compact compacts a keyIndex by removing the versions with smaller or equal
-// revision than the given atRev except the largest one (If the largest one is
-// a tombstone, it will not be kept).
-// If a generation becomes empty during compaction, it will be removed.
-func (ki *keyIndex) compact(lg *zap.Logger, atRev int64, available map[revision]struct{}) {
-	if ki.isEmpty() {
-		if lg != nil {
-			lg.Panic(
-				"'compact' got an unexpected empty keyIndex",
-				zap.String("key", string(ki.key)),
-			)
-		} else {
-			plog.Panicf("store.keyindex: unexpected compact on empty keyIndex %s", string(ki.key))
-		}
-	}
-
-	genIdx, revIndex := ki.doCompact(atRev, available)
-
-	g := &ki.generations[genIdx]
-	if !g.isEmpty() {
-		// remove the previous contents.
-		if revIndex != -1 {
-			g.revs = g.revs[revIndex:]
-		}
-		// remove any tombstone
-		if len(g.revs) == 1 && genIdx != len(ki.generations)-1 {
-			delete(available, g.revs[0])
-			genIdx++
-		}
-	}
-
-	// remove the previous generations.
-	ki.generations = ki.generations[genIdx:]
-}
-
-// keep finds the revision to be kept if compact is called at given atRev.
-func (ki *keyIndex) keep(atRev int64, available map[revision]struct{}) {
-	if ki.isEmpty() {
-		return
-	}
-
-	genIdx, revIndex := ki.doCompact(atRev, available)
-	g := &ki.generations[genIdx]
-	if !g.isEmpty() {
-		// remove any tombstone
-		if revIndex == len(g.revs)-1 && genIdx != len(ki.generations)-1 {
-			delete(available, g.revs[revIndex])
-		}
-	}
-}
-
-func (ki *keyIndex) doCompact(atRev int64, available map[revision]struct{}) (genIdx int, revIndex int) {
-	// walk until reaching the first revision smaller or equal to "atRev",
-	// and add the revision to the available map
-	f := func(rev revision) bool {
-		if rev.main <= atRev {
-			available[rev] = struct{}{}
-			return false
-		}
-		return true
-	}
-
-	genIdx, g := 0, &ki.generations[0]
-	// find first generation includes atRev or created after atRev
-	for genIdx < len(ki.generations)-1 {
-		if tomb := g.revs[len(g.revs)-1].main; tomb > atRev {
-			break
-		}
-		genIdx++
-		g = &ki.generations[genIdx]
-	}
-
-	revIndex = g.walk(f)
-
-	return genIdx, revIndex
-}
-
-func (ki *keyIndex) isEmpty() bool {
-	return len(ki.generations) == 1 && ki.generations[0].isEmpty()
-}
-
-// findGeneration finds out the generation of the keyIndex that the
-// given rev belongs to. If the given rev is at the gap of two generations,
-// which means that the key does not exist at the given rev, it returns nil.
-func (ki *keyIndex) findGeneration(rev int64) *generation {
-	lastg := len(ki.generations) - 1
-	cg := lastg
-
-	for cg >= 0 {
-		if len(ki.generations[cg].revs) == 0 {
-			cg--
-			continue
-		}
-		g := ki.generations[cg]
-		if cg != lastg {
-			if tomb := g.revs[len(g.revs)-1].main; tomb <= rev {
-				return nil
-			}
-		}
-		if g.revs[0].main <= rev {
-			return &ki.generations[cg]
-		}
-		cg--
-	}
-	return nil
-}
-
-func (ki *keyIndex) Less(b btree.Item) bool {
-	return bytes.Compare(ki.key, b.(*keyIndex).key) == -1
-}
-
-func (ki *keyIndex) equal(b *keyIndex) bool {
-	if !bytes.Equal(ki.key, b.key) {
-		return false
-	}
-	if ki.modified != b.modified {
-		return false
-	}
-	if len(ki.generations) != len(b.generations) {
-		return false
-	}
-	for i := range ki.generations {
-		ag, bg := ki.generations[i], b.generations[i]
-		if !ag.equal(bg) {
-			return false
-		}
-	}
-	return true
-}
-
-func (ki *keyIndex) String() string {
-	var s string
-	for _, g := range ki.generations {
-		s += g.String()
-	}
-	return s
-}
-
-// generation contains multiple revisions of a key.
-type generation struct {
-	ver     int64
-	created revision // when the generation is created (put in first revision).
-	revs    []revision
-}
-
-func (g *generation) isEmpty() bool { return g == nil || len(g.revs) == 0 }
-
-// walk walks through the revisions in the generation in descending order.
-// It passes the revision to the given function.
-// walk returns until: 1. it finishes walking all pairs 2. the function returns false.
-// walk returns the position at where it stopped. If it stopped after
-// finishing walking, -1 will be returned.
-func (g *generation) walk(f func(rev revision) bool) int {
-	l := len(g.revs)
-	for i := range g.revs {
-		ok := f(g.revs[l-i-1])
-		if !ok {
-			return l - i - 1
-		}
-	}
-	return -1
-}
-
-func (g *generation) String() string {
-	return fmt.Sprintf("g: created[%d] ver[%d], revs %#v\n", g.created, g.ver, g.revs)
-}
-
-func (g generation) equal(b generation) bool {
-	if g.ver != b.ver {
-		return false
-	}
-	if len(g.revs) != len(b.revs) {
-		return false
-	}
-
-	for i := range g.revs {
-		ar, br := g.revs[i], b.revs[i]
-		if ar != br {
-			return false
-		}
-	}
-	return true
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/kv.go b/vendor/go.etcd.io/etcd/mvcc/kv.go
deleted file mode 100644
index 8e898a5..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/kv.go
+++ /dev/null
@@ -1,149 +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 mvcc
-
-import (
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-type RangeOptions struct {
-	Limit int64
-	Rev   int64
-	Count bool
-}
-
-type RangeResult struct {
-	KVs   []mvccpb.KeyValue
-	Rev   int64
-	Count int
-}
-
-type ReadView interface {
-	// FirstRev returns the first KV revision at the time of opening the txn.
-	// After a compaction, the first revision increases to the compaction
-	// revision.
-	FirstRev() int64
-
-	// Rev returns the revision of the KV at the time of opening the txn.
-	Rev() int64
-
-	// Range gets the keys in the range at rangeRev.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	// If rangeRev <=0, range gets the keys at currentRev.
-	// If `end` is nil, the request returns the key.
-	// If `end` is not nil and not empty, it gets the keys in range [key, range_end).
-	// If `end` is not nil and empty, it gets the keys greater than or equal to key.
-	// Limit limits the number of keys returned.
-	// If the required rev is compacted, ErrCompacted will be returned.
-	Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error)
-}
-
-// TxnRead represents a read-only transaction with operations that will not
-// block other read transactions.
-type TxnRead interface {
-	ReadView
-	// End marks the transaction is complete and ready to commit.
-	End()
-}
-
-type WriteView interface {
-	// DeleteRange deletes the given range from the store.
-	// A deleteRange increases the rev of the store if any key in the range exists.
-	// The number of key deleted will be returned.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	// It also generates one event for each key delete in the event history.
-	// if the `end` is nil, deleteRange deletes the key.
-	// if the `end` is not nil, deleteRange deletes the keys in range [key, range_end).
-	DeleteRange(key, end []byte) (n, rev int64)
-
-	// Put puts the given key, value into the store. Put also takes additional argument lease to
-	// attach a lease to a key-value pair as meta-data. KV implementation does not validate the lease
-	// id.
-	// A put also increases the rev of the store, and generates one event in the event history.
-	// The returned rev is the current revision of the KV when the operation is executed.
-	Put(key, value []byte, lease lease.LeaseID) (rev int64)
-}
-
-// TxnWrite represents a transaction that can modify the store.
-type TxnWrite interface {
-	TxnRead
-	WriteView
-	// Changes gets the changes made since opening the write txn.
-	Changes() []mvccpb.KeyValue
-}
-
-// txnReadWrite coerces a read txn to a write, panicking on any write operation.
-type txnReadWrite struct{ TxnRead }
-
-func (trw *txnReadWrite) DeleteRange(key, end []byte) (n, rev int64) { panic("unexpected DeleteRange") }
-func (trw *txnReadWrite) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	panic("unexpected Put")
-}
-func (trw *txnReadWrite) Changes() []mvccpb.KeyValue { return nil }
-
-func NewReadOnlyTxnWrite(txn TxnRead) TxnWrite { return &txnReadWrite{txn} }
-
-type KV interface {
-	ReadView
-	WriteView
-
-	// Read creates a read transaction.
-	Read() TxnRead
-
-	// Write creates a write transaction.
-	Write() TxnWrite
-
-	// Hash computes the hash of the KV's backend.
-	Hash() (hash uint32, revision int64, err error)
-
-	// HashByRev computes the hash of all MVCC revisions up to a given revision.
-	HashByRev(rev int64) (hash uint32, revision int64, compactRev int64, err error)
-
-	// Compact frees all superseded keys with revisions less than rev.
-	Compact(rev int64) (<-chan struct{}, error)
-
-	// Commit commits outstanding txns into the underlying backend.
-	Commit()
-
-	// Restore restores the KV store from a backend.
-	Restore(b backend.Backend) error
-	Close() error
-}
-
-// WatchableKV is a KV that can be watched.
-type WatchableKV interface {
-	KV
-	Watchable
-}
-
-// Watchable is the interface that wraps the NewWatchStream function.
-type Watchable interface {
-	// NewWatchStream returns a WatchStream that can be used to
-	// watch events happened or happening on the KV.
-	NewWatchStream() WatchStream
-}
-
-// ConsistentWatchableKV is a WatchableKV that understands the consistency
-// algorithm and consistent index.
-// If the consistent index of executing entry is not larger than the
-// consistent index of ConsistentWatchableKV, all operations in
-// this entry are skipped and return empty response.
-type ConsistentWatchableKV interface {
-	WatchableKV
-	// ConsistentIndex returns the current consistent index of the KV.
-	ConsistentIndex() uint64
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/kv_view.go b/vendor/go.etcd.io/etcd/mvcc/kv_view.go
deleted file mode 100644
index bd2e777..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/kv_view.go
+++ /dev/null
@@ -1,51 +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 mvcc
-
-import "go.etcd.io/etcd/lease"
-
-type readView struct{ kv KV }
-
-func (rv *readView) FirstRev() int64 {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.FirstRev()
-}
-
-func (rv *readView) Rev() int64 {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.Rev()
-}
-
-func (rv *readView) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	tr := rv.kv.Read()
-	defer tr.End()
-	return tr.Range(key, end, ro)
-}
-
-type writeView struct{ kv KV }
-
-func (wv *writeView) DeleteRange(key, end []byte) (n, rev int64) {
-	tw := wv.kv.Write()
-	defer tw.End()
-	return tw.DeleteRange(key, end)
-}
-
-func (wv *writeView) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	tw := wv.kv.Write()
-	defer tw.End()
-	return tw.Put(key, value, lease)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/kvstore.go b/vendor/go.etcd.io/etcd/mvcc/kvstore.go
deleted file mode 100644
index e367ebb..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/kvstore.go
+++ /dev/null
@@ -1,620 +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 mvcc
-
-import (
-	"context"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"hash/crc32"
-	"math"
-	"sync"
-	"sync/atomic"
-	"time"
-
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-	"go.etcd.io/etcd/pkg/schedule"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-)
-
-var (
-	keyBucketName  = []byte("key")
-	metaBucketName = []byte("meta")
-
-	consistentIndexKeyName  = []byte("consistent_index")
-	scheduledCompactKeyName = []byte("scheduledCompactRev")
-	finishedCompactKeyName  = []byte("finishedCompactRev")
-
-	ErrCompacted = errors.New("mvcc: required revision has been compacted")
-	ErrFutureRev = errors.New("mvcc: required revision is a future revision")
-	ErrCanceled  = errors.New("mvcc: watcher is canceled")
-	ErrClosed    = errors.New("mvcc: closed")
-
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "mvcc")
-)
-
-const (
-	// markedRevBytesLen is the byte length of marked revision.
-	// The first `revBytesLen` bytes represents a normal revision. The last
-	// one byte is the mark.
-	markedRevBytesLen      = revBytesLen + 1
-	markBytePosition       = markedRevBytesLen - 1
-	markTombstone     byte = 't'
-)
-
-var restoreChunkKeys = 10000 // non-const for testing
-var defaultCompactBatchLimit = 1000
-
-// ConsistentIndexGetter is an interface that wraps the Get method.
-// Consistent index is the offset of an entry in a consistent replicated log.
-type ConsistentIndexGetter interface {
-	// ConsistentIndex returns the consistent index of current executing entry.
-	ConsistentIndex() uint64
-}
-
-type StoreConfig struct {
-	CompactionBatchLimit int
-}
-
-type store struct {
-	ReadView
-	WriteView
-
-	// consistentIndex caches the "consistent_index" key's value. Accessed
-	// through atomics so must be 64-bit aligned.
-	consistentIndex uint64
-
-	cfg StoreConfig
-
-	// mu read locks for txns and write locks for non-txn store changes.
-	mu sync.RWMutex
-
-	ig ConsistentIndexGetter
-
-	b       backend.Backend
-	kvindex index
-
-	le lease.Lessor
-
-	// revMuLock protects currentRev and compactMainRev.
-	// Locked at end of write txn and released after write txn unlock lock.
-	// Locked before locking read txn and released after locking.
-	revMu sync.RWMutex
-	// currentRev is the revision of the last completed transaction.
-	currentRev int64
-	// compactMainRev is the main revision of the last compaction.
-	compactMainRev int64
-
-	// bytesBuf8 is a byte slice of length 8
-	// to avoid a repetitive allocation in saveIndex.
-	bytesBuf8 []byte
-
-	fifoSched schedule.Scheduler
-
-	stopc chan struct{}
-
-	lg *zap.Logger
-}
-
-// NewStore returns a new store. It is useful to create a store inside
-// mvcc pkg. It should only be used for testing externally.
-func NewStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter, cfg StoreConfig) *store {
-	if cfg.CompactionBatchLimit == 0 {
-		cfg.CompactionBatchLimit = defaultCompactBatchLimit
-	}
-	s := &store{
-		cfg:     cfg,
-		b:       b,
-		ig:      ig,
-		kvindex: newTreeIndex(lg),
-
-		le: le,
-
-		currentRev:     1,
-		compactMainRev: -1,
-
-		bytesBuf8: make([]byte, 8),
-		fifoSched: schedule.NewFIFOScheduler(),
-
-		stopc: make(chan struct{}),
-
-		lg: lg,
-	}
-	s.ReadView = &readView{s}
-	s.WriteView = &writeView{s}
-	if s.le != nil {
-		s.le.SetRangeDeleter(func() lease.TxnDelete { return s.Write() })
-	}
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tx.UnsafeCreateBucket(keyBucketName)
-	tx.UnsafeCreateBucket(metaBucketName)
-	tx.Unlock()
-	s.b.ForceCommit()
-
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if err := s.restore(); err != nil {
-		// TODO: return the error instead of panic here?
-		panic("failed to recover store from backend")
-	}
-
-	return s
-}
-
-func (s *store) compactBarrier(ctx context.Context, ch chan struct{}) {
-	if ctx == nil || ctx.Err() != nil {
-		s.mu.Lock()
-		select {
-		case <-s.stopc:
-		default:
-			f := func(ctx context.Context) { s.compactBarrier(ctx, ch) }
-			s.fifoSched.Schedule(f)
-		}
-		s.mu.Unlock()
-		return
-	}
-	close(ch)
-}
-
-func (s *store) Hash() (hash uint32, revision int64, err error) {
-	// TODO: hash and revision could be inconsistent, one possible fix is to add s.revMu.RLock() at the beginning of function, which is costly
-	start := time.Now()
-
-	s.b.ForceCommit()
-	h, err := s.b.Hash(DefaultIgnores)
-
-	hashSec.Observe(time.Since(start).Seconds())
-	return h, s.currentRev, err
-}
-
-func (s *store) HashByRev(rev int64) (hash uint32, currentRev int64, compactRev int64, err error) {
-	start := time.Now()
-
-	s.mu.RLock()
-	s.revMu.RLock()
-	compactRev, currentRev = s.compactMainRev, s.currentRev
-	s.revMu.RUnlock()
-
-	if rev > 0 && rev <= compactRev {
-		s.mu.RUnlock()
-		return 0, 0, compactRev, ErrCompacted
-	} else if rev > 0 && rev > currentRev {
-		s.mu.RUnlock()
-		return 0, currentRev, 0, ErrFutureRev
-	}
-
-	if rev == 0 {
-		rev = currentRev
-	}
-	keep := s.kvindex.Keep(rev)
-
-	tx := s.b.ReadTx()
-	tx.RLock()
-	defer tx.RUnlock()
-	s.mu.RUnlock()
-
-	upper := revision{main: rev + 1}
-	lower := revision{main: compactRev + 1}
-	h := crc32.New(crc32.MakeTable(crc32.Castagnoli))
-
-	h.Write(keyBucketName)
-	err = tx.UnsafeForEach(keyBucketName, func(k, v []byte) error {
-		kr := bytesToRev(k)
-		if !upper.GreaterThan(kr) {
-			return nil
-		}
-		// skip revisions that are scheduled for deletion
-		// due to compacting; don't skip if there isn't one.
-		if lower.GreaterThan(kr) && len(keep) > 0 {
-			if _, ok := keep[kr]; !ok {
-				return nil
-			}
-		}
-		h.Write(k)
-		h.Write(v)
-		return nil
-	})
-	hash = h.Sum32()
-
-	hashRevSec.Observe(time.Since(start).Seconds())
-	return hash, currentRev, compactRev, err
-}
-
-func (s *store) updateCompactRev(rev int64) (<-chan struct{}, error) {
-	s.revMu.Lock()
-	if rev <= s.compactMainRev {
-		ch := make(chan struct{})
-		f := func(ctx context.Context) { s.compactBarrier(ctx, ch) }
-		s.fifoSched.Schedule(f)
-		s.revMu.Unlock()
-		return ch, ErrCompacted
-	}
-	if rev > s.currentRev {
-		s.revMu.Unlock()
-		return nil, ErrFutureRev
-	}
-
-	s.compactMainRev = rev
-
-	rbytes := newRevBytes()
-	revToBytes(revision{main: rev}, rbytes)
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tx.UnsafePut(metaBucketName, scheduledCompactKeyName, rbytes)
-	tx.Unlock()
-	// ensure that desired compaction is persisted
-	s.b.ForceCommit()
-
-	s.revMu.Unlock()
-
-	return nil, nil
-}
-
-func (s *store) compact(rev int64) (<-chan struct{}, error) {
-	start := time.Now()
-	keep := s.kvindex.Compact(rev)
-	ch := make(chan struct{})
-	var j = func(ctx context.Context) {
-		if ctx.Err() != nil {
-			s.compactBarrier(ctx, ch)
-			return
-		}
-		if !s.scheduleCompaction(rev, keep) {
-			s.compactBarrier(nil, ch)
-			return
-		}
-		close(ch)
-	}
-
-	s.fifoSched.Schedule(j)
-
-	indexCompactionPauseMs.Observe(float64(time.Since(start) / time.Millisecond))
-	return ch, nil
-}
-
-func (s *store) compactLockfree(rev int64) (<-chan struct{}, error) {
-	ch, err := s.updateCompactRev(rev)
-	if nil != err {
-		return ch, err
-	}
-
-	return s.compact(rev)
-}
-
-func (s *store) Compact(rev int64) (<-chan struct{}, error) {
-	s.mu.Lock()
-
-	ch, err := s.updateCompactRev(rev)
-
-	if err != nil {
-		s.mu.Unlock()
-		return ch, err
-	}
-	s.mu.Unlock()
-
-	return s.compact(rev)
-}
-
-// DefaultIgnores is a map of keys to ignore in hash checking.
-var DefaultIgnores map[backend.IgnoreKey]struct{}
-
-func init() {
-	DefaultIgnores = map[backend.IgnoreKey]struct{}{
-		// consistent index might be changed due to v2 internal sync, which
-		// is not controllable by the user.
-		{Bucket: string(metaBucketName), Key: string(consistentIndexKeyName)}: {},
-	}
-}
-
-func (s *store) Commit() {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	tx := s.b.BatchTx()
-	tx.Lock()
-	s.saveIndex(tx)
-	tx.Unlock()
-	s.b.ForceCommit()
-}
-
-func (s *store) Restore(b backend.Backend) error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	close(s.stopc)
-	s.fifoSched.Stop()
-
-	atomic.StoreUint64(&s.consistentIndex, 0)
-	s.b = b
-	s.kvindex = newTreeIndex(s.lg)
-	s.currentRev = 1
-	s.compactMainRev = -1
-	s.fifoSched = schedule.NewFIFOScheduler()
-	s.stopc = make(chan struct{})
-
-	return s.restore()
-}
-
-func (s *store) restore() error {
-	s.setupMetricsReporter()
-
-	min, max := newRevBytes(), newRevBytes()
-	revToBytes(revision{main: 1}, min)
-	revToBytes(revision{main: math.MaxInt64, sub: math.MaxInt64}, max)
-
-	keyToLease := make(map[string]lease.LeaseID)
-
-	// restore index
-	tx := s.b.BatchTx()
-	tx.Lock()
-
-	_, finishedCompactBytes := tx.UnsafeRange(metaBucketName, finishedCompactKeyName, nil, 0)
-	if len(finishedCompactBytes) != 0 {
-		s.compactMainRev = bytesToRev(finishedCompactBytes[0]).main
-
-		if s.lg != nil {
-			s.lg.Info(
-				"restored last compact revision",
-				zap.String("meta-bucket-name", string(metaBucketName)),
-				zap.String("meta-bucket-name-key", string(finishedCompactKeyName)),
-				zap.Int64("restored-compact-revision", s.compactMainRev),
-			)
-		} else {
-			plog.Printf("restore compact to %d", s.compactMainRev)
-		}
-	}
-	_, scheduledCompactBytes := tx.UnsafeRange(metaBucketName, scheduledCompactKeyName, nil, 0)
-	scheduledCompact := int64(0)
-	if len(scheduledCompactBytes) != 0 {
-		scheduledCompact = bytesToRev(scheduledCompactBytes[0]).main
-	}
-
-	// index keys concurrently as they're loaded in from tx
-	keysGauge.Set(0)
-	rkvc, revc := restoreIntoIndex(s.lg, s.kvindex)
-	for {
-		keys, vals := tx.UnsafeRange(keyBucketName, min, max, int64(restoreChunkKeys))
-		if len(keys) == 0 {
-			break
-		}
-		// rkvc blocks if the total pending keys exceeds the restore
-		// chunk size to keep keys from consuming too much memory.
-		restoreChunk(s.lg, rkvc, keys, vals, keyToLease)
-		if len(keys) < restoreChunkKeys {
-			// partial set implies final set
-			break
-		}
-		// next set begins after where this one ended
-		newMin := bytesToRev(keys[len(keys)-1][:revBytesLen])
-		newMin.sub++
-		revToBytes(newMin, min)
-	}
-	close(rkvc)
-	s.currentRev = <-revc
-
-	// keys in the range [compacted revision -N, compaction] might all be deleted due to compaction.
-	// the correct revision should be set to compaction revision in the case, not the largest revision
-	// we have seen.
-	if s.currentRev < s.compactMainRev {
-		s.currentRev = s.compactMainRev
-	}
-	if scheduledCompact <= s.compactMainRev {
-		scheduledCompact = 0
-	}
-
-	for key, lid := range keyToLease {
-		if s.le == nil {
-			panic("no lessor to attach lease")
-		}
-		err := s.le.Attach(lid, []lease.LeaseItem{{Key: key}})
-		if err != nil {
-			if s.lg != nil {
-				s.lg.Warn(
-					"failed to attach a lease",
-					zap.String("lease-id", fmt.Sprintf("%016x", lid)),
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("unexpected Attach error: %v", err)
-			}
-		}
-	}
-
-	tx.Unlock()
-
-	if scheduledCompact != 0 {
-		s.compactLockfree(scheduledCompact)
-
-		if s.lg != nil {
-			s.lg.Info(
-				"resume scheduled compaction",
-				zap.String("meta-bucket-name", string(metaBucketName)),
-				zap.String("meta-bucket-name-key", string(scheduledCompactKeyName)),
-				zap.Int64("scheduled-compact-revision", scheduledCompact),
-			)
-		} else {
-			plog.Printf("resume scheduled compaction at %d", scheduledCompact)
-		}
-	}
-
-	return nil
-}
-
-type revKeyValue struct {
-	key  []byte
-	kv   mvccpb.KeyValue
-	kstr string
-}
-
-func restoreIntoIndex(lg *zap.Logger, idx index) (chan<- revKeyValue, <-chan int64) {
-	rkvc, revc := make(chan revKeyValue, restoreChunkKeys), make(chan int64, 1)
-	go func() {
-		currentRev := int64(1)
-		defer func() { revc <- currentRev }()
-		// restore the tree index from streaming the unordered index.
-		kiCache := make(map[string]*keyIndex, restoreChunkKeys)
-		for rkv := range rkvc {
-			ki, ok := kiCache[rkv.kstr]
-			// purge kiCache if many keys but still missing in the cache
-			if !ok && len(kiCache) >= restoreChunkKeys {
-				i := 10
-				for k := range kiCache {
-					delete(kiCache, k)
-					if i--; i == 0 {
-						break
-					}
-				}
-			}
-			// cache miss, fetch from tree index if there
-			if !ok {
-				ki = &keyIndex{key: rkv.kv.Key}
-				if idxKey := idx.KeyIndex(ki); idxKey != nil {
-					kiCache[rkv.kstr], ki = idxKey, idxKey
-					ok = true
-				}
-			}
-			rev := bytesToRev(rkv.key)
-			currentRev = rev.main
-			if ok {
-				if isTombstone(rkv.key) {
-					ki.tombstone(lg, rev.main, rev.sub)
-					continue
-				}
-				ki.put(lg, rev.main, rev.sub)
-			} else if !isTombstone(rkv.key) {
-				ki.restore(lg, revision{rkv.kv.CreateRevision, 0}, rev, rkv.kv.Version)
-				idx.Insert(ki)
-				kiCache[rkv.kstr] = ki
-			}
-		}
-	}()
-	return rkvc, revc
-}
-
-func restoreChunk(lg *zap.Logger, kvc chan<- revKeyValue, keys, vals [][]byte, keyToLease map[string]lease.LeaseID) {
-	for i, key := range keys {
-		rkv := revKeyValue{key: key}
-		if err := rkv.kv.Unmarshal(vals[i]); err != nil {
-			if lg != nil {
-				lg.Fatal("failed to unmarshal mvccpb.KeyValue", zap.Error(err))
-			} else {
-				plog.Fatalf("cannot unmarshal event: %v", err)
-			}
-		}
-		rkv.kstr = string(rkv.kv.Key)
-		if isTombstone(key) {
-			delete(keyToLease, rkv.kstr)
-		} else if lid := lease.LeaseID(rkv.kv.Lease); lid != lease.NoLease {
-			keyToLease[rkv.kstr] = lid
-		} else {
-			delete(keyToLease, rkv.kstr)
-		}
-		kvc <- rkv
-	}
-}
-
-func (s *store) Close() error {
-	close(s.stopc)
-	s.fifoSched.Stop()
-	return nil
-}
-
-func (s *store) saveIndex(tx backend.BatchTx) {
-	if s.ig == nil {
-		return
-	}
-	bs := s.bytesBuf8
-	ci := s.ig.ConsistentIndex()
-	binary.BigEndian.PutUint64(bs, ci)
-	// put the index into the underlying backend
-	// tx has been locked in TxnBegin, so there is no need to lock it again
-	tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs)
-	atomic.StoreUint64(&s.consistentIndex, ci)
-}
-
-func (s *store) ConsistentIndex() uint64 {
-	if ci := atomic.LoadUint64(&s.consistentIndex); ci > 0 {
-		return ci
-	}
-	tx := s.b.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-	_, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0)
-	if len(vs) == 0 {
-		return 0
-	}
-	v := binary.BigEndian.Uint64(vs[0])
-	atomic.StoreUint64(&s.consistentIndex, v)
-	return v
-}
-
-func (s *store) setupMetricsReporter() {
-	b := s.b
-	reportDbTotalSizeInBytesMu.Lock()
-	reportDbTotalSizeInBytes = func() float64 { return float64(b.Size()) }
-	reportDbTotalSizeInBytesMu.Unlock()
-	reportDbTotalSizeInBytesDebugMu.Lock()
-	reportDbTotalSizeInBytesDebug = func() float64 { return float64(b.Size()) }
-	reportDbTotalSizeInBytesDebugMu.Unlock()
-	reportDbTotalSizeInUseInBytesMu.Lock()
-	reportDbTotalSizeInUseInBytes = func() float64 { return float64(b.SizeInUse()) }
-	reportDbTotalSizeInUseInBytesMu.Unlock()
-	reportDbOpenReadTxNMu.Lock()
-	reportDbOpenReadTxN = func() float64 { return float64(b.OpenReadTxN()) }
-	reportDbOpenReadTxNMu.Unlock()
-	reportCurrentRevMu.Lock()
-	reportCurrentRev = func() float64 {
-		s.revMu.RLock()
-		defer s.revMu.RUnlock()
-		return float64(s.currentRev)
-	}
-	reportCurrentRevMu.Unlock()
-	reportCompactRevMu.Lock()
-	reportCompactRev = func() float64 {
-		s.revMu.RLock()
-		defer s.revMu.RUnlock()
-		return float64(s.compactMainRev)
-	}
-	reportCompactRevMu.Unlock()
-}
-
-// appendMarkTombstone appends tombstone mark to normal revision bytes.
-func appendMarkTombstone(lg *zap.Logger, b []byte) []byte {
-	if len(b) != revBytesLen {
-		if lg != nil {
-			lg.Panic(
-				"cannot append tombstone mark to non-normal revision bytes",
-				zap.Int("expected-revision-bytes-size", revBytesLen),
-				zap.Int("given-revision-bytes-size", len(b)),
-			)
-		} else {
-			plog.Panicf("cannot append mark to non normal revision bytes")
-		}
-	}
-	return append(b, markTombstone)
-}
-
-// isTombstone checks whether the revision bytes is a tombstone.
-func isTombstone(b []byte) bool {
-	return len(b) == markedRevBytesLen && b[markBytePosition] == markTombstone
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/kvstore_compaction.go b/vendor/go.etcd.io/etcd/mvcc/kvstore_compaction.go
deleted file mode 100644
index 2adb498..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/kvstore_compaction.go
+++ /dev/null
@@ -1,79 +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 mvcc
-
-import (
-	"encoding/binary"
-	"time"
-
-	"go.uber.org/zap"
-)
-
-func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struct{}) bool {
-	totalStart := time.Now()
-	defer func() { dbCompactionTotalMs.Observe(float64(time.Since(totalStart) / time.Millisecond)) }()
-	keyCompactions := 0
-	defer func() { dbCompactionKeysCounter.Add(float64(keyCompactions)) }()
-
-	end := make([]byte, 8)
-	binary.BigEndian.PutUint64(end, uint64(compactMainRev+1))
-
-	last := make([]byte, 8+1+8)
-	for {
-		var rev revision
-
-		start := time.Now()
-
-		tx := s.b.BatchTx()
-		tx.Lock()
-		keys, _ := tx.UnsafeRange(keyBucketName, last, end, int64(s.cfg.CompactionBatchLimit))
-		for _, key := range keys {
-			rev = bytesToRev(key)
-			if _, ok := keep[rev]; !ok {
-				tx.UnsafeDelete(keyBucketName, key)
-			}
-		}
-
-		if len(keys) < s.cfg.CompactionBatchLimit {
-			rbytes := make([]byte, 8+1+8)
-			revToBytes(revision{main: compactMainRev}, rbytes)
-			tx.UnsafePut(metaBucketName, finishedCompactKeyName, rbytes)
-			tx.Unlock()
-			if s.lg != nil {
-				s.lg.Info(
-					"finished scheduled compaction",
-					zap.Int64("compact-revision", compactMainRev),
-					zap.Duration("took", time.Since(totalStart)),
-				)
-			} else {
-				plog.Infof("finished scheduled compaction at %d (took %v)", compactMainRev, time.Since(totalStart))
-			}
-			return true
-		}
-
-		// update last
-		revToBytes(revision{main: rev.main, sub: rev.sub + 1}, last)
-		tx.Unlock()
-		// Immediately commit the compaction deletes instead of letting them accumulate in the write buffer
-		s.b.ForceCommit()
-		dbCompactionPauseMs.Observe(float64(time.Since(start) / time.Millisecond))
-
-		select {
-		case <-time.After(10 * time.Millisecond):
-		case <-s.stopc:
-			return false
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/kvstore_txn.go b/vendor/go.etcd.io/etcd/mvcc/kvstore_txn.go
deleted file mode 100644
index 9698254..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/kvstore_txn.go
+++ /dev/null
@@ -1,313 +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 mvcc
-
-import (
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-	"go.uber.org/zap"
-)
-
-type storeTxnRead struct {
-	s  *store
-	tx backend.ReadTx
-
-	firstRev int64
-	rev      int64
-}
-
-func (s *store) Read() TxnRead {
-	s.mu.RLock()
-	s.revMu.RLock()
-	// backend holds b.readTx.RLock() only when creating the concurrentReadTx. After
-	// ConcurrentReadTx is created, it will not block write transaction.
-	tx := s.b.ConcurrentReadTx()
-	tx.RLock() // RLock is no-op. concurrentReadTx does not need to be locked after it is created.
-	firstRev, rev := s.compactMainRev, s.currentRev
-	s.revMu.RUnlock()
-	return newMetricsTxnRead(&storeTxnRead{s, tx, firstRev, rev})
-}
-
-func (tr *storeTxnRead) FirstRev() int64 { return tr.firstRev }
-func (tr *storeTxnRead) Rev() int64      { return tr.rev }
-
-func (tr *storeTxnRead) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	return tr.rangeKeys(key, end, tr.Rev(), ro)
-}
-
-func (tr *storeTxnRead) End() {
-	tr.tx.RUnlock() // RUnlock signals the end of concurrentReadTx.
-	tr.s.mu.RUnlock()
-}
-
-type storeTxnWrite struct {
-	storeTxnRead
-	tx backend.BatchTx
-	// beginRev is the revision where the txn begins; it will write to the next revision.
-	beginRev int64
-	changes  []mvccpb.KeyValue
-}
-
-func (s *store) Write() TxnWrite {
-	s.mu.RLock()
-	tx := s.b.BatchTx()
-	tx.Lock()
-	tw := &storeTxnWrite{
-		storeTxnRead: storeTxnRead{s, tx, 0, 0},
-		tx:           tx,
-		beginRev:     s.currentRev,
-		changes:      make([]mvccpb.KeyValue, 0, 4),
-	}
-	return newMetricsTxnWrite(tw)
-}
-
-func (tw *storeTxnWrite) Rev() int64 { return tw.beginRev }
-
-func (tw *storeTxnWrite) Range(key, end []byte, ro RangeOptions) (r *RangeResult, err error) {
-	rev := tw.beginRev
-	if len(tw.changes) > 0 {
-		rev++
-	}
-	return tw.rangeKeys(key, end, rev, ro)
-}
-
-func (tw *storeTxnWrite) DeleteRange(key, end []byte) (int64, int64) {
-	if n := tw.deleteRange(key, end); n != 0 || len(tw.changes) > 0 {
-		return n, tw.beginRev + 1
-	}
-	return 0, tw.beginRev
-}
-
-func (tw *storeTxnWrite) Put(key, value []byte, lease lease.LeaseID) int64 {
-	tw.put(key, value, lease)
-	return tw.beginRev + 1
-}
-
-func (tw *storeTxnWrite) End() {
-	// only update index if the txn modifies the mvcc state.
-	if len(tw.changes) != 0 {
-		tw.s.saveIndex(tw.tx)
-		// hold revMu lock to prevent new read txns from opening until writeback.
-		tw.s.revMu.Lock()
-		tw.s.currentRev++
-	}
-	tw.tx.Unlock()
-	if len(tw.changes) != 0 {
-		tw.s.revMu.Unlock()
-	}
-	tw.s.mu.RUnlock()
-}
-
-func (tr *storeTxnRead) rangeKeys(key, end []byte, curRev int64, ro RangeOptions) (*RangeResult, error) {
-	rev := ro.Rev
-	if rev > curRev {
-		return &RangeResult{KVs: nil, Count: -1, Rev: curRev}, ErrFutureRev
-	}
-	if rev <= 0 {
-		rev = curRev
-	}
-	if rev < tr.s.compactMainRev {
-		return &RangeResult{KVs: nil, Count: -1, Rev: 0}, ErrCompacted
-	}
-
-	revpairs := tr.s.kvindex.Revisions(key, end, rev)
-	if len(revpairs) == 0 {
-		return &RangeResult{KVs: nil, Count: 0, Rev: curRev}, nil
-	}
-	if ro.Count {
-		return &RangeResult{KVs: nil, Count: len(revpairs), Rev: curRev}, nil
-	}
-
-	limit := int(ro.Limit)
-	if limit <= 0 || limit > len(revpairs) {
-		limit = len(revpairs)
-	}
-
-	kvs := make([]mvccpb.KeyValue, limit)
-	revBytes := newRevBytes()
-	for i, revpair := range revpairs[:len(kvs)] {
-		revToBytes(revpair, revBytes)
-		_, vs := tr.tx.UnsafeRange(keyBucketName, revBytes, nil, 0)
-		if len(vs) != 1 {
-			if tr.s.lg != nil {
-				tr.s.lg.Fatal(
-					"range failed to find revision pair",
-					zap.Int64("revision-main", revpair.main),
-					zap.Int64("revision-sub", revpair.sub),
-				)
-			} else {
-				plog.Fatalf("range cannot find rev (%d,%d)", revpair.main, revpair.sub)
-			}
-		}
-		if err := kvs[i].Unmarshal(vs[0]); err != nil {
-			if tr.s.lg != nil {
-				tr.s.lg.Fatal(
-					"failed to unmarshal mvccpb.KeyValue",
-					zap.Error(err),
-				)
-			} else {
-				plog.Fatalf("cannot unmarshal event: %v", err)
-			}
-		}
-	}
-	return &RangeResult{KVs: kvs, Count: len(revpairs), Rev: curRev}, nil
-}
-
-func (tw *storeTxnWrite) put(key, value []byte, leaseID lease.LeaseID) {
-	rev := tw.beginRev + 1
-	c := rev
-	oldLease := lease.NoLease
-
-	// if the key exists before, use its previous created and
-	// get its previous leaseID
-	_, created, ver, err := tw.s.kvindex.Get(key, rev)
-	if err == nil {
-		c = created.main
-		oldLease = tw.s.le.GetLease(lease.LeaseItem{Key: string(key)})
-	}
-
-	ibytes := newRevBytes()
-	idxRev := revision{main: rev, sub: int64(len(tw.changes))}
-	revToBytes(idxRev, ibytes)
-
-	ver = ver + 1
-	kv := mvccpb.KeyValue{
-		Key:            key,
-		Value:          value,
-		CreateRevision: c,
-		ModRevision:    rev,
-		Version:        ver,
-		Lease:          int64(leaseID),
-	}
-
-	d, err := kv.Marshal()
-	if err != nil {
-		if tw.storeTxnRead.s.lg != nil {
-			tw.storeTxnRead.s.lg.Fatal(
-				"failed to marshal mvccpb.KeyValue",
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot marshal event: %v", err)
-		}
-	}
-
-	tw.tx.UnsafeSeqPut(keyBucketName, ibytes, d)
-	tw.s.kvindex.Put(key, idxRev)
-	tw.changes = append(tw.changes, kv)
-
-	if oldLease != lease.NoLease {
-		if tw.s.le == nil {
-			panic("no lessor to detach lease")
-		}
-		err = tw.s.le.Detach(oldLease, []lease.LeaseItem{{Key: string(key)}})
-		if err != nil {
-			if tw.storeTxnRead.s.lg != nil {
-				tw.storeTxnRead.s.lg.Fatal(
-					"failed to detach old lease from a key",
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("unexpected error from lease detach: %v", err)
-			}
-		}
-	}
-	if leaseID != lease.NoLease {
-		if tw.s.le == nil {
-			panic("no lessor to attach lease")
-		}
-		err = tw.s.le.Attach(leaseID, []lease.LeaseItem{{Key: string(key)}})
-		if err != nil {
-			panic("unexpected error from lease Attach")
-		}
-	}
-}
-
-func (tw *storeTxnWrite) deleteRange(key, end []byte) int64 {
-	rrev := tw.beginRev
-	if len(tw.changes) > 0 {
-		rrev++
-	}
-	keys, _ := tw.s.kvindex.Range(key, end, rrev)
-	if len(keys) == 0 {
-		return 0
-	}
-	for _, key := range keys {
-		tw.delete(key)
-	}
-	return int64(len(keys))
-}
-
-func (tw *storeTxnWrite) delete(key []byte) {
-	ibytes := newRevBytes()
-	idxRev := revision{main: tw.beginRev + 1, sub: int64(len(tw.changes))}
-	revToBytes(idxRev, ibytes)
-
-	if tw.storeTxnRead.s != nil && tw.storeTxnRead.s.lg != nil {
-		ibytes = appendMarkTombstone(tw.storeTxnRead.s.lg, ibytes)
-	} else {
-		// TODO: remove this in v3.5
-		ibytes = appendMarkTombstone(nil, ibytes)
-	}
-
-	kv := mvccpb.KeyValue{Key: key}
-
-	d, err := kv.Marshal()
-	if err != nil {
-		if tw.storeTxnRead.s.lg != nil {
-			tw.storeTxnRead.s.lg.Fatal(
-				"failed to marshal mvccpb.KeyValue",
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot marshal event: %v", err)
-		}
-	}
-
-	tw.tx.UnsafeSeqPut(keyBucketName, ibytes, d)
-	err = tw.s.kvindex.Tombstone(key, idxRev)
-	if err != nil {
-		if tw.storeTxnRead.s.lg != nil {
-			tw.storeTxnRead.s.lg.Fatal(
-				"failed to tombstone an existing key",
-				zap.String("key", string(key)),
-				zap.Error(err),
-			)
-		} else {
-			plog.Fatalf("cannot tombstone an existing key (%s): %v", string(key), err)
-		}
-	}
-	tw.changes = append(tw.changes, kv)
-
-	item := lease.LeaseItem{Key: string(key)}
-	leaseID := tw.s.le.GetLease(item)
-
-	if leaseID != lease.NoLease {
-		err = tw.s.le.Detach(leaseID, []lease.LeaseItem{item})
-		if err != nil {
-			if tw.storeTxnRead.s.lg != nil {
-				tw.storeTxnRead.s.lg.Fatal(
-					"failed to detach old lease from a key",
-					zap.Error(err),
-				)
-			} else {
-				plog.Errorf("cannot detach %v", err)
-			}
-		}
-	}
-}
-
-func (tw *storeTxnWrite) Changes() []mvccpb.KeyValue { return tw.changes }
diff --git a/vendor/go.etcd.io/etcd/mvcc/metrics.go b/vendor/go.etcd.io/etcd/mvcc/metrics.go
deleted file mode 100644
index 7526ee4..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/metrics.go
+++ /dev/null
@@ -1,336 +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 mvcc
-
-import (
-	"sync"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-var (
-	rangeCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "mvcc",
-			Name:      "range_total",
-			Help:      "Total number of ranges seen by this member.",
-		})
-	rangeCounterDebug = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "range_total",
-			Help:      "Total number of ranges seen by this member.",
-		})
-
-	putCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "mvcc",
-			Name:      "put_total",
-			Help:      "Total number of puts seen by this member.",
-		})
-	// TODO: remove in 3.5 release
-	putCounterDebug = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "put_total",
-			Help:      "Total number of puts seen by this member.",
-		})
-
-	deleteCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "mvcc",
-			Name:      "delete_total",
-			Help:      "Total number of deletes seen by this member.",
-		})
-	// TODO: remove in 3.5 release
-	deleteCounterDebug = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "delete_total",
-			Help:      "Total number of deletes seen by this member.",
-		})
-
-	txnCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd",
-			Subsystem: "mvcc",
-			Name:      "txn_total",
-			Help:      "Total number of txns seen by this member.",
-		})
-	txnCounterDebug = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "txn_total",
-			Help:      "Total number of txns seen by this member.",
-		})
-
-	keysGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "keys_total",
-			Help:      "Total number of keys.",
-		})
-
-	watchStreamGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "watch_stream_total",
-			Help:      "Total number of watch streams.",
-		})
-
-	watcherGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "watcher_total",
-			Help:      "Total number of watchers.",
-		})
-
-	slowWatcherGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "slow_watcher_total",
-			Help:      "Total number of unsynced slow watchers.",
-		})
-
-	totalEventsCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "events_total",
-			Help:      "Total number of events sent by this member.",
-		})
-
-	pendingEventsGauge = prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "pending_events_total",
-			Help:      "Total number of pending events to be sent.",
-		})
-
-	indexCompactionPauseMs = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "index_compaction_pause_duration_milliseconds",
-			Help:      "Bucketed histogram of index compaction pause duration.",
-
-			// lowest bucket start of upper bound 0.5 ms with factor 2
-			// highest bucket start of 0.5 ms * 2^13 == 4.096 sec
-			Buckets: prometheus.ExponentialBuckets(0.5, 2, 14),
-		})
-
-	dbCompactionPauseMs = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_pause_duration_milliseconds",
-			Help:      "Bucketed histogram of db compaction pause duration.",
-
-			// lowest bucket start of upper bound 1 ms with factor 2
-			// highest bucket start of 1 ms * 2^12 == 4.096 sec
-			Buckets: prometheus.ExponentialBuckets(1, 2, 13),
-		})
-
-	dbCompactionTotalMs = prometheus.NewHistogram(
-		prometheus.HistogramOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_total_duration_milliseconds",
-			Help:      "Bucketed histogram of db compaction total duration.",
-
-			// lowest bucket start of upper bound 100 ms with factor 2
-			// highest bucket start of 100 ms * 2^13 == 8.192 sec
-			Buckets: prometheus.ExponentialBuckets(100, 2, 14),
-		})
-
-	dbCompactionKeysCounter = prometheus.NewCounter(
-		prometheus.CounterOpts{
-			Namespace: "etcd_debugging",
-			Subsystem: "mvcc",
-			Name:      "db_compaction_keys_total",
-			Help:      "Total number of db keys compacted.",
-		})
-
-	dbTotalSize = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_bytes",
-		Help:      "Total size of the underlying database physically allocated in bytes.",
-	},
-		func() float64 {
-			reportDbTotalSizeInBytesMu.RLock()
-			defer reportDbTotalSizeInBytesMu.RUnlock()
-			return reportDbTotalSizeInBytes()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbTotalSizeInBytesMu sync.RWMutex
-	reportDbTotalSizeInBytes   = func() float64 { return 0 }
-
-	// TODO: remove this in v3.5
-	dbTotalSizeDebug = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_bytes",
-		Help:      "Total size of the underlying database physically allocated in bytes.",
-	},
-		func() float64 {
-			reportDbTotalSizeInBytesDebugMu.RLock()
-			defer reportDbTotalSizeInBytesDebugMu.RUnlock()
-			return reportDbTotalSizeInBytesDebug()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbTotalSizeInBytesDebugMu sync.RWMutex
-	reportDbTotalSizeInBytesDebug   = func() float64 { return 0 }
-
-	dbTotalSizeInUse = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "db_total_size_in_use_in_bytes",
-		Help:      "Total size of the underlying database logically in use in bytes.",
-	},
-		func() float64 {
-			reportDbTotalSizeInUseInBytesMu.RLock()
-			defer reportDbTotalSizeInUseInBytesMu.RUnlock()
-			return reportDbTotalSizeInUseInBytes()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbTotalSizeInUseInBytesMu sync.RWMutex
-	reportDbTotalSizeInUseInBytes   = func() float64 { return 0 }
-
-	dbOpenReadTxN = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "db_open_read_transactions",
-		Help:      "The number of currently open read transactions",
-	},
-
-		func() float64 {
-			reportDbOpenReadTxNMu.RLock()
-			defer reportDbOpenReadTxNMu.RUnlock()
-			return reportDbOpenReadTxN()
-		},
-	)
-	// overridden by mvcc initialization
-	reportDbOpenReadTxNMu sync.RWMutex
-	reportDbOpenReadTxN   = func() float64 { return 0 }
-
-	hashSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "hash_duration_seconds",
-		Help:      "The latency distribution of storage hash operation.",
-
-		// 100 MB usually takes 100 ms, so start with 10 MB of 10 ms
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^14 == 163.84 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 15),
-	})
-
-	hashRevSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "mvcc",
-		Name:      "hash_rev_duration_seconds",
-		Help:      "The latency distribution of storage hash by revision operation.",
-
-		// 100 MB usually takes 100 ms, so start with 10 MB of 10 ms
-		// lowest bucket start of upper bound 0.01 sec (10 ms) with factor 2
-		// highest bucket start of 0.01 sec * 2^14 == 163.84 sec
-		Buckets: prometheus.ExponentialBuckets(.01, 2, 15),
-	})
-
-	currentRev = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "mvcc",
-		Name:      "current_revision",
-		Help:      "The current revision of store.",
-	},
-		func() float64 {
-			reportCurrentRevMu.RLock()
-			defer reportCurrentRevMu.RUnlock()
-			return reportCurrentRev()
-		},
-	)
-	// overridden by mvcc initialization
-	reportCurrentRevMu sync.RWMutex
-	reportCurrentRev   = func() float64 { return 0 }
-
-	compactRev = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
-		Namespace: "etcd_debugging",
-		Subsystem: "mvcc",
-		Name:      "compact_revision",
-		Help:      "The revision of the last compaction in store.",
-	},
-		func() float64 {
-			reportCompactRevMu.RLock()
-			defer reportCompactRevMu.RUnlock()
-			return reportCompactRev()
-		},
-	)
-	// overridden by mvcc initialization
-	reportCompactRevMu sync.RWMutex
-	reportCompactRev   = func() float64 { return 0 }
-)
-
-func init() {
-	prometheus.MustRegister(rangeCounter)
-	prometheus.MustRegister(rangeCounterDebug)
-	prometheus.MustRegister(putCounter)
-	prometheus.MustRegister(putCounterDebug)
-	prometheus.MustRegister(deleteCounter)
-	prometheus.MustRegister(deleteCounterDebug)
-	prometheus.MustRegister(txnCounter)
-	prometheus.MustRegister(txnCounterDebug)
-	prometheus.MustRegister(keysGauge)
-	prometheus.MustRegister(watchStreamGauge)
-	prometheus.MustRegister(watcherGauge)
-	prometheus.MustRegister(slowWatcherGauge)
-	prometheus.MustRegister(totalEventsCounter)
-	prometheus.MustRegister(pendingEventsGauge)
-	prometheus.MustRegister(indexCompactionPauseMs)
-	prometheus.MustRegister(dbCompactionPauseMs)
-	prometheus.MustRegister(dbCompactionTotalMs)
-	prometheus.MustRegister(dbCompactionKeysCounter)
-	prometheus.MustRegister(dbTotalSize)
-	prometheus.MustRegister(dbTotalSizeDebug)
-	prometheus.MustRegister(dbTotalSizeInUse)
-	prometheus.MustRegister(dbOpenReadTxN)
-	prometheus.MustRegister(hashSec)
-	prometheus.MustRegister(hashRevSec)
-	prometheus.MustRegister(currentRev)
-	prometheus.MustRegister(compactRev)
-}
-
-// ReportEventReceived reports that an event is received.
-// This function should be called when the external systems received an
-// event from mvcc.Watcher.
-func ReportEventReceived(n int) {
-	pendingEventsGauge.Sub(float64(n))
-	totalEventsCounter.Add(float64(n))
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/metrics_txn.go b/vendor/go.etcd.io/etcd/mvcc/metrics_txn.go
deleted file mode 100644
index 64b629c..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/metrics_txn.go
+++ /dev/null
@@ -1,67 +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 mvcc
-
-import "go.etcd.io/etcd/lease"
-
-type metricsTxnWrite struct {
-	TxnWrite
-	ranges  uint
-	puts    uint
-	deletes uint
-}
-
-func newMetricsTxnRead(tr TxnRead) TxnRead {
-	return &metricsTxnWrite{&txnReadWrite{tr}, 0, 0, 0}
-}
-
-func newMetricsTxnWrite(tw TxnWrite) TxnWrite {
-	return &metricsTxnWrite{tw, 0, 0, 0}
-}
-
-func (tw *metricsTxnWrite) Range(key, end []byte, ro RangeOptions) (*RangeResult, error) {
-	tw.ranges++
-	return tw.TxnWrite.Range(key, end, ro)
-}
-
-func (tw *metricsTxnWrite) DeleteRange(key, end []byte) (n, rev int64) {
-	tw.deletes++
-	return tw.TxnWrite.DeleteRange(key, end)
-}
-
-func (tw *metricsTxnWrite) Put(key, value []byte, lease lease.LeaseID) (rev int64) {
-	tw.puts++
-	return tw.TxnWrite.Put(key, value, lease)
-}
-
-func (tw *metricsTxnWrite) End() {
-	defer tw.TxnWrite.End()
-	if sum := tw.ranges + tw.puts + tw.deletes; sum > 1 {
-		txnCounter.Inc()
-		txnCounterDebug.Inc() // TODO: remove in 3.5 release
-	}
-
-	ranges := float64(tw.ranges)
-	rangeCounter.Add(ranges)
-	rangeCounterDebug.Add(ranges) // TODO: remove in 3.5 release
-
-	puts := float64(tw.puts)
-	putCounter.Add(puts)
-	putCounterDebug.Add(puts) // TODO: remove in 3.5 release
-
-	deletes := float64(tw.deletes)
-	deleteCounter.Add(deletes)
-	deleteCounterDebug.Add(deletes) // TODO: remove in 3.5 release
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.pb.go b/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.pb.go
deleted file mode 100644
index 23fe337..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.pb.go
+++ /dev/null
@@ -1,718 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: kv.proto
-
-/*
-	Package mvccpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		kv.proto
-
-	It has these top-level messages:
-		KeyValue
-		Event
-*/
-package mvccpb
-
-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 Event_EventType int32
-
-const (
-	PUT    Event_EventType = 0
-	DELETE Event_EventType = 1
-)
-
-var Event_EventType_name = map[int32]string{
-	0: "PUT",
-	1: "DELETE",
-}
-var Event_EventType_value = map[string]int32{
-	"PUT":    0,
-	"DELETE": 1,
-}
-
-func (x Event_EventType) String() string {
-	return proto.EnumName(Event_EventType_name, int32(x))
-}
-func (Event_EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptorKv, []int{1, 0} }
-
-type KeyValue struct {
-	// key is the key in bytes. An empty key is not allowed.
-	Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-	// create_revision is the revision of last creation on this key.
-	CreateRevision int64 `protobuf:"varint,2,opt,name=create_revision,json=createRevision,proto3" json:"create_revision,omitempty"`
-	// mod_revision is the revision of last modification on this key.
-	ModRevision int64 `protobuf:"varint,3,opt,name=mod_revision,json=modRevision,proto3" json:"mod_revision,omitempty"`
-	// version is the version of the key. A deletion resets
-	// the version to zero and any modification of the key
-	// increases its version.
-	Version int64 `protobuf:"varint,4,opt,name=version,proto3" json:"version,omitempty"`
-	// value is the value held by the key, in bytes.
-	Value []byte `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"`
-	// lease is the ID of the lease that attached to key.
-	// When the attached lease expires, the key will be deleted.
-	// If lease is 0, then no lease is attached to the key.
-	Lease int64 `protobuf:"varint,6,opt,name=lease,proto3" json:"lease,omitempty"`
-}
-
-func (m *KeyValue) Reset()                    { *m = KeyValue{} }
-func (m *KeyValue) String() string            { return proto.CompactTextString(m) }
-func (*KeyValue) ProtoMessage()               {}
-func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptorKv, []int{0} }
-
-type Event struct {
-	// type is the kind of event. If type is a PUT, it indicates
-	// new data has been stored to the key. If type is a DELETE,
-	// it indicates the key was deleted.
-	Type Event_EventType `protobuf:"varint,1,opt,name=type,proto3,enum=mvccpb.Event_EventType" json:"type,omitempty"`
-	// kv holds the KeyValue for the event.
-	// A PUT event contains current kv pair.
-	// A PUT event with kv.Version=1 indicates the creation of a key.
-	// A DELETE/EXPIRE event contains the deleted key with
-	// its modification revision set to the revision of deletion.
-	Kv *KeyValue `protobuf:"bytes,2,opt,name=kv" json:"kv,omitempty"`
-	// prev_kv holds the key-value pair before the event happens.
-	PrevKv *KeyValue `protobuf:"bytes,3,opt,name=prev_kv,json=prevKv" json:"prev_kv,omitempty"`
-}
-
-func (m *Event) Reset()                    { *m = Event{} }
-func (m *Event) String() string            { return proto.CompactTextString(m) }
-func (*Event) ProtoMessage()               {}
-func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorKv, []int{1} }
-
-func init() {
-	proto.RegisterType((*KeyValue)(nil), "mvccpb.KeyValue")
-	proto.RegisterType((*Event)(nil), "mvccpb.Event")
-	proto.RegisterEnum("mvccpb.Event_EventType", Event_EventType_name, Event_EventType_value)
-}
-func (m *KeyValue) 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 *KeyValue) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Key) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
-	}
-	if m.CreateRevision != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.CreateRevision))
-	}
-	if m.ModRevision != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.ModRevision))
-	}
-	if m.Version != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.Version))
-	}
-	if len(m.Value) > 0 {
-		dAtA[i] = 0x2a
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
-	}
-	if m.Lease != 0 {
-		dAtA[i] = 0x30
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.Lease))
-	}
-	return i, nil
-}
-
-func (m *Event) 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 *Event) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if m.Type != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.Type))
-	}
-	if m.Kv != nil {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.Kv.Size()))
-		n1, err := m.Kv.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
-	}
-	if m.PrevKv != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintKv(dAtA, i, uint64(m.PrevKv.Size()))
-		n2, err := m.PrevKv.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n2
-	}
-	return i, nil
-}
-
-func encodeVarintKv(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 *KeyValue) Size() (n int) {
-	var l int
-	_ = l
-	l = len(m.Key)
-	if l > 0 {
-		n += 1 + l + sovKv(uint64(l))
-	}
-	if m.CreateRevision != 0 {
-		n += 1 + sovKv(uint64(m.CreateRevision))
-	}
-	if m.ModRevision != 0 {
-		n += 1 + sovKv(uint64(m.ModRevision))
-	}
-	if m.Version != 0 {
-		n += 1 + sovKv(uint64(m.Version))
-	}
-	l = len(m.Value)
-	if l > 0 {
-		n += 1 + l + sovKv(uint64(l))
-	}
-	if m.Lease != 0 {
-		n += 1 + sovKv(uint64(m.Lease))
-	}
-	return n
-}
-
-func (m *Event) Size() (n int) {
-	var l int
-	_ = l
-	if m.Type != 0 {
-		n += 1 + sovKv(uint64(m.Type))
-	}
-	if m.Kv != nil {
-		l = m.Kv.Size()
-		n += 1 + l + sovKv(uint64(l))
-	}
-	if m.PrevKv != nil {
-		l = m.PrevKv.Size()
-		n += 1 + l + sovKv(uint64(l))
-	}
-	return n
-}
-
-func sovKv(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozKv(x uint64) (n int) {
-	return sovKv(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *KeyValue) 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 ErrIntOverflowKv
-			}
-			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: KeyValue: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: KeyValue: 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 ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthKv
-			}
-			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 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field CreateRevision", wireType)
-			}
-			m.CreateRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.CreateRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ModRevision", wireType)
-			}
-			m.ModRevision = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ModRevision |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
-			}
-			m.Version = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Version |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 5:
-			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 ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthKv
-			}
-			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
-		case 6:
-			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 ErrIntOverflowKv
-				}
-				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 := skipKv(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthKv
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func (m *Event) 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 ErrIntOverflowKv
-			}
-			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: Event: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (Event_EventType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		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 ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthKv
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.Kv == nil {
-				m.Kv = &KeyValue{}
-			}
-			if err := m.Kv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field PrevKv", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowKv
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthKv
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if m.PrevKv == nil {
-				m.PrevKv = &KeyValue{}
-			}
-			if err := m.PrevKv.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipKv(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthKv
-			}
-			if (iNdEx + skippy) > l {
-				return io.ErrUnexpectedEOF
-			}
-			iNdEx += skippy
-		}
-	}
-
-	if iNdEx > l {
-		return io.ErrUnexpectedEOF
-	}
-	return nil
-}
-func skipKv(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, ErrIntOverflowKv
-			}
-			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, ErrIntOverflowKv
-				}
-				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, ErrIntOverflowKv
-				}
-				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, ErrInvalidLengthKv
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowKv
-					}
-					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 := skipKv(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 (
-	ErrInvalidLengthKv = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowKv   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("kv.proto", fileDescriptorKv) }
-
-var fileDescriptorKv = []byte{
-	// 303 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4e, 0xc2, 0x40,
-	0x14, 0x86, 0x3b, 0x14, 0x0a, 0x3e, 0x08, 0x36, 0x13, 0x12, 0x27, 0x2e, 0x26, 0x95, 0x8d, 0x18,
-	0x13, 0x4c, 0xf0, 0x06, 0xc6, 0xae, 0x70, 0x61, 0x1a, 0x74, 0x4b, 0x4a, 0x79, 0x21, 0xa4, 0x94,
-	0x69, 0x4a, 0x9d, 0xa4, 0x37, 0x71, 0xef, 0xde, 0x73, 0xb0, 0xe4, 0x08, 0x52, 0x2f, 0x62, 0xfa,
-	0xc6, 0xe2, 0xc6, 0xcd, 0xe4, 0xfd, 0xff, 0xff, 0x65, 0xe6, 0x7f, 0x03, 0x9d, 0x58, 0x8f, 0xd3,
-	0x4c, 0xe5, 0x8a, 0x3b, 0x89, 0x8e, 0xa2, 0x74, 0x71, 0x39, 0x58, 0xa9, 0x95, 0x22, 0xeb, 0xae,
-	0x9a, 0x4c, 0x3a, 0xfc, 0x64, 0xd0, 0x99, 0x62, 0xf1, 0x1a, 0x6e, 0xde, 0x90, 0xbb, 0x60, 0xc7,
-	0x58, 0x08, 0xe6, 0xb1, 0x51, 0x2f, 0xa8, 0x46, 0x7e, 0x0d, 0xe7, 0x51, 0x86, 0x61, 0x8e, 0xf3,
-	0x0c, 0xf5, 0x7a, 0xb7, 0x56, 0x5b, 0xd1, 0xf0, 0xd8, 0xc8, 0x0e, 0xfa, 0xc6, 0x0e, 0x7e, 0x5d,
-	0x7e, 0x05, 0xbd, 0x44, 0x2d, 0xff, 0x28, 0x9b, 0xa8, 0x6e, 0xa2, 0x96, 0x27, 0x44, 0x40, 0x5b,
-	0x63, 0x46, 0x69, 0x93, 0xd2, 0x5a, 0xf2, 0x01, 0xb4, 0x74, 0x55, 0x40, 0xb4, 0xe8, 0x65, 0x23,
-	0x2a, 0x77, 0x83, 0xe1, 0x0e, 0x85, 0x43, 0xb4, 0x11, 0xc3, 0x0f, 0x06, 0x2d, 0x5f, 0xe3, 0x36,
-	0xe7, 0xb7, 0xd0, 0xcc, 0x8b, 0x14, 0xa9, 0x6e, 0x7f, 0x72, 0x31, 0x36, 0x7b, 0x8e, 0x29, 0x34,
-	0xe7, 0xac, 0x48, 0x31, 0x20, 0x88, 0x7b, 0xd0, 0x88, 0x35, 0x75, 0xef, 0x4e, 0xdc, 0x1a, 0xad,
-	0x17, 0x0f, 0x1a, 0xb1, 0xe6, 0x37, 0xd0, 0x4e, 0x33, 0xd4, 0xf3, 0x58, 0x53, 0xf9, 0xff, 0x30,
-	0xa7, 0x02, 0xa6, 0x7a, 0xe8, 0xc1, 0xd9, 0xe9, 0x7e, 0xde, 0x06, 0xfb, 0xf9, 0x65, 0xe6, 0x5a,
-	0x1c, 0xc0, 0x79, 0xf4, 0x9f, 0xfc, 0x99, 0xef, 0xb2, 0x07, 0xb1, 0x3f, 0x4a, 0xeb, 0x70, 0x94,
-	0xd6, 0xbe, 0x94, 0xec, 0x50, 0x4a, 0xf6, 0x55, 0x4a, 0xf6, 0xfe, 0x2d, 0xad, 0x85, 0x43, 0xff,
-	0x7e, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x45, 0x92, 0x5d, 0xa1, 0x01, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.proto b/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.proto
deleted file mode 100644
index 23c911b..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/mvccpb/kv.proto
+++ /dev/null
@@ -1,49 +0,0 @@
-syntax = "proto3";
-package mvccpb;
-
-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;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-message KeyValue {
-  // key is the key in bytes. An empty key is not allowed.
-  bytes key = 1;
-  // create_revision is the revision of last creation on this key.
-  int64 create_revision = 2;
-  // mod_revision is the revision of last modification on this key.
-  int64 mod_revision = 3;
-  // version is the version of the key. A deletion resets
-  // the version to zero and any modification of the key
-  // increases its version.
-  int64 version = 4;
-  // value is the value held by the key, in bytes.
-  bytes value = 5;
-  // lease is the ID of the lease that attached to key.
-  // When the attached lease expires, the key will be deleted.
-  // If lease is 0, then no lease is attached to the key.
-  int64 lease = 6;
-}
-
-message Event {
-  enum EventType {
-    PUT = 0;
-    DELETE = 1;
-  }
-  // type is the kind of event. If type is a PUT, it indicates
-  // new data has been stored to the key. If type is a DELETE,
-  // it indicates the key was deleted.
-  EventType type = 1;
-  // kv holds the KeyValue for the event.
-  // A PUT event contains current kv pair.
-  // A PUT event with kv.Version=1 indicates the creation of a key.
-  // A DELETE/EXPIRE event contains the deleted key with
-  // its modification revision set to the revision of deletion.
-  KeyValue kv = 2;
-
-  // prev_kv holds the key-value pair before the event happens.
-  KeyValue prev_kv = 3;
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/revision.go b/vendor/go.etcd.io/etcd/mvcc/revision.go
deleted file mode 100644
index d621386..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/revision.go
+++ /dev/null
@@ -1,67 +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 mvcc
-
-import "encoding/binary"
-
-// revBytesLen is the byte length of a normal revision.
-// First 8 bytes is the revision.main in big-endian format. The 9th byte
-// is a '_'. The last 8 bytes is the revision.sub in big-endian format.
-const revBytesLen = 8 + 1 + 8
-
-// A revision indicates modification of the key-value space.
-// The set of changes that share same main revision changes the key-value space atomically.
-type revision struct {
-	// main is the main revision of a set of changes that happen atomically.
-	main int64
-
-	// sub is the sub revision of a change in a set of changes that happen
-	// atomically. Each change has different increasing sub revision in that
-	// set.
-	sub int64
-}
-
-func (a revision) GreaterThan(b revision) bool {
-	if a.main > b.main {
-		return true
-	}
-	if a.main < b.main {
-		return false
-	}
-	return a.sub > b.sub
-}
-
-func newRevBytes() []byte {
-	return make([]byte, revBytesLen, markedRevBytesLen)
-}
-
-func revToBytes(rev revision, bytes []byte) {
-	binary.BigEndian.PutUint64(bytes, uint64(rev.main))
-	bytes[8] = '_'
-	binary.BigEndian.PutUint64(bytes[9:], uint64(rev.sub))
-}
-
-func bytesToRev(bytes []byte) revision {
-	return revision{
-		main: int64(binary.BigEndian.Uint64(bytes[0:8])),
-		sub:  int64(binary.BigEndian.Uint64(bytes[9:])),
-	}
-}
-
-type revisions []revision
-
-func (a revisions) Len() int           { return len(a) }
-func (a revisions) Less(i, j int) bool { return a[j].GreaterThan(a[i]) }
-func (a revisions) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
diff --git a/vendor/go.etcd.io/etcd/mvcc/util.go b/vendor/go.etcd.io/etcd/mvcc/util.go
deleted file mode 100644
index 032621a..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/util.go
+++ /dev/null
@@ -1,57 +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 mvcc
-
-import (
-	"encoding/binary"
-	"fmt"
-
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-func UpdateConsistentIndex(be backend.Backend, index uint64) {
-	tx := be.BatchTx()
-	tx.Lock()
-	defer tx.Unlock()
-
-	var oldi uint64
-	_, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0)
-	if len(vs) != 0 {
-		oldi = binary.BigEndian.Uint64(vs[0])
-	}
-
-	if index <= oldi {
-		return
-	}
-
-	bs := make([]byte, 8)
-	binary.BigEndian.PutUint64(bs, index)
-	tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs)
-}
-
-func WriteKV(be backend.Backend, kv mvccpb.KeyValue) {
-	ibytes := newRevBytes()
-	revToBytes(revision{main: kv.ModRevision}, ibytes)
-
-	d, err := kv.Marshal()
-	if err != nil {
-		panic(fmt.Errorf("cannot marshal event: %v", err))
-	}
-
-	be.BatchTx().Lock()
-	be.BatchTx().UnsafePut(keyBucketName, ibytes, d)
-	be.BatchTx().Unlock()
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/watchable_store.go b/vendor/go.etcd.io/etcd/mvcc/watchable_store.go
deleted file mode 100644
index 3cf491d..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/watchable_store.go
+++ /dev/null
@@ -1,552 +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 mvcc
-
-import (
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/lease"
-	"go.etcd.io/etcd/mvcc/backend"
-	"go.etcd.io/etcd/mvcc/mvccpb"
-	"go.uber.org/zap"
-)
-
-// non-const so modifiable by tests
-var (
-	// chanBufLen is the length of the buffered chan
-	// for sending out watched events.
-	// TODO: find a good buf value. 1024 is just a random one that
-	// seems to be reasonable.
-	chanBufLen = 1024
-
-	// maxWatchersPerSync is the number of watchers to sync in a single batch
-	maxWatchersPerSync = 512
-)
-
-type watchable interface {
-	watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc)
-	progress(w *watcher)
-	rev() int64
-}
-
-type watchableStore struct {
-	*store
-
-	// mu protects watcher groups and batches. It should never be locked
-	// before locking store.mu to avoid deadlock.
-	mu sync.RWMutex
-
-	// victims are watcher batches that were blocked on the watch channel
-	victims []watcherBatch
-	victimc chan struct{}
-
-	// contains all unsynced watchers that needs to sync with events that have happened
-	unsynced watcherGroup
-
-	// contains all synced watchers that are in sync with the progress of the store.
-	// The key of the map is the key that the watcher watches on.
-	synced watcherGroup
-
-	stopc chan struct{}
-	wg    sync.WaitGroup
-}
-
-// cancelFunc updates unsynced and synced maps when running
-// cancel operations.
-type cancelFunc func()
-
-func New(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter, cfg StoreConfig) ConsistentWatchableKV {
-	return newWatchableStore(lg, b, le, ig, cfg)
-}
-
-func newWatchableStore(lg *zap.Logger, b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter, cfg StoreConfig) *watchableStore {
-	s := &watchableStore{
-		store:    NewStore(lg, b, le, ig, cfg),
-		victimc:  make(chan struct{}, 1),
-		unsynced: newWatcherGroup(),
-		synced:   newWatcherGroup(),
-		stopc:    make(chan struct{}),
-	}
-	s.store.ReadView = &readView{s}
-	s.store.WriteView = &writeView{s}
-	if s.le != nil {
-		// use this store as the deleter so revokes trigger watch events
-		s.le.SetRangeDeleter(func() lease.TxnDelete { return s.Write() })
-	}
-	s.wg.Add(2)
-	go s.syncWatchersLoop()
-	go s.syncVictimsLoop()
-	return s
-}
-
-func (s *watchableStore) Close() error {
-	close(s.stopc)
-	s.wg.Wait()
-	return s.store.Close()
-}
-
-func (s *watchableStore) NewWatchStream() WatchStream {
-	watchStreamGauge.Inc()
-	return &watchStream{
-		watchable: s,
-		ch:        make(chan WatchResponse, chanBufLen),
-		cancels:   make(map[WatchID]cancelFunc),
-		watchers:  make(map[WatchID]*watcher),
-	}
-}
-
-func (s *watchableStore) watch(key, end []byte, startRev int64, id WatchID, ch chan<- WatchResponse, fcs ...FilterFunc) (*watcher, cancelFunc) {
-	wa := &watcher{
-		key:    key,
-		end:    end,
-		minRev: startRev,
-		id:     id,
-		ch:     ch,
-		fcs:    fcs,
-	}
-
-	s.mu.Lock()
-	s.revMu.RLock()
-	synced := startRev > s.store.currentRev || startRev == 0
-	if synced {
-		wa.minRev = s.store.currentRev + 1
-		if startRev > wa.minRev {
-			wa.minRev = startRev
-		}
-	}
-	if synced {
-		s.synced.add(wa)
-	} else {
-		slowWatcherGauge.Inc()
-		s.unsynced.add(wa)
-	}
-	s.revMu.RUnlock()
-	s.mu.Unlock()
-
-	watcherGauge.Inc()
-
-	return wa, func() { s.cancelWatcher(wa) }
-}
-
-// cancelWatcher removes references of the watcher from the watchableStore
-func (s *watchableStore) cancelWatcher(wa *watcher) {
-	for {
-		s.mu.Lock()
-		if s.unsynced.delete(wa) {
-			slowWatcherGauge.Dec()
-			break
-		} else if s.synced.delete(wa) {
-			break
-		} else if wa.compacted {
-			break
-		} else if wa.ch == nil {
-			// already canceled (e.g., cancel/close race)
-			break
-		}
-
-		if !wa.victim {
-			panic("watcher not victim but not in watch groups")
-		}
-
-		var victimBatch watcherBatch
-		for _, wb := range s.victims {
-			if wb[wa] != nil {
-				victimBatch = wb
-				break
-			}
-		}
-		if victimBatch != nil {
-			slowWatcherGauge.Dec()
-			delete(victimBatch, wa)
-			break
-		}
-
-		// victim being processed so not accessible; retry
-		s.mu.Unlock()
-		time.Sleep(time.Millisecond)
-	}
-
-	watcherGauge.Dec()
-	wa.ch = nil
-	s.mu.Unlock()
-}
-
-func (s *watchableStore) Restore(b backend.Backend) error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	err := s.store.Restore(b)
-	if err != nil {
-		return err
-	}
-
-	for wa := range s.synced.watchers {
-		wa.restore = true
-		s.unsynced.add(wa)
-	}
-	s.synced = newWatcherGroup()
-	return nil
-}
-
-// syncWatchersLoop syncs the watcher in the unsynced map every 100ms.
-func (s *watchableStore) syncWatchersLoop() {
-	defer s.wg.Done()
-
-	for {
-		s.mu.RLock()
-		st := time.Now()
-		lastUnsyncedWatchers := s.unsynced.size()
-		s.mu.RUnlock()
-
-		unsyncedWatchers := 0
-		if lastUnsyncedWatchers > 0 {
-			unsyncedWatchers = s.syncWatchers()
-		}
-		syncDuration := time.Since(st)
-
-		waitDuration := 100 * time.Millisecond
-		// more work pending?
-		if unsyncedWatchers != 0 && lastUnsyncedWatchers > unsyncedWatchers {
-			// be fair to other store operations by yielding time taken
-			waitDuration = syncDuration
-		}
-
-		select {
-		case <-time.After(waitDuration):
-		case <-s.stopc:
-			return
-		}
-	}
-}
-
-// syncVictimsLoop tries to write precomputed watcher responses to
-// watchers that had a blocked watcher channel
-func (s *watchableStore) syncVictimsLoop() {
-	defer s.wg.Done()
-
-	for {
-		for s.moveVictims() != 0 {
-			// try to update all victim watchers
-		}
-		s.mu.RLock()
-		isEmpty := len(s.victims) == 0
-		s.mu.RUnlock()
-
-		var tickc <-chan time.Time
-		if !isEmpty {
-			tickc = time.After(10 * time.Millisecond)
-		}
-
-		select {
-		case <-tickc:
-		case <-s.victimc:
-		case <-s.stopc:
-			return
-		}
-	}
-}
-
-// moveVictims tries to update watches with already pending event data
-func (s *watchableStore) moveVictims() (moved int) {
-	s.mu.Lock()
-	victims := s.victims
-	s.victims = nil
-	s.mu.Unlock()
-
-	var newVictim watcherBatch
-	for _, wb := range victims {
-		// try to send responses again
-		for w, eb := range wb {
-			// watcher has observed the store up to, but not including, w.minRev
-			rev := w.minRev - 1
-			if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) {
-				pendingEventsGauge.Add(float64(len(eb.evs)))
-			} else {
-				if newVictim == nil {
-					newVictim = make(watcherBatch)
-				}
-				newVictim[w] = eb
-				continue
-			}
-			moved++
-		}
-
-		// assign completed victim watchers to unsync/sync
-		s.mu.Lock()
-		s.store.revMu.RLock()
-		curRev := s.store.currentRev
-		for w, eb := range wb {
-			if newVictim != nil && newVictim[w] != nil {
-				// couldn't send watch response; stays victim
-				continue
-			}
-			w.victim = false
-			if eb.moreRev != 0 {
-				w.minRev = eb.moreRev
-			}
-			if w.minRev <= curRev {
-				s.unsynced.add(w)
-			} else {
-				slowWatcherGauge.Dec()
-				s.synced.add(w)
-			}
-		}
-		s.store.revMu.RUnlock()
-		s.mu.Unlock()
-	}
-
-	if len(newVictim) > 0 {
-		s.mu.Lock()
-		s.victims = append(s.victims, newVictim)
-		s.mu.Unlock()
-	}
-
-	return moved
-}
-
-// syncWatchers syncs unsynced watchers by:
-//	1. choose a set of watchers from the unsynced watcher group
-//	2. iterate over the set to get the minimum revision and remove compacted watchers
-//	3. use minimum revision to get all key-value pairs and send those events to watchers
-//	4. remove synced watchers in set from unsynced group and move to synced group
-func (s *watchableStore) syncWatchers() int {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-
-	if s.unsynced.size() == 0 {
-		return 0
-	}
-
-	s.store.revMu.RLock()
-	defer s.store.revMu.RUnlock()
-
-	// in order to find key-value pairs from unsynced watchers, we need to
-	// find min revision index, and these revisions can be used to
-	// query the backend store of key-value pairs
-	curRev := s.store.currentRev
-	compactionRev := s.store.compactMainRev
-
-	wg, minRev := s.unsynced.choose(maxWatchersPerSync, curRev, compactionRev)
-	minBytes, maxBytes := newRevBytes(), newRevBytes()
-	revToBytes(revision{main: minRev}, minBytes)
-	revToBytes(revision{main: curRev + 1}, maxBytes)
-
-	// UnsafeRange returns keys and values. And in boltdb, keys are revisions.
-	// values are actual key-value pairs in backend.
-	tx := s.store.b.ReadTx()
-	tx.RLock()
-	revs, vs := tx.UnsafeRange(keyBucketName, minBytes, maxBytes, 0)
-	var evs []mvccpb.Event
-	if s.store != nil && s.store.lg != nil {
-		evs = kvsToEvents(s.store.lg, wg, revs, vs)
-	} else {
-		// TODO: remove this in v3.5
-		evs = kvsToEvents(nil, wg, revs, vs)
-	}
-	tx.RUnlock()
-
-	var victims watcherBatch
-	wb := newWatcherBatch(wg, evs)
-	for w := range wg.watchers {
-		w.minRev = curRev + 1
-
-		eb, ok := wb[w]
-		if !ok {
-			// bring un-notified watcher to synced
-			s.synced.add(w)
-			s.unsynced.delete(w)
-			continue
-		}
-
-		if eb.moreRev != 0 {
-			w.minRev = eb.moreRev
-		}
-
-		if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: curRev}) {
-			pendingEventsGauge.Add(float64(len(eb.evs)))
-		} else {
-			if victims == nil {
-				victims = make(watcherBatch)
-			}
-			w.victim = true
-		}
-
-		if w.victim {
-			victims[w] = eb
-		} else {
-			if eb.moreRev != 0 {
-				// stay unsynced; more to read
-				continue
-			}
-			s.synced.add(w)
-		}
-		s.unsynced.delete(w)
-	}
-	s.addVictim(victims)
-
-	vsz := 0
-	for _, v := range s.victims {
-		vsz += len(v)
-	}
-	slowWatcherGauge.Set(float64(s.unsynced.size() + vsz))
-
-	return s.unsynced.size()
-}
-
-// kvsToEvents gets all events for the watchers from all key-value pairs
-func kvsToEvents(lg *zap.Logger, wg *watcherGroup, revs, vals [][]byte) (evs []mvccpb.Event) {
-	for i, v := range vals {
-		var kv mvccpb.KeyValue
-		if err := kv.Unmarshal(v); err != nil {
-			if lg != nil {
-				lg.Panic("failed to unmarshal mvccpb.KeyValue", zap.Error(err))
-			} else {
-				plog.Panicf("cannot unmarshal event: %v", err)
-			}
-		}
-
-		if !wg.contains(string(kv.Key)) {
-			continue
-		}
-
-		ty := mvccpb.PUT
-		if isTombstone(revs[i]) {
-			ty = mvccpb.DELETE
-			// patch in mod revision so watchers won't skip
-			kv.ModRevision = bytesToRev(revs[i]).main
-		}
-		evs = append(evs, mvccpb.Event{Kv: &kv, Type: ty})
-	}
-	return evs
-}
-
-// notify notifies the fact that given event at the given rev just happened to
-// watchers that watch on the key of the event.
-func (s *watchableStore) notify(rev int64, evs []mvccpb.Event) {
-	var victim watcherBatch
-	for w, eb := range newWatcherBatch(&s.synced, evs) {
-		if eb.revs != 1 {
-			if s.store != nil && s.store.lg != nil {
-				s.store.lg.Panic(
-					"unexpected multiple revisions in watch notification",
-					zap.Int("number-of-revisions", eb.revs),
-				)
-			} else {
-				plog.Panicf("unexpected multiple revisions in notification")
-			}
-		}
-		if w.send(WatchResponse{WatchID: w.id, Events: eb.evs, Revision: rev}) {
-			pendingEventsGauge.Add(float64(len(eb.evs)))
-		} else {
-			// move slow watcher to victims
-			w.minRev = rev + 1
-			if victim == nil {
-				victim = make(watcherBatch)
-			}
-			w.victim = true
-			victim[w] = eb
-			s.synced.delete(w)
-			slowWatcherGauge.Inc()
-		}
-	}
-	s.addVictim(victim)
-}
-
-func (s *watchableStore) addVictim(victim watcherBatch) {
-	if victim == nil {
-		return
-	}
-	s.victims = append(s.victims, victim)
-	select {
-	case s.victimc <- struct{}{}:
-	default:
-	}
-}
-
-func (s *watchableStore) rev() int64 { return s.store.Rev() }
-
-func (s *watchableStore) progress(w *watcher) {
-	s.mu.RLock()
-	defer s.mu.RUnlock()
-
-	if _, ok := s.synced.watchers[w]; ok {
-		w.send(WatchResponse{WatchID: w.id, Revision: s.rev()})
-		// If the ch is full, this watcher is receiving events.
-		// We do not need to send progress at all.
-	}
-}
-
-type watcher struct {
-	// the watcher key
-	key []byte
-	// end indicates the end of the range to watch.
-	// If end is set, the watcher is on a range.
-	end []byte
-
-	// victim is set when ch is blocked and undergoing victim processing
-	victim bool
-
-	// compacted is set when the watcher is removed because of compaction
-	compacted bool
-
-	// restore is true when the watcher is being restored from leader snapshot
-	// which means that this watcher has just been moved from "synced" to "unsynced"
-	// watcher group, possibly with a future revision when it was first added
-	// to the synced watcher
-	// "unsynced" watcher revision must always be <= current revision,
-	// except when the watcher were to be moved from "synced" watcher group
-	restore bool
-
-	// minRev is the minimum revision update the watcher will accept
-	minRev int64
-	id     WatchID
-
-	fcs []FilterFunc
-	// a chan to send out the watch response.
-	// The chan might be shared with other watchers.
-	ch chan<- WatchResponse
-}
-
-func (w *watcher) send(wr WatchResponse) bool {
-	progressEvent := len(wr.Events) == 0
-
-	if len(w.fcs) != 0 {
-		ne := make([]mvccpb.Event, 0, len(wr.Events))
-		for i := range wr.Events {
-			filtered := false
-			for _, filter := range w.fcs {
-				if filter(wr.Events[i]) {
-					filtered = true
-					break
-				}
-			}
-			if !filtered {
-				ne = append(ne, wr.Events[i])
-			}
-		}
-		wr.Events = ne
-	}
-
-	// if all events are filtered out, we should send nothing.
-	if !progressEvent && len(wr.Events) == 0 {
-		return true
-	}
-	select {
-	case w.ch <- wr:
-		return true
-	default:
-		return false
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/watchable_store_txn.go b/vendor/go.etcd.io/etcd/mvcc/watchable_store_txn.go
deleted file mode 100644
index 3bcfa4d..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/watchable_store_txn.go
+++ /dev/null
@@ -1,51 +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 mvcc
-
-import "go.etcd.io/etcd/mvcc/mvccpb"
-
-func (tw *watchableStoreTxnWrite) End() {
-	changes := tw.Changes()
-	if len(changes) == 0 {
-		tw.TxnWrite.End()
-		return
-	}
-
-	rev := tw.Rev() + 1
-	evs := make([]mvccpb.Event, len(changes))
-	for i, change := range changes {
-		evs[i].Kv = &changes[i]
-		if change.CreateRevision == 0 {
-			evs[i].Type = mvccpb.DELETE
-			evs[i].Kv.ModRevision = rev
-		} else {
-			evs[i].Type = mvccpb.PUT
-		}
-	}
-
-	// end write txn under watchable store lock so the updates are visible
-	// when asynchronous event posting checks the current store revision
-	tw.s.mu.Lock()
-	tw.s.notify(rev, evs)
-	tw.TxnWrite.End()
-	tw.s.mu.Unlock()
-}
-
-type watchableStoreTxnWrite struct {
-	TxnWrite
-	s *watchableStore
-}
-
-func (s *watchableStore) Write() TxnWrite { return &watchableStoreTxnWrite{s.store.Write(), s} }
diff --git a/vendor/go.etcd.io/etcd/mvcc/watcher.go b/vendor/go.etcd.io/etcd/mvcc/watcher.go
deleted file mode 100644
index 2846d62..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/watcher.go
+++ /dev/null
@@ -1,193 +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 mvcc
-
-import (
-	"bytes"
-	"errors"
-	"sync"
-
-	"go.etcd.io/etcd/mvcc/mvccpb"
-)
-
-// AutoWatchID is the watcher ID passed in WatchStream.Watch when no
-// user-provided ID is available. If pass, an ID will automatically be assigned.
-const AutoWatchID WatchID = 0
-
-var (
-	ErrWatcherNotExist    = errors.New("mvcc: watcher does not exist")
-	ErrEmptyWatcherRange  = errors.New("mvcc: watcher range is empty")
-	ErrWatcherDuplicateID = errors.New("mvcc: duplicate watch ID provided on the WatchStream")
-)
-
-type WatchID int64
-
-// FilterFunc returns true if the given event should be filtered out.
-type FilterFunc func(e mvccpb.Event) bool
-
-type WatchStream interface {
-	// Watch creates a watcher. The watcher watches the events happening or
-	// happened on the given key or range [key, end) from the given startRev.
-	//
-	// The whole event history can be watched unless compacted.
-	// If "startRev" <=0, watch observes events after currentRev.
-	//
-	// The returned "id" is the ID of this watcher. It appears as WatchID
-	// in events that are sent to the created watcher through stream channel.
-	// The watch ID is used when it's not equal to AutoWatchID. Otherwise,
-	// an auto-generated watch ID is returned.
-	Watch(id WatchID, key, end []byte, startRev int64, fcs ...FilterFunc) (WatchID, error)
-
-	// Chan returns a chan. All watch response will be sent to the returned chan.
-	Chan() <-chan WatchResponse
-
-	// RequestProgress requests the progress of the watcher with given ID. The response
-	// will only be sent if the watcher is currently synced.
-	// The responses will be sent through the WatchRespone Chan attached
-	// with this stream to ensure correct ordering.
-	// The responses contains no events. The revision in the response is the progress
-	// of the watchers since the watcher is currently synced.
-	RequestProgress(id WatchID)
-
-	// Cancel cancels a watcher by giving its ID. If watcher does not exist, an error will be
-	// returned.
-	Cancel(id WatchID) error
-
-	// Close closes Chan and release all related resources.
-	Close()
-
-	// Rev returns the current revision of the KV the stream watches on.
-	Rev() int64
-}
-
-type WatchResponse struct {
-	// WatchID is the WatchID of the watcher this response sent to.
-	WatchID WatchID
-
-	// Events contains all the events that needs to send.
-	Events []mvccpb.Event
-
-	// Revision is the revision of the KV when the watchResponse is created.
-	// For a normal response, the revision should be the same as the last
-	// modified revision inside Events. For a delayed response to a unsynced
-	// watcher, the revision is greater than the last modified revision
-	// inside Events.
-	Revision int64
-
-	// CompactRevision is set when the watcher is cancelled due to compaction.
-	CompactRevision int64
-}
-
-// watchStream contains a collection of watchers that share
-// one streaming chan to send out watched events and other control events.
-type watchStream struct {
-	watchable watchable
-	ch        chan WatchResponse
-
-	mu sync.Mutex // guards fields below it
-	// nextID is the ID pre-allocated for next new watcher in this stream
-	nextID   WatchID
-	closed   bool
-	cancels  map[WatchID]cancelFunc
-	watchers map[WatchID]*watcher
-}
-
-// Watch creates a new watcher in the stream and returns its WatchID.
-func (ws *watchStream) Watch(id WatchID, key, end []byte, startRev int64, fcs ...FilterFunc) (WatchID, error) {
-	// prevent wrong range where key >= end lexicographically
-	// watch request with 'WithFromKey' has empty-byte range end
-	if len(end) != 0 && bytes.Compare(key, end) != -1 {
-		return -1, ErrEmptyWatcherRange
-	}
-
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-	if ws.closed {
-		return -1, ErrEmptyWatcherRange
-	}
-
-	if id == AutoWatchID {
-		for ws.watchers[ws.nextID] != nil {
-			ws.nextID++
-		}
-		id = ws.nextID
-		ws.nextID++
-	} else if _, ok := ws.watchers[id]; ok {
-		return -1, ErrWatcherDuplicateID
-	}
-
-	w, c := ws.watchable.watch(key, end, startRev, id, ws.ch, fcs...)
-
-	ws.cancels[id] = c
-	ws.watchers[id] = w
-	return id, nil
-}
-
-func (ws *watchStream) Chan() <-chan WatchResponse {
-	return ws.ch
-}
-
-func (ws *watchStream) Cancel(id WatchID) error {
-	ws.mu.Lock()
-	cancel, ok := ws.cancels[id]
-	w := ws.watchers[id]
-	ok = ok && !ws.closed
-	ws.mu.Unlock()
-
-	if !ok {
-		return ErrWatcherNotExist
-	}
-	cancel()
-
-	ws.mu.Lock()
-	// The watch isn't removed until cancel so that if Close() is called,
-	// it will wait for the cancel. Otherwise, Close() could close the
-	// watch channel while the store is still posting events.
-	if ww := ws.watchers[id]; ww == w {
-		delete(ws.cancels, id)
-		delete(ws.watchers, id)
-	}
-	ws.mu.Unlock()
-
-	return nil
-}
-
-func (ws *watchStream) Close() {
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-
-	for _, cancel := range ws.cancels {
-		cancel()
-	}
-	ws.closed = true
-	close(ws.ch)
-	watchStreamGauge.Dec()
-}
-
-func (ws *watchStream) Rev() int64 {
-	ws.mu.Lock()
-	defer ws.mu.Unlock()
-	return ws.watchable.rev()
-}
-
-func (ws *watchStream) RequestProgress(id WatchID) {
-	ws.mu.Lock()
-	w, ok := ws.watchers[id]
-	ws.mu.Unlock()
-	if !ok {
-		return
-	}
-	ws.watchable.progress(w)
-}
diff --git a/vendor/go.etcd.io/etcd/mvcc/watcher_group.go b/vendor/go.etcd.io/etcd/mvcc/watcher_group.go
deleted file mode 100644
index 151f0de..0000000
--- a/vendor/go.etcd.io/etcd/mvcc/watcher_group.go
+++ /dev/null
@@ -1,293 +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 mvcc
-
-import (
-	"fmt"
-	"math"
-
-	"go.etcd.io/etcd/mvcc/mvccpb"
-	"go.etcd.io/etcd/pkg/adt"
-)
-
-var (
-	// watchBatchMaxRevs is the maximum distinct revisions that
-	// may be sent to an unsynced watcher at a time. Declared as
-	// var instead of const for testing purposes.
-	watchBatchMaxRevs = 1000
-)
-
-type eventBatch struct {
-	// evs is a batch of revision-ordered events
-	evs []mvccpb.Event
-	// revs is the minimum unique revisions observed for this batch
-	revs int
-	// moreRev is first revision with more events following this batch
-	moreRev int64
-}
-
-func (eb *eventBatch) add(ev mvccpb.Event) {
-	if eb.revs > watchBatchMaxRevs {
-		// maxed out batch size
-		return
-	}
-
-	if len(eb.evs) == 0 {
-		// base case
-		eb.revs = 1
-		eb.evs = append(eb.evs, ev)
-		return
-	}
-
-	// revision accounting
-	ebRev := eb.evs[len(eb.evs)-1].Kv.ModRevision
-	evRev := ev.Kv.ModRevision
-	if evRev > ebRev {
-		eb.revs++
-		if eb.revs > watchBatchMaxRevs {
-			eb.moreRev = evRev
-			return
-		}
-	}
-
-	eb.evs = append(eb.evs, ev)
-}
-
-type watcherBatch map[*watcher]*eventBatch
-
-func (wb watcherBatch) add(w *watcher, ev mvccpb.Event) {
-	eb := wb[w]
-	if eb == nil {
-		eb = &eventBatch{}
-		wb[w] = eb
-	}
-	eb.add(ev)
-}
-
-// newWatcherBatch maps watchers to their matched events. It enables quick
-// events look up by watcher.
-func newWatcherBatch(wg *watcherGroup, evs []mvccpb.Event) watcherBatch {
-	if len(wg.watchers) == 0 {
-		return nil
-	}
-
-	wb := make(watcherBatch)
-	for _, ev := range evs {
-		for w := range wg.watcherSetByKey(string(ev.Kv.Key)) {
-			if ev.Kv.ModRevision >= w.minRev {
-				// don't double notify
-				wb.add(w, ev)
-			}
-		}
-	}
-	return wb
-}
-
-type watcherSet map[*watcher]struct{}
-
-func (w watcherSet) add(wa *watcher) {
-	if _, ok := w[wa]; ok {
-		panic("add watcher twice!")
-	}
-	w[wa] = struct{}{}
-}
-
-func (w watcherSet) union(ws watcherSet) {
-	for wa := range ws {
-		w.add(wa)
-	}
-}
-
-func (w watcherSet) delete(wa *watcher) {
-	if _, ok := w[wa]; !ok {
-		panic("removing missing watcher!")
-	}
-	delete(w, wa)
-}
-
-type watcherSetByKey map[string]watcherSet
-
-func (w watcherSetByKey) add(wa *watcher) {
-	set := w[string(wa.key)]
-	if set == nil {
-		set = make(watcherSet)
-		w[string(wa.key)] = set
-	}
-	set.add(wa)
-}
-
-func (w watcherSetByKey) delete(wa *watcher) bool {
-	k := string(wa.key)
-	if v, ok := w[k]; ok {
-		if _, ok := v[wa]; ok {
-			delete(v, wa)
-			if len(v) == 0 {
-				// remove the set; nothing left
-				delete(w, k)
-			}
-			return true
-		}
-	}
-	return false
-}
-
-// watcherGroup is a collection of watchers organized by their ranges
-type watcherGroup struct {
-	// keyWatchers has the watchers that watch on a single key
-	keyWatchers watcherSetByKey
-	// ranges has the watchers that watch a range; it is sorted by interval
-	ranges adt.IntervalTree
-	// watchers is the set of all watchers
-	watchers watcherSet
-}
-
-func newWatcherGroup() watcherGroup {
-	return watcherGroup{
-		keyWatchers: make(watcherSetByKey),
-		ranges:      adt.NewIntervalTree(),
-		watchers:    make(watcherSet),
-	}
-}
-
-// add puts a watcher in the group.
-func (wg *watcherGroup) add(wa *watcher) {
-	wg.watchers.add(wa)
-	if wa.end == nil {
-		wg.keyWatchers.add(wa)
-		return
-	}
-
-	// interval already registered?
-	ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end))
-	if iv := wg.ranges.Find(ivl); iv != nil {
-		iv.Val.(watcherSet).add(wa)
-		return
-	}
-
-	// not registered, put in interval tree
-	ws := make(watcherSet)
-	ws.add(wa)
-	wg.ranges.Insert(ivl, ws)
-}
-
-// contains is whether the given key has a watcher in the group.
-func (wg *watcherGroup) contains(key string) bool {
-	_, ok := wg.keyWatchers[key]
-	return ok || wg.ranges.Intersects(adt.NewStringAffinePoint(key))
-}
-
-// size gives the number of unique watchers in the group.
-func (wg *watcherGroup) size() int { return len(wg.watchers) }
-
-// delete removes a watcher from the group.
-func (wg *watcherGroup) delete(wa *watcher) bool {
-	if _, ok := wg.watchers[wa]; !ok {
-		return false
-	}
-	wg.watchers.delete(wa)
-	if wa.end == nil {
-		wg.keyWatchers.delete(wa)
-		return true
-	}
-
-	ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end))
-	iv := wg.ranges.Find(ivl)
-	if iv == nil {
-		return false
-	}
-
-	ws := iv.Val.(watcherSet)
-	delete(ws, wa)
-	if len(ws) == 0 {
-		// remove interval missing watchers
-		if ok := wg.ranges.Delete(ivl); !ok {
-			panic("could not remove watcher from interval tree")
-		}
-	}
-
-	return true
-}
-
-// choose selects watchers from the watcher group to update
-func (wg *watcherGroup) choose(maxWatchers int, curRev, compactRev int64) (*watcherGroup, int64) {
-	if len(wg.watchers) < maxWatchers {
-		return wg, wg.chooseAll(curRev, compactRev)
-	}
-	ret := newWatcherGroup()
-	for w := range wg.watchers {
-		if maxWatchers <= 0 {
-			break
-		}
-		maxWatchers--
-		ret.add(w)
-	}
-	return &ret, ret.chooseAll(curRev, compactRev)
-}
-
-func (wg *watcherGroup) chooseAll(curRev, compactRev int64) int64 {
-	minRev := int64(math.MaxInt64)
-	for w := range wg.watchers {
-		if w.minRev > curRev {
-			// after network partition, possibly choosing future revision watcher from restore operation
-			// with watch key "proxy-namespace__lostleader" and revision "math.MaxInt64 - 2"
-			// do not panic when such watcher had been moved from "synced" watcher during restore operation
-			if !w.restore {
-				panic(fmt.Errorf("watcher minimum revision %d should not exceed current revision %d", w.minRev, curRev))
-			}
-
-			// mark 'restore' done, since it's chosen
-			w.restore = false
-		}
-		if w.minRev < compactRev {
-			select {
-			case w.ch <- WatchResponse{WatchID: w.id, CompactRevision: compactRev}:
-				w.compacted = true
-				wg.delete(w)
-			default:
-				// retry next time
-			}
-			continue
-		}
-		if minRev > w.minRev {
-			minRev = w.minRev
-		}
-	}
-	return minRev
-}
-
-// watcherSetByKey gets the set of watchers that receive events on the given key.
-func (wg *watcherGroup) watcherSetByKey(key string) watcherSet {
-	wkeys := wg.keyWatchers[key]
-	wranges := wg.ranges.Stab(adt.NewStringAffinePoint(key))
-
-	// zero-copy cases
-	switch {
-	case len(wranges) == 0:
-		// no need to merge ranges or copy; reuse single-key set
-		return wkeys
-	case len(wranges) == 0 && len(wkeys) == 0:
-		return nil
-	case len(wranges) == 1 && len(wkeys) == 0:
-		return wranges[0].Val.(watcherSet)
-	}
-
-	// copy case
-	ret := make(watcherSet)
-	ret.union(wg.keyWatchers[key])
-	for _, item := range wranges {
-		ret.union(item.Val.(watcherSet))
-	}
-	return ret
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/adt/README.md b/vendor/go.etcd.io/etcd/pkg/adt/README.md
deleted file mode 100644
index a2089cd..0000000
--- a/vendor/go.etcd.io/etcd/pkg/adt/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-
-## Red-Black Tree
-
-*"Introduction to Algorithms" (Cormen et al, 3rd ed.), Chapter 13*
-
-1. Every node is either red or black.
-2. The root is black.
-3. Every leaf (NIL) is black.
-4. If a node is red, then both its children are black.
-5. For each node, all simple paths from the node to descendant leaves contain the
-same number of black nodes.
-
-For example,
-
-```go
-import (
-    "fmt"
-
-    "go.etcd.io/etcd/pkg/adt"
-)
-
-func main() {
-    ivt := adt.NewIntervalTree()
-    ivt.Insert(NewInt64Interval(510, 511), 0)
-    ivt.Insert(NewInt64Interval(82, 83), 0)
-    ivt.Insert(NewInt64Interval(830, 831), 0)
-    ...
-```
-
-After inserting the values `510`, `82`, `830`, `11`, `383`, `647`, `899`, `261`, `410`, `514`, `815`, `888`, `972`, `238`, `292`, `953`.
-
-![red-black-tree-01-insertion.png](img/red-black-tree-01-insertion.png)
-
-Deleting the node `514` should not trigger any rebalancing:
-
-![red-black-tree-02-delete-514.png](img/red-black-tree-02-delete-514.png)
-
-Deleting the node `11` triggers multiple rotates for rebalancing:
-
-![red-black-tree-03-delete-11.png](img/red-black-tree-03-delete-11.png)
-![red-black-tree-04-delete-11.png](img/red-black-tree-04-delete-11.png)
-![red-black-tree-05-delete-11.png](img/red-black-tree-05-delete-11.png)
-![red-black-tree-06-delete-11.png](img/red-black-tree-06-delete-11.png)
-![red-black-tree-07-delete-11.png](img/red-black-tree-07-delete-11.png)
-![red-black-tree-08-delete-11.png](img/red-black-tree-08-delete-11.png)
-![red-black-tree-09-delete-11.png](img/red-black-tree-09-delete-11.png)
-
-Try yourself at https://www.cs.usfca.edu/~galles/visualization/RedBlack.html.
diff --git a/vendor/go.etcd.io/etcd/pkg/adt/doc.go b/vendor/go.etcd.io/etcd/pkg/adt/doc.go
deleted file mode 100644
index 1a95591..0000000
--- a/vendor/go.etcd.io/etcd/pkg/adt/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 adt implements useful abstract data types.
-package adt
diff --git a/vendor/go.etcd.io/etcd/pkg/adt/interval_tree.go b/vendor/go.etcd.io/etcd/pkg/adt/interval_tree.go
deleted file mode 100644
index 2e5b2dd..0000000
--- a/vendor/go.etcd.io/etcd/pkg/adt/interval_tree.go
+++ /dev/null
@@ -1,951 +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 adt
-
-import (
-	"bytes"
-	"fmt"
-	"math"
-	"strings"
-)
-
-// Comparable is an interface for trichotomic comparisons.
-type Comparable interface {
-	// Compare gives the result of a 3-way comparison
-	// a.Compare(b) = 1 => a > b
-	// a.Compare(b) = 0 => a == b
-	// a.Compare(b) = -1 => a < b
-	Compare(c Comparable) int
-}
-
-type rbcolor int
-
-const (
-	black rbcolor = iota
-	red
-)
-
-func (c rbcolor) String() string {
-	switch c {
-	case black:
-		return "black"
-	case red:
-		return "black"
-	default:
-		panic(fmt.Errorf("unknown color %d", c))
-	}
-}
-
-// Interval implements a Comparable interval [begin, end)
-// TODO: support different sorts of intervals: (a,b), [a,b], (a, b]
-type Interval struct {
-	Begin Comparable
-	End   Comparable
-}
-
-// Compare on an interval gives == if the interval overlaps.
-func (ivl *Interval) Compare(c Comparable) int {
-	ivl2 := c.(*Interval)
-	ivbCmpBegin := ivl.Begin.Compare(ivl2.Begin)
-	ivbCmpEnd := ivl.Begin.Compare(ivl2.End)
-	iveCmpBegin := ivl.End.Compare(ivl2.Begin)
-
-	// ivl is left of ivl2
-	if ivbCmpBegin < 0 && iveCmpBegin <= 0 {
-		return -1
-	}
-
-	// iv is right of iv2
-	if ivbCmpEnd >= 0 {
-		return 1
-	}
-
-	return 0
-}
-
-type intervalNode struct {
-	// iv is the interval-value pair entry.
-	iv IntervalValue
-	// max endpoint of all descendent nodes.
-	max Comparable
-	// left and right are sorted by low endpoint of key interval
-	left, right *intervalNode
-	// parent is the direct ancestor of the node
-	parent *intervalNode
-	c      rbcolor
-}
-
-func (x *intervalNode) color(sentinel *intervalNode) rbcolor {
-	if x == sentinel {
-		return black
-	}
-	return x.c
-}
-
-func (x *intervalNode) height(sentinel *intervalNode) int {
-	if x == sentinel {
-		return 0
-	}
-	ld := x.left.height(sentinel)
-	rd := x.right.height(sentinel)
-	if ld < rd {
-		return rd + 1
-	}
-	return ld + 1
-}
-
-func (x *intervalNode) min(sentinel *intervalNode) *intervalNode {
-	for x.left != sentinel {
-		x = x.left
-	}
-	return x
-}
-
-// successor is the next in-order node in the tree
-func (x *intervalNode) successor(sentinel *intervalNode) *intervalNode {
-	if x.right != sentinel {
-		return x.right.min(sentinel)
-	}
-	y := x.parent
-	for y != sentinel && x == y.right {
-		x = y
-		y = y.parent
-	}
-	return y
-}
-
-// updateMax updates the maximum values for a node and its ancestors
-func (x *intervalNode) updateMax(sentinel *intervalNode) {
-	for x != sentinel {
-		oldmax := x.max
-		max := x.iv.Ivl.End
-		if x.left != sentinel && x.left.max.Compare(max) > 0 {
-			max = x.left.max
-		}
-		if x.right != sentinel && x.right.max.Compare(max) > 0 {
-			max = x.right.max
-		}
-		if oldmax.Compare(max) == 0 {
-			break
-		}
-		x.max = max
-		x = x.parent
-	}
-}
-
-type nodeVisitor func(n *intervalNode) bool
-
-// visit will call a node visitor on each node that overlaps the given interval
-func (x *intervalNode) visit(iv *Interval, sentinel *intervalNode, nv nodeVisitor) bool {
-	if x == sentinel {
-		return true
-	}
-	v := iv.Compare(&x.iv.Ivl)
-	switch {
-	case v < 0:
-		if !x.left.visit(iv, sentinel, nv) {
-			return false
-		}
-	case v > 0:
-		maxiv := Interval{x.iv.Ivl.Begin, x.max}
-		if maxiv.Compare(iv) == 0 {
-			if !x.left.visit(iv, sentinel, nv) || !x.right.visit(iv, sentinel, nv) {
-				return false
-			}
-		}
-	default:
-		if !x.left.visit(iv, sentinel, nv) || !nv(x) || !x.right.visit(iv, sentinel, nv) {
-			return false
-		}
-	}
-	return true
-}
-
-// IntervalValue represents a range tree node that contains a range and a value.
-type IntervalValue struct {
-	Ivl Interval
-	Val interface{}
-}
-
-// IntervalTree represents a (mostly) textbook implementation of the
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.) chapter 13 red-black tree
-// and chapter 14.3 interval tree with search supporting "stabbing queries".
-type IntervalTree interface {
-	// Insert adds a node with the given interval into the tree.
-	Insert(ivl Interval, val interface{})
-	// Delete removes the node with the given interval from the tree, returning
-	// true if a node is in fact removed.
-	Delete(ivl Interval) bool
-	// Len gives the number of elements in the tree.
-	Len() int
-	// Height is the number of levels in the tree; one node has height 1.
-	Height() int
-	// MaxHeight is the expected maximum tree height given the number of nodes.
-	MaxHeight() int
-	// Visit calls a visitor function on every tree node intersecting the given interval.
-	// It will visit each interval [x, y) in ascending order sorted on x.
-	Visit(ivl Interval, ivv IntervalVisitor)
-	// Find gets the IntervalValue for the node matching the given interval
-	Find(ivl Interval) *IntervalValue
-	// Intersects returns true if there is some tree node intersecting the given interval.
-	Intersects(iv Interval) bool
-	// Contains returns true if the interval tree's keys cover the entire given interval.
-	Contains(ivl Interval) bool
-	// Stab returns a slice with all elements in the tree intersecting the interval.
-	Stab(iv Interval) []*IntervalValue
-	// Union merges a given interval tree into the receiver.
-	Union(inIvt IntervalTree, ivl Interval)
-}
-
-// NewIntervalTree returns a new interval tree.
-func NewIntervalTree() IntervalTree {
-	sentinel := &intervalNode{
-		iv:     IntervalValue{},
-		max:    nil,
-		left:   nil,
-		right:  nil,
-		parent: nil,
-		c:      black,
-	}
-	return &intervalTree{
-		root:     sentinel,
-		count:    0,
-		sentinel: sentinel,
-	}
-}
-
-type intervalTree struct {
-	root  *intervalNode
-	count int
-
-	// red-black NIL node
-	// use 'sentinel' as a dummy object to simplify boundary conditions
-	// use the sentinel to treat a nil child of a node x as an ordinary node whose parent is x
-	// use one shared sentinel to represent all nil leaves and the root's parent
-	sentinel *intervalNode
-}
-
-// TODO: make this consistent with textbook implementation
-//
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p324
-//
-//	 0. RB-DELETE(T, z)
-//	 1.
-//	 2. y = z
-//	 3. y-original-color = y.color
-//	 4.
-//	 5. if z.left == T.nil
-//	 6. 	x = z.right
-//	 7. 	RB-TRANSPLANT(T, z, z.right)
-//	 8. else if z.right == T.nil
-//	 9. 	x = z.left
-//	10. 	RB-TRANSPLANT(T, z, z.left)
-//	11. else
-//	12. 	y = TREE-MINIMUM(z.right)
-//	13. 	y-original-color = y.color
-//	14. 	x = y.right
-//	15. 	if y.p == z
-//	16. 		x.p = y
-//	17. 	else
-//	18. 		RB-TRANSPLANT(T, y, y.right)
-//	19. 		y.right = z.right
-//	20. 		y.right.p = y
-//	21. 	RB-TRANSPLANT(T, z, y)
-//	22. 	y.left = z.left
-//	23. 	y.left.p = y
-//	24. 	y.color = z.color
-//	25.
-//	26. if y-original-color == BLACK
-//	27. 	RB-DELETE-FIXUP(T, x)
-
-// Delete removes the node with the given interval from the tree, returning
-// true if a node is in fact removed.
-func (ivt *intervalTree) Delete(ivl Interval) bool {
-	z := ivt.find(ivl)
-	if z == ivt.sentinel {
-		return false
-	}
-
-	y := z
-	if z.left != ivt.sentinel && z.right != ivt.sentinel {
-		y = z.successor(ivt.sentinel)
-	}
-
-	x := ivt.sentinel
-	if y.left != ivt.sentinel {
-		x = y.left
-	} else if y.right != ivt.sentinel {
-		x = y.right
-	}
-
-	x.parent = y.parent
-
-	if y.parent == ivt.sentinel {
-		ivt.root = x
-	} else {
-		if y == y.parent.left {
-			y.parent.left = x
-		} else {
-			y.parent.right = x
-		}
-		y.parent.updateMax(ivt.sentinel)
-	}
-	if y != z {
-		z.iv = y.iv
-		z.updateMax(ivt.sentinel)
-	}
-
-	if y.color(ivt.sentinel) == black {
-		ivt.deleteFixup(x)
-	}
-
-	ivt.count--
-	return true
-}
-
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.4, p326
-//
-//	 0. RB-DELETE-FIXUP(T, z)
-//	 1.
-//	 2. while x ≠ T.root and x.color == BLACK
-//	 3. 	if x == x.p.left
-//	 4. 		w = x.p.right
-//	 5. 		if w.color == RED
-//	 6. 			w.color = BLACK
-//	 7. 			x.p.color = RED
-//	 8. 			LEFT-ROTATE(T, x, p)
-//	 9. 		if w.left.color == BLACK and w.right.color == BLACK
-//	10. 			w.color = RED
-//	11. 			x = x.p
-//	12. 		else if w.right.color == BLACK
-//	13. 				w.left.color = BLACK
-//	14. 				w.color = RED
-//	15. 				RIGHT-ROTATE(T, w)
-//	16. 				w = w.p.right
-//	17. 			w.color = x.p.color
-//	18. 			x.p.color = BLACK
-//	19. 			LEFT-ROTATE(T, w.p)
-//	20. 			x = T.root
-//	21. 	else
-//	22. 		w = x.p.left
-//	23. 		if w.color == RED
-//	24. 			w.color = BLACK
-//	25. 			x.p.color = RED
-//	26. 			RIGHT-ROTATE(T, x, p)
-//	27. 		if w.right.color == BLACK and w.left.color == BLACK
-//	28. 			w.color = RED
-//	29. 			x = x.p
-//	30. 		else if w.left.color == BLACK
-//	31. 				w.right.color = BLACK
-//	32. 				w.color = RED
-//	33. 				LEFT-ROTATE(T, w)
-//	34. 				w = w.p.left
-//	35. 			w.color = x.p.color
-//	36. 			x.p.color = BLACK
-//	37. 			RIGHT-ROTATE(T, w.p)
-//	38. 			x = T.root
-//	39.
-//	40. x.color = BLACK
-//
-func (ivt *intervalTree) deleteFixup(x *intervalNode) {
-	for x != ivt.root && x.color(ivt.sentinel) == black {
-		if x == x.parent.left { // line 3-20
-			w := x.parent.right
-			if w.color(ivt.sentinel) == red {
-				w.c = black
-				x.parent.c = red
-				ivt.rotateLeft(x.parent)
-				w = x.parent.right
-			}
-			if w == nil {
-				break
-			}
-			if w.left.color(ivt.sentinel) == black && w.right.color(ivt.sentinel) == black {
-				w.c = red
-				x = x.parent
-			} else {
-				if w.right.color(ivt.sentinel) == black {
-					w.left.c = black
-					w.c = red
-					ivt.rotateRight(w)
-					w = x.parent.right
-				}
-				w.c = x.parent.color(ivt.sentinel)
-				x.parent.c = black
-				w.right.c = black
-				ivt.rotateLeft(x.parent)
-				x = ivt.root
-			}
-		} else { // line 22-38
-			// same as above but with left and right exchanged
-			w := x.parent.left
-			if w.color(ivt.sentinel) == red {
-				w.c = black
-				x.parent.c = red
-				ivt.rotateRight(x.parent)
-				w = x.parent.left
-			}
-			if w == nil {
-				break
-			}
-			if w.left.color(ivt.sentinel) == black && w.right.color(ivt.sentinel) == black {
-				w.c = red
-				x = x.parent
-			} else {
-				if w.left.color(ivt.sentinel) == black {
-					w.right.c = black
-					w.c = red
-					ivt.rotateLeft(w)
-					w = x.parent.left
-				}
-				w.c = x.parent.color(ivt.sentinel)
-				x.parent.c = black
-				w.left.c = black
-				ivt.rotateRight(x.parent)
-				x = ivt.root
-			}
-		}
-	}
-
-	if x != nil {
-		x.c = black
-	}
-}
-
-func (ivt *intervalTree) createIntervalNode(ivl Interval, val interface{}) *intervalNode {
-	return &intervalNode{
-		iv:     IntervalValue{ivl, val},
-		max:    ivl.End,
-		c:      red,
-		left:   ivt.sentinel,
-		right:  ivt.sentinel,
-		parent: ivt.sentinel,
-	}
-}
-
-// TODO: make this consistent with textbook implementation
-//
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p315
-//
-//	 0. RB-INSERT(T, z)
-//	 1.
-//	 2. y = T.nil
-//	 3. x = T.root
-//	 4.
-//	 5. while x ≠ T.nil
-//	 6. 	y = x
-//	 7. 	if z.key < x.key
-//	 8. 		x = x.left
-//	 9. 	else
-//	10. 		x = x.right
-//	11.
-//	12. z.p = y
-//	13.
-//	14. if y == T.nil
-//	15. 	T.root = z
-//	16. else if z.key < y.key
-//	17. 	y.left = z
-//	18. else
-//	19. 	y.right = z
-//	20.
-//	21. z.left = T.nil
-//	22. z.right = T.nil
-//	23. z.color = RED
-//	24.
-//	25. RB-INSERT-FIXUP(T, z)
-
-// Insert adds a node with the given interval into the tree.
-func (ivt *intervalTree) Insert(ivl Interval, val interface{}) {
-	y := ivt.sentinel
-	z := ivt.createIntervalNode(ivl, val)
-	x := ivt.root
-	for x != ivt.sentinel {
-		y = x
-		if z.iv.Ivl.Begin.Compare(x.iv.Ivl.Begin) < 0 {
-			x = x.left
-		} else {
-			x = x.right
-		}
-	}
-
-	z.parent = y
-	if y == ivt.sentinel {
-		ivt.root = z
-	} else {
-		if z.iv.Ivl.Begin.Compare(y.iv.Ivl.Begin) < 0 {
-			y.left = z
-		} else {
-			y.right = z
-		}
-		y.updateMax(ivt.sentinel)
-	}
-	z.c = red
-
-	ivt.insertFixup(z)
-	ivt.count++
-}
-
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.3, p316
-//
-//	 0. RB-INSERT-FIXUP(T, z)
-//	 1.
-//	 2. while z.p.color == RED
-//	 3. 	if z.p == z.p.p.left
-//	 4. 		y = z.p.p.right
-//	 5. 		if y.color == RED
-//	 6. 			z.p.color = BLACK
-//	 7. 			y.color = BLACK
-//	 8. 			z.p.p.color = RED
-//	 9. 			z = z.p.p
-//	10. 		else if z == z.p.right
-//	11. 				z = z.p
-//	12. 				LEFT-ROTATE(T, z)
-//	13. 			z.p.color = BLACK
-//	14. 			z.p.p.color = RED
-//	15. 			RIGHT-ROTATE(T, z.p.p)
-//	16. 	else
-//	17. 		y = z.p.p.left
-//	18. 		if y.color == RED
-//	19. 			z.p.color = BLACK
-//	20. 			y.color = BLACK
-//	21. 			z.p.p.color = RED
-//	22. 			z = z.p.p
-//	23. 		else if z == z.p.right
-//	24. 				z = z.p
-//	25. 				RIGHT-ROTATE(T, z)
-//	26. 			z.p.color = BLACK
-//	27. 			z.p.p.color = RED
-//	28. 			LEFT-ROTATE(T, z.p.p)
-//	29.
-//	30. T.root.color = BLACK
-//
-func (ivt *intervalTree) insertFixup(z *intervalNode) {
-	for z.parent.color(ivt.sentinel) == red {
-		if z.parent == z.parent.parent.left { // line 3-15
-
-			y := z.parent.parent.right
-			if y.color(ivt.sentinel) == red {
-				y.c = black
-				z.parent.c = black
-				z.parent.parent.c = red
-				z = z.parent.parent
-			} else {
-				if z == z.parent.right {
-					z = z.parent
-					ivt.rotateLeft(z)
-				}
-				z.parent.c = black
-				z.parent.parent.c = red
-				ivt.rotateRight(z.parent.parent)
-			}
-		} else { // line 16-28
-			// same as then with left/right exchanged
-			y := z.parent.parent.left
-			if y.color(ivt.sentinel) == red {
-				y.c = black
-				z.parent.c = black
-				z.parent.parent.c = red
-				z = z.parent.parent
-			} else {
-				if z == z.parent.left {
-					z = z.parent
-					ivt.rotateRight(z)
-				}
-				z.parent.c = black
-				z.parent.parent.c = red
-				ivt.rotateLeft(z.parent.parent)
-			}
-		}
-	}
-
-	// line 30
-	ivt.root.c = black
-}
-
-// rotateLeft moves x so it is left of its right child
-//
-// "Introduction to Algorithms" (Cormen et al, 3rd ed.), chapter 13.2, p313
-//
-//	 0. LEFT-ROTATE(T, x)
-//	 1.
-//	 2. y = x.right
-//	 3. x.right = y.left
-//	 4.
-//	 5. if y.left ≠ T.nil
-//	 6. 	y.left.p = x
-//	 7.
-//	 8. y.p = x.p
-//	 9.
-//	10. if x.p == T.nil
-//	11. 	T.root = y
-//	12. else if x == x.p.left
-//	13. 	x.p.left = y
-//	14. else
-//	15. 	x.p.right = y
-//	16.
-//	17. y.left = x
-//	18. x.p = y
-//
-func (ivt *intervalTree) rotateLeft(x *intervalNode) {
-	// rotateLeft x must have right child
-	if x.right == ivt.sentinel {
-		return
-	}
-
-	// line 2-3
-	y := x.right
-	x.right = y.left
-
-	// line 5-6
-	if y.left != ivt.sentinel {
-		y.left.parent = x
-	}
-	x.updateMax(ivt.sentinel)
-
-	// line 10-15, 18
-	ivt.replaceParent(x, y)
-
-	// line 17
-	y.left = x
-	y.updateMax(ivt.sentinel)
-}
-
-// rotateRight moves x so it is right of its left child
-//
-//	 0. RIGHT-ROTATE(T, x)
-//	 1.
-//	 2. y = x.left
-//	 3. x.left = y.right
-//	 4.
-//	 5. if y.right ≠ T.nil
-//	 6. 	y.right.p = x
-//	 7.
-//	 8. y.p = x.p
-//	 9.
-//	10. if x.p == T.nil
-//	11. 	T.root = y
-//	12. else if x == x.p.right
-//	13. 	x.p.right = y
-//	14. else
-//	15. 	x.p.left = y
-//	16.
-//	17. y.right = x
-//	18. x.p = y
-//
-func (ivt *intervalTree) rotateRight(x *intervalNode) {
-	// rotateRight x must have left child
-	if x.left == ivt.sentinel {
-		return
-	}
-
-	// line 2-3
-	y := x.left
-	x.left = y.right
-
-	// line 5-6
-	if y.right != ivt.sentinel {
-		y.right.parent = x
-	}
-	x.updateMax(ivt.sentinel)
-
-	// line 10-15, 18
-	ivt.replaceParent(x, y)
-
-	// line 17
-	y.right = x
-	y.updateMax(ivt.sentinel)
-}
-
-// replaceParent replaces x's parent with y
-func (ivt *intervalTree) replaceParent(x *intervalNode, y *intervalNode) {
-	y.parent = x.parent
-	if x.parent == ivt.sentinel {
-		ivt.root = y
-	} else {
-		if x == x.parent.left {
-			x.parent.left = y
-		} else {
-			x.parent.right = y
-		}
-		x.parent.updateMax(ivt.sentinel)
-	}
-	x.parent = y
-}
-
-// Len gives the number of elements in the tree
-func (ivt *intervalTree) Len() int { return ivt.count }
-
-// Height is the number of levels in the tree; one node has height 1.
-func (ivt *intervalTree) Height() int { return ivt.root.height(ivt.sentinel) }
-
-// MaxHeight is the expected maximum tree height given the number of nodes
-func (ivt *intervalTree) MaxHeight() int {
-	return int((2 * math.Log2(float64(ivt.Len()+1))) + 0.5)
-}
-
-// IntervalVisitor is used on tree searches; return false to stop searching.
-type IntervalVisitor func(n *IntervalValue) bool
-
-// Visit calls a visitor function on every tree node intersecting the given interval.
-// It will visit each interval [x, y) in ascending order sorted on x.
-func (ivt *intervalTree) Visit(ivl Interval, ivv IntervalVisitor) {
-	ivt.root.visit(&ivl, ivt.sentinel, func(n *intervalNode) bool { return ivv(&n.iv) })
-}
-
-// find the exact node for a given interval
-func (ivt *intervalTree) find(ivl Interval) *intervalNode {
-	ret := ivt.sentinel
-	f := func(n *intervalNode) bool {
-		if n.iv.Ivl != ivl {
-			return true
-		}
-		ret = n
-		return false
-	}
-	ivt.root.visit(&ivl, ivt.sentinel, f)
-	return ret
-}
-
-// Find gets the IntervalValue for the node matching the given interval
-func (ivt *intervalTree) Find(ivl Interval) (ret *IntervalValue) {
-	n := ivt.find(ivl)
-	if n == ivt.sentinel {
-		return nil
-	}
-	return &n.iv
-}
-
-// Intersects returns true if there is some tree node intersecting the given interval.
-func (ivt *intervalTree) Intersects(iv Interval) bool {
-	x := ivt.root
-	for x != ivt.sentinel && iv.Compare(&x.iv.Ivl) != 0 {
-		if x.left != ivt.sentinel && x.left.max.Compare(iv.Begin) > 0 {
-			x = x.left
-		} else {
-			x = x.right
-		}
-	}
-	return x != ivt.sentinel
-}
-
-// Contains returns true if the interval tree's keys cover the entire given interval.
-func (ivt *intervalTree) Contains(ivl Interval) bool {
-	var maxEnd, minBegin Comparable
-
-	isContiguous := true
-	ivt.Visit(ivl, func(n *IntervalValue) bool {
-		if minBegin == nil {
-			minBegin = n.Ivl.Begin
-			maxEnd = n.Ivl.End
-			return true
-		}
-		if maxEnd.Compare(n.Ivl.Begin) < 0 {
-			isContiguous = false
-			return false
-		}
-		if n.Ivl.End.Compare(maxEnd) > 0 {
-			maxEnd = n.Ivl.End
-		}
-		return true
-	})
-
-	return isContiguous && minBegin != nil && maxEnd.Compare(ivl.End) >= 0 && minBegin.Compare(ivl.Begin) <= 0
-}
-
-// Stab returns a slice with all elements in the tree intersecting the interval.
-func (ivt *intervalTree) Stab(iv Interval) (ivs []*IntervalValue) {
-	if ivt.count == 0 {
-		return nil
-	}
-	f := func(n *IntervalValue) bool { ivs = append(ivs, n); return true }
-	ivt.Visit(iv, f)
-	return ivs
-}
-
-// Union merges a given interval tree into the receiver.
-func (ivt *intervalTree) Union(inIvt IntervalTree, ivl Interval) {
-	f := func(n *IntervalValue) bool {
-		ivt.Insert(n.Ivl, n.Val)
-		return true
-	}
-	inIvt.Visit(ivl, f)
-}
-
-type visitedInterval struct {
-	root  Interval
-	left  Interval
-	right Interval
-	color rbcolor
-	depth int
-}
-
-func (vi visitedInterval) String() string {
-	bd := new(strings.Builder)
-	bd.WriteString(fmt.Sprintf("root [%v,%v,%v], left [%v,%v], right [%v,%v], depth %d",
-		vi.root.Begin, vi.root.End, vi.color,
-		vi.left.Begin, vi.left.End,
-		vi.right.Begin, vi.right.End,
-		vi.depth,
-	))
-	return bd.String()
-}
-
-// visitLevel traverses tree in level order.
-// used for testing
-func (ivt *intervalTree) visitLevel() []visitedInterval {
-	if ivt.root == ivt.sentinel {
-		return nil
-	}
-
-	rs := make([]visitedInterval, 0, ivt.Len())
-
-	type pair struct {
-		node  *intervalNode
-		depth int
-	}
-	queue := []pair{{ivt.root, 0}}
-	for len(queue) > 0 {
-		f := queue[0]
-		queue = queue[1:]
-
-		vi := visitedInterval{
-			root:  f.node.iv.Ivl,
-			color: f.node.color(ivt.sentinel),
-			depth: f.depth,
-		}
-		if f.node.left != ivt.sentinel {
-			vi.left = f.node.left.iv.Ivl
-			queue = append(queue, pair{f.node.left, f.depth + 1})
-		}
-		if f.node.right != ivt.sentinel {
-			vi.right = f.node.right.iv.Ivl
-			queue = append(queue, pair{f.node.right, f.depth + 1})
-		}
-
-		rs = append(rs, vi)
-	}
-
-	return rs
-}
-
-type StringComparable string
-
-func (s StringComparable) Compare(c Comparable) int {
-	sc := c.(StringComparable)
-	if s < sc {
-		return -1
-	}
-	if s > sc {
-		return 1
-	}
-	return 0
-}
-
-func NewStringInterval(begin, end string) Interval {
-	return Interval{StringComparable(begin), StringComparable(end)}
-}
-
-func NewStringPoint(s string) Interval {
-	return Interval{StringComparable(s), StringComparable(s + "\x00")}
-}
-
-// StringAffineComparable treats "" as > all other strings
-type StringAffineComparable string
-
-func (s StringAffineComparable) Compare(c Comparable) int {
-	sc := c.(StringAffineComparable)
-
-	if len(s) == 0 {
-		if len(sc) == 0 {
-			return 0
-		}
-		return 1
-	}
-	if len(sc) == 0 {
-		return -1
-	}
-
-	if s < sc {
-		return -1
-	}
-	if s > sc {
-		return 1
-	}
-	return 0
-}
-
-func NewStringAffineInterval(begin, end string) Interval {
-	return Interval{StringAffineComparable(begin), StringAffineComparable(end)}
-}
-
-func NewStringAffinePoint(s string) Interval {
-	return NewStringAffineInterval(s, s+"\x00")
-}
-
-func NewInt64Interval(a int64, b int64) Interval {
-	return Interval{Int64Comparable(a), Int64Comparable(b)}
-}
-
-func newInt64EmptyInterval() Interval {
-	return Interval{Begin: nil, End: nil}
-}
-
-func NewInt64Point(a int64) Interval {
-	return Interval{Int64Comparable(a), Int64Comparable(a + 1)}
-}
-
-type Int64Comparable int64
-
-func (v Int64Comparable) Compare(c Comparable) int {
-	vc := c.(Int64Comparable)
-	cmp := v - vc
-	if cmp < 0 {
-		return -1
-	}
-	if cmp > 0 {
-		return 1
-	}
-	return 0
-}
-
-// BytesAffineComparable treats empty byte arrays as > all other byte arrays
-type BytesAffineComparable []byte
-
-func (b BytesAffineComparable) Compare(c Comparable) int {
-	bc := c.(BytesAffineComparable)
-
-	if len(b) == 0 {
-		if len(bc) == 0 {
-			return 0
-		}
-		return 1
-	}
-	if len(bc) == 0 {
-		return -1
-	}
-
-	return bytes.Compare(b, bc)
-}
-
-func NewBytesAffineInterval(begin, end []byte) Interval {
-	return Interval{BytesAffineComparable(begin), BytesAffineComparable(end)}
-}
-
-func NewBytesAffinePoint(b []byte) Interval {
-	be := make([]byte, len(b)+1)
-	copy(be, b)
-	be[len(b)] = 0
-	return NewBytesAffineInterval(b, be)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/contention/contention.go b/vendor/go.etcd.io/etcd/pkg/contention/contention.go
deleted file mode 100644
index 26ce9a2..0000000
--- a/vendor/go.etcd.io/etcd/pkg/contention/contention.go
+++ /dev/null
@@ -1,69 +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 contention
-
-import (
-	"sync"
-	"time"
-)
-
-// TimeoutDetector detects routine starvations by
-// observing the actual time duration to finish an action
-// or between two events that should happen in a fixed
-// interval. If the observed duration is longer than
-// the expectation, the detector will report the result.
-type TimeoutDetector struct {
-	mu          sync.Mutex // protects all
-	maxDuration time.Duration
-	// map from event to time
-	// time is the last seen time of the event.
-	records map[uint64]time.Time
-}
-
-// NewTimeoutDetector creates the TimeoutDetector.
-func NewTimeoutDetector(maxDuration time.Duration) *TimeoutDetector {
-	return &TimeoutDetector{
-		maxDuration: maxDuration,
-		records:     make(map[uint64]time.Time),
-	}
-}
-
-// Reset resets the NewTimeoutDetector.
-func (td *TimeoutDetector) Reset() {
-	td.mu.Lock()
-	defer td.mu.Unlock()
-
-	td.records = make(map[uint64]time.Time)
-}
-
-// Observe observes an event for given id. It returns false and exceeded duration
-// if the interval is longer than the expectation.
-func (td *TimeoutDetector) Observe(which uint64) (bool, time.Duration) {
-	td.mu.Lock()
-	defer td.mu.Unlock()
-
-	ok := true
-	now := time.Now()
-	exceed := time.Duration(0)
-
-	if pt, found := td.records[which]; found {
-		exceed = now.Sub(pt) - td.maxDuration
-		if exceed > 0 {
-			ok = false
-		}
-	}
-	td.records[which] = now
-	return ok, exceed
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/contention/doc.go b/vendor/go.etcd.io/etcd/pkg/contention/doc.go
deleted file mode 100644
index daf4522..0000000
--- a/vendor/go.etcd.io/etcd/pkg/contention/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 contention provides facilities for detecting system contention.
-package contention
diff --git a/vendor/go.etcd.io/etcd/pkg/cpuutil/doc.go b/vendor/go.etcd.io/etcd/pkg/cpuutil/doc.go
deleted file mode 100644
index 0323b2d..0000000
--- a/vendor/go.etcd.io/etcd/pkg/cpuutil/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 cpuutil provides facilities for detecting cpu-specific features.
-package cpuutil
diff --git a/vendor/go.etcd.io/etcd/pkg/cpuutil/endian.go b/vendor/go.etcd.io/etcd/pkg/cpuutil/endian.go
deleted file mode 100644
index 06c06cd..0000000
--- a/vendor/go.etcd.io/etcd/pkg/cpuutil/endian.go
+++ /dev/null
@@ -1,36 +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 cpuutil
-
-import (
-	"encoding/binary"
-	"unsafe"
-)
-
-const intWidth int = int(unsafe.Sizeof(0))
-
-var byteOrder binary.ByteOrder
-
-// ByteOrder returns the byte order for the CPU's native endianness.
-func ByteOrder() binary.ByteOrder { return byteOrder }
-
-func init() {
-	i := int(0x1)
-	if v := (*[intWidth]byte)(unsafe.Pointer(&i)); v[0] == 0 {
-		byteOrder = binary.BigEndian
-	} else {
-		byteOrder = binary.LittleEndian
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/crc/crc.go b/vendor/go.etcd.io/etcd/pkg/crc/crc.go
deleted file mode 100644
index 4b998a4..0000000
--- a/vendor/go.etcd.io/etcd/pkg/crc/crc.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package crc provides utility function for cyclic redundancy check
-// algorithms.
-package crc
-
-import (
-	"hash"
-	"hash/crc32"
-)
-
-// The size of a CRC-32 checksum in bytes.
-const Size = 4
-
-type digest struct {
-	crc uint32
-	tab *crc32.Table
-}
-
-// New creates a new hash.Hash32 computing the CRC-32 checksum
-// using the polynomial represented by the Table.
-// Modified by xiangli to take a prevcrc.
-func New(prev uint32, tab *crc32.Table) hash.Hash32 { return &digest{prev, tab} }
-
-func (d *digest) Size() int { return Size }
-
-func (d *digest) BlockSize() int { return 1 }
-
-func (d *digest) Reset() { d.crc = 0 }
-
-func (d *digest) Write(p []byte) (n int, err error) {
-	d.crc = crc32.Update(d.crc, d.tab, p)
-	return len(p), nil
-}
-
-func (d *digest) Sum32() uint32 { return d.crc }
-
-func (d *digest) Sum(in []byte) []byte {
-	s := d.Sum32()
-	return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/debugutil/doc.go b/vendor/go.etcd.io/etcd/pkg/debugutil/doc.go
deleted file mode 100644
index 74499eb..0000000
--- a/vendor/go.etcd.io/etcd/pkg/debugutil/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 debugutil includes utility functions for debugging.
-package debugutil
diff --git a/vendor/go.etcd.io/etcd/pkg/debugutil/pprof.go b/vendor/go.etcd.io/etcd/pkg/debugutil/pprof.go
deleted file mode 100644
index 8d5544a..0000000
--- a/vendor/go.etcd.io/etcd/pkg/debugutil/pprof.go
+++ /dev/null
@@ -1,47 +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 debugutil
-
-import (
-	"net/http"
-	"net/http/pprof"
-	"runtime"
-)
-
-const HTTPPrefixPProf = "/debug/pprof"
-
-// PProfHandlers returns a map of pprof handlers keyed by the HTTP path.
-func PProfHandlers() map[string]http.Handler {
-	// set only when there's no existing setting
-	if runtime.SetMutexProfileFraction(-1) == 0 {
-		// 1 out of 5 mutex events are reported, on average
-		runtime.SetMutexProfileFraction(5)
-	}
-
-	m := make(map[string]http.Handler)
-
-	m[HTTPPrefixPProf+"/"] = http.HandlerFunc(pprof.Index)
-	m[HTTPPrefixPProf+"/profile"] = http.HandlerFunc(pprof.Profile)
-	m[HTTPPrefixPProf+"/symbol"] = http.HandlerFunc(pprof.Symbol)
-	m[HTTPPrefixPProf+"/cmdline"] = http.HandlerFunc(pprof.Cmdline)
-	m[HTTPPrefixPProf+"/trace "] = http.HandlerFunc(pprof.Trace)
-	m[HTTPPrefixPProf+"/heap"] = pprof.Handler("heap")
-	m[HTTPPrefixPProf+"/goroutine"] = pprof.Handler("goroutine")
-	m[HTTPPrefixPProf+"/threadcreate"] = pprof.Handler("threadcreate")
-	m[HTTPPrefixPProf+"/block"] = pprof.Handler("block")
-	m[HTTPPrefixPProf+"/mutex"] = pprof.Handler("mutex")
-
-	return m
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/dir_unix.go b/vendor/go.etcd.io/etcd/pkg/fileutil/dir_unix.go
deleted file mode 100644
index 58a77df..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/dir_unix.go
+++ /dev/null
@@ -1,22 +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.
-
-// +build !windows
-
-package fileutil
-
-import "os"
-
-// OpenDir opens a directory for syncing.
-func OpenDir(path string) (*os.File, error) { return os.Open(path) }
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/dir_windows.go b/vendor/go.etcd.io/etcd/pkg/fileutil/dir_windows.go
deleted file mode 100644
index c123395..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/dir_windows.go
+++ /dev/null
@@ -1,46 +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.
-
-// +build windows
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// OpenDir opens a directory in windows with write access for syncing.
-func OpenDir(path string) (*os.File, error) {
-	fd, err := openDir(path)
-	if err != nil {
-		return nil, err
-	}
-	return os.NewFile(uintptr(fd), path), nil
-}
-
-func openDir(path string) (fd syscall.Handle, err error) {
-	if len(path) == 0 {
-		return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
-	}
-	pathp, err := syscall.UTF16PtrFromString(path)
-	if err != nil {
-		return syscall.InvalidHandle, err
-	}
-	access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
-	sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
-	createmode := uint32(syscall.OPEN_EXISTING)
-	fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
-	return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/doc.go b/vendor/go.etcd.io/etcd/pkg/fileutil/doc.go
deleted file mode 100644
index 69dde5a..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/doc.go
+++ /dev/null
@@ -1,16 +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 fileutil implements utility functions related to files and paths.
-package fileutil
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/fileutil.go b/vendor/go.etcd.io/etcd/pkg/fileutil/fileutil.go
deleted file mode 100644
index 5d9fb53..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/fileutil.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 fileutil
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-const (
-	// PrivateFileMode grants owner to read/write a file.
-	PrivateFileMode = 0600
-	// PrivateDirMode grants owner to make/remove files inside the directory.
-	PrivateDirMode = 0700
-)
-
-var plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "pkg/fileutil")
-
-// IsDirWriteable checks if dir is writable by writing and removing a file
-// to dir. It returns nil if dir is writable.
-func IsDirWriteable(dir string) error {
-	f := filepath.Join(dir, ".touch")
-	if err := ioutil.WriteFile(f, []byte(""), PrivateFileMode); err != nil {
-		return err
-	}
-	return os.Remove(f)
-}
-
-// TouchDirAll is similar to os.MkdirAll. It creates directories with 0700 permission if any directory
-// does not exists. TouchDirAll also ensures the given directory is writable.
-func TouchDirAll(dir string) error {
-	// If path is already a directory, MkdirAll does nothing
-	// and returns nil.
-	err := os.MkdirAll(dir, PrivateDirMode)
-	if err != nil {
-		// if mkdirAll("a/text") and "text" is not
-		// a directory, this will return syscall.ENOTDIR
-		return err
-	}
-	return IsDirWriteable(dir)
-}
-
-// CreateDirAll is similar to TouchDirAll but returns error
-// if the deepest directory was not empty.
-func CreateDirAll(dir string) error {
-	err := TouchDirAll(dir)
-	if err == nil {
-		var ns []string
-		ns, err = ReadDir(dir)
-		if err != nil {
-			return err
-		}
-		if len(ns) != 0 {
-			err = fmt.Errorf("expected %q to be empty, got %q", dir, ns)
-		}
-	}
-	return err
-}
-
-// Exist returns true if a file or directory exists.
-func Exist(name string) bool {
-	_, err := os.Stat(name)
-	return err == nil
-}
-
-// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily
-// shorten the length of the file.
-func ZeroToEnd(f *os.File) error {
-	// TODO: support FALLOC_FL_ZERO_RANGE
-	off, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	lenf, lerr := f.Seek(0, io.SeekEnd)
-	if lerr != nil {
-		return lerr
-	}
-	if err = f.Truncate(off); err != nil {
-		return err
-	}
-	// make sure blocks remain allocated
-	if err = Preallocate(f, lenf, true); err != nil {
-		return err
-	}
-	_, err = f.Seek(off, io.SeekStart)
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock.go
deleted file mode 100644
index 338627f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock.go
+++ /dev/null
@@ -1,26 +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 fileutil
-
-import (
-	"errors"
-	"os"
-)
-
-var (
-	ErrLocked = errors.New("fileutil: file already locked")
-)
-
-type LockedFile struct{ *os.File }
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_flock.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_flock.go
deleted file mode 100644
index 542550b..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_flock.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.
-
-// +build !windows,!plan9,!solaris
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func flockTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
-		f.Close()
-		if err == syscall.EWOULDBLOCK {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func flockLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_linux.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_linux.go
deleted file mode 100644
index b0abc98..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_linux.go
+++ /dev/null
@@ -1,97 +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.
-
-// +build linux
-
-package fileutil
-
-import (
-	"fmt"
-	"io"
-	"os"
-	"syscall"
-)
-
-// This used to call syscall.Flock() but that call fails with EBADF on NFS.
-// An alternative is lockf() which works on NFS but that call lets a process lock
-// the same file twice. Instead, use Linux's non-standard open file descriptor
-// locks which will block if the process already holds the file lock.
-//
-// constants from /usr/include/bits/fcntl-linux.h
-const (
-	F_OFD_GETLK  = 37
-	F_OFD_SETLK  = 37
-	F_OFD_SETLKW = 38
-)
-
-var (
-	wrlck = syscall.Flock_t{
-		Type:   syscall.F_WRLCK,
-		Whence: int16(io.SeekStart),
-		Start:  0,
-		Len:    0,
-	}
-
-	linuxTryLockFile = flockTryLockFile
-	linuxLockFile    = flockLockFile
-)
-
-func init() {
-	// use open file descriptor locks if the system supports it
-	getlk := syscall.Flock_t{Type: syscall.F_RDLCK}
-	if err := syscall.FcntlFlock(0, F_OFD_GETLK, &getlk); err == nil {
-		linuxTryLockFile = ofdTryLockFile
-		linuxLockFile = ofdLockFile
-	}
-}
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return linuxTryLockFile(path, flag, perm)
-}
-
-func ofdTryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, fmt.Errorf("ofdTryLockFile failed to open %q (%v)", path, err)
-	}
-
-	flock := wrlck
-	if err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLK, &flock); err != nil {
-		f.Close()
-		if err == syscall.EWOULDBLOCK {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return linuxLockFile(path, flag, perm)
-}
-
-func ofdLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, fmt.Errorf("ofdLockFile failed to open %q (%v)", path, err)
-	}
-
-	flock := wrlck
-	err = syscall.FcntlFlock(f.Fd(), F_OFD_SETLKW, &flock)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_plan9.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_plan9.go
deleted file mode 100644
index fee6a7c..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_plan9.go
+++ /dev/null
@@ -1,45 +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 fileutil
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil {
-		return nil, err
-	}
-	f, err := os.Open(path, flag, perm)
-	if err != nil {
-		return nil, ErrLocked
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	if err := os.Chmod(path, syscall.DMEXCL|PrivateFileMode); err != nil {
-		return nil, err
-	}
-	for {
-		f, err := os.OpenFile(path, flag, perm)
-		if err == nil {
-			return &LockedFile{f}, nil
-		}
-		time.Sleep(10 * time.Millisecond)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_solaris.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_solaris.go
deleted file mode 100644
index 352ca55..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_solaris.go
+++ /dev/null
@@ -1,62 +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.
-
-// +build solaris
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	var lock syscall.Flock_t
-	lock.Start = 0
-	lock.Len = 0
-	lock.Pid = 0
-	lock.Type = syscall.F_WRLCK
-	lock.Whence = 0
-	lock.Pid = 0
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &lock); err != nil {
-		f.Close()
-		if err == syscall.EAGAIN {
-			err = ErrLocked
-		}
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	var lock syscall.Flock_t
-	lock.Start = 0
-	lock.Len = 0
-	lock.Pid = 0
-	lock.Type = syscall.F_WRLCK
-	lock.Whence = 0
-	f, err := os.OpenFile(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err = syscall.FcntlFlock(f.Fd(), syscall.F_SETLKW, &lock); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_unix.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_unix.go
deleted file mode 100644
index ed01164..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_unix.go
+++ /dev/null
@@ -1,29 +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.
-
-// +build !windows,!plan9,!solaris,!linux
-
-package fileutil
-
-import (
-	"os"
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return flockTryLockFile(path, flag, perm)
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	return flockLockFile(path, flag, perm)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_windows.go b/vendor/go.etcd.io/etcd/pkg/fileutil/lock_windows.go
deleted file mode 100644
index b181723..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/lock_windows.go
+++ /dev/null
@@ -1,125 +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.
-
-// +build windows
-
-package fileutil
-
-import (
-	"errors"
-	"fmt"
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-var (
-	modkernel32    = syscall.NewLazyDLL("kernel32.dll")
-	procLockFileEx = modkernel32.NewProc("LockFileEx")
-
-	errLocked = errors.New("The process cannot access the file because another process has locked a portion of the file.")
-)
-
-const (
-	// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
-	LOCKFILE_EXCLUSIVE_LOCK   = 2
-	LOCKFILE_FAIL_IMMEDIATELY = 1
-
-	// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
-	errLockViolation syscall.Errno = 0x21
-)
-
-func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := open(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := lockFile(syscall.Handle(f.Fd()), LOCKFILE_FAIL_IMMEDIATELY); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
-	f, err := open(path, flag, perm)
-	if err != nil {
-		return nil, err
-	}
-	if err := lockFile(syscall.Handle(f.Fd()), 0); err != nil {
-		f.Close()
-		return nil, err
-	}
-	return &LockedFile{f}, nil
-}
-
-func open(path string, flag int, perm os.FileMode) (*os.File, error) {
-	if path == "" {
-		return nil, fmt.Errorf("cannot open empty filename")
-	}
-	var access uint32
-	switch flag {
-	case syscall.O_RDONLY:
-		access = syscall.GENERIC_READ
-	case syscall.O_WRONLY:
-		access = syscall.GENERIC_WRITE
-	case syscall.O_RDWR:
-		access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
-	case syscall.O_WRONLY | syscall.O_CREAT:
-		access = syscall.GENERIC_ALL
-	default:
-		panic(fmt.Errorf("flag %v is not supported", flag))
-	}
-	fd, err := syscall.CreateFile(&(syscall.StringToUTF16(path)[0]),
-		access,
-		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		nil,
-		syscall.OPEN_ALWAYS,
-		syscall.FILE_ATTRIBUTE_NORMAL,
-		0)
-	if err != nil {
-		return nil, err
-	}
-	return os.NewFile(uintptr(fd), path), nil
-}
-
-func lockFile(fd syscall.Handle, flags uint32) error {
-	var flag uint32 = LOCKFILE_EXCLUSIVE_LOCK
-	flag |= flags
-	if fd == syscall.InvalidHandle {
-		return nil
-	}
-	err := lockFileEx(fd, flag, 1, 0, &syscall.Overlapped{})
-	if err == nil {
-		return nil
-	} else if err.Error() == errLocked.Error() {
-		return ErrLocked
-	} else if err != errLockViolation {
-		return err
-	}
-	return nil
-}
-
-func lockFileEx(h syscall.Handle, flags, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) {
-	var reserved uint32 = 0
-	r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = syscall.EINVAL
-		}
-	}
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate.go b/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate.go
deleted file mode 100644
index c747b7c..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate.go
+++ /dev/null
@@ -1,54 +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 fileutil
-
-import (
-	"io"
-	"os"
-)
-
-// Preallocate tries to allocate the space for given
-// file. This operation is only supported on linux by a
-// few filesystems (btrfs, ext4, etc.).
-// If the operation is unsupported, no error will be returned.
-// Otherwise, the error encountered will be returned.
-func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error {
-	if sizeInBytes == 0 {
-		// fallocate will return EINVAL if length is 0; skip
-		return nil
-	}
-	if extendFile {
-		return preallocExtend(f, sizeInBytes)
-	}
-	return preallocFixed(f, sizeInBytes)
-}
-
-func preallocExtendTrunc(f *os.File, sizeInBytes int64) error {
-	curOff, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	size, err := f.Seek(sizeInBytes, io.SeekEnd)
-	if err != nil {
-		return err
-	}
-	if _, err = f.Seek(curOff, io.SeekStart); err != nil {
-		return err
-	}
-	if sizeInBytes > size {
-		return nil
-	}
-	return f.Truncate(sizeInBytes)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_darwin.go b/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_darwin.go
deleted file mode 100644
index 5a6dccf..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_darwin.go
+++ /dev/null
@@ -1,65 +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.
-
-// +build darwin
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	if err := preallocFixed(f, sizeInBytes); err != nil {
-		return err
-	}
-	return preallocExtendTrunc(f, sizeInBytes)
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error {
-	// allocate all requested space or no space at all
-	// TODO: allocate contiguous space on disk with F_ALLOCATECONTIG flag
-	fstore := &syscall.Fstore_t{
-		Flags:   syscall.F_ALLOCATEALL,
-		Posmode: syscall.F_PEOFPOSMODE,
-		Length:  sizeInBytes}
-	p := unsafe.Pointer(fstore)
-	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_PREALLOCATE), uintptr(p))
-	if errno == 0 || errno == syscall.ENOTSUP {
-		return nil
-	}
-
-	// wrong argument to fallocate syscall
-	if errno == syscall.EINVAL {
-		// filesystem "st_blocks" are allocated in the units of
-		// "Allocation Block Size" (run "diskutil info /" command)
-		var stat syscall.Stat_t
-		syscall.Fstat(int(f.Fd()), &stat)
-
-		// syscall.Statfs_t.Bsize is "optimal transfer block size"
-		// and contains matching 4096 value when latest OS X kernel
-		// supports 4,096 KB filesystem block size
-		var statfs syscall.Statfs_t
-		syscall.Fstatfs(int(f.Fd()), &statfs)
-		blockSize := int64(statfs.Bsize)
-
-		if stat.Blocks*blockSize >= sizeInBytes {
-			// enough blocks are already allocated
-			return nil
-		}
-	}
-	return errno
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unix.go b/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unix.go
deleted file mode 100644
index 50bd84f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unix.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.
-
-// +build linux
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	// use mode = 0 to change size
-	err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes)
-	if err != nil {
-		errno, ok := err.(syscall.Errno)
-		// not supported; fallback
-		// fallocate EINTRs frequently in some environments; fallback
-		if ok && (errno == syscall.ENOTSUP || errno == syscall.EINTR) {
-			return preallocExtendTrunc(f, sizeInBytes)
-		}
-	}
-	return err
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error {
-	// use mode = 1 to keep size; see FALLOC_FL_KEEP_SIZE
-	err := syscall.Fallocate(int(f.Fd()), 1, 0, sizeInBytes)
-	if err != nil {
-		errno, ok := err.(syscall.Errno)
-		// treat not supported as nil error
-		if ok && errno == syscall.ENOTSUP {
-			return nil
-		}
-	}
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unsupported.go b/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unsupported.go
deleted file mode 100644
index 162fbc5..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/preallocate_unsupported.go
+++ /dev/null
@@ -1,25 +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.
-
-// +build !linux,!darwin
-
-package fileutil
-
-import "os"
-
-func preallocExtend(f *os.File, sizeInBytes int64) error {
-	return preallocExtendTrunc(f, sizeInBytes)
-}
-
-func preallocFixed(f *os.File, sizeInBytes int64) error { return nil }
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/purge.go b/vendor/go.etcd.io/etcd/pkg/fileutil/purge.go
deleted file mode 100644
index fda96c3..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/purge.go
+++ /dev/null
@@ -1,88 +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 fileutil
-
-import (
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"go.uber.org/zap"
-)
-
-func PurgeFile(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}) <-chan error {
-	return purgeFile(lg, dirname, suffix, max, interval, stop, nil)
-}
-
-// purgeFile is the internal implementation for PurgeFile which can post purged files to purgec if non-nil.
-func purgeFile(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}, purgec chan<- string) <-chan error {
-	errC := make(chan error, 1)
-	go func() {
-		for {
-			fnames, err := ReadDir(dirname)
-			if err != nil {
-				errC <- err
-				return
-			}
-			newfnames := make([]string, 0)
-			for _, fname := range fnames {
-				if strings.HasSuffix(fname, suffix) {
-					newfnames = append(newfnames, fname)
-				}
-			}
-			sort.Strings(newfnames)
-			fnames = newfnames
-			for len(newfnames) > int(max) {
-				f := filepath.Join(dirname, newfnames[0])
-				l, err := TryLockFile(f, os.O_WRONLY, PrivateFileMode)
-				if err != nil {
-					break
-				}
-				if err = os.Remove(f); err != nil {
-					errC <- err
-					return
-				}
-				if err = l.Close(); err != nil {
-					if lg != nil {
-						lg.Warn("failed to unlock/close", zap.String("path", l.Name()), zap.Error(err))
-					} else {
-						plog.Errorf("error unlocking %s when purging file (%v)", l.Name(), err)
-					}
-					errC <- err
-					return
-				}
-				if lg != nil {
-					lg.Info("purged", zap.String("path", f))
-				} else {
-					plog.Infof("purged file %s successfully", f)
-				}
-				newfnames = newfnames[1:]
-			}
-			if purgec != nil {
-				for i := 0; i < len(fnames)-len(newfnames); i++ {
-					purgec <- fnames[i]
-				}
-			}
-			select {
-			case <-time.After(interval):
-			case <-stop:
-				return
-			}
-		}
-	}()
-	return errC
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/read_dir.go b/vendor/go.etcd.io/etcd/pkg/fileutil/read_dir.go
deleted file mode 100644
index 2eeaa89..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/read_dir.go
+++ /dev/null
@@ -1,70 +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 fileutil
-
-import (
-	"os"
-	"path/filepath"
-	"sort"
-)
-
-// ReadDirOp represents an read-directory operation.
-type ReadDirOp struct {
-	ext string
-}
-
-// ReadDirOption configures archiver operations.
-type ReadDirOption func(*ReadDirOp)
-
-// WithExt filters file names by their extensions.
-// (e.g. WithExt(".wal") to list only WAL files)
-func WithExt(ext string) ReadDirOption {
-	return func(op *ReadDirOp) { op.ext = ext }
-}
-
-func (op *ReadDirOp) applyOpts(opts []ReadDirOption) {
-	for _, opt := range opts {
-		opt(op)
-	}
-}
-
-// ReadDir returns the filenames in the given directory in sorted order.
-func ReadDir(d string, opts ...ReadDirOption) ([]string, error) {
-	op := &ReadDirOp{}
-	op.applyOpts(opts)
-
-	dir, err := os.Open(d)
-	if err != nil {
-		return nil, err
-	}
-	defer dir.Close()
-
-	names, err := dir.Readdirnames(-1)
-	if err != nil {
-		return nil, err
-	}
-	sort.Strings(names)
-
-	if op.ext != "" {
-		tss := make([]string, 0)
-		for _, v := range names {
-			if filepath.Ext(v) == op.ext {
-				tss = append(tss, v)
-			}
-		}
-		names = tss
-	}
-	return names, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/sync.go b/vendor/go.etcd.io/etcd/pkg/fileutil/sync.go
deleted file mode 100644
index 54dd41f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/sync.go
+++ /dev/null
@@ -1,29 +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.
-
-// +build !linux,!darwin
-
-package fileutil
-
-import "os"
-
-// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform.
-func Fsync(f *os.File) error {
-	return f.Sync()
-}
-
-// Fdatasync is a wrapper around file.Sync(). Special handling is needed on linux platform.
-func Fdatasync(f *os.File) error {
-	return f.Sync()
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/sync_darwin.go b/vendor/go.etcd.io/etcd/pkg/fileutil/sync_darwin.go
deleted file mode 100644
index c2f39bf..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/sync_darwin.go
+++ /dev/null
@@ -1,40 +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.
-
-// +build darwin
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// Fsync on HFS/OSX flushes the data on to the physical drive but the drive
-// may not write it to the persistent media for quite sometime and it may be
-// written in out-of-order sequence. Using F_FULLFSYNC ensures that the
-// physical drive's buffer will also get flushed to the media.
-func Fsync(f *os.File) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_FULLFSYNC), uintptr(0))
-	if errno == 0 {
-		return nil
-	}
-	return errno
-}
-
-// Fdatasync on darwin platform invokes fcntl(F_FULLFSYNC) for actual persistence
-// on physical drive media.
-func Fdatasync(f *os.File) error {
-	return Fsync(f)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/fileutil/sync_linux.go b/vendor/go.etcd.io/etcd/pkg/fileutil/sync_linux.go
deleted file mode 100644
index 1bbced9..0000000
--- a/vendor/go.etcd.io/etcd/pkg/fileutil/sync_linux.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.
-
-// +build linux
-
-package fileutil
-
-import (
-	"os"
-	"syscall"
-)
-
-// Fsync is a wrapper around file.Sync(). Special handling is needed on darwin platform.
-func Fsync(f *os.File) error {
-	return f.Sync()
-}
-
-// Fdatasync is similar to fsync(), but does not flush modified metadata
-// unless that metadata is needed in order to allow a subsequent data retrieval
-// to be correctly handled.
-func Fdatasync(f *os.File) error {
-	return syscall.Fdatasync(int(f.Fd()))
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/flag.go b/vendor/go.etcd.io/etcd/pkg/flags/flag.go
deleted file mode 100644
index 215902c..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/flag.go
+++ /dev/null
@@ -1,121 +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 flags implements command-line flag parsing.
-package flags
-
-import (
-	"flag"
-	"fmt"
-	"os"
-	"strings"
-
-	"github.com/coreos/pkg/capnslog"
-	"github.com/spf13/pflag"
-)
-
-var plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "pkg/flags")
-
-// SetFlagsFromEnv parses all registered flags in the given flagset,
-// and if they are not already set it attempts to set their values from
-// environment variables. Environment variables take the name of the flag but
-// are UPPERCASE, have the given prefix  and any dashes are replaced by
-// underscores - for example: some-flag => ETCD_SOME_FLAG
-func SetFlagsFromEnv(prefix string, fs *flag.FlagSet) error {
-	var err error
-	alreadySet := make(map[string]bool)
-	fs.Visit(func(f *flag.Flag) {
-		alreadySet[FlagToEnv(prefix, f.Name)] = true
-	})
-	usedEnvKey := make(map[string]bool)
-	fs.VisitAll(func(f *flag.Flag) {
-		if serr := setFlagFromEnv(fs, prefix, f.Name, usedEnvKey, alreadySet, true); serr != nil {
-			err = serr
-		}
-	})
-	verifyEnv(prefix, usedEnvKey, alreadySet)
-	return err
-}
-
-// SetPflagsFromEnv is similar to SetFlagsFromEnv. However, the accepted flagset type is pflag.FlagSet
-// and it does not do any logging.
-func SetPflagsFromEnv(prefix string, fs *pflag.FlagSet) error {
-	var err error
-	alreadySet := make(map[string]bool)
-	usedEnvKey := make(map[string]bool)
-	fs.VisitAll(func(f *pflag.Flag) {
-		if f.Changed {
-			alreadySet[FlagToEnv(prefix, f.Name)] = true
-		}
-		if serr := setFlagFromEnv(fs, prefix, f.Name, usedEnvKey, alreadySet, false); serr != nil {
-			err = serr
-		}
-	})
-	verifyEnv(prefix, usedEnvKey, alreadySet)
-	return err
-}
-
-// FlagToEnv converts flag string to upper-case environment variable key string.
-func FlagToEnv(prefix, name string) string {
-	return prefix + "_" + strings.ToUpper(strings.Replace(name, "-", "_", -1))
-}
-
-func verifyEnv(prefix string, usedEnvKey, alreadySet map[string]bool) {
-	for _, env := range os.Environ() {
-		kv := strings.SplitN(env, "=", 2)
-		if len(kv) != 2 {
-			plog.Warningf("found invalid env %s", env)
-		}
-		if usedEnvKey[kv[0]] {
-			continue
-		}
-		if alreadySet[kv[0]] {
-			plog.Fatalf("conflicting environment variable %q is shadowed by corresponding command-line flag (either unset environment variable or disable flag)", kv[0])
-		}
-		if strings.HasPrefix(env, prefix+"_") {
-			plog.Warningf("unrecognized environment variable %s", env)
-		}
-	}
-}
-
-type flagSetter interface {
-	Set(fk string, fv string) error
-}
-
-func setFlagFromEnv(fs flagSetter, prefix, fname string, usedEnvKey, alreadySet map[string]bool, log bool) error {
-	key := FlagToEnv(prefix, fname)
-	if !alreadySet[key] {
-		val := os.Getenv(key)
-		if val != "" {
-			usedEnvKey[key] = true
-			if serr := fs.Set(fname, val); serr != nil {
-				return fmt.Errorf("invalid value %q for %s: %v", val, key, serr)
-			}
-			if log {
-				plog.Infof("recognized and used environment variable %s=%s", key, val)
-			}
-		}
-	}
-	return nil
-}
-
-func IsSet(fs *flag.FlagSet, name string) bool {
-	set := false
-	fs.Visit(func(f *flag.Flag) {
-		if f.Name == name {
-			set = true
-		}
-	})
-	return set
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/ignored.go b/vendor/go.etcd.io/etcd/pkg/flags/ignored.go
deleted file mode 100644
index 9953049..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/ignored.go
+++ /dev/null
@@ -1,36 +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 flags
-
-// IgnoredFlag encapsulates a flag that may have been previously valid but is
-// now ignored. If an IgnoredFlag is set, a warning is printed and
-// operation continues.
-type IgnoredFlag struct {
-	Name string
-}
-
-// IsBoolFlag is defined to allow the flag to be defined without an argument
-func (f *IgnoredFlag) IsBoolFlag() bool {
-	return true
-}
-
-func (f *IgnoredFlag) Set(s string) error {
-	plog.Warningf(`flag "-%s" is no longer supported - ignoring.`, f.Name)
-	return nil
-}
-
-func (f *IgnoredFlag) String() string {
-	return ""
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/selective_string.go b/vendor/go.etcd.io/etcd/pkg/flags/selective_string.go
deleted file mode 100644
index 4b90fbf..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/selective_string.go
+++ /dev/null
@@ -1,114 +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 flags
-
-import (
-	"errors"
-	"fmt"
-	"sort"
-	"strings"
-)
-
-// SelectiveStringValue implements the flag.Value interface.
-type SelectiveStringValue struct {
-	v      string
-	valids map[string]struct{}
-}
-
-// Set verifies the argument to be a valid member of the allowed values
-// before setting the underlying flag value.
-func (ss *SelectiveStringValue) Set(s string) error {
-	if _, ok := ss.valids[s]; ok {
-		ss.v = s
-		return nil
-	}
-	return errors.New("invalid value")
-}
-
-// String returns the set value (if any) of the SelectiveStringValue
-func (ss *SelectiveStringValue) String() string {
-	return ss.v
-}
-
-// Valids returns the list of valid strings.
-func (ss *SelectiveStringValue) Valids() []string {
-	s := make([]string, 0, len(ss.valids))
-	for k := range ss.valids {
-		s = append(s, k)
-	}
-	sort.Strings(s)
-	return s
-}
-
-// NewSelectiveStringValue creates a new string flag
-// for which any one of the given strings is a valid value,
-// and any other value is an error.
-//
-// valids[0] will be default value. Caller must be sure
-// len(valids) != 0 or it will panic.
-func NewSelectiveStringValue(valids ...string) *SelectiveStringValue {
-	vm := make(map[string]struct{})
-	for _, v := range valids {
-		vm[v] = struct{}{}
-	}
-	return &SelectiveStringValue{valids: vm, v: valids[0]}
-}
-
-// SelectiveStringsValue implements the flag.Value interface.
-type SelectiveStringsValue struct {
-	vs     []string
-	valids map[string]struct{}
-}
-
-// Set verifies the argument to be a valid member of the allowed values
-// before setting the underlying flag value.
-func (ss *SelectiveStringsValue) Set(s string) error {
-	vs := strings.Split(s, ",")
-	for i := range vs {
-		if _, ok := ss.valids[vs[i]]; ok {
-			ss.vs = append(ss.vs, vs[i])
-		} else {
-			return fmt.Errorf("invalid value %q", vs[i])
-		}
-	}
-	sort.Strings(ss.vs)
-	return nil
-}
-
-// String returns the set value (if any) of the SelectiveStringsValue.
-func (ss *SelectiveStringsValue) String() string {
-	return strings.Join(ss.vs, ",")
-}
-
-// Valids returns the list of valid strings.
-func (ss *SelectiveStringsValue) Valids() []string {
-	s := make([]string, 0, len(ss.valids))
-	for k := range ss.valids {
-		s = append(s, k)
-	}
-	sort.Strings(s)
-	return s
-}
-
-// NewSelectiveStringsValue creates a new string slice flag
-// for which any one of the given strings is a valid value,
-// and any other value is an error.
-func NewSelectiveStringsValue(valids ...string) *SelectiveStringsValue {
-	vm := make(map[string]struct{})
-	for _, v := range valids {
-		vm[v] = struct{}{}
-	}
-	return &SelectiveStringsValue{valids: vm, vs: []string{}}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/strings.go b/vendor/go.etcd.io/etcd/pkg/flags/strings.go
deleted file mode 100644
index 3e47fb3..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/strings.go
+++ /dev/null
@@ -1,52 +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 flags
-
-import (
-	"flag"
-	"sort"
-	"strings"
-)
-
-// StringsValue wraps "sort.StringSlice".
-type StringsValue sort.StringSlice
-
-// Set parses a command line set of strings, separated by comma.
-// Implements "flag.Value" interface.
-func (ss *StringsValue) Set(s string) error {
-	*ss = strings.Split(s, ",")
-	return nil
-}
-
-// String implements "flag.Value" interface.
-func (ss *StringsValue) String() string { return strings.Join(*ss, ",") }
-
-// NewStringsValue implements string slice as "flag.Value" interface.
-// Given value is to be separated by comma.
-func NewStringsValue(s string) (ss *StringsValue) {
-	if s == "" {
-		return &StringsValue{}
-	}
-	ss = new(StringsValue)
-	if err := ss.Set(s); err != nil {
-		plog.Panicf("new StringsValue should never fail: %v", err)
-	}
-	return ss
-}
-
-// StringsFromFlag returns a string slice from the flag.
-func StringsFromFlag(fs *flag.FlagSet, flagName string) []string {
-	return []string(*fs.Lookup(flagName).Value.(*StringsValue))
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/unique_strings.go b/vendor/go.etcd.io/etcd/pkg/flags/unique_strings.go
deleted file mode 100644
index e220ee0..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/unique_strings.go
+++ /dev/null
@@ -1,76 +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 flags
-
-import (
-	"flag"
-	"sort"
-	"strings"
-)
-
-// UniqueStringsValue wraps a list of unique strings.
-// The values are set in order.
-type UniqueStringsValue struct {
-	Values map[string]struct{}
-}
-
-// Set parses a command line set of strings, separated by comma.
-// Implements "flag.Value" interface.
-// The values are set in order.
-func (us *UniqueStringsValue) Set(s string) error {
-	us.Values = make(map[string]struct{})
-	for _, v := range strings.Split(s, ",") {
-		us.Values[v] = struct{}{}
-	}
-	return nil
-}
-
-// String implements "flag.Value" interface.
-func (us *UniqueStringsValue) String() string {
-	return strings.Join(us.stringSlice(), ",")
-}
-
-func (us *UniqueStringsValue) stringSlice() []string {
-	ss := make([]string, 0, len(us.Values))
-	for v := range us.Values {
-		ss = append(ss, v)
-	}
-	sort.Strings(ss)
-	return ss
-}
-
-// NewUniqueStringsValue implements string slice as "flag.Value" interface.
-// Given value is to be separated by comma.
-// The values are set in order.
-func NewUniqueStringsValue(s string) (us *UniqueStringsValue) {
-	us = &UniqueStringsValue{Values: make(map[string]struct{})}
-	if s == "" {
-		return us
-	}
-	if err := us.Set(s); err != nil {
-		plog.Panicf("new UniqueStringsValue should never fail: %v", err)
-	}
-	return us
-}
-
-// UniqueStringsFromFlag returns a string slice from the flag.
-func UniqueStringsFromFlag(fs *flag.FlagSet, flagName string) []string {
-	return (*fs.Lookup(flagName).Value.(*UniqueStringsValue)).stringSlice()
-}
-
-// UniqueStringsMapFromFlag returns a map of strings from the flag.
-func UniqueStringsMapFromFlag(fs *flag.FlagSet, flagName string) map[string]struct{} {
-	return (*fs.Lookup(flagName).Value.(*UniqueStringsValue)).Values
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/unique_urls.go b/vendor/go.etcd.io/etcd/pkg/flags/unique_urls.go
deleted file mode 100644
index 9b4178c..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/unique_urls.go
+++ /dev/null
@@ -1,92 +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 flags
-
-import (
-	"flag"
-	"net/url"
-	"sort"
-	"strings"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-// UniqueURLs contains unique URLs
-// with non-URL exceptions.
-type UniqueURLs struct {
-	Values  map[string]struct{}
-	uss     []url.URL
-	Allowed map[string]struct{}
-}
-
-// Set parses a command line set of URLs formatted like:
-// http://127.0.0.1:2380,http://10.1.1.2:80
-// Implements "flag.Value" interface.
-func (us *UniqueURLs) Set(s string) error {
-	if _, ok := us.Values[s]; ok {
-		return nil
-	}
-	if _, ok := us.Allowed[s]; ok {
-		us.Values[s] = struct{}{}
-		return nil
-	}
-	ss, err := types.NewURLs(strings.Split(s, ","))
-	if err != nil {
-		return err
-	}
-	us.Values = make(map[string]struct{})
-	us.uss = make([]url.URL, 0)
-	for _, v := range ss {
-		us.Values[v.String()] = struct{}{}
-		us.uss = append(us.uss, v)
-	}
-	return nil
-}
-
-// String implements "flag.Value" interface.
-func (us *UniqueURLs) String() string {
-	all := make([]string, 0, len(us.Values))
-	for u := range us.Values {
-		all = append(all, u)
-	}
-	sort.Strings(all)
-	return strings.Join(all, ",")
-}
-
-// NewUniqueURLsWithExceptions implements "url.URL" slice as flag.Value interface.
-// Given value is to be separated by comma.
-func NewUniqueURLsWithExceptions(s string, exceptions ...string) *UniqueURLs {
-	us := &UniqueURLs{Values: make(map[string]struct{}), Allowed: make(map[string]struct{})}
-	for _, v := range exceptions {
-		us.Allowed[v] = struct{}{}
-	}
-	if s == "" {
-		return us
-	}
-	if err := us.Set(s); err != nil {
-		plog.Panicf("new UniqueURLs should never fail: %v", err)
-	}
-	return us
-}
-
-// UniqueURLsFromFlag returns a slice from urls got from the flag.
-func UniqueURLsFromFlag(fs *flag.FlagSet, urlsFlagName string) []url.URL {
-	return (*fs.Lookup(urlsFlagName).Value.(*UniqueURLs)).uss
-}
-
-// UniqueURLsMapFromFlag returns a map from url strings got from the flag.
-func UniqueURLsMapFromFlag(fs *flag.FlagSet, urlsFlagName string) map[string]struct{} {
-	return (*fs.Lookup(urlsFlagName).Value.(*UniqueURLs)).Values
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/flags/urls.go b/vendor/go.etcd.io/etcd/pkg/flags/urls.go
deleted file mode 100644
index ca90970..0000000
--- a/vendor/go.etcd.io/etcd/pkg/flags/urls.go
+++ /dev/null
@@ -1,65 +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 flags
-
-import (
-	"flag"
-	"net/url"
-	"strings"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-// URLsValue wraps "types.URLs".
-type URLsValue types.URLs
-
-// Set parses a command line set of URLs formatted like:
-// http://127.0.0.1:2380,http://10.1.1.2:80
-// Implements "flag.Value" interface.
-func (us *URLsValue) Set(s string) error {
-	ss, err := types.NewURLs(strings.Split(s, ","))
-	if err != nil {
-		return err
-	}
-	*us = URLsValue(ss)
-	return nil
-}
-
-// String implements "flag.Value" interface.
-func (us *URLsValue) String() string {
-	all := make([]string, len(*us))
-	for i, u := range *us {
-		all[i] = u.String()
-	}
-	return strings.Join(all, ",")
-}
-
-// NewURLsValue implements "url.URL" slice as flag.Value interface.
-// Given value is to be separated by comma.
-func NewURLsValue(s string) *URLsValue {
-	if s == "" {
-		return &URLsValue{}
-	}
-	v := &URLsValue{}
-	if err := v.Set(s); err != nil {
-		plog.Panicf("new URLsValue should never fail: %v", err)
-	}
-	return v
-}
-
-// URLsFromFlag returns a slices from url got from the flag.
-func URLsFromFlag(fs *flag.FlagSet, urlsFlagName string) []url.URL {
-	return []url.URL(*fs.Lookup(urlsFlagName).Value.(*URLsValue))
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/httputil/httputil.go b/vendor/go.etcd.io/etcd/pkg/httputil/httputil.go
deleted file mode 100644
index 3bf58a3..0000000
--- a/vendor/go.etcd.io/etcd/pkg/httputil/httputil.go
+++ /dev/null
@@ -1,50 +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.
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package httputil provides HTTP utility functions.
-package httputil
-
-import (
-	"io"
-	"io/ioutil"
-	"net"
-	"net/http"
-)
-
-// GracefulClose drains http.Response.Body until it hits EOF
-// and closes it. This prevents TCP/TLS connections from closing,
-// therefore available for reuse.
-// Borrowed from golang/net/context/ctxhttp/cancelreq.go.
-func GracefulClose(resp *http.Response) {
-	io.Copy(ioutil.Discard, resp.Body)
-	resp.Body.Close()
-}
-
-// GetHostname returns the hostname from request Host field.
-// It returns empty string, if Host field contains invalid
-// value (e.g. "localhost:::" with too many colons).
-func GetHostname(req *http.Request) string {
-	if req == nil {
-		return ""
-	}
-	h, _, err := net.SplitHostPort(req.Host)
-	if err != nil {
-		return req.Host
-	}
-	return h
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/idutil/id.go b/vendor/go.etcd.io/etcd/pkg/idutil/id.go
deleted file mode 100644
index 63a02cd..0000000
--- a/vendor/go.etcd.io/etcd/pkg/idutil/id.go
+++ /dev/null
@@ -1,75 +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 idutil implements utility functions for generating unique,
-// randomized ids.
-package idutil
-
-import (
-	"math"
-	"sync/atomic"
-	"time"
-)
-
-const (
-	tsLen     = 5 * 8
-	cntLen    = 8
-	suffixLen = tsLen + cntLen
-)
-
-// Generator generates unique identifiers based on counters, timestamps, and
-// a node member ID.
-//
-// The initial id is in this format:
-// High order 2 bytes are from memberID, next 5 bytes are from timestamp,
-// and low order one byte is a counter.
-// | prefix   | suffix              |
-// | 2 bytes  | 5 bytes   | 1 byte  |
-// | memberID | timestamp | cnt     |
-//
-// The timestamp 5 bytes is different when the machine is restart
-// after 1 ms and before 35 years.
-//
-// It increases suffix to generate the next id.
-// The count field may overflow to timestamp field, which is intentional.
-// It helps to extend the event window to 2^56. This doesn't break that
-// id generated after restart is unique because etcd throughput is <<
-// 256req/ms(250k reqs/second).
-type Generator struct {
-	// high order 2 bytes
-	prefix uint64
-	// low order 6 bytes
-	suffix uint64
-}
-
-func NewGenerator(memberID uint16, now time.Time) *Generator {
-	prefix := uint64(memberID) << suffixLen
-	unixMilli := uint64(now.UnixNano()) / uint64(time.Millisecond/time.Nanosecond)
-	suffix := lowbit(unixMilli, tsLen) << cntLen
-	return &Generator{
-		prefix: prefix,
-		suffix: suffix,
-	}
-}
-
-// Next generates a id that is unique.
-func (g *Generator) Next() uint64 {
-	suffix := atomic.AddUint64(&g.suffix, 1)
-	id := g.prefix | lowbit(suffix, suffixLen)
-	return id
-}
-
-func lowbit(x uint64, n uint) uint64 {
-	return x & (math.MaxUint64 >> (64 - n))
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/ioutil/pagewriter.go b/vendor/go.etcd.io/etcd/pkg/ioutil/pagewriter.go
deleted file mode 100644
index 72de159..0000000
--- a/vendor/go.etcd.io/etcd/pkg/ioutil/pagewriter.go
+++ /dev/null
@@ -1,106 +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 ioutil
-
-import (
-	"io"
-)
-
-var defaultBufferBytes = 128 * 1024
-
-// PageWriter implements the io.Writer interface so that writes will
-// either be in page chunks or from flushing.
-type PageWriter struct {
-	w io.Writer
-	// pageOffset tracks the page offset of the base of the buffer
-	pageOffset int
-	// pageBytes is the number of bytes per page
-	pageBytes int
-	// bufferedBytes counts the number of bytes pending for write in the buffer
-	bufferedBytes int
-	// buf holds the write buffer
-	buf []byte
-	// bufWatermarkBytes is the number of bytes the buffer can hold before it needs
-	// to be flushed. It is less than len(buf) so there is space for slack writes
-	// to bring the writer to page alignment.
-	bufWatermarkBytes int
-}
-
-// NewPageWriter creates a new PageWriter. pageBytes is the number of bytes
-// to write per page. pageOffset is the starting offset of io.Writer.
-func NewPageWriter(w io.Writer, pageBytes, pageOffset int) *PageWriter {
-	return &PageWriter{
-		w:                 w,
-		pageOffset:        pageOffset,
-		pageBytes:         pageBytes,
-		buf:               make([]byte, defaultBufferBytes+pageBytes),
-		bufWatermarkBytes: defaultBufferBytes,
-	}
-}
-
-func (pw *PageWriter) Write(p []byte) (n int, err error) {
-	if len(p)+pw.bufferedBytes <= pw.bufWatermarkBytes {
-		// no overflow
-		copy(pw.buf[pw.bufferedBytes:], p)
-		pw.bufferedBytes += len(p)
-		return len(p), nil
-	}
-	// complete the slack page in the buffer if unaligned
-	slack := pw.pageBytes - ((pw.pageOffset + pw.bufferedBytes) % pw.pageBytes)
-	if slack != pw.pageBytes {
-		partial := slack > len(p)
-		if partial {
-			// not enough data to complete the slack page
-			slack = len(p)
-		}
-		// special case: writing to slack page in buffer
-		copy(pw.buf[pw.bufferedBytes:], p[:slack])
-		pw.bufferedBytes += slack
-		n = slack
-		p = p[slack:]
-		if partial {
-			// avoid forcing an unaligned flush
-			return n, nil
-		}
-	}
-	// buffer contents are now page-aligned; clear out
-	if err = pw.Flush(); err != nil {
-		return n, err
-	}
-	// directly write all complete pages without copying
-	if len(p) > pw.pageBytes {
-		pages := len(p) / pw.pageBytes
-		c, werr := pw.w.Write(p[:pages*pw.pageBytes])
-		n += c
-		if werr != nil {
-			return n, werr
-		}
-		p = p[pages*pw.pageBytes:]
-	}
-	// write remaining tail to buffer
-	c, werr := pw.Write(p)
-	n += c
-	return n, werr
-}
-
-func (pw *PageWriter) Flush() error {
-	if pw.bufferedBytes == 0 {
-		return nil
-	}
-	_, err := pw.w.Write(pw.buf[:pw.bufferedBytes])
-	pw.pageOffset = (pw.pageOffset + pw.bufferedBytes) % pw.pageBytes
-	pw.bufferedBytes = 0
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/ioutil/readcloser.go b/vendor/go.etcd.io/etcd/pkg/ioutil/readcloser.go
deleted file mode 100644
index d3efcfe..0000000
--- a/vendor/go.etcd.io/etcd/pkg/ioutil/readcloser.go
+++ /dev/null
@@ -1,66 +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 ioutil
-
-import (
-	"fmt"
-	"io"
-)
-
-// ReaderAndCloser implements io.ReadCloser interface by combining
-// reader and closer together.
-type ReaderAndCloser struct {
-	io.Reader
-	io.Closer
-}
-
-var (
-	ErrShortRead = fmt.Errorf("ioutil: short read")
-	ErrExpectEOF = fmt.Errorf("ioutil: expect EOF")
-)
-
-// NewExactReadCloser returns a ReadCloser that returns errors if the underlying
-// reader does not read back exactly the requested number of bytes.
-func NewExactReadCloser(rc io.ReadCloser, totalBytes int64) io.ReadCloser {
-	return &exactReadCloser{rc: rc, totalBytes: totalBytes}
-}
-
-type exactReadCloser struct {
-	rc         io.ReadCloser
-	br         int64
-	totalBytes int64
-}
-
-func (e *exactReadCloser) Read(p []byte) (int, error) {
-	n, err := e.rc.Read(p)
-	e.br += int64(n)
-	if e.br > e.totalBytes {
-		return 0, ErrExpectEOF
-	}
-	if e.br < e.totalBytes && n == 0 {
-		return 0, ErrShortRead
-	}
-	return n, err
-}
-
-func (e *exactReadCloser) Close() error {
-	if err := e.rc.Close(); err != nil {
-		return err
-	}
-	if e.br < e.totalBytes {
-		return ErrShortRead
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/ioutil/reader.go b/vendor/go.etcd.io/etcd/pkg/ioutil/reader.go
deleted file mode 100644
index 0703ed4..0000000
--- a/vendor/go.etcd.io/etcd/pkg/ioutil/reader.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 ioutil implements I/O utility functions.
-package ioutil
-
-import "io"
-
-// NewLimitedBufferReader returns a reader that reads from the given reader
-// but limits the amount of data returned to at most n bytes.
-func NewLimitedBufferReader(r io.Reader, n int) io.Reader {
-	return &limitedBufferReader{
-		r: r,
-		n: n,
-	}
-}
-
-type limitedBufferReader struct {
-	r io.Reader
-	n int
-}
-
-func (r *limitedBufferReader) Read(p []byte) (n int, err error) {
-	np := p
-	if len(np) > r.n {
-		np = np[:r.n]
-	}
-	return r.r.Read(np)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/ioutil/util.go b/vendor/go.etcd.io/etcd/pkg/ioutil/util.go
deleted file mode 100644
index 6a6746e..0000000
--- a/vendor/go.etcd.io/etcd/pkg/ioutil/util.go
+++ /dev/null
@@ -1,43 +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 ioutil
-
-import (
-	"io"
-	"os"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-)
-
-// WriteAndSyncFile behaves just like ioutil.WriteFile in the standard library,
-// but calls Sync before closing the file. WriteAndSyncFile guarantees the data
-// is synced if there is no error returned.
-func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error {
-	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
-	if err != nil {
-		return err
-	}
-	n, err := f.Write(data)
-	if err == nil && n < len(data) {
-		err = io.ErrShortWrite
-	}
-	if err == nil {
-		err = fileutil.Fsync(f)
-	}
-	if err1 := f.Close(); err == nil {
-		err = err1
-	}
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/discard_logger.go b/vendor/go.etcd.io/etcd/pkg/logutil/discard_logger.go
deleted file mode 100644
index 81b0a9d..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/discard_logger.go
+++ /dev/null
@@ -1,46 +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 logutil
-
-import (
-	"log"
-
-	"google.golang.org/grpc/grpclog"
-)
-
-// assert that "discardLogger" satisfy "Logger" interface
-var _ Logger = &discardLogger{}
-
-// NewDiscardLogger returns a new Logger that discards everything except "fatal".
-func NewDiscardLogger() Logger { return &discardLogger{} }
-
-type discardLogger struct{}
-
-func (l *discardLogger) Info(args ...interface{})                    {}
-func (l *discardLogger) Infoln(args ...interface{})                  {}
-func (l *discardLogger) Infof(format string, args ...interface{})    {}
-func (l *discardLogger) Warning(args ...interface{})                 {}
-func (l *discardLogger) Warningln(args ...interface{})               {}
-func (l *discardLogger) Warningf(format string, args ...interface{}) {}
-func (l *discardLogger) Error(args ...interface{})                   {}
-func (l *discardLogger) Errorln(args ...interface{})                 {}
-func (l *discardLogger) Errorf(format string, args ...interface{})   {}
-func (l *discardLogger) Fatal(args ...interface{})                   { log.Fatal(args...) }
-func (l *discardLogger) Fatalln(args ...interface{})                 { log.Fatalln(args...) }
-func (l *discardLogger) Fatalf(format string, args ...interface{})   { log.Fatalf(format, args...) }
-func (l *discardLogger) V(lvl int) bool {
-	return false
-}
-func (l *discardLogger) Lvl(lvl int) grpclog.LoggerV2 { return l }
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/doc.go b/vendor/go.etcd.io/etcd/pkg/logutil/doc.go
deleted file mode 100644
index e919f24..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/doc.go
+++ /dev/null
@@ -1,16 +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 logutil includes utilities to facilitate logging.
-package logutil
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/log_level.go b/vendor/go.etcd.io/etcd/pkg/logutil/log_level.go
deleted file mode 100644
index d57e173..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/log_level.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 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 logutil
-
-import (
-	"fmt"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-)
-
-var DefaultLogLevel = "info"
-
-// ConvertToZapLevel converts log level string to zapcore.Level.
-func ConvertToZapLevel(lvl string) zapcore.Level {
-	switch lvl {
-	case "debug":
-		return zap.DebugLevel
-	case "info":
-		return zap.InfoLevel
-	case "warn":
-		return zap.WarnLevel
-	case "error":
-		return zap.ErrorLevel
-	case "dpanic":
-		return zap.DPanicLevel
-	case "panic":
-		return zap.PanicLevel
-	case "fatal":
-		return zap.FatalLevel
-	default:
-		panic(fmt.Sprintf("unknown level %q", lvl))
-	}
-}
-
-// ConvertToCapnslogLogLevel convert log level string to capnslog.LogLevel.
-// TODO: deprecate this in 3.5
-func ConvertToCapnslogLogLevel(lvl string) capnslog.LogLevel {
-	switch lvl {
-	case "debug":
-		return capnslog.DEBUG
-	case "info":
-		return capnslog.INFO
-	case "warn":
-		return capnslog.WARNING
-	case "error":
-		return capnslog.ERROR
-	case "dpanic":
-		return capnslog.CRITICAL
-	case "panic":
-		return capnslog.CRITICAL
-	case "fatal":
-		return capnslog.CRITICAL
-	default:
-		panic(fmt.Sprintf("unknown level %q", lvl))
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/logger.go b/vendor/go.etcd.io/etcd/pkg/logutil/logger.go
deleted file mode 100644
index e7da80e..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/logger.go
+++ /dev/null
@@ -1,64 +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 logutil
-
-import "google.golang.org/grpc/grpclog"
-
-// Logger defines logging interface.
-// TODO: deprecate in v3.5.
-type Logger interface {
-	grpclog.LoggerV2
-
-	// Lvl returns logger if logger's verbosity level >= "lvl".
-	// Otherwise, logger that discards everything.
-	Lvl(lvl int) grpclog.LoggerV2
-}
-
-// assert that "defaultLogger" satisfy "Logger" interface
-var _ Logger = &defaultLogger{}
-
-// NewLogger wraps "grpclog.LoggerV2" that implements "Logger" interface.
-//
-// For example:
-//
-//  var defaultLogger Logger
-//  g := grpclog.NewLoggerV2WithVerbosity(os.Stderr, os.Stderr, os.Stderr, 4)
-//  defaultLogger = NewLogger(g)
-//
-func NewLogger(g grpclog.LoggerV2) Logger { return &defaultLogger{g: g} }
-
-type defaultLogger struct {
-	g grpclog.LoggerV2
-}
-
-func (l *defaultLogger) Info(args ...interface{})                    { l.g.Info(args...) }
-func (l *defaultLogger) Infoln(args ...interface{})                  { l.g.Info(args...) }
-func (l *defaultLogger) Infof(format string, args ...interface{})    { l.g.Infof(format, args...) }
-func (l *defaultLogger) Warning(args ...interface{})                 { l.g.Warning(args...) }
-func (l *defaultLogger) Warningln(args ...interface{})               { l.g.Warning(args...) }
-func (l *defaultLogger) Warningf(format string, args ...interface{}) { l.g.Warningf(format, args...) }
-func (l *defaultLogger) Error(args ...interface{})                   { l.g.Error(args...) }
-func (l *defaultLogger) Errorln(args ...interface{})                 { l.g.Error(args...) }
-func (l *defaultLogger) Errorf(format string, args ...interface{})   { l.g.Errorf(format, args...) }
-func (l *defaultLogger) Fatal(args ...interface{})                   { l.g.Fatal(args...) }
-func (l *defaultLogger) Fatalln(args ...interface{})                 { l.g.Fatal(args...) }
-func (l *defaultLogger) Fatalf(format string, args ...interface{})   { l.g.Fatalf(format, args...) }
-func (l *defaultLogger) V(lvl int) bool                              { return l.g.V(lvl) }
-func (l *defaultLogger) Lvl(lvl int) grpclog.LoggerV2 {
-	if l.g.V(lvl) {
-		return l
-	}
-	return &discardLogger{}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/merge_logger.go b/vendor/go.etcd.io/etcd/pkg/logutil/merge_logger.go
deleted file mode 100644
index 866b6f7..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/merge_logger.go
+++ /dev/null
@@ -1,194 +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 logutil
-
-import (
-	"fmt"
-	"sync"
-	"time"
-
-	"github.com/coreos/pkg/capnslog"
-)
-
-var (
-	defaultMergePeriod     = time.Second
-	defaultTimeOutputScale = 10 * time.Millisecond
-
-	outputInterval = time.Second
-)
-
-// line represents a log line that can be printed out
-// through capnslog.PackageLogger.
-type line struct {
-	level capnslog.LogLevel
-	str   string
-}
-
-func (l line) append(s string) line {
-	return line{
-		level: l.level,
-		str:   l.str + " " + s,
-	}
-}
-
-// status represents the merge status of a line.
-type status struct {
-	period time.Duration
-
-	start time.Time // start time of latest merge period
-	count int       // number of merged lines from starting
-}
-
-func (s *status) isInMergePeriod(now time.Time) bool {
-	return s.period == 0 || s.start.Add(s.period).After(now)
-}
-
-func (s *status) isEmpty() bool { return s.count == 0 }
-
-func (s *status) summary(now time.Time) string {
-	ts := s.start.Round(defaultTimeOutputScale)
-	took := now.Round(defaultTimeOutputScale).Sub(ts)
-	return fmt.Sprintf("[merged %d repeated lines in %s]", s.count, took)
-}
-
-func (s *status) reset(now time.Time) {
-	s.start = now
-	s.count = 0
-}
-
-// MergeLogger supports merge logging, which merges repeated log lines
-// and prints summary log lines instead.
-//
-// For merge logging, MergeLogger prints out the line when the line appears
-// at the first time. MergeLogger holds the same log line printed within
-// defaultMergePeriod, and prints out summary log line at the end of defaultMergePeriod.
-// It stops merging when the line doesn't appear within the
-// defaultMergePeriod.
-type MergeLogger struct {
-	*capnslog.PackageLogger
-
-	mu      sync.Mutex // protect statusm
-	statusm map[line]*status
-}
-
-func NewMergeLogger(logger *capnslog.PackageLogger) *MergeLogger {
-	l := &MergeLogger{
-		PackageLogger: logger,
-		statusm:       make(map[line]*status),
-	}
-	go l.outputLoop()
-	return l
-}
-
-func (l *MergeLogger) MergeInfo(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.INFO,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeInfof(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.INFO,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeNotice(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.NOTICE,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeNoticef(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.NOTICE,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeWarning(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.WARNING,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeWarningf(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.WARNING,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) MergeError(entries ...interface{}) {
-	l.merge(line{
-		level: capnslog.ERROR,
-		str:   fmt.Sprint(entries...),
-	})
-}
-
-func (l *MergeLogger) MergeErrorf(format string, args ...interface{}) {
-	l.merge(line{
-		level: capnslog.ERROR,
-		str:   fmt.Sprintf(format, args...),
-	})
-}
-
-func (l *MergeLogger) merge(ln line) {
-	l.mu.Lock()
-
-	// increase count if the logger is merging the line
-	if status, ok := l.statusm[ln]; ok {
-		status.count++
-		l.mu.Unlock()
-		return
-	}
-
-	// initialize status of the line
-	l.statusm[ln] = &status{
-		period: defaultMergePeriod,
-		start:  time.Now(),
-	}
-	// release the lock before IO operation
-	l.mu.Unlock()
-	// print out the line at its first time
-	l.PackageLogger.Logf(ln.level, ln.str)
-}
-
-func (l *MergeLogger) outputLoop() {
-	for now := range time.Tick(outputInterval) {
-		var outputs []line
-
-		l.mu.Lock()
-		for ln, status := range l.statusm {
-			if status.isInMergePeriod(now) {
-				continue
-			}
-			if status.isEmpty() {
-				delete(l.statusm, ln)
-				continue
-			}
-			outputs = append(outputs, ln.append(status.summary(now)))
-			status.reset(now)
-		}
-		l.mu.Unlock()
-
-		for _, o := range outputs {
-			l.PackageLogger.Logf(o.level, o.str)
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/package_logger.go b/vendor/go.etcd.io/etcd/pkg/logutil/package_logger.go
deleted file mode 100644
index 729cbdb..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/package_logger.go
+++ /dev/null
@@ -1,60 +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 logutil
-
-import (
-	"github.com/coreos/pkg/capnslog"
-	"google.golang.org/grpc/grpclog"
-)
-
-// assert that "packageLogger" satisfy "Logger" interface
-var _ Logger = &packageLogger{}
-
-// NewPackageLogger wraps "*capnslog.PackageLogger" that implements "Logger" interface.
-//
-// For example:
-//
-//  var defaultLogger Logger
-//  defaultLogger = NewPackageLogger("go.etcd.io/etcd", "snapshot")
-//
-func NewPackageLogger(repo, pkg string) Logger {
-	return &packageLogger{p: capnslog.NewPackageLogger(repo, pkg)}
-}
-
-type packageLogger struct {
-	p *capnslog.PackageLogger
-}
-
-func (l *packageLogger) Info(args ...interface{})                    { l.p.Info(args...) }
-func (l *packageLogger) Infoln(args ...interface{})                  { l.p.Info(args...) }
-func (l *packageLogger) Infof(format string, args ...interface{})    { l.p.Infof(format, args...) }
-func (l *packageLogger) Warning(args ...interface{})                 { l.p.Warning(args...) }
-func (l *packageLogger) Warningln(args ...interface{})               { l.p.Warning(args...) }
-func (l *packageLogger) Warningf(format string, args ...interface{}) { l.p.Warningf(format, args...) }
-func (l *packageLogger) Error(args ...interface{})                   { l.p.Error(args...) }
-func (l *packageLogger) Errorln(args ...interface{})                 { l.p.Error(args...) }
-func (l *packageLogger) Errorf(format string, args ...interface{})   { l.p.Errorf(format, args...) }
-func (l *packageLogger) Fatal(args ...interface{})                   { l.p.Fatal(args...) }
-func (l *packageLogger) Fatalln(args ...interface{})                 { l.p.Fatal(args...) }
-func (l *packageLogger) Fatalf(format string, args ...interface{})   { l.p.Fatalf(format, args...) }
-func (l *packageLogger) V(lvl int) bool {
-	return l.p.LevelAt(capnslog.LogLevel(lvl))
-}
-func (l *packageLogger) Lvl(lvl int) grpclog.LoggerV2 {
-	if l.p.LevelAt(capnslog.LogLevel(lvl)) {
-		return l
-	}
-	return &discardLogger{}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/zap.go b/vendor/go.etcd.io/etcd/pkg/logutil/zap.go
deleted file mode 100644
index 8fc6e03..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/zap.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019 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 logutil
-
-import (
-	"sort"
-
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-)
-
-// DefaultZapLoggerConfig defines default zap logger configuration.
-var DefaultZapLoggerConfig = zap.Config{
-	Level: zap.NewAtomicLevelAt(ConvertToZapLevel(DefaultLogLevel)),
-
-	Development: false,
-	Sampling: &zap.SamplingConfig{
-		Initial:    100,
-		Thereafter: 100,
-	},
-
-	Encoding: "json",
-
-	// copied from "zap.NewProductionEncoderConfig" with some updates
-	EncoderConfig: zapcore.EncoderConfig{
-		TimeKey:        "ts",
-		LevelKey:       "level",
-		NameKey:        "logger",
-		CallerKey:      "caller",
-		MessageKey:     "msg",
-		StacktraceKey:  "stacktrace",
-		LineEnding:     zapcore.DefaultLineEnding,
-		EncodeLevel:    zapcore.LowercaseLevelEncoder,
-		EncodeTime:     zapcore.ISO8601TimeEncoder,
-		EncodeDuration: zapcore.StringDurationEncoder,
-		EncodeCaller:   zapcore.ShortCallerEncoder,
-	},
-
-	// Use "/dev/null" to discard all
-	OutputPaths:      []string{"stderr"},
-	ErrorOutputPaths: []string{"stderr"},
-}
-
-// MergeOutputPaths merges logging output paths, resolving conflicts.
-func MergeOutputPaths(cfg zap.Config) zap.Config {
-	outputs := make(map[string]struct{})
-	for _, v := range cfg.OutputPaths {
-		outputs[v] = struct{}{}
-	}
-	outputSlice := make([]string, 0)
-	if _, ok := outputs["/dev/null"]; ok {
-		// "/dev/null" to discard all
-		outputSlice = []string{"/dev/null"}
-	} else {
-		for k := range outputs {
-			outputSlice = append(outputSlice, k)
-		}
-	}
-	cfg.OutputPaths = outputSlice
-	sort.Strings(cfg.OutputPaths)
-
-	errOutputs := make(map[string]struct{})
-	for _, v := range cfg.ErrorOutputPaths {
-		errOutputs[v] = struct{}{}
-	}
-	errOutputSlice := make([]string, 0)
-	if _, ok := errOutputs["/dev/null"]; ok {
-		// "/dev/null" to discard all
-		errOutputSlice = []string{"/dev/null"}
-	} else {
-		for k := range errOutputs {
-			errOutputSlice = append(errOutputSlice, k)
-		}
-	}
-	cfg.ErrorOutputPaths = errOutputSlice
-	sort.Strings(cfg.ErrorOutputPaths)
-
-	return cfg
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/zap_grpc.go b/vendor/go.etcd.io/etcd/pkg/logutil/zap_grpc.go
deleted file mode 100644
index 3f48d81..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/zap_grpc.go
+++ /dev/null
@@ -1,111 +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 logutil
-
-import (
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-	"google.golang.org/grpc/grpclog"
-)
-
-// NewGRPCLoggerV2 converts "*zap.Logger" to "grpclog.LoggerV2".
-// It discards all INFO level logging in gRPC, if debug level
-// is not enabled in "*zap.Logger".
-func NewGRPCLoggerV2(lcfg zap.Config) (grpclog.LoggerV2, error) {
-	lg, err := lcfg.Build(zap.AddCallerSkip(1)) // to annotate caller outside of "logutil"
-	if err != nil {
-		return nil, err
-	}
-	return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()}, nil
-}
-
-// NewGRPCLoggerV2FromZapCore creates "grpclog.LoggerV2" from "zap.Core"
-// and "zapcore.WriteSyncer". It discards all INFO level logging in gRPC,
-// if debug level is not enabled in "*zap.Logger".
-func NewGRPCLoggerV2FromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) grpclog.LoggerV2 {
-	// "AddCallerSkip" to annotate caller outside of "logutil"
-	lg := zap.New(cr, zap.AddCaller(), zap.AddCallerSkip(1), zap.ErrorOutput(syncer))
-	return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()}
-}
-
-type zapGRPCLogger struct {
-	lg    *zap.Logger
-	sugar *zap.SugaredLogger
-}
-
-func (zl *zapGRPCLogger) Info(args ...interface{}) {
-	if !zl.lg.Core().Enabled(zapcore.DebugLevel) {
-		return
-	}
-	zl.sugar.Info(args...)
-}
-
-func (zl *zapGRPCLogger) Infoln(args ...interface{}) {
-	if !zl.lg.Core().Enabled(zapcore.DebugLevel) {
-		return
-	}
-	zl.sugar.Info(args...)
-}
-
-func (zl *zapGRPCLogger) Infof(format string, args ...interface{}) {
-	if !zl.lg.Core().Enabled(zapcore.DebugLevel) {
-		return
-	}
-	zl.sugar.Infof(format, args...)
-}
-
-func (zl *zapGRPCLogger) Warning(args ...interface{}) {
-	zl.sugar.Warn(args...)
-}
-
-func (zl *zapGRPCLogger) Warningln(args ...interface{}) {
-	zl.sugar.Warn(args...)
-}
-
-func (zl *zapGRPCLogger) Warningf(format string, args ...interface{}) {
-	zl.sugar.Warnf(format, args...)
-}
-
-func (zl *zapGRPCLogger) Error(args ...interface{}) {
-	zl.sugar.Error(args...)
-}
-
-func (zl *zapGRPCLogger) Errorln(args ...interface{}) {
-	zl.sugar.Error(args...)
-}
-
-func (zl *zapGRPCLogger) Errorf(format string, args ...interface{}) {
-	zl.sugar.Errorf(format, args...)
-}
-
-func (zl *zapGRPCLogger) Fatal(args ...interface{}) {
-	zl.sugar.Fatal(args...)
-}
-
-func (zl *zapGRPCLogger) Fatalln(args ...interface{}) {
-	zl.sugar.Fatal(args...)
-}
-
-func (zl *zapGRPCLogger) Fatalf(format string, args ...interface{}) {
-	zl.sugar.Fatalf(format, args...)
-}
-
-func (zl *zapGRPCLogger) V(l int) bool {
-	// infoLog == 0
-	if l <= 0 { // debug level, then we ignore info level in gRPC
-		return !zl.lg.Core().Enabled(zapcore.DebugLevel)
-	}
-	return true
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/zap_journal.go b/vendor/go.etcd.io/etcd/pkg/logutil/zap_journal.go
deleted file mode 100644
index fcd3903..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/zap_journal.go
+++ /dev/null
@@ -1,92 +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.
-
-// +build !windows
-
-package logutil
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"os"
-	"path/filepath"
-
-	"go.etcd.io/etcd/pkg/systemd"
-
-	"github.com/coreos/go-systemd/journal"
-	"go.uber.org/zap/zapcore"
-)
-
-// NewJournalWriter wraps "io.Writer" to redirect log output
-// to the local systemd journal. If journald send fails, it fails
-// back to writing to the original writer.
-// The decode overhead is only <30µs per write.
-// Reference: https://github.com/coreos/pkg/blob/master/capnslog/journald_formatter.go
-func NewJournalWriter(wr io.Writer) (io.Writer, error) {
-	return &journalWriter{Writer: wr}, systemd.DialJournal()
-}
-
-type journalWriter struct {
-	io.Writer
-}
-
-// WARN: assume that etcd uses default field names in zap encoder config
-// make sure to keep this up-to-date!
-type logLine struct {
-	Level  string `json:"level"`
-	Caller string `json:"caller"`
-}
-
-func (w *journalWriter) Write(p []byte) (int, error) {
-	line := &logLine{}
-	if err := json.NewDecoder(bytes.NewReader(p)).Decode(line); err != nil {
-		return 0, err
-	}
-
-	var pri journal.Priority
-	switch line.Level {
-	case zapcore.DebugLevel.String():
-		pri = journal.PriDebug
-	case zapcore.InfoLevel.String():
-		pri = journal.PriInfo
-
-	case zapcore.WarnLevel.String():
-		pri = journal.PriWarning
-	case zapcore.ErrorLevel.String():
-		pri = journal.PriErr
-
-	case zapcore.DPanicLevel.String():
-		pri = journal.PriCrit
-	case zapcore.PanicLevel.String():
-		pri = journal.PriCrit
-	case zapcore.FatalLevel.String():
-		pri = journal.PriCrit
-
-	default:
-		panic(fmt.Errorf("unknown log level: %q", line.Level))
-	}
-
-	err := journal.Send(string(p), pri, map[string]string{
-		"PACKAGE":           filepath.Dir(line.Caller),
-		"SYSLOG_IDENTIFIER": filepath.Base(os.Args[0]),
-	})
-	if err != nil {
-		// "journal" also falls back to stderr
-		// "fmt.Fprintln(os.Stderr, s)"
-		return w.Writer.Write(p)
-	}
-	return 0, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/logutil/zap_raft.go b/vendor/go.etcd.io/etcd/pkg/logutil/zap_raft.go
deleted file mode 100644
index f016b30..0000000
--- a/vendor/go.etcd.io/etcd/pkg/logutil/zap_raft.go
+++ /dev/null
@@ -1,102 +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 logutil
-
-import (
-	"errors"
-
-	"go.etcd.io/etcd/raft"
-
-	"go.uber.org/zap"
-	"go.uber.org/zap/zapcore"
-)
-
-// NewRaftLogger builds "raft.Logger" from "*zap.Config".
-func NewRaftLogger(lcfg *zap.Config) (raft.Logger, error) {
-	if lcfg == nil {
-		return nil, errors.New("nil zap.Config")
-	}
-	lg, err := lcfg.Build(zap.AddCallerSkip(1)) // to annotate caller outside of "logutil"
-	if err != nil {
-		return nil, err
-	}
-	return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}, nil
-}
-
-// NewRaftLoggerZap converts "*zap.Logger" to "raft.Logger".
-func NewRaftLoggerZap(lg *zap.Logger) raft.Logger {
-	return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}
-}
-
-// NewRaftLoggerFromZapCore creates "raft.Logger" from "zap.Core"
-// and "zapcore.WriteSyncer".
-func NewRaftLoggerFromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) raft.Logger {
-	// "AddCallerSkip" to annotate caller outside of "logutil"
-	lg := zap.New(cr, zap.AddCaller(), zap.AddCallerSkip(1), zap.ErrorOutput(syncer))
-	return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}
-}
-
-type zapRaftLogger struct {
-	lg    *zap.Logger
-	sugar *zap.SugaredLogger
-}
-
-func (zl *zapRaftLogger) Debug(args ...interface{}) {
-	zl.sugar.Debug(args...)
-}
-
-func (zl *zapRaftLogger) Debugf(format string, args ...interface{}) {
-	zl.sugar.Debugf(format, args...)
-}
-
-func (zl *zapRaftLogger) Error(args ...interface{}) {
-	zl.sugar.Error(args...)
-}
-
-func (zl *zapRaftLogger) Errorf(format string, args ...interface{}) {
-	zl.sugar.Errorf(format, args...)
-}
-
-func (zl *zapRaftLogger) Info(args ...interface{}) {
-	zl.sugar.Info(args...)
-}
-
-func (zl *zapRaftLogger) Infof(format string, args ...interface{}) {
-	zl.sugar.Infof(format, args...)
-}
-
-func (zl *zapRaftLogger) Warning(args ...interface{}) {
-	zl.sugar.Warn(args...)
-}
-
-func (zl *zapRaftLogger) Warningf(format string, args ...interface{}) {
-	zl.sugar.Warnf(format, args...)
-}
-
-func (zl *zapRaftLogger) Fatal(args ...interface{}) {
-	zl.sugar.Fatal(args...)
-}
-
-func (zl *zapRaftLogger) Fatalf(format string, args ...interface{}) {
-	zl.sugar.Fatalf(format, args...)
-}
-
-func (zl *zapRaftLogger) Panic(args ...interface{}) {
-	zl.sugar.Panic(args...)
-}
-
-func (zl *zapRaftLogger) Panicf(format string, args ...interface{}) {
-	zl.sugar.Panicf(format, args...)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/doc.go b/vendor/go.etcd.io/etcd/pkg/netutil/doc.go
deleted file mode 100644
index 5d92d03..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/doc.go
+++ /dev/null
@@ -1,16 +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 netutil implements network-related utility functions.
-package netutil
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/isolate_linux.go b/vendor/go.etcd.io/etcd/pkg/netutil/isolate_linux.go
deleted file mode 100644
index 418580a..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/isolate_linux.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 netutil
-
-import (
-	"fmt"
-	"os/exec"
-)
-
-// DropPort drops all tcp packets that are received from the given port and sent to the given port.
-func DropPort(port int) error {
-	cmdStr := fmt.Sprintf("sudo iptables -A OUTPUT -p tcp --destination-port %d -j DROP", port)
-	if _, err := exec.Command("/bin/sh", "-c", cmdStr).Output(); err != nil {
-		return err
-	}
-	cmdStr = fmt.Sprintf("sudo iptables -A INPUT -p tcp --destination-port %d -j DROP", port)
-	_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
-	return err
-}
-
-// RecoverPort stops dropping tcp packets at given port.
-func RecoverPort(port int) error {
-	cmdStr := fmt.Sprintf("sudo iptables -D OUTPUT -p tcp --destination-port %d -j DROP", port)
-	if _, err := exec.Command("/bin/sh", "-c", cmdStr).Output(); err != nil {
-		return err
-	}
-	cmdStr = fmt.Sprintf("sudo iptables -D INPUT -p tcp --destination-port %d -j DROP", port)
-	_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
-	return err
-}
-
-// SetLatency adds latency in millisecond scale with random variations.
-func SetLatency(ms, rv int) error {
-	ifces, err := GetDefaultInterfaces()
-	if err != nil {
-		return err
-	}
-
-	if rv > ms {
-		rv = 1
-	}
-	for ifce := range ifces {
-		cmdStr := fmt.Sprintf("sudo tc qdisc add dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
-		_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
-		if err != nil {
-			// the rule has already been added. Overwrite it.
-			cmdStr = fmt.Sprintf("sudo tc qdisc change dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
-			_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
-			if err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-// RemoveLatency resets latency configurations.
-func RemoveLatency() error {
-	ifces, err := GetDefaultInterfaces()
-	if err != nil {
-		return err
-	}
-	for ifce := range ifces {
-		_, err = exec.Command("/bin/sh", "-c", fmt.Sprintf("sudo tc qdisc del dev %s root netem", ifce)).Output()
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/isolate_stub.go b/vendor/go.etcd.io/etcd/pkg/netutil/isolate_stub.go
deleted file mode 100644
index 7f4c3e6..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/isolate_stub.go
+++ /dev/null
@@ -1,25 +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.
-
-// +build !linux
-
-package netutil
-
-func DropPort(port int) error { return nil }
-
-func RecoverPort(port int) error { return nil }
-
-func SetLatency(ms, rv int) error { return nil }
-
-func RemoveLatency() error { return nil }
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/netutil.go b/vendor/go.etcd.io/etcd/pkg/netutil/netutil.go
deleted file mode 100644
index faef646..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/netutil.go
+++ /dev/null
@@ -1,213 +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 netutil
-
-import (
-	"context"
-	"fmt"
-	"net"
-	"net/url"
-	"reflect"
-	"sort"
-	"time"
-
-	"go.etcd.io/etcd/pkg/types"
-
-	"go.uber.org/zap"
-)
-
-// indirection for testing
-var resolveTCPAddr = resolveTCPAddrDefault
-
-const retryInterval = time.Second
-
-// taken from go's ResolveTCP code but uses configurable ctx
-func resolveTCPAddrDefault(ctx context.Context, addr string) (*net.TCPAddr, error) {
-	host, port, serr := net.SplitHostPort(addr)
-	if serr != nil {
-		return nil, serr
-	}
-	portnum, perr := net.DefaultResolver.LookupPort(ctx, "tcp", port)
-	if perr != nil {
-		return nil, perr
-	}
-
-	var ips []net.IPAddr
-	if ip := net.ParseIP(host); ip != nil {
-		ips = []net.IPAddr{{IP: ip}}
-	} else {
-		// Try as a DNS name.
-		ipss, err := net.DefaultResolver.LookupIPAddr(ctx, host)
-		if err != nil {
-			return nil, err
-		}
-		ips = ipss
-	}
-	// randomize?
-	ip := ips[0]
-	return &net.TCPAddr{IP: ip.IP, Port: portnum, Zone: ip.Zone}, nil
-}
-
-// resolveTCPAddrs is a convenience wrapper for net.ResolveTCPAddr.
-// resolveTCPAddrs return a new set of url.URLs, in which all DNS hostnames
-// are resolved.
-func resolveTCPAddrs(ctx context.Context, lg *zap.Logger, urls [][]url.URL) ([][]url.URL, error) {
-	newurls := make([][]url.URL, 0)
-	for _, us := range urls {
-		nus := make([]url.URL, len(us))
-		for i, u := range us {
-			nu, err := url.Parse(u.String())
-			if err != nil {
-				return nil, fmt.Errorf("failed to parse %q (%v)", u.String(), err)
-			}
-			nus[i] = *nu
-		}
-		for i, u := range nus {
-			h, err := resolveURL(ctx, lg, u)
-			if err != nil {
-				return nil, fmt.Errorf("failed to resolve %q (%v)", u.String(), err)
-			}
-			if h != "" {
-				nus[i].Host = h
-			}
-		}
-		newurls = append(newurls, nus)
-	}
-	return newurls, nil
-}
-
-func resolveURL(ctx context.Context, lg *zap.Logger, u url.URL) (string, error) {
-	if u.Scheme == "unix" || u.Scheme == "unixs" {
-		// unix sockets don't resolve over TCP
-		return "", nil
-	}
-	host, _, err := net.SplitHostPort(u.Host)
-	if err != nil {
-		lg.Warn(
-			"failed to parse URL Host while resolving URL",
-			zap.String("url", u.String()),
-			zap.String("host", u.Host),
-			zap.Error(err),
-		)
-		return "", err
-	}
-	if host == "localhost" || net.ParseIP(host) != nil {
-		return "", nil
-	}
-	for ctx.Err() == nil {
-		tcpAddr, err := resolveTCPAddr(ctx, u.Host)
-		if err == nil {
-			lg.Info(
-				"resolved URL Host",
-				zap.String("url", u.String()),
-				zap.String("host", u.Host),
-				zap.String("resolved-addr", tcpAddr.String()),
-			)
-			return tcpAddr.String(), nil
-		}
-
-		lg.Warn(
-			"failed to resolve URL Host",
-			zap.String("url", u.String()),
-			zap.String("host", u.Host),
-			zap.Duration("retry-interval", retryInterval),
-			zap.Error(err),
-		)
-
-		select {
-		case <-ctx.Done():
-			lg.Warn(
-				"failed to resolve URL Host; returning",
-				zap.String("url", u.String()),
-				zap.String("host", u.Host),
-				zap.Duration("retry-interval", retryInterval),
-				zap.Error(err),
-			)
-			return "", err
-		case <-time.After(retryInterval):
-		}
-	}
-	return "", ctx.Err()
-}
-
-// urlsEqual checks equality of url.URLS between two arrays.
-// This check pass even if an URL is in hostname and opposite is in IP address.
-func urlsEqual(ctx context.Context, lg *zap.Logger, a []url.URL, b []url.URL) (bool, error) {
-	if len(a) != len(b) {
-		return false, fmt.Errorf("len(%q) != len(%q)", urlsToStrings(a), urlsToStrings(b))
-	}
-	urls, err := resolveTCPAddrs(ctx, lg, [][]url.URL{a, b})
-	if err != nil {
-		return false, err
-	}
-	preva, prevb := a, b
-	a, b = urls[0], urls[1]
-	sort.Sort(types.URLs(a))
-	sort.Sort(types.URLs(b))
-	for i := range a {
-		if !reflect.DeepEqual(a[i], b[i]) {
-			return false, fmt.Errorf("%q(resolved from %q) != %q(resolved from %q)",
-				a[i].String(), preva[i].String(),
-				b[i].String(), prevb[i].String(),
-			)
-		}
-	}
-	return true, nil
-}
-
-// URLStringsEqual returns "true" if given URLs are valid
-// and resolved to same IP addresses. Otherwise, return "false"
-// and error, if any.
-func URLStringsEqual(ctx context.Context, lg *zap.Logger, a []string, b []string) (bool, error) {
-	if len(a) != len(b) {
-		return false, fmt.Errorf("len(%q) != len(%q)", a, b)
-	}
-	urlsA := make([]url.URL, 0)
-	for _, str := range a {
-		u, err := url.Parse(str)
-		if err != nil {
-			return false, fmt.Errorf("failed to parse %q", str)
-		}
-		urlsA = append(urlsA, *u)
-	}
-	urlsB := make([]url.URL, 0)
-	for _, str := range b {
-		u, err := url.Parse(str)
-		if err != nil {
-			return false, fmt.Errorf("failed to parse %q", str)
-		}
-		urlsB = append(urlsB, *u)
-	}
-	if lg == nil {
-		lg, _ = zap.NewProduction()
-		if lg == nil {
-			lg = zap.NewExample()
-		}
-	}
-	return urlsEqual(ctx, lg, urlsA, urlsB)
-}
-
-func urlsToStrings(us []url.URL) []string {
-	rs := make([]string, len(us))
-	for i := range us {
-		rs[i] = us[i].String()
-	}
-	return rs
-}
-
-func IsNetworkTimeoutError(err error) bool {
-	nerr, ok := err.(net.Error)
-	return ok && nerr.Timeout()
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/routes.go b/vendor/go.etcd.io/etcd/pkg/netutil/routes.go
deleted file mode 100644
index 3eb6a19..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/routes.go
+++ /dev/null
@@ -1,33 +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.
-
-// +build !linux
-
-package netutil
-
-import (
-	"fmt"
-	"runtime"
-)
-
-// GetDefaultHost fetches the a resolvable name that corresponds
-// to the machine's default routable interface
-func GetDefaultHost() (string, error) {
-	return "", fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
-}
-
-// GetDefaultInterfaces fetches the device name of default routable interface.
-func GetDefaultInterfaces() (map[string]uint8, error) {
-	return nil, fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/netutil/routes_linux.go b/vendor/go.etcd.io/etcd/pkg/netutil/routes_linux.go
deleted file mode 100644
index 5118d3d..0000000
--- a/vendor/go.etcd.io/etcd/pkg/netutil/routes_linux.go
+++ /dev/null
@@ -1,250 +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.
-
-// +build linux
-
-package netutil
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"net"
-	"sort"
-	"syscall"
-
-	"go.etcd.io/etcd/pkg/cpuutil"
-)
-
-var errNoDefaultRoute = fmt.Errorf("could not find default route")
-var errNoDefaultHost = fmt.Errorf("could not find default host")
-var errNoDefaultInterface = fmt.Errorf("could not find default interface")
-
-// GetDefaultHost obtains the first IP address of machine from the routing table and returns the IP address as string.
-// An IPv4 address is preferred to an IPv6 address for backward compatibility.
-func GetDefaultHost() (string, error) {
-	rmsgs, rerr := getDefaultRoutes()
-	if rerr != nil {
-		return "", rerr
-	}
-
-	// prioritize IPv4
-	if rmsg, ok := rmsgs[syscall.AF_INET]; ok {
-		if host, err := chooseHost(syscall.AF_INET, rmsg); host != "" || err != nil {
-			return host, err
-		}
-		delete(rmsgs, syscall.AF_INET)
-	}
-
-	// sort so choice is deterministic
-	var families []int
-	for family := range rmsgs {
-		families = append(families, int(family))
-	}
-	sort.Ints(families)
-
-	for _, f := range families {
-		family := uint8(f)
-		if host, err := chooseHost(family, rmsgs[family]); host != "" || err != nil {
-			return host, err
-		}
-	}
-
-	return "", errNoDefaultHost
-}
-
-func chooseHost(family uint8, rmsg *syscall.NetlinkMessage) (string, error) {
-	host, oif, err := parsePREFSRC(rmsg)
-	if host != "" || err != nil {
-		return host, err
-	}
-
-	// prefsrc not detected, fall back to getting address from iface
-	ifmsg, ierr := getIfaceAddr(oif, family)
-	if ierr != nil {
-		return "", ierr
-	}
-
-	attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
-	if aerr != nil {
-		return "", aerr
-	}
-
-	for _, attr := range attrs {
-		// search for RTA_DST because ipv6 doesn't have RTA_SRC
-		if attr.Attr.Type == syscall.RTA_DST {
-			return net.IP(attr.Value).String(), nil
-		}
-	}
-
-	return "", nil
-}
-
-func getDefaultRoutes() (map[uint8]*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC)
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	routes := make(map[uint8]*syscall.NetlinkMessage)
-	rtmsg := syscall.RtMsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWROUTE {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofRtMsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &rtmsg); rerr != nil {
-			continue
-		}
-		if rtmsg.Dst_len == 0 && rtmsg.Table == syscall.RT_TABLE_MAIN {
-			// zero-length Dst_len implies default route
-			msg := m
-			routes[rtmsg.Family] = &msg
-		}
-	}
-
-	if len(routes) > 0 {
-		return routes, nil
-	}
-
-	return nil, errNoDefaultRoute
-}
-
-// Used to get an address of interface.
-func getIfaceAddr(idx uint32, family uint8) (*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, int(family))
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	ifaddrmsg := syscall.IfAddrmsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWADDR {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfAddrmsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifaddrmsg); rerr != nil {
-			continue
-		}
-		if ifaddrmsg.Index == idx {
-			return &m, nil
-		}
-	}
-
-	return nil, fmt.Errorf("could not find address for interface index %v", idx)
-
-}
-
-// Used to get a name of interface.
-func getIfaceLink(idx uint32) (*syscall.NetlinkMessage, error) {
-	dat, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
-	if err != nil {
-		return nil, err
-	}
-
-	msgs, msgErr := syscall.ParseNetlinkMessage(dat)
-	if msgErr != nil {
-		return nil, msgErr
-	}
-
-	ifinfomsg := syscall.IfInfomsg{}
-	for _, m := range msgs {
-		if m.Header.Type != syscall.RTM_NEWLINK {
-			continue
-		}
-		buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfInfomsg])
-		if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifinfomsg); rerr != nil {
-			continue
-		}
-		if ifinfomsg.Index == int32(idx) {
-			return &m, nil
-		}
-	}
-
-	return nil, fmt.Errorf("could not find link for interface index %v", idx)
-}
-
-// GetDefaultInterfaces gets names of interfaces and returns a map[interface]families.
-func GetDefaultInterfaces() (map[string]uint8, error) {
-	interfaces := make(map[string]uint8)
-	rmsgs, rerr := getDefaultRoutes()
-	if rerr != nil {
-		return interfaces, rerr
-	}
-
-	for family, rmsg := range rmsgs {
-		_, oif, err := parsePREFSRC(rmsg)
-		if err != nil {
-			return interfaces, err
-		}
-
-		ifmsg, ierr := getIfaceLink(oif)
-		if ierr != nil {
-			return interfaces, ierr
-		}
-
-		attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
-		if aerr != nil {
-			return interfaces, aerr
-		}
-
-		for _, attr := range attrs {
-			if attr.Attr.Type == syscall.IFLA_IFNAME {
-				// key is an interface name
-				// possible values: 2 - AF_INET, 10 - AF_INET6, 12 - dualstack
-				interfaces[string(attr.Value[:len(attr.Value)-1])] += family
-			}
-		}
-	}
-	if len(interfaces) > 0 {
-		return interfaces, nil
-	}
-	return interfaces, errNoDefaultInterface
-}
-
-// parsePREFSRC returns preferred source address and output interface index (RTA_OIF).
-func parsePREFSRC(m *syscall.NetlinkMessage) (host string, oif uint32, err error) {
-	var attrs []syscall.NetlinkRouteAttr
-	attrs, err = syscall.ParseNetlinkRouteAttr(m)
-	if err != nil {
-		return "", 0, err
-	}
-
-	for _, attr := range attrs {
-		if attr.Attr.Type == syscall.RTA_PREFSRC {
-			host = net.IP(attr.Value).String()
-		}
-		if attr.Attr.Type == syscall.RTA_OIF {
-			oif = cpuutil.ByteOrder().Uint32(attr.Value)
-		}
-		if host != "" && oif != uint32(0) {
-			break
-		}
-	}
-
-	if oif == 0 {
-		err = errNoDefaultRoute
-	}
-	return host, oif, err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/pathutil/path.go b/vendor/go.etcd.io/etcd/pkg/pathutil/path.go
deleted file mode 100644
index f26254b..0000000
--- a/vendor/go.etcd.io/etcd/pkg/pathutil/path.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pathutil implements utility functions for handling slash-separated
-// paths.
-package pathutil
-
-import "path"
-
-// CanonicalURLPath returns the canonical url path for p, which follows the rules:
-// 1. the path always starts with "/"
-// 2. replace multiple slashes with a single slash
-// 3. replace each '.' '..' path name element with equivalent one
-// 4. keep the trailing slash
-// The function is borrowed from stdlib http.cleanPath in server.go.
-func CanonicalURLPath(p string) string {
-	if p == "" {
-		return "/"
-	}
-	if p[0] != '/' {
-		p = "/" + p
-	}
-	np := path.Clean(p)
-	// path.Clean removes trailing slash except for root,
-	// put the trailing slash back if necessary.
-	if p[len(p)-1] == '/' && np != "/" {
-		np += "/"
-	}
-	return np
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/pbutil/pbutil.go b/vendor/go.etcd.io/etcd/pkg/pbutil/pbutil.go
deleted file mode 100644
index 53167ff..0000000
--- a/vendor/go.etcd.io/etcd/pkg/pbutil/pbutil.go
+++ /dev/null
@@ -1,60 +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 pbutil defines interfaces for handling Protocol Buffer objects.
-package pbutil
-
-import "github.com/coreos/pkg/capnslog"
-
-var (
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "pkg/pbutil")
-)
-
-type Marshaler interface {
-	Marshal() (data []byte, err error)
-}
-
-type Unmarshaler interface {
-	Unmarshal(data []byte) error
-}
-
-func MustMarshal(m Marshaler) []byte {
-	d, err := m.Marshal()
-	if err != nil {
-		plog.Panicf("marshal should never fail (%v)", err)
-	}
-	return d
-}
-
-func MustUnmarshal(um Unmarshaler, data []byte) {
-	if err := um.Unmarshal(data); err != nil {
-		plog.Panicf("unmarshal should never fail (%v)", err)
-	}
-}
-
-func MaybeUnmarshal(um Unmarshaler, data []byte) bool {
-	if err := um.Unmarshal(data); err != nil {
-		return false
-	}
-	return true
-}
-
-func GetBool(v *bool) (vv bool, set bool) {
-	if v == nil {
-		return false, false
-	}
-	return *v, true
-}
-
-func Boolp(b bool) *bool { return &b }
diff --git a/vendor/go.etcd.io/etcd/pkg/runtime/fds_linux.go b/vendor/go.etcd.io/etcd/pkg/runtime/fds_linux.go
deleted file mode 100644
index 8e9359d..0000000
--- a/vendor/go.etcd.io/etcd/pkg/runtime/fds_linux.go
+++ /dev/null
@@ -1,37 +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 runtime implements utility functions for runtime systems.
-package runtime
-
-import (
-	"io/ioutil"
-	"syscall"
-)
-
-func FDLimit() (uint64, error) {
-	var rlimit syscall.Rlimit
-	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil {
-		return 0, err
-	}
-	return rlimit.Cur, nil
-}
-
-func FDUsage() (uint64, error) {
-	fds, err := ioutil.ReadDir("/proc/self/fd")
-	if err != nil {
-		return 0, err
-	}
-	return uint64(len(fds)), nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/runtime/fds_other.go b/vendor/go.etcd.io/etcd/pkg/runtime/fds_other.go
deleted file mode 100644
index 0cbdb88..0000000
--- a/vendor/go.etcd.io/etcd/pkg/runtime/fds_other.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.
-
-// +build !linux
-
-package runtime
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func FDLimit() (uint64, error) {
-	return 0, fmt.Errorf("cannot get FDLimit on %s", runtime.GOOS)
-}
-
-func FDUsage() (uint64, error) {
-	return 0, fmt.Errorf("cannot get FDUsage on %s", runtime.GOOS)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/schedule/doc.go b/vendor/go.etcd.io/etcd/pkg/schedule/doc.go
deleted file mode 100644
index cca2c75..0000000
--- a/vendor/go.etcd.io/etcd/pkg/schedule/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 schedule provides mechanisms and policies for scheduling units of work.
-package schedule
diff --git a/vendor/go.etcd.io/etcd/pkg/schedule/schedule.go b/vendor/go.etcd.io/etcd/pkg/schedule/schedule.go
deleted file mode 100644
index 234d019..0000000
--- a/vendor/go.etcd.io/etcd/pkg/schedule/schedule.go
+++ /dev/null
@@ -1,165 +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 schedule
-
-import (
-	"context"
-	"sync"
-)
-
-type Job func(context.Context)
-
-// Scheduler can schedule jobs.
-type Scheduler interface {
-	// Schedule asks the scheduler to schedule a job defined by the given func.
-	// Schedule to a stopped scheduler might panic.
-	Schedule(j Job)
-
-	// Pending returns number of pending jobs
-	Pending() int
-
-	// Scheduled returns the number of scheduled jobs (excluding pending jobs)
-	Scheduled() int
-
-	// Finished returns the number of finished jobs
-	Finished() int
-
-	// WaitFinish waits until at least n job are finished and all pending jobs are finished.
-	WaitFinish(n int)
-
-	// Stop stops the scheduler.
-	Stop()
-}
-
-type fifo struct {
-	mu sync.Mutex
-
-	resume    chan struct{}
-	scheduled int
-	finished  int
-	pendings  []Job
-
-	ctx    context.Context
-	cancel context.CancelFunc
-
-	finishCond *sync.Cond
-	donec      chan struct{}
-}
-
-// NewFIFOScheduler returns a Scheduler that schedules jobs in FIFO
-// order sequentially
-func NewFIFOScheduler() Scheduler {
-	f := &fifo{
-		resume: make(chan struct{}, 1),
-		donec:  make(chan struct{}, 1),
-	}
-	f.finishCond = sync.NewCond(&f.mu)
-	f.ctx, f.cancel = context.WithCancel(context.Background())
-	go f.run()
-	return f
-}
-
-// Schedule schedules a job that will be ran in FIFO order sequentially.
-func (f *fifo) Schedule(j Job) {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-
-	if f.cancel == nil {
-		panic("schedule: schedule to stopped scheduler")
-	}
-
-	if len(f.pendings) == 0 {
-		select {
-		case f.resume <- struct{}{}:
-		default:
-		}
-	}
-	f.pendings = append(f.pendings, j)
-}
-
-func (f *fifo) Pending() int {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	return len(f.pendings)
-}
-
-func (f *fifo) Scheduled() int {
-	f.mu.Lock()
-	defer f.mu.Unlock()
-	return f.scheduled
-}
-
-func (f *fifo) Finished() int {
-	f.finishCond.L.Lock()
-	defer f.finishCond.L.Unlock()
-	return f.finished
-}
-
-func (f *fifo) WaitFinish(n int) {
-	f.finishCond.L.Lock()
-	for f.finished < n || len(f.pendings) != 0 {
-		f.finishCond.Wait()
-	}
-	f.finishCond.L.Unlock()
-}
-
-// Stop stops the scheduler and cancels all pending jobs.
-func (f *fifo) Stop() {
-	f.mu.Lock()
-	f.cancel()
-	f.cancel = nil
-	f.mu.Unlock()
-	<-f.donec
-}
-
-func (f *fifo) run() {
-	// TODO: recover from job panic?
-	defer func() {
-		close(f.donec)
-		close(f.resume)
-	}()
-
-	for {
-		var todo Job
-		f.mu.Lock()
-		if len(f.pendings) != 0 {
-			f.scheduled++
-			todo = f.pendings[0]
-		}
-		f.mu.Unlock()
-		if todo == nil {
-			select {
-			case <-f.resume:
-			case <-f.ctx.Done():
-				f.mu.Lock()
-				pendings := f.pendings
-				f.pendings = nil
-				f.mu.Unlock()
-				// clean up pending jobs
-				for _, todo := range pendings {
-					todo(f.ctx)
-				}
-				return
-			}
-		} else {
-			todo(f.ctx)
-			f.finishCond.L.Lock()
-			f.finished++
-			f.pendings = f.pendings[1:]
-			f.finishCond.Broadcast()
-			f.finishCond.L.Unlock()
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/srv/srv.go b/vendor/go.etcd.io/etcd/pkg/srv/srv.go
deleted file mode 100644
index c356002..0000000
--- a/vendor/go.etcd.io/etcd/pkg/srv/srv.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 srv looks up DNS SRV records.
-package srv
-
-import (
-	"fmt"
-	"net"
-	"net/url"
-	"strings"
-
-	"go.etcd.io/etcd/pkg/types"
-)
-
-var (
-	// indirection for testing
-	lookupSRV      = net.LookupSRV // net.DefaultResolver.LookupSRV when ctxs don't conflict
-	resolveTCPAddr = net.ResolveTCPAddr
-)
-
-// GetCluster gets the cluster information via DNS discovery.
-// Also sees each entry as a separate instance.
-func GetCluster(serviceScheme, service, name, dns string, apurls types.URLs) ([]string, error) {
-	tempName := int(0)
-	tcp2ap := make(map[string]url.URL)
-
-	// First, resolve the apurls
-	for _, url := range apurls {
-		tcpAddr, err := resolveTCPAddr("tcp", url.Host)
-		if err != nil {
-			return nil, err
-		}
-		tcp2ap[tcpAddr.String()] = url
-	}
-
-	stringParts := []string{}
-	updateNodeMap := func(service, scheme string) error {
-		_, addrs, err := lookupSRV(service, "tcp", dns)
-		if err != nil {
-			return err
-		}
-		for _, srv := range addrs {
-			port := fmt.Sprintf("%d", srv.Port)
-			host := net.JoinHostPort(srv.Target, port)
-			tcpAddr, terr := resolveTCPAddr("tcp", host)
-			if terr != nil {
-				err = terr
-				continue
-			}
-			n := ""
-			url, ok := tcp2ap[tcpAddr.String()]
-			if ok {
-				n = name
-			}
-			if n == "" {
-				n = fmt.Sprintf("%d", tempName)
-				tempName++
-			}
-			// SRV records have a trailing dot but URL shouldn't.
-			shortHost := strings.TrimSuffix(srv.Target, ".")
-			urlHost := net.JoinHostPort(shortHost, port)
-			if ok && url.Scheme != scheme {
-				err = fmt.Errorf("bootstrap at %s from DNS for %s has scheme mismatch with expected peer %s", scheme+"://"+urlHost, service, url.String())
-			} else {
-				stringParts = append(stringParts, fmt.Sprintf("%s=%s://%s", n, scheme, urlHost))
-			}
-		}
-		if len(stringParts) == 0 {
-			return err
-		}
-		return nil
-	}
-
-	err := updateNodeMap(service, serviceScheme)
-	if err != nil {
-		return nil, fmt.Errorf("error querying DNS SRV records for _%s %s", service, err)
-	}
-	return stringParts, nil
-}
-
-type SRVClients struct {
-	Endpoints []string
-	SRVs      []*net.SRV
-}
-
-// GetClient looks up the client endpoints for a service and domain.
-func GetClient(service, domain string, serviceName string) (*SRVClients, error) {
-	var urls []*url.URL
-	var srvs []*net.SRV
-
-	updateURLs := func(service, scheme string) error {
-		_, addrs, err := lookupSRV(service, "tcp", domain)
-		if err != nil {
-			return err
-		}
-		for _, srv := range addrs {
-			urls = append(urls, &url.URL{
-				Scheme: scheme,
-				Host:   net.JoinHostPort(srv.Target, fmt.Sprintf("%d", srv.Port)),
-			})
-		}
-		srvs = append(srvs, addrs...)
-		return nil
-	}
-
-	errHTTPS := updateURLs(GetSRVService(service, serviceName, "https"), "https")
-	errHTTP := updateURLs(GetSRVService(service, serviceName, "http"), "http")
-
-	if errHTTPS != nil && errHTTP != nil {
-		return nil, fmt.Errorf("dns lookup errors: %s and %s", errHTTPS, errHTTP)
-	}
-
-	endpoints := make([]string, len(urls))
-	for i := range urls {
-		endpoints[i] = urls[i].String()
-	}
-	return &SRVClients{Endpoints: endpoints, SRVs: srvs}, nil
-}
-
-// GetSRVService generates a SRV service including an optional suffix.
-func GetSRVService(service, serviceName string, scheme string) (SRVService string) {
-	if scheme == "https" {
-		service = fmt.Sprintf("%s-ssl", service)
-	}
-
-	if serviceName != "" {
-		return fmt.Sprintf("%s-%s", service, serviceName)
-	}
-	return service
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/systemd/doc.go b/vendor/go.etcd.io/etcd/pkg/systemd/doc.go
deleted file mode 100644
index 30e77ce..0000000
--- a/vendor/go.etcd.io/etcd/pkg/systemd/doc.go
+++ /dev/null
@@ -1,16 +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 systemd provides utility functions for systemd.
-package systemd
diff --git a/vendor/go.etcd.io/etcd/pkg/systemd/journal.go b/vendor/go.etcd.io/etcd/pkg/systemd/journal.go
deleted file mode 100644
index b861c69..0000000
--- a/vendor/go.etcd.io/etcd/pkg/systemd/journal.go
+++ /dev/null
@@ -1,29 +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 systemd
-
-import "net"
-
-// DialJournal returns no error if the process can dial journal socket.
-// Returns an error if dial failed, whichi indicates journald is not available
-// (e.g. run embedded etcd as docker daemon).
-// Reference: https://github.com/coreos/go-systemd/blob/master/journal/journal.go.
-func DialJournal() error {
-	conn, err := net.Dial("unixgram", "/run/systemd/journal/socket")
-	if conn != nil {
-		defer conn.Close()
-	}
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/tlsutil/cipher_suites.go b/vendor/go.etcd.io/etcd/pkg/tlsutil/cipher_suites.go
deleted file mode 100644
index b5916bb..0000000
--- a/vendor/go.etcd.io/etcd/pkg/tlsutil/cipher_suites.go
+++ /dev/null
@@ -1,51 +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 tlsutil
-
-import "crypto/tls"
-
-// cipher suites implemented by Go
-// https://github.com/golang/go/blob/dev.boringcrypto.go1.10/src/crypto/tls/cipher_suites.go
-var cipherSuites = map[string]uint16{
-	"TLS_RSA_WITH_RC4_128_SHA":                tls.TLS_RSA_WITH_RC4_128_SHA,
-	"TLS_RSA_WITH_3DES_EDE_CBC_SHA":           tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-	"TLS_RSA_WITH_AES_128_CBC_SHA":            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
-	"TLS_RSA_WITH_AES_256_CBC_SHA":            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
-	"TLS_RSA_WITH_AES_128_CBC_SHA256":         tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
-	"TLS_RSA_WITH_AES_128_GCM_SHA256":         tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
-	"TLS_RSA_WITH_AES_256_GCM_SHA384":         tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA":        tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_RC4_128_SHA":          tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA":     tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-	"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA":      tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-	"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
-	"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305":    tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-	"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305":  tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
-}
-
-// GetCipherSuite returns the corresponding cipher suite,
-// and boolean value if it is supported.
-func GetCipherSuite(s string) (uint16, bool) {
-	v, ok := cipherSuites[s]
-	return v, ok
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/tlsutil/doc.go b/vendor/go.etcd.io/etcd/pkg/tlsutil/doc.go
deleted file mode 100644
index 3b6aa67..0000000
--- a/vendor/go.etcd.io/etcd/pkg/tlsutil/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 tlsutil provides utility functions for handling TLS.
-package tlsutil
diff --git a/vendor/go.etcd.io/etcd/pkg/tlsutil/tlsutil.go b/vendor/go.etcd.io/etcd/pkg/tlsutil/tlsutil.go
deleted file mode 100644
index 3a5aef0..0000000
--- a/vendor/go.etcd.io/etcd/pkg/tlsutil/tlsutil.go
+++ /dev/null
@@ -1,73 +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 tlsutil
-
-import (
-	"crypto/tls"
-	"crypto/x509"
-	"encoding/pem"
-	"io/ioutil"
-)
-
-// NewCertPool creates x509 certPool with provided CA files.
-func NewCertPool(CAFiles []string) (*x509.CertPool, error) {
-	certPool := x509.NewCertPool()
-
-	for _, CAFile := range CAFiles {
-		pemByte, err := ioutil.ReadFile(CAFile)
-		if err != nil {
-			return nil, err
-		}
-
-		for {
-			var block *pem.Block
-			block, pemByte = pem.Decode(pemByte)
-			if block == nil {
-				break
-			}
-			cert, err := x509.ParseCertificate(block.Bytes)
-			if err != nil {
-				return nil, err
-			}
-
-			certPool.AddCert(cert)
-		}
-	}
-
-	return certPool, nil
-}
-
-// NewCert generates TLS cert by using the given cert,key and parse function.
-func NewCert(certfile, keyfile string, parseFunc func([]byte, []byte) (tls.Certificate, error)) (*tls.Certificate, error) {
-	cert, err := ioutil.ReadFile(certfile)
-	if err != nil {
-		return nil, err
-	}
-
-	key, err := ioutil.ReadFile(keyfile)
-	if err != nil {
-		return nil, err
-	}
-
-	if parseFunc == nil {
-		parseFunc = tls.X509KeyPair
-	}
-
-	tlsCert, err := parseFunc(cert, key)
-	if err != nil {
-		return nil, err
-	}
-	return &tlsCert, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/doc.go b/vendor/go.etcd.io/etcd/pkg/transport/doc.go
deleted file mode 100644
index 37658ce..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/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 transport implements various HTTP transport utilities based on Go
-// net package.
-package transport
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/keepalive_listener.go b/vendor/go.etcd.io/etcd/pkg/transport/keepalive_listener.go
deleted file mode 100644
index 4ff8e7f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/keepalive_listener.go
+++ /dev/null
@@ -1,94 +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 transport
-
-import (
-	"crypto/tls"
-	"fmt"
-	"net"
-	"time"
-)
-
-type keepAliveConn interface {
-	SetKeepAlive(bool) error
-	SetKeepAlivePeriod(d time.Duration) error
-}
-
-// NewKeepAliveListener returns a listener that listens on the given address.
-// Be careful when wrap around KeepAliveListener with another Listener if TLSInfo is not nil.
-// Some pkgs (like go/http) might expect Listener to return TLSConn type to start TLS handshake.
-// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
-func NewKeepAliveListener(l net.Listener, scheme string, tlscfg *tls.Config) (net.Listener, error) {
-	if scheme == "https" {
-		if tlscfg == nil {
-			return nil, fmt.Errorf("cannot listen on TLS for given listener: KeyFile and CertFile are not presented")
-		}
-		return newTLSKeepaliveListener(l, tlscfg), nil
-	}
-
-	return &keepaliveListener{
-		Listener: l,
-	}, nil
-}
-
-type keepaliveListener struct{ net.Listener }
-
-func (kln *keepaliveListener) Accept() (net.Conn, error) {
-	c, err := kln.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	kac := c.(keepAliveConn)
-	// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
-	// default on linux:  30 + 8 * 30
-	// default on osx:    30 + 8 * 75
-	kac.SetKeepAlive(true)
-	kac.SetKeepAlivePeriod(30 * time.Second)
-	return c, nil
-}
-
-// A tlsKeepaliveListener implements a network listener (net.Listener) for TLS connections.
-type tlsKeepaliveListener struct {
-	net.Listener
-	config *tls.Config
-}
-
-// Accept waits for and returns the next incoming TLS connection.
-// The returned connection c is a *tls.Conn.
-func (l *tlsKeepaliveListener) Accept() (c net.Conn, err error) {
-	c, err = l.Listener.Accept()
-	if err != nil {
-		return
-	}
-	kac := c.(keepAliveConn)
-	// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
-	// default on linux:  30 + 8 * 30
-	// default on osx:    30 + 8 * 75
-	kac.SetKeepAlive(true)
-	kac.SetKeepAlivePeriod(30 * time.Second)
-	c = tls.Server(c, l.config)
-	return c, nil
-}
-
-// NewListener creates a Listener which accepts connections from an inner
-// Listener and wraps each connection with Server.
-// The configuration config must be non-nil and must have
-// at least one certificate.
-func newTLSKeepaliveListener(inner net.Listener, config *tls.Config) net.Listener {
-	l := &tlsKeepaliveListener{}
-	l.Listener = inner
-	l.config = config
-	return l
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/limit_listen.go b/vendor/go.etcd.io/etcd/pkg/transport/limit_listen.go
deleted file mode 100644
index 930c542..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/limit_listen.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2013 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 transport provides network utility functions, complementing the more
-// common ones in the net package.
-package transport
-
-import (
-	"errors"
-	"net"
-	"sync"
-	"time"
-)
-
-var (
-	ErrNotTCP = errors.New("only tcp connections have keepalive")
-)
-
-// LimitListener returns a Listener that accepts at most n simultaneous
-// connections from the provided Listener.
-func LimitListener(l net.Listener, n int) net.Listener {
-	return &limitListener{l, make(chan struct{}, n)}
-}
-
-type limitListener struct {
-	net.Listener
-	sem chan struct{}
-}
-
-func (l *limitListener) acquire() { l.sem <- struct{}{} }
-func (l *limitListener) release() { <-l.sem }
-
-func (l *limitListener) Accept() (net.Conn, error) {
-	l.acquire()
-	c, err := l.Listener.Accept()
-	if err != nil {
-		l.release()
-		return nil, err
-	}
-	return &limitListenerConn{Conn: c, release: l.release}, nil
-}
-
-type limitListenerConn struct {
-	net.Conn
-	releaseOnce sync.Once
-	release     func()
-}
-
-func (l *limitListenerConn) Close() error {
-	err := l.Conn.Close()
-	l.releaseOnce.Do(l.release)
-	return err
-}
-
-func (l *limitListenerConn) SetKeepAlive(doKeepAlive bool) error {
-	tcpc, ok := l.Conn.(*net.TCPConn)
-	if !ok {
-		return ErrNotTCP
-	}
-	return tcpc.SetKeepAlive(doKeepAlive)
-}
-
-func (l *limitListenerConn) SetKeepAlivePeriod(d time.Duration) error {
-	tcpc, ok := l.Conn.(*net.TCPConn)
-	if !ok {
-		return ErrNotTCP
-	}
-	return tcpc.SetKeepAlivePeriod(d)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/listener.go b/vendor/go.etcd.io/etcd/pkg/transport/listener.go
deleted file mode 100644
index fa12911..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/listener.go
+++ /dev/null
@@ -1,451 +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 transport
-
-import (
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/tls"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"math/big"
-	"net"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
-
-	"go.etcd.io/etcd/pkg/tlsutil"
-
-	"go.uber.org/zap"
-)
-
-// NewListener creates a new listner.
-func NewListener(addr, scheme string, tlsinfo *TLSInfo) (l net.Listener, err error) {
-	if l, err = newListener(addr, scheme); err != nil {
-		return nil, err
-	}
-	return wrapTLS(scheme, tlsinfo, l)
-}
-
-func newListener(addr string, scheme string) (net.Listener, error) {
-	if scheme == "unix" || scheme == "unixs" {
-		// unix sockets via unix://laddr
-		return NewUnixListener(addr)
-	}
-	return net.Listen("tcp", addr)
-}
-
-func wrapTLS(scheme string, tlsinfo *TLSInfo, l net.Listener) (net.Listener, error) {
-	if scheme != "https" && scheme != "unixs" {
-		return l, nil
-	}
-	if tlsinfo != nil && tlsinfo.SkipClientSANVerify {
-		return NewTLSListener(l, tlsinfo)
-	}
-	return newTLSListener(l, tlsinfo, checkSAN)
-}
-
-type TLSInfo struct {
-	CertFile            string
-	KeyFile             string
-	TrustedCAFile       string
-	ClientCertAuth      bool
-	CRLFile             string
-	InsecureSkipVerify  bool
-	SkipClientSANVerify bool
-
-	// ServerName ensures the cert matches the given host in case of discovery / virtual hosting
-	ServerName string
-
-	// HandshakeFailure is optionally called when a connection fails to handshake. The
-	// connection will be closed immediately afterwards.
-	HandshakeFailure func(*tls.Conn, error)
-
-	// CipherSuites is a list of supported cipher suites.
-	// If empty, Go auto-populates it by default.
-	// Note that cipher suites are prioritized in the given order.
-	CipherSuites []uint16
-
-	selfCert bool
-
-	// parseFunc exists to simplify testing. Typically, parseFunc
-	// should be left nil. In that case, tls.X509KeyPair will be used.
-	parseFunc func([]byte, []byte) (tls.Certificate, error)
-
-	// AllowedCN is a CN which must be provided by a client.
-	AllowedCN string
-
-	// AllowedHostname is an IP address or hostname that must match the TLS
-	// certificate provided by a client.
-	AllowedHostname string
-
-	// Logger logs TLS errors.
-	// If nil, all logs are discarded.
-	Logger *zap.Logger
-
-	// EmptyCN indicates that the cert must have empty CN.
-	// If true, ClientConfig() will return an error for a cert with non empty CN.
-	EmptyCN bool
-}
-
-func (info TLSInfo) String() string {
-	return fmt.Sprintf("cert = %s, key = %s, trusted-ca = %s, client-cert-auth = %v, crl-file = %s", info.CertFile, info.KeyFile, info.TrustedCAFile, info.ClientCertAuth, info.CRLFile)
-}
-
-func (info TLSInfo) Empty() bool {
-	return info.CertFile == "" && info.KeyFile == ""
-}
-
-func SelfCert(lg *zap.Logger, dirpath string, hosts []string, additionalUsages ...x509.ExtKeyUsage) (info TLSInfo, err error) {
-	if err = os.MkdirAll(dirpath, 0700); err != nil {
-		return
-	}
-	info.Logger = lg
-
-	certPath := filepath.Join(dirpath, "cert.pem")
-	keyPath := filepath.Join(dirpath, "key.pem")
-	_, errcert := os.Stat(certPath)
-	_, errkey := os.Stat(keyPath)
-	if errcert == nil && errkey == nil {
-		info.CertFile = certPath
-		info.KeyFile = keyPath
-		info.selfCert = true
-		return
-	}
-
-	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
-	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
-	if err != nil {
-		if info.Logger != nil {
-			info.Logger.Warn(
-				"cannot generate random number",
-				zap.Error(err),
-			)
-		}
-		return
-	}
-
-	tmpl := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject:      pkix.Name{Organization: []string{"etcd"}},
-		NotBefore:    time.Now(),
-		NotAfter:     time.Now().Add(365 * (24 * time.Hour)),
-
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
-		ExtKeyUsage:           append([]x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, additionalUsages...),
-		BasicConstraintsValid: true,
-	}
-
-	for _, host := range hosts {
-		h, _, _ := net.SplitHostPort(host)
-		if ip := net.ParseIP(h); ip != nil {
-			tmpl.IPAddresses = append(tmpl.IPAddresses, ip)
-		} else {
-			tmpl.DNSNames = append(tmpl.DNSNames, h)
-		}
-	}
-
-	priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
-	if err != nil {
-		if info.Logger != nil {
-			info.Logger.Warn(
-				"cannot generate ECDSA key",
-				zap.Error(err),
-			)
-		}
-		return
-	}
-
-	derBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
-	if err != nil {
-		if info.Logger != nil {
-			info.Logger.Warn(
-				"cannot generate x509 certificate",
-				zap.Error(err),
-			)
-		}
-		return
-	}
-
-	certOut, err := os.Create(certPath)
-	if err != nil {
-		info.Logger.Warn(
-			"cannot cert file",
-			zap.String("path", certPath),
-			zap.Error(err),
-		)
-		return
-	}
-	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
-	certOut.Close()
-	if info.Logger != nil {
-		info.Logger.Info("created cert file", zap.String("path", certPath))
-	}
-
-	b, err := x509.MarshalECPrivateKey(priv)
-	if err != nil {
-		return
-	}
-	keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		if info.Logger != nil {
-			info.Logger.Warn(
-				"cannot key file",
-				zap.String("path", keyPath),
-				zap.Error(err),
-			)
-		}
-		return
-	}
-	pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
-	keyOut.Close()
-	if info.Logger != nil {
-		info.Logger.Info("created key file", zap.String("path", keyPath))
-	}
-	return SelfCert(lg, dirpath, hosts)
-}
-
-// baseConfig is called on initial TLS handshake start.
-//
-// Previously,
-// 1. Server has non-empty (*tls.Config).Certificates on client hello
-// 2. Server calls (*tls.Config).GetCertificate iff:
-//    - Server's (*tls.Config).Certificates is not empty, or
-//    - Client supplies SNI; non-empty (*tls.ClientHelloInfo).ServerName
-//
-// When (*tls.Config).Certificates is always populated on initial handshake,
-// client is expected to provide a valid matching SNI to pass the TLS
-// verification, thus trigger server (*tls.Config).GetCertificate to reload
-// TLS assets. However, a cert whose SAN field does not include domain names
-// but only IP addresses, has empty (*tls.ClientHelloInfo).ServerName, thus
-// it was never able to trigger TLS reload on initial handshake; first
-// ceritifcate object was being used, never being updated.
-//
-// Now, (*tls.Config).Certificates is created empty on initial TLS client
-// handshake, in order to trigger (*tls.Config).GetCertificate and populate
-// rest of the certificates on every new TLS connection, even when client
-// SNI is empty (e.g. cert only includes IPs).
-func (info TLSInfo) baseConfig() (*tls.Config, error) {
-	if info.KeyFile == "" || info.CertFile == "" {
-		return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)
-	}
-	if info.Logger == nil {
-		info.Logger = zap.NewNop()
-	}
-
-	_, err := tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-	if err != nil {
-		return nil, err
-	}
-
-	cfg := &tls.Config{
-		MinVersion: tls.VersionTLS12,
-		ServerName: info.ServerName,
-	}
-
-	if len(info.CipherSuites) > 0 {
-		cfg.CipherSuites = info.CipherSuites
-	}
-
-	// Client certificates may be verified by either an exact match on the CN,
-	// or a more general check of the CN and SANs.
-	var verifyCertificate func(*x509.Certificate) bool
-	if info.AllowedCN != "" {
-		if info.AllowedHostname != "" {
-			return nil, fmt.Errorf("AllowedCN and AllowedHostname are mutually exclusive (cn=%q, hostname=%q)", info.AllowedCN, info.AllowedHostname)
-		}
-		verifyCertificate = func(cert *x509.Certificate) bool {
-			return info.AllowedCN == cert.Subject.CommonName
-		}
-	}
-	if info.AllowedHostname != "" {
-		verifyCertificate = func(cert *x509.Certificate) bool {
-			return cert.VerifyHostname(info.AllowedHostname) == nil
-		}
-	}
-	if verifyCertificate != nil {
-		cfg.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
-			for _, chains := range verifiedChains {
-				if len(chains) != 0 {
-					if verifyCertificate(chains[0]) {
-						return nil
-					}
-				}
-			}
-			return errors.New("client certificate authentication failed")
-		}
-	}
-
-	// this only reloads certs when there's a client request
-	// TODO: support server-side refresh (e.g. inotify, SIGHUP), caching
-	cfg.GetCertificate = func(clientHello *tls.ClientHelloInfo) (cert *tls.Certificate, err error) {
-		cert, err = tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-		if os.IsNotExist(err) {
-			if info.Logger != nil {
-				info.Logger.Warn(
-					"failed to find peer cert files",
-					zap.String("cert-file", info.CertFile),
-					zap.String("key-file", info.KeyFile),
-					zap.Error(err),
-				)
-			}
-		} else if err != nil {
-			if info.Logger != nil {
-				info.Logger.Warn(
-					"failed to create peer certificate",
-					zap.String("cert-file", info.CertFile),
-					zap.String("key-file", info.KeyFile),
-					zap.Error(err),
-				)
-			}
-		}
-		return cert, err
-	}
-	cfg.GetClientCertificate = func(unused *tls.CertificateRequestInfo) (cert *tls.Certificate, err error) {
-		cert, err = tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc)
-		if os.IsNotExist(err) {
-			if info.Logger != nil {
-				info.Logger.Warn(
-					"failed to find client cert files",
-					zap.String("cert-file", info.CertFile),
-					zap.String("key-file", info.KeyFile),
-					zap.Error(err),
-				)
-			}
-		} else if err != nil {
-			if info.Logger != nil {
-				info.Logger.Warn(
-					"failed to create client certificate",
-					zap.String("cert-file", info.CertFile),
-					zap.String("key-file", info.KeyFile),
-					zap.Error(err),
-				)
-			}
-		}
-		return cert, err
-	}
-	return cfg, nil
-}
-
-// cafiles returns a list of CA file paths.
-func (info TLSInfo) cafiles() []string {
-	cs := make([]string, 0)
-	if info.TrustedCAFile != "" {
-		cs = append(cs, info.TrustedCAFile)
-	}
-	return cs
-}
-
-// ServerConfig generates a tls.Config object for use by an HTTP server.
-func (info TLSInfo) ServerConfig() (*tls.Config, error) {
-	cfg, err := info.baseConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	cfg.ClientAuth = tls.NoClientCert
-	if info.TrustedCAFile != "" || info.ClientCertAuth {
-		cfg.ClientAuth = tls.RequireAndVerifyClientCert
-	}
-
-	cs := info.cafiles()
-	if len(cs) > 0 {
-		cp, err := tlsutil.NewCertPool(cs)
-		if err != nil {
-			return nil, err
-		}
-		cfg.ClientCAs = cp
-	}
-
-	// "h2" NextProtos is necessary for enabling HTTP2 for go's HTTP server
-	cfg.NextProtos = []string{"h2"}
-
-	// go1.13 enables TLS 1.3 by default
-	// and in TLS 1.3, cipher suites are not configurable
-	// setting Max TLS version to TLS 1.2 for go 1.13
-	cfg.MaxVersion = tls.VersionTLS12
-
-	return cfg, nil
-}
-
-// ClientConfig generates a tls.Config object for use by an HTTP client.
-func (info TLSInfo) ClientConfig() (*tls.Config, error) {
-	var cfg *tls.Config
-	var err error
-
-	if !info.Empty() {
-		cfg, err = info.baseConfig()
-		if err != nil {
-			return nil, err
-		}
-	} else {
-		cfg = &tls.Config{ServerName: info.ServerName}
-	}
-	cfg.InsecureSkipVerify = info.InsecureSkipVerify
-
-	cs := info.cafiles()
-	if len(cs) > 0 {
-		cfg.RootCAs, err = tlsutil.NewCertPool(cs)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	if info.selfCert {
-		cfg.InsecureSkipVerify = true
-	}
-
-	if info.EmptyCN {
-		hasNonEmptyCN := false
-		cn := ""
-		tlsutil.NewCert(info.CertFile, info.KeyFile, func(certPEMBlock []byte, keyPEMBlock []byte) (tls.Certificate, error) {
-			var block *pem.Block
-			block, _ = pem.Decode(certPEMBlock)
-			cert, err := x509.ParseCertificate(block.Bytes)
-			if err != nil {
-				return tls.Certificate{}, err
-			}
-			if len(cert.Subject.CommonName) != 0 {
-				hasNonEmptyCN = true
-				cn = cert.Subject.CommonName
-			}
-			return tls.X509KeyPair(certPEMBlock, keyPEMBlock)
-		})
-		if hasNonEmptyCN {
-			return nil, fmt.Errorf("cert has non empty Common Name (%s)", cn)
-		}
-	}
-
-	// go1.13 enables TLS 1.3 by default
-	// and in TLS 1.3, cipher suites are not configurable
-	// setting Max TLS version to TLS 1.2 for go 1.13
-	cfg.MaxVersion = tls.VersionTLS12
-
-	return cfg, nil
-}
-
-// IsClosedConnError returns true if the error is from closing listener, cmux.
-// copied from golang.org/x/net/http2/http2.go
-func IsClosedConnError(err error) bool {
-	// 'use of closed network connection' (Go <=1.8)
-	// 'use of closed file or network connection' (Go >1.8, internal/poll.ErrClosing)
-	// 'mux: listener closed' (cmux.ErrListenerClosed)
-	return err != nil && strings.Contains(err.Error(), "closed")
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/listener_tls.go b/vendor/go.etcd.io/etcd/pkg/transport/listener_tls.go
deleted file mode 100644
index 6f16009..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/listener_tls.go
+++ /dev/null
@@ -1,272 +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 transport
-
-import (
-	"context"
-	"crypto/tls"
-	"crypto/x509"
-	"fmt"
-	"io/ioutil"
-	"net"
-	"strings"
-	"sync"
-)
-
-// tlsListener overrides a TLS listener so it will reject client
-// certificates with insufficient SAN credentials or CRL revoked
-// certificates.
-type tlsListener struct {
-	net.Listener
-	connc            chan net.Conn
-	donec            chan struct{}
-	err              error
-	handshakeFailure func(*tls.Conn, error)
-	check            tlsCheckFunc
-}
-
-type tlsCheckFunc func(context.Context, *tls.Conn) error
-
-// NewTLSListener handshakes TLS connections and performs optional CRL checking.
-func NewTLSListener(l net.Listener, tlsinfo *TLSInfo) (net.Listener, error) {
-	check := func(context.Context, *tls.Conn) error { return nil }
-	return newTLSListener(l, tlsinfo, check)
-}
-
-func newTLSListener(l net.Listener, tlsinfo *TLSInfo, check tlsCheckFunc) (net.Listener, error) {
-	if tlsinfo == nil || tlsinfo.Empty() {
-		l.Close()
-		return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", l.Addr().String())
-	}
-	tlscfg, err := tlsinfo.ServerConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	hf := tlsinfo.HandshakeFailure
-	if hf == nil {
-		hf = func(*tls.Conn, error) {}
-	}
-
-	if len(tlsinfo.CRLFile) > 0 {
-		prevCheck := check
-		check = func(ctx context.Context, tlsConn *tls.Conn) error {
-			if err := prevCheck(ctx, tlsConn); err != nil {
-				return err
-			}
-			st := tlsConn.ConnectionState()
-			if certs := st.PeerCertificates; len(certs) > 0 {
-				return checkCRL(tlsinfo.CRLFile, certs)
-			}
-			return nil
-		}
-	}
-
-	tlsl := &tlsListener{
-		Listener:         tls.NewListener(l, tlscfg),
-		connc:            make(chan net.Conn),
-		donec:            make(chan struct{}),
-		handshakeFailure: hf,
-		check:            check,
-	}
-	go tlsl.acceptLoop()
-	return tlsl, nil
-}
-
-func (l *tlsListener) Accept() (net.Conn, error) {
-	select {
-	case conn := <-l.connc:
-		return conn, nil
-	case <-l.donec:
-		return nil, l.err
-	}
-}
-
-func checkSAN(ctx context.Context, tlsConn *tls.Conn) error {
-	st := tlsConn.ConnectionState()
-	if certs := st.PeerCertificates; len(certs) > 0 {
-		addr := tlsConn.RemoteAddr().String()
-		return checkCertSAN(ctx, certs[0], addr)
-	}
-	return nil
-}
-
-// acceptLoop launches each TLS handshake in a separate goroutine
-// to prevent a hanging TLS connection from blocking other connections.
-func (l *tlsListener) acceptLoop() {
-	var wg sync.WaitGroup
-	var pendingMu sync.Mutex
-
-	pending := make(map[net.Conn]struct{})
-	ctx, cancel := context.WithCancel(context.Background())
-	defer func() {
-		cancel()
-		pendingMu.Lock()
-		for c := range pending {
-			c.Close()
-		}
-		pendingMu.Unlock()
-		wg.Wait()
-		close(l.donec)
-	}()
-
-	for {
-		conn, err := l.Listener.Accept()
-		if err != nil {
-			l.err = err
-			return
-		}
-
-		pendingMu.Lock()
-		pending[conn] = struct{}{}
-		pendingMu.Unlock()
-
-		wg.Add(1)
-		go func() {
-			defer func() {
-				if conn != nil {
-					conn.Close()
-				}
-				wg.Done()
-			}()
-
-			tlsConn := conn.(*tls.Conn)
-			herr := tlsConn.Handshake()
-			pendingMu.Lock()
-			delete(pending, conn)
-			pendingMu.Unlock()
-
-			if herr != nil {
-				l.handshakeFailure(tlsConn, herr)
-				return
-			}
-			if err := l.check(ctx, tlsConn); err != nil {
-				l.handshakeFailure(tlsConn, err)
-				return
-			}
-
-			select {
-			case l.connc <- tlsConn:
-				conn = nil
-			case <-ctx.Done():
-			}
-		}()
-	}
-}
-
-func checkCRL(crlPath string, cert []*x509.Certificate) error {
-	// TODO: cache
-	crlBytes, err := ioutil.ReadFile(crlPath)
-	if err != nil {
-		return err
-	}
-	certList, err := x509.ParseCRL(crlBytes)
-	if err != nil {
-		return err
-	}
-	revokedSerials := make(map[string]struct{})
-	for _, rc := range certList.TBSCertList.RevokedCertificates {
-		revokedSerials[string(rc.SerialNumber.Bytes())] = struct{}{}
-	}
-	for _, c := range cert {
-		serial := string(c.SerialNumber.Bytes())
-		if _, ok := revokedSerials[serial]; ok {
-			return fmt.Errorf("transport: certificate serial %x revoked", serial)
-		}
-	}
-	return nil
-}
-
-func checkCertSAN(ctx context.Context, cert *x509.Certificate, remoteAddr string) error {
-	if len(cert.IPAddresses) == 0 && len(cert.DNSNames) == 0 {
-		return nil
-	}
-	h, _, herr := net.SplitHostPort(remoteAddr)
-	if herr != nil {
-		return herr
-	}
-	if len(cert.IPAddresses) > 0 {
-		cerr := cert.VerifyHostname(h)
-		if cerr == nil {
-			return nil
-		}
-		if len(cert.DNSNames) == 0 {
-			return cerr
-		}
-	}
-	if len(cert.DNSNames) > 0 {
-		ok, err := isHostInDNS(ctx, h, cert.DNSNames)
-		if ok {
-			return nil
-		}
-		errStr := ""
-		if err != nil {
-			errStr = " (" + err.Error() + ")"
-		}
-		return fmt.Errorf("tls: %q does not match any of DNSNames %q"+errStr, h, cert.DNSNames)
-	}
-	return nil
-}
-
-func isHostInDNS(ctx context.Context, host string, dnsNames []string) (ok bool, err error) {
-	// reverse lookup
-	wildcards, names := []string{}, []string{}
-	for _, dns := range dnsNames {
-		if strings.HasPrefix(dns, "*.") {
-			wildcards = append(wildcards, dns[1:])
-		} else {
-			names = append(names, dns)
-		}
-	}
-	lnames, lerr := net.DefaultResolver.LookupAddr(ctx, host)
-	for _, name := range lnames {
-		// strip trailing '.' from PTR record
-		if name[len(name)-1] == '.' {
-			name = name[:len(name)-1]
-		}
-		for _, wc := range wildcards {
-			if strings.HasSuffix(name, wc) {
-				return true, nil
-			}
-		}
-		for _, n := range names {
-			if n == name {
-				return true, nil
-			}
-		}
-	}
-	err = lerr
-
-	// forward lookup
-	for _, dns := range names {
-		addrs, lerr := net.DefaultResolver.LookupHost(ctx, dns)
-		if lerr != nil {
-			err = lerr
-			continue
-		}
-		for _, addr := range addrs {
-			if addr == host {
-				return true, nil
-			}
-		}
-	}
-	return false, err
-}
-
-func (l *tlsListener) Close() error {
-	err := l.Listener.Close()
-	<-l.donec
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/timeout_conn.go b/vendor/go.etcd.io/etcd/pkg/transport/timeout_conn.go
deleted file mode 100644
index 7e8c020..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/timeout_conn.go
+++ /dev/null
@@ -1,44 +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 transport
-
-import (
-	"net"
-	"time"
-)
-
-type timeoutConn struct {
-	net.Conn
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-}
-
-func (c timeoutConn) Write(b []byte) (n int, err error) {
-	if c.wtimeoutd > 0 {
-		if err := c.SetWriteDeadline(time.Now().Add(c.wtimeoutd)); err != nil {
-			return 0, err
-		}
-	}
-	return c.Conn.Write(b)
-}
-
-func (c timeoutConn) Read(b []byte) (n int, err error) {
-	if c.rdtimeoutd > 0 {
-		if err := c.SetReadDeadline(time.Now().Add(c.rdtimeoutd)); err != nil {
-			return 0, err
-		}
-	}
-	return c.Conn.Read(b)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/timeout_dialer.go b/vendor/go.etcd.io/etcd/pkg/transport/timeout_dialer.go
deleted file mode 100644
index 6ae39ec..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/timeout_dialer.go
+++ /dev/null
@@ -1,36 +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 transport
-
-import (
-	"net"
-	"time"
-)
-
-type rwTimeoutDialer struct {
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-	net.Dialer
-}
-
-func (d *rwTimeoutDialer) Dial(network, address string) (net.Conn, error) {
-	conn, err := d.Dialer.Dial(network, address)
-	tconn := &timeoutConn{
-		rdtimeoutd: d.rdtimeoutd,
-		wtimeoutd:  d.wtimeoutd,
-		Conn:       conn,
-	}
-	return tconn, err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/timeout_listener.go b/vendor/go.etcd.io/etcd/pkg/transport/timeout_listener.go
deleted file mode 100644
index 273e99f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/timeout_listener.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 transport
-
-import (
-	"net"
-	"time"
-)
-
-// NewTimeoutListener returns a listener that listens on the given address.
-// If read/write on the accepted connection blocks longer than its time limit,
-// it will return timeout error.
-func NewTimeoutListener(addr string, scheme string, tlsinfo *TLSInfo, rdtimeoutd, wtimeoutd time.Duration) (net.Listener, error) {
-	ln, err := newListener(addr, scheme)
-	if err != nil {
-		return nil, err
-	}
-	ln = &rwTimeoutListener{
-		Listener:   ln,
-		rdtimeoutd: rdtimeoutd,
-		wtimeoutd:  wtimeoutd,
-	}
-	if ln, err = wrapTLS(scheme, tlsinfo, ln); err != nil {
-		return nil, err
-	}
-	return ln, nil
-}
-
-type rwTimeoutListener struct {
-	net.Listener
-	wtimeoutd  time.Duration
-	rdtimeoutd time.Duration
-}
-
-func (rwln *rwTimeoutListener) Accept() (net.Conn, error) {
-	c, err := rwln.Listener.Accept()
-	if err != nil {
-		return nil, err
-	}
-	return timeoutConn{
-		Conn:       c,
-		wtimeoutd:  rwln.wtimeoutd,
-		rdtimeoutd: rwln.rdtimeoutd,
-	}, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/timeout_transport.go b/vendor/go.etcd.io/etcd/pkg/transport/timeout_transport.go
deleted file mode 100644
index ea16b4c..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/timeout_transport.go
+++ /dev/null
@@ -1,51 +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 transport
-
-import (
-	"net"
-	"net/http"
-	"time"
-)
-
-// NewTimeoutTransport returns a transport created using the given TLS info.
-// If read/write on the created connection blocks longer than its time limit,
-// it will return timeout error.
-// If read/write timeout is set, transport will not be able to reuse connection.
-func NewTimeoutTransport(info TLSInfo, dialtimeoutd, rdtimeoutd, wtimeoutd time.Duration) (*http.Transport, error) {
-	tr, err := NewTransport(info, dialtimeoutd)
-	if err != nil {
-		return nil, err
-	}
-
-	if rdtimeoutd != 0 || wtimeoutd != 0 {
-		// the timed out connection will timeout soon after it is idle.
-		// it should not be put back to http transport as an idle connection for future usage.
-		tr.MaxIdleConnsPerHost = -1
-	} else {
-		// allow more idle connections between peers to avoid unnecessary port allocation.
-		tr.MaxIdleConnsPerHost = 1024
-	}
-
-	tr.Dial = (&rwTimeoutDialer{
-		Dialer: net.Dialer{
-			Timeout:   dialtimeoutd,
-			KeepAlive: 30 * time.Second,
-		},
-		rdtimeoutd: rdtimeoutd,
-		wtimeoutd:  wtimeoutd,
-	}).Dial
-	return tr, nil
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/tls.go b/vendor/go.etcd.io/etcd/pkg/transport/tls.go
deleted file mode 100644
index 62fe0d3..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/tls.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 transport
-
-import (
-	"fmt"
-	"strings"
-	"time"
-)
-
-// ValidateSecureEndpoints scans the given endpoints against tls info, returning only those
-// endpoints that could be validated as secure.
-func ValidateSecureEndpoints(tlsInfo TLSInfo, eps []string) ([]string, error) {
-	t, err := NewTransport(tlsInfo, 5*time.Second)
-	if err != nil {
-		return nil, err
-	}
-	var errs []string
-	var endpoints []string
-	for _, ep := range eps {
-		if !strings.HasPrefix(ep, "https://") {
-			errs = append(errs, fmt.Sprintf("%q is insecure", ep))
-			continue
-		}
-		conn, cerr := t.Dial("tcp", ep[len("https://"):])
-		if cerr != nil {
-			errs = append(errs, fmt.Sprintf("%q failed to dial (%v)", ep, cerr))
-			continue
-		}
-		conn.Close()
-		endpoints = append(endpoints, ep)
-	}
-	if len(errs) != 0 {
-		err = fmt.Errorf("%s", strings.Join(errs, ","))
-	}
-	return endpoints, err
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/transport.go b/vendor/go.etcd.io/etcd/pkg/transport/transport.go
deleted file mode 100644
index 4a7fe69..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/transport.go
+++ /dev/null
@@ -1,71 +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 transport
-
-import (
-	"net"
-	"net/http"
-	"strings"
-	"time"
-)
-
-type unixTransport struct{ *http.Transport }
-
-func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, error) {
-	cfg, err := info.ClientConfig()
-	if err != nil {
-		return nil, err
-	}
-
-	t := &http.Transport{
-		Proxy: http.ProxyFromEnvironment,
-		Dial: (&net.Dialer{
-			Timeout: dialtimeoutd,
-			// value taken from http.DefaultTransport
-			KeepAlive: 30 * time.Second,
-		}).Dial,
-		// value taken from http.DefaultTransport
-		TLSHandshakeTimeout: 10 * time.Second,
-		TLSClientConfig:     cfg,
-	}
-
-	dialer := (&net.Dialer{
-		Timeout:   dialtimeoutd,
-		KeepAlive: 30 * time.Second,
-	})
-	dial := func(net, addr string) (net.Conn, error) {
-		return dialer.Dial("unix", addr)
-	}
-
-	tu := &http.Transport{
-		Proxy:               http.ProxyFromEnvironment,
-		Dial:                dial,
-		TLSHandshakeTimeout: 10 * time.Second,
-		TLSClientConfig:     cfg,
-	}
-	ut := &unixTransport{tu}
-
-	t.RegisterProtocol("unix", ut)
-	t.RegisterProtocol("unixs", ut)
-
-	return t, nil
-}
-
-func (urt *unixTransport) RoundTrip(req *http.Request) (*http.Response, error) {
-	url := *req.URL
-	req.URL = &url
-	req.URL.Scheme = strings.Replace(req.URL.Scheme, "unix", "http", 1)
-	return urt.Transport.RoundTrip(req)
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/transport/unix_listener.go b/vendor/go.etcd.io/etcd/pkg/transport/unix_listener.go
deleted file mode 100644
index 123e203..0000000
--- a/vendor/go.etcd.io/etcd/pkg/transport/unix_listener.go
+++ /dev/null
@@ -1,40 +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 transport
-
-import (
-	"net"
-	"os"
-)
-
-type unixListener struct{ net.Listener }
-
-func NewUnixListener(addr string) (net.Listener, error) {
-	if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
-		return nil, err
-	}
-	l, err := net.Listen("unix", addr)
-	if err != nil {
-		return nil, err
-	}
-	return &unixListener{l}, nil
-}
-
-func (ul *unixListener) Close() error {
-	if err := os.Remove(ul.Addr().String()); err != nil && !os.IsNotExist(err) {
-		return err
-	}
-	return ul.Listener.Close()
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/types/doc.go b/vendor/go.etcd.io/etcd/pkg/types/doc.go
deleted file mode 100644
index de8ef0b..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/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 types declares various data types and implements type-checking
-// functions.
-package types
diff --git a/vendor/go.etcd.io/etcd/pkg/types/id.go b/vendor/go.etcd.io/etcd/pkg/types/id.go
deleted file mode 100644
index ae00388..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/id.go
+++ /dev/null
@@ -1,39 +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 types
-
-import "strconv"
-
-// ID represents a generic identifier which is canonically
-// stored as a uint64 but is typically represented as a
-// base-16 string for input/output
-type ID uint64
-
-func (i ID) String() string {
-	return strconv.FormatUint(uint64(i), 16)
-}
-
-// IDFromString attempts to create an ID from a base-16 string.
-func IDFromString(s string) (ID, error) {
-	i, err := strconv.ParseUint(s, 16, 64)
-	return ID(i), err
-}
-
-// IDSlice implements the sort interface
-type IDSlice []ID
-
-func (p IDSlice) Len() int           { return len(p) }
-func (p IDSlice) Less(i, j int) bool { return uint64(p[i]) < uint64(p[j]) }
-func (p IDSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
diff --git a/vendor/go.etcd.io/etcd/pkg/types/set.go b/vendor/go.etcd.io/etcd/pkg/types/set.go
deleted file mode 100644
index e7a3cdc..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/set.go
+++ /dev/null
@@ -1,195 +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 types
-
-import (
-	"reflect"
-	"sort"
-	"sync"
-)
-
-type Set interface {
-	Add(string)
-	Remove(string)
-	Contains(string) bool
-	Equals(Set) bool
-	Length() int
-	Values() []string
-	Copy() Set
-	Sub(Set) Set
-}
-
-func NewUnsafeSet(values ...string) *unsafeSet {
-	set := &unsafeSet{make(map[string]struct{})}
-	for _, v := range values {
-		set.Add(v)
-	}
-	return set
-}
-
-func NewThreadsafeSet(values ...string) *tsafeSet {
-	us := NewUnsafeSet(values...)
-	return &tsafeSet{us, sync.RWMutex{}}
-}
-
-type unsafeSet struct {
-	d map[string]struct{}
-}
-
-// Add adds a new value to the set (no-op if the value is already present)
-func (us *unsafeSet) Add(value string) {
-	us.d[value] = struct{}{}
-}
-
-// Remove removes the given value from the set
-func (us *unsafeSet) Remove(value string) {
-	delete(us.d, value)
-}
-
-// Contains returns whether the set contains the given value
-func (us *unsafeSet) Contains(value string) (exists bool) {
-	_, exists = us.d[value]
-	return exists
-}
-
-// ContainsAll returns whether the set contains all given values
-func (us *unsafeSet) ContainsAll(values []string) bool {
-	for _, s := range values {
-		if !us.Contains(s) {
-			return false
-		}
-	}
-	return true
-}
-
-// Equals returns whether the contents of two sets are identical
-func (us *unsafeSet) Equals(other Set) bool {
-	v1 := sort.StringSlice(us.Values())
-	v2 := sort.StringSlice(other.Values())
-	v1.Sort()
-	v2.Sort()
-	return reflect.DeepEqual(v1, v2)
-}
-
-// Length returns the number of elements in the set
-func (us *unsafeSet) Length() int {
-	return len(us.d)
-}
-
-// Values returns the values of the Set in an unspecified order.
-func (us *unsafeSet) Values() (values []string) {
-	values = make([]string, 0)
-	for val := range us.d {
-		values = append(values, val)
-	}
-	return values
-}
-
-// Copy creates a new Set containing the values of the first
-func (us *unsafeSet) Copy() Set {
-	cp := NewUnsafeSet()
-	for val := range us.d {
-		cp.Add(val)
-	}
-
-	return cp
-}
-
-// Sub removes all elements in other from the set
-func (us *unsafeSet) Sub(other Set) Set {
-	oValues := other.Values()
-	result := us.Copy().(*unsafeSet)
-
-	for _, val := range oValues {
-		if _, ok := result.d[val]; !ok {
-			continue
-		}
-		delete(result.d, val)
-	}
-
-	return result
-}
-
-type tsafeSet struct {
-	us *unsafeSet
-	m  sync.RWMutex
-}
-
-func (ts *tsafeSet) Add(value string) {
-	ts.m.Lock()
-	defer ts.m.Unlock()
-	ts.us.Add(value)
-}
-
-func (ts *tsafeSet) Remove(value string) {
-	ts.m.Lock()
-	defer ts.m.Unlock()
-	ts.us.Remove(value)
-}
-
-func (ts *tsafeSet) Contains(value string) (exists bool) {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-	return ts.us.Contains(value)
-}
-
-func (ts *tsafeSet) Equals(other Set) bool {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-
-	// If ts and other represent the same variable, avoid calling
-	// ts.us.Equals(other), to avoid double RLock bug
-	if _other, ok := other.(*tsafeSet); ok {
-		if _other == ts {
-			return true
-		}
-	}
-	return ts.us.Equals(other)
-}
-
-func (ts *tsafeSet) Length() int {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-	return ts.us.Length()
-}
-
-func (ts *tsafeSet) Values() (values []string) {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-	return ts.us.Values()
-}
-
-func (ts *tsafeSet) Copy() Set {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-	usResult := ts.us.Copy().(*unsafeSet)
-	return &tsafeSet{usResult, sync.RWMutex{}}
-}
-
-func (ts *tsafeSet) Sub(other Set) Set {
-	ts.m.RLock()
-	defer ts.m.RUnlock()
-
-	// If ts and other represent the same variable, avoid calling
-	// ts.us.Sub(other), to avoid double RLock bug
-	if _other, ok := other.(*tsafeSet); ok {
-		if _other == ts {
-			usResult := NewUnsafeSet()
-			return &tsafeSet{usResult, sync.RWMutex{}}
-		}
-	}
-	usResult := ts.us.Sub(other).(*unsafeSet)
-	return &tsafeSet{usResult, sync.RWMutex{}}
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/types/slice.go b/vendor/go.etcd.io/etcd/pkg/types/slice.go
deleted file mode 100644
index 0dd9ca7..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/slice.go
+++ /dev/null
@@ -1,22 +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 types
-
-// Uint64Slice implements sort interface
-type Uint64Slice []uint64
-
-func (p Uint64Slice) Len() int           { return len(p) }
-func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
-func (p Uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
diff --git a/vendor/go.etcd.io/etcd/pkg/types/urls.go b/vendor/go.etcd.io/etcd/pkg/types/urls.go
deleted file mode 100644
index 9e5d03f..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/urls.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 types
-
-import (
-	"errors"
-	"fmt"
-	"net"
-	"net/url"
-	"sort"
-	"strings"
-)
-
-type URLs []url.URL
-
-func NewURLs(strs []string) (URLs, error) {
-	all := make([]url.URL, len(strs))
-	if len(all) == 0 {
-		return nil, errors.New("no valid URLs given")
-	}
-	for i, in := range strs {
-		in = strings.TrimSpace(in)
-		u, err := url.Parse(in)
-		if err != nil {
-			return nil, err
-		}
-		if u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "unix" && u.Scheme != "unixs" {
-			return nil, fmt.Errorf("URL scheme must be http, https, unix, or unixs: %s", in)
-		}
-		if _, _, err := net.SplitHostPort(u.Host); err != nil {
-			return nil, fmt.Errorf(`URL address does not have the form "host:port": %s`, in)
-		}
-		if u.Path != "" {
-			return nil, fmt.Errorf("URL must not contain a path: %s", in)
-		}
-		all[i] = *u
-	}
-	us := URLs(all)
-	us.Sort()
-
-	return us, nil
-}
-
-func MustNewURLs(strs []string) URLs {
-	urls, err := NewURLs(strs)
-	if err != nil {
-		panic(err)
-	}
-	return urls
-}
-
-func (us URLs) String() string {
-	return strings.Join(us.StringSlice(), ",")
-}
-
-func (us *URLs) Sort() {
-	sort.Sort(us)
-}
-func (us URLs) Len() int           { return len(us) }
-func (us URLs) Less(i, j int) bool { return us[i].String() < us[j].String() }
-func (us URLs) Swap(i, j int)      { us[i], us[j] = us[j], us[i] }
-
-func (us URLs) StringSlice() []string {
-	out := make([]string, len(us))
-	for i := range us {
-		out[i] = us[i].String()
-	}
-
-	return out
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go b/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go
deleted file mode 100644
index 47690cc..0000000
--- a/vendor/go.etcd.io/etcd/pkg/types/urlsmap.go
+++ /dev/null
@@ -1,107 +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 types
-
-import (
-	"fmt"
-	"sort"
-	"strings"
-)
-
-// URLsMap is a map from a name to its URLs.
-type URLsMap map[string]URLs
-
-// NewURLsMap returns a URLsMap instantiated from the given string,
-// which consists of discovery-formatted names-to-URLs, like:
-// mach0=http://1.1.1.1:2380,mach0=http://2.2.2.2::2380,mach1=http://3.3.3.3:2380,mach2=http://4.4.4.4:2380
-func NewURLsMap(s string) (URLsMap, error) {
-	m := parse(s)
-
-	cl := URLsMap{}
-	for name, urls := range m {
-		us, err := NewURLs(urls)
-		if err != nil {
-			return nil, err
-		}
-		cl[name] = us
-	}
-	return cl, nil
-}
-
-// NewURLsMapFromStringMap takes a map of strings and returns a URLsMap. The
-// string values in the map can be multiple values separated by the sep string.
-func NewURLsMapFromStringMap(m map[string]string, sep string) (URLsMap, error) {
-	var err error
-	um := URLsMap{}
-	for k, v := range m {
-		um[k], err = NewURLs(strings.Split(v, sep))
-		if err != nil {
-			return nil, err
-		}
-	}
-	return um, nil
-}
-
-// String turns URLsMap into discovery-formatted name-to-URLs sorted by name.
-func (c URLsMap) String() string {
-	var pairs []string
-	for name, urls := range c {
-		for _, url := range urls {
-			pairs = append(pairs, fmt.Sprintf("%s=%s", name, url.String()))
-		}
-	}
-	sort.Strings(pairs)
-	return strings.Join(pairs, ",")
-}
-
-// URLs returns a list of all URLs.
-// The returned list is sorted in ascending lexicographical order.
-func (c URLsMap) URLs() []string {
-	var urls []string
-	for _, us := range c {
-		for _, u := range us {
-			urls = append(urls, u.String())
-		}
-	}
-	sort.Strings(urls)
-	return urls
-}
-
-// Len returns the size of URLsMap.
-func (c URLsMap) Len() int {
-	return len(c)
-}
-
-// parse parses the given string and returns a map listing the values specified for each key.
-func parse(s string) map[string][]string {
-	m := make(map[string][]string)
-	for s != "" {
-		key := s
-		if i := strings.IndexAny(key, ","); i >= 0 {
-			key, s = key[:i], key[i+1:]
-		} else {
-			s = ""
-		}
-		if key == "" {
-			continue
-		}
-		value := ""
-		if i := strings.Index(key, "="); i >= 0 {
-			key, value = key[:i], key[i+1:]
-		}
-		m[key] = append(m[key], value)
-	}
-	return m
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/wait/wait.go b/vendor/go.etcd.io/etcd/pkg/wait/wait.go
deleted file mode 100644
index 9b1df41..0000000
--- a/vendor/go.etcd.io/etcd/pkg/wait/wait.go
+++ /dev/null
@@ -1,91 +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 wait provides utility functions for polling, listening using Go
-// channel.
-package wait
-
-import (
-	"log"
-	"sync"
-)
-
-// Wait is an interface that provides the ability to wait and trigger events that
-// are associated with IDs.
-type Wait interface {
-	// Register waits returns a chan that waits on the given ID.
-	// The chan will be triggered when Trigger is called with
-	// the same ID.
-	Register(id uint64) <-chan interface{}
-	// Trigger triggers the waiting chans with the given ID.
-	Trigger(id uint64, x interface{})
-	IsRegistered(id uint64) bool
-}
-
-type list struct {
-	l sync.RWMutex
-	m map[uint64]chan interface{}
-}
-
-// New creates a Wait.
-func New() Wait {
-	return &list{m: make(map[uint64]chan interface{})}
-}
-
-func (w *list) Register(id uint64) <-chan interface{} {
-	w.l.Lock()
-	defer w.l.Unlock()
-	ch := w.m[id]
-	if ch == nil {
-		ch = make(chan interface{}, 1)
-		w.m[id] = ch
-	} else {
-		log.Panicf("dup id %x", id)
-	}
-	return ch
-}
-
-func (w *list) Trigger(id uint64, x interface{}) {
-	w.l.Lock()
-	ch := w.m[id]
-	delete(w.m, id)
-	w.l.Unlock()
-	if ch != nil {
-		ch <- x
-		close(ch)
-	}
-}
-
-func (w *list) IsRegistered(id uint64) bool {
-	w.l.RLock()
-	defer w.l.RUnlock()
-	_, ok := w.m[id]
-	return ok
-}
-
-type waitWithResponse struct {
-	ch <-chan interface{}
-}
-
-func NewWithResponse(ch <-chan interface{}) Wait {
-	return &waitWithResponse{ch: ch}
-}
-
-func (w *waitWithResponse) Register(id uint64) <-chan interface{} {
-	return w.ch
-}
-func (w *waitWithResponse) Trigger(id uint64, x interface{}) {}
-func (w *waitWithResponse) IsRegistered(id uint64) bool {
-	panic("waitWithResponse.IsRegistered() shouldn't be called")
-}
diff --git a/vendor/go.etcd.io/etcd/pkg/wait/wait_time.go b/vendor/go.etcd.io/etcd/pkg/wait/wait_time.go
deleted file mode 100644
index 297e48a..0000000
--- a/vendor/go.etcd.io/etcd/pkg/wait/wait_time.go
+++ /dev/null
@@ -1,66 +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 wait
-
-import "sync"
-
-type WaitTime interface {
-	// Wait returns a chan that waits on the given logical deadline.
-	// The chan will be triggered when Trigger is called with a
-	// deadline that is later than the one it is waiting for.
-	Wait(deadline uint64) <-chan struct{}
-	// Trigger triggers all the waiting chans with an earlier logical deadline.
-	Trigger(deadline uint64)
-}
-
-var closec chan struct{}
-
-func init() { closec = make(chan struct{}); close(closec) }
-
-type timeList struct {
-	l                   sync.Mutex
-	lastTriggerDeadline uint64
-	m                   map[uint64]chan struct{}
-}
-
-func NewTimeList() *timeList {
-	return &timeList{m: make(map[uint64]chan struct{})}
-}
-
-func (tl *timeList) Wait(deadline uint64) <-chan struct{} {
-	tl.l.Lock()
-	defer tl.l.Unlock()
-	if tl.lastTriggerDeadline >= deadline {
-		return closec
-	}
-	ch := tl.m[deadline]
-	if ch == nil {
-		ch = make(chan struct{})
-		tl.m[deadline] = ch
-	}
-	return ch
-}
-
-func (tl *timeList) Trigger(deadline uint64) {
-	tl.l.Lock()
-	defer tl.l.Unlock()
-	tl.lastTriggerDeadline = deadline
-	for t, ch := range tl.m {
-		if t <= deadline {
-			delete(tl.m, t)
-			close(ch)
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go
deleted file mode 100644
index 59dbe6b..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/auth_client_adapter.go
+++ /dev/null
@@ -1,93 +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 adapter
-
-import (
-	"context"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	grpc "google.golang.org/grpc"
-)
-
-type as2ac struct{ as pb.AuthServer }
-
-func AuthServerToAuthClient(as pb.AuthServer) pb.AuthClient {
-	return &as2ac{as}
-}
-
-func (s *as2ac) AuthEnable(ctx context.Context, in *pb.AuthEnableRequest, opts ...grpc.CallOption) (*pb.AuthEnableResponse, error) {
-	return s.as.AuthEnable(ctx, in)
-}
-
-func (s *as2ac) AuthDisable(ctx context.Context, in *pb.AuthDisableRequest, opts ...grpc.CallOption) (*pb.AuthDisableResponse, error) {
-	return s.as.AuthDisable(ctx, in)
-}
-
-func (s *as2ac) Authenticate(ctx context.Context, in *pb.AuthenticateRequest, opts ...grpc.CallOption) (*pb.AuthenticateResponse, error) {
-	return s.as.Authenticate(ctx, in)
-}
-
-func (s *as2ac) RoleAdd(ctx context.Context, in *pb.AuthRoleAddRequest, opts ...grpc.CallOption) (*pb.AuthRoleAddResponse, error) {
-	return s.as.RoleAdd(ctx, in)
-}
-
-func (s *as2ac) RoleDelete(ctx context.Context, in *pb.AuthRoleDeleteRequest, opts ...grpc.CallOption) (*pb.AuthRoleDeleteResponse, error) {
-	return s.as.RoleDelete(ctx, in)
-}
-
-func (s *as2ac) RoleGet(ctx context.Context, in *pb.AuthRoleGetRequest, opts ...grpc.CallOption) (*pb.AuthRoleGetResponse, error) {
-	return s.as.RoleGet(ctx, in)
-}
-
-func (s *as2ac) RoleList(ctx context.Context, in *pb.AuthRoleListRequest, opts ...grpc.CallOption) (*pb.AuthRoleListResponse, error) {
-	return s.as.RoleList(ctx, in)
-}
-
-func (s *as2ac) RoleRevokePermission(ctx context.Context, in *pb.AuthRoleRevokePermissionRequest, opts ...grpc.CallOption) (*pb.AuthRoleRevokePermissionResponse, error) {
-	return s.as.RoleRevokePermission(ctx, in)
-}
-
-func (s *as2ac) RoleGrantPermission(ctx context.Context, in *pb.AuthRoleGrantPermissionRequest, opts ...grpc.CallOption) (*pb.AuthRoleGrantPermissionResponse, error) {
-	return s.as.RoleGrantPermission(ctx, in)
-}
-
-func (s *as2ac) UserDelete(ctx context.Context, in *pb.AuthUserDeleteRequest, opts ...grpc.CallOption) (*pb.AuthUserDeleteResponse, error) {
-	return s.as.UserDelete(ctx, in)
-}
-
-func (s *as2ac) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (*pb.AuthUserAddResponse, error) {
-	return s.as.UserAdd(ctx, in)
-}
-
-func (s *as2ac) UserGet(ctx context.Context, in *pb.AuthUserGetRequest, opts ...grpc.CallOption) (*pb.AuthUserGetResponse, error) {
-	return s.as.UserGet(ctx, in)
-}
-
-func (s *as2ac) UserList(ctx context.Context, in *pb.AuthUserListRequest, opts ...grpc.CallOption) (*pb.AuthUserListResponse, error) {
-	return s.as.UserList(ctx, in)
-}
-
-func (s *as2ac) UserGrantRole(ctx context.Context, in *pb.AuthUserGrantRoleRequest, opts ...grpc.CallOption) (*pb.AuthUserGrantRoleResponse, error) {
-	return s.as.UserGrantRole(ctx, in)
-}
-
-func (s *as2ac) UserRevokeRole(ctx context.Context, in *pb.AuthUserRevokeRoleRequest, opts ...grpc.CallOption) (*pb.AuthUserRevokeRoleResponse, error) {
-	return s.as.UserRevokeRole(ctx, in)
-}
-
-func (s *as2ac) UserChangePassword(ctx context.Context, in *pb.AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*pb.AuthUserChangePasswordResponse, error) {
-	return s.as.UserChangePassword(ctx, in)
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/chan_stream.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/chan_stream.go
deleted file mode 100644
index 1af514b..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/chan_stream.go
+++ /dev/null
@@ -1,167 +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 adapter
-
-import (
-	"context"
-
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/codes"
-	"google.golang.org/grpc/metadata"
-	"google.golang.org/grpc/status"
-)
-
-// chanServerStream implements grpc.ServerStream with a chanStream
-type chanServerStream struct {
-	headerc  chan<- metadata.MD
-	trailerc chan<- metadata.MD
-	grpc.Stream
-
-	headers []metadata.MD
-}
-
-func (ss *chanServerStream) SendHeader(md metadata.MD) error {
-	if ss.headerc == nil {
-		return errAlreadySentHeader
-	}
-	outmd := make(map[string][]string)
-	for _, h := range append(ss.headers, md) {
-		for k, v := range h {
-			outmd[k] = v
-		}
-	}
-	select {
-	case ss.headerc <- outmd:
-		ss.headerc = nil
-		ss.headers = nil
-		return nil
-	case <-ss.Context().Done():
-	}
-	return ss.Context().Err()
-}
-
-func (ss *chanServerStream) SetHeader(md metadata.MD) error {
-	if ss.headerc == nil {
-		return errAlreadySentHeader
-	}
-	ss.headers = append(ss.headers, md)
-	return nil
-}
-
-func (ss *chanServerStream) SetTrailer(md metadata.MD) {
-	ss.trailerc <- md
-}
-
-// chanClientStream implements grpc.ClientStream with a chanStream
-type chanClientStream struct {
-	headerc  <-chan metadata.MD
-	trailerc <-chan metadata.MD
-	*chanStream
-}
-
-func (cs *chanClientStream) Header() (metadata.MD, error) {
-	select {
-	case md := <-cs.headerc:
-		return md, nil
-	case <-cs.Context().Done():
-	}
-	return nil, cs.Context().Err()
-}
-
-func (cs *chanClientStream) Trailer() metadata.MD {
-	select {
-	case md := <-cs.trailerc:
-		return md
-	case <-cs.Context().Done():
-		return nil
-	}
-}
-
-func (cs *chanClientStream) CloseSend() error {
-	close(cs.chanStream.sendc)
-	return nil
-}
-
-// chanStream implements grpc.Stream using channels
-type chanStream struct {
-	recvc  <-chan interface{}
-	sendc  chan<- interface{}
-	ctx    context.Context
-	cancel context.CancelFunc
-}
-
-func (s *chanStream) Context() context.Context { return s.ctx }
-
-func (s *chanStream) SendMsg(m interface{}) error {
-	select {
-	case s.sendc <- m:
-		if err, ok := m.(error); ok {
-			return err
-		}
-		return nil
-	case <-s.ctx.Done():
-	}
-	return s.ctx.Err()
-}
-
-func (s *chanStream) RecvMsg(m interface{}) error {
-	v := m.(*interface{})
-	for {
-		select {
-		case msg, ok := <-s.recvc:
-			if !ok {
-				return status.Error(codes.Canceled, "the client connection is closing")
-			}
-			if err, ok := msg.(error); ok {
-				return err
-			}
-			*v = msg
-			return nil
-		case <-s.ctx.Done():
-		}
-		if len(s.recvc) == 0 {
-			// prioritize any pending recv messages over canceled context
-			break
-		}
-	}
-	return s.ctx.Err()
-}
-
-func newPipeStream(ctx context.Context, ssHandler func(chanServerStream) error) chanClientStream {
-	// ch1 is buffered so server can send error on close
-	ch1, ch2 := make(chan interface{}, 1), make(chan interface{})
-	headerc, trailerc := make(chan metadata.MD, 1), make(chan metadata.MD, 1)
-
-	cctx, ccancel := context.WithCancel(ctx)
-	cli := &chanStream{recvc: ch1, sendc: ch2, ctx: cctx, cancel: ccancel}
-	cs := chanClientStream{headerc, trailerc, cli}
-
-	sctx, scancel := context.WithCancel(ctx)
-	srv := &chanStream{recvc: ch2, sendc: ch1, ctx: sctx, cancel: scancel}
-	ss := chanServerStream{headerc, trailerc, srv, nil}
-
-	go func() {
-		if err := ssHandler(ss); err != nil {
-			select {
-			case srv.sendc <- err:
-			case <-sctx.Done():
-			case <-cctx.Done():
-			}
-		}
-		scancel()
-		ccancel()
-	}()
-	return cs
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go
deleted file mode 100644
index 73a6fdf..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/cluster_client_adapter.go
+++ /dev/null
@@ -1,49 +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 adapter
-
-import (
-	"context"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type cls2clc struct{ cls pb.ClusterServer }
-
-func ClusterServerToClusterClient(cls pb.ClusterServer) pb.ClusterClient {
-	return &cls2clc{cls}
-}
-
-func (s *cls2clc) MemberList(ctx context.Context, r *pb.MemberListRequest, opts ...grpc.CallOption) (*pb.MemberListResponse, error) {
-	return s.cls.MemberList(ctx, r)
-}
-
-func (s *cls2clc) MemberAdd(ctx context.Context, r *pb.MemberAddRequest, opts ...grpc.CallOption) (*pb.MemberAddResponse, error) {
-	return s.cls.MemberAdd(ctx, r)
-}
-
-func (s *cls2clc) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest, opts ...grpc.CallOption) (*pb.MemberUpdateResponse, error) {
-	return s.cls.MemberUpdate(ctx, r)
-}
-
-func (s *cls2clc) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest, opts ...grpc.CallOption) (*pb.MemberRemoveResponse, error) {
-	return s.cls.MemberRemove(ctx, r)
-}
-
-func (s *cls2clc) MemberPromote(ctx context.Context, r *pb.MemberPromoteRequest, opts ...grpc.CallOption) (*pb.MemberPromoteResponse, error) {
-	return s.cls.MemberPromote(ctx, r)
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/doc.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/doc.go
deleted file mode 100644
index 7170be2..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/doc.go
+++ /dev/null
@@ -1,17 +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 adapter provides gRPC adapters between client and server
-// gRPC interfaces without needing to go through a gRPC connection.
-package adapter
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/election_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/election_client_adapter.go
deleted file mode 100644
index 4722be0..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/election_client_adapter.go
+++ /dev/null
@@ -1,80 +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 adapter
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/etcdserver/api/v3election/v3electionpb"
-
-	"google.golang.org/grpc"
-)
-
-type es2ec struct{ es v3electionpb.ElectionServer }
-
-func ElectionServerToElectionClient(es v3electionpb.ElectionServer) v3electionpb.ElectionClient {
-	return &es2ec{es}
-}
-
-func (s *es2ec) Campaign(ctx context.Context, r *v3electionpb.CampaignRequest, opts ...grpc.CallOption) (*v3electionpb.CampaignResponse, error) {
-	return s.es.Campaign(ctx, r)
-}
-
-func (s *es2ec) Proclaim(ctx context.Context, r *v3electionpb.ProclaimRequest, opts ...grpc.CallOption) (*v3electionpb.ProclaimResponse, error) {
-	return s.es.Proclaim(ctx, r)
-}
-
-func (s *es2ec) Leader(ctx context.Context, r *v3electionpb.LeaderRequest, opts ...grpc.CallOption) (*v3electionpb.LeaderResponse, error) {
-	return s.es.Leader(ctx, r)
-}
-
-func (s *es2ec) Resign(ctx context.Context, r *v3electionpb.ResignRequest, opts ...grpc.CallOption) (*v3electionpb.ResignResponse, error) {
-	return s.es.Resign(ctx, r)
-}
-
-func (s *es2ec) Observe(ctx context.Context, in *v3electionpb.LeaderRequest, opts ...grpc.CallOption) (v3electionpb.Election_ObserveClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.es.Observe(in, &es2ecServerStream{ss})
-	})
-	return &es2ecClientStream{cs}, nil
-}
-
-// es2ecClientStream implements Election_ObserveClient
-type es2ecClientStream struct{ chanClientStream }
-
-// es2ecServerStream implements Election_ObserveServer
-type es2ecServerStream struct{ chanServerStream }
-
-func (s *es2ecClientStream) Send(rr *v3electionpb.LeaderRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *es2ecClientStream) Recv() (*v3electionpb.LeaderResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*v3electionpb.LeaderResponse), nil
-}
-
-func (s *es2ecServerStream) Send(rr *v3electionpb.LeaderResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *es2ecServerStream) Recv() (*v3electionpb.LeaderRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*v3electionpb.LeaderRequest), nil
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/kv_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/kv_client_adapter.go
deleted file mode 100644
index b1a7820..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/kv_client_adapter.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 adapter
-
-import (
-	"context"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	grpc "google.golang.org/grpc"
-)
-
-type kvs2kvc struct{ kvs pb.KVServer }
-
-func KvServerToKvClient(kvs pb.KVServer) pb.KVClient {
-	return &kvs2kvc{kvs}
-}
-
-func (s *kvs2kvc) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (*pb.RangeResponse, error) {
-	return s.kvs.Range(ctx, in)
-}
-
-func (s *kvs2kvc) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (*pb.PutResponse, error) {
-	return s.kvs.Put(ctx, in)
-}
-
-func (s *kvs2kvc) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (*pb.DeleteRangeResponse, error) {
-	return s.kvs.DeleteRange(ctx, in)
-}
-
-func (s *kvs2kvc) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (*pb.TxnResponse, error) {
-	return s.kvs.Txn(ctx, in)
-}
-
-func (s *kvs2kvc) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (*pb.CompactionResponse, error) {
-	return s.kvs.Compact(ctx, in)
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go
deleted file mode 100644
index a58408f..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lease_client_adapter.go
+++ /dev/null
@@ -1,82 +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 adapter
-
-import (
-	"context"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type ls2lc struct {
-	leaseServer pb.LeaseServer
-}
-
-func LeaseServerToLeaseClient(ls pb.LeaseServer) pb.LeaseClient {
-	return &ls2lc{ls}
-}
-
-func (c *ls2lc) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (*pb.LeaseGrantResponse, error) {
-	return c.leaseServer.LeaseGrant(ctx, in)
-}
-
-func (c *ls2lc) LeaseRevoke(ctx context.Context, in *pb.LeaseRevokeRequest, opts ...grpc.CallOption) (*pb.LeaseRevokeResponse, error) {
-	return c.leaseServer.LeaseRevoke(ctx, in)
-}
-
-func (c *ls2lc) LeaseKeepAlive(ctx context.Context, opts ...grpc.CallOption) (pb.Lease_LeaseKeepAliveClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return c.leaseServer.LeaseKeepAlive(&ls2lcServerStream{ss})
-	})
-	return &ls2lcClientStream{cs}, nil
-}
-
-func (c *ls2lc) LeaseTimeToLive(ctx context.Context, in *pb.LeaseTimeToLiveRequest, opts ...grpc.CallOption) (*pb.LeaseTimeToLiveResponse, error) {
-	return c.leaseServer.LeaseTimeToLive(ctx, in)
-}
-
-func (c *ls2lc) LeaseLeases(ctx context.Context, in *pb.LeaseLeasesRequest, opts ...grpc.CallOption) (*pb.LeaseLeasesResponse, error) {
-	return c.leaseServer.LeaseLeases(ctx, in)
-}
-
-// ls2lcClientStream implements Lease_LeaseKeepAliveClient
-type ls2lcClientStream struct{ chanClientStream }
-
-// ls2lcServerStream implements Lease_LeaseKeepAliveServer
-type ls2lcServerStream struct{ chanServerStream }
-
-func (s *ls2lcClientStream) Send(rr *pb.LeaseKeepAliveRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *ls2lcClientStream) Recv() (*pb.LeaseKeepAliveResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.LeaseKeepAliveResponse), nil
-}
-
-func (s *ls2lcServerStream) Send(rr *pb.LeaseKeepAliveResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *ls2lcServerStream) Recv() (*pb.LeaseKeepAliveRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.LeaseKeepAliveRequest), nil
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go
deleted file mode 100644
index 65b5641..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/lock_client_adapter.go
+++ /dev/null
@@ -1,37 +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 adapter
-
-import (
-	"context"
-
-	"go.etcd.io/etcd/etcdserver/api/v3lock/v3lockpb"
-
-	"google.golang.org/grpc"
-)
-
-type ls2lsc struct{ ls v3lockpb.LockServer }
-
-func LockServerToLockClient(ls v3lockpb.LockServer) v3lockpb.LockClient {
-	return &ls2lsc{ls}
-}
-
-func (s *ls2lsc) Lock(ctx context.Context, r *v3lockpb.LockRequest, opts ...grpc.CallOption) (*v3lockpb.LockResponse, error) {
-	return s.ls.Lock(ctx, r)
-}
-
-func (s *ls2lsc) Unlock(ctx context.Context, r *v3lockpb.UnlockRequest, opts ...grpc.CallOption) (*v3lockpb.UnlockResponse, error) {
-	return s.ls.Unlock(ctx, r)
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go
deleted file mode 100644
index 4a8781b..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/maintenance_client_adapter.go
+++ /dev/null
@@ -1,88 +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 adapter
-
-import (
-	"context"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-
-	"google.golang.org/grpc"
-)
-
-type mts2mtc struct{ mts pb.MaintenanceServer }
-
-func MaintenanceServerToMaintenanceClient(mts pb.MaintenanceServer) pb.MaintenanceClient {
-	return &mts2mtc{mts}
-}
-
-func (s *mts2mtc) Alarm(ctx context.Context, r *pb.AlarmRequest, opts ...grpc.CallOption) (*pb.AlarmResponse, error) {
-	return s.mts.Alarm(ctx, r)
-}
-
-func (s *mts2mtc) Status(ctx context.Context, r *pb.StatusRequest, opts ...grpc.CallOption) (*pb.StatusResponse, error) {
-	return s.mts.Status(ctx, r)
-}
-
-func (s *mts2mtc) Defragment(ctx context.Context, dr *pb.DefragmentRequest, opts ...grpc.CallOption) (*pb.DefragmentResponse, error) {
-	return s.mts.Defragment(ctx, dr)
-}
-
-func (s *mts2mtc) Hash(ctx context.Context, r *pb.HashRequest, opts ...grpc.CallOption) (*pb.HashResponse, error) {
-	return s.mts.Hash(ctx, r)
-}
-
-func (s *mts2mtc) HashKV(ctx context.Context, r *pb.HashKVRequest, opts ...grpc.CallOption) (*pb.HashKVResponse, error) {
-	return s.mts.HashKV(ctx, r)
-}
-
-func (s *mts2mtc) MoveLeader(ctx context.Context, r *pb.MoveLeaderRequest, opts ...grpc.CallOption) (*pb.MoveLeaderResponse, error) {
-	return s.mts.MoveLeader(ctx, r)
-}
-
-func (s *mts2mtc) Snapshot(ctx context.Context, in *pb.SnapshotRequest, opts ...grpc.CallOption) (pb.Maintenance_SnapshotClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.mts.Snapshot(in, &ss2scServerStream{ss})
-	})
-	return &ss2scClientStream{cs}, nil
-}
-
-// ss2scClientStream implements Maintenance_SnapshotClient
-type ss2scClientStream struct{ chanClientStream }
-
-// ss2scServerStream implements Maintenance_SnapshotServer
-type ss2scServerStream struct{ chanServerStream }
-
-func (s *ss2scClientStream) Send(rr *pb.SnapshotRequest) error {
-	return s.SendMsg(rr)
-}
-func (s *ss2scClientStream) Recv() (*pb.SnapshotResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.SnapshotResponse), nil
-}
-
-func (s *ss2scServerStream) Send(rr *pb.SnapshotResponse) error {
-	return s.SendMsg(rr)
-}
-func (s *ss2scServerStream) Recv() (*pb.SnapshotRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.SnapshotRequest), nil
-}
diff --git a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go b/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go
deleted file mode 100644
index 2f629cc..0000000
--- a/vendor/go.etcd.io/etcd/proxy/grpcproxy/adapter/watch_client_adapter.go
+++ /dev/null
@@ -1,66 +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 adapter
-
-import (
-	"context"
-	"errors"
-
-	pb "go.etcd.io/etcd/etcdserver/etcdserverpb"
-	"google.golang.org/grpc"
-)
-
-var errAlreadySentHeader = errors.New("adapter: already sent header")
-
-type ws2wc struct{ wserv pb.WatchServer }
-
-func WatchServerToWatchClient(wserv pb.WatchServer) pb.WatchClient {
-	return &ws2wc{wserv}
-}
-
-func (s *ws2wc) Watch(ctx context.Context, opts ...grpc.CallOption) (pb.Watch_WatchClient, error) {
-	cs := newPipeStream(ctx, func(ss chanServerStream) error {
-		return s.wserv.Watch(&ws2wcServerStream{ss})
-	})
-	return &ws2wcClientStream{cs}, nil
-}
-
-// ws2wcClientStream implements Watch_WatchClient
-type ws2wcClientStream struct{ chanClientStream }
-
-// ws2wcServerStream implements Watch_WatchServer
-type ws2wcServerStream struct{ chanServerStream }
-
-func (s *ws2wcClientStream) Send(wr *pb.WatchRequest) error {
-	return s.SendMsg(wr)
-}
-func (s *ws2wcClientStream) Recv() (*pb.WatchResponse, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.WatchResponse), nil
-}
-
-func (s *ws2wcServerStream) Send(wr *pb.WatchResponse) error {
-	return s.SendMsg(wr)
-}
-func (s *ws2wcServerStream) Recv() (*pb.WatchRequest, error) {
-	var v interface{}
-	if err := s.RecvMsg(&v); err != nil {
-		return nil, err
-	}
-	return v.(*pb.WatchRequest), nil
-}
diff --git a/vendor/go.etcd.io/etcd/raft/OWNERS b/vendor/go.etcd.io/etcd/raft/OWNERS
deleted file mode 100644
index ab78106..0000000
--- a/vendor/go.etcd.io/etcd/raft/OWNERS
+++ /dev/null
@@ -1,19 +0,0 @@
-approvers:
-- heyitsanthony
-- philips
-- fanminshi
-- gyuho
-- mitake
-- jpbetz
-- xiang90
-- bdarnell
-reviewers:
-- heyitsanthony
-- philips
-- fanminshi
-- gyuho
-- mitake
-- jpbetz
-- xiang90
-- bdarnell
-- tschottdorf
diff --git a/vendor/go.etcd.io/etcd/raft/README.md b/vendor/go.etcd.io/etcd/raft/README.md
deleted file mode 100644
index 83cf040..0000000
--- a/vendor/go.etcd.io/etcd/raft/README.md
+++ /dev/null
@@ -1,197 +0,0 @@
-# Raft library
-
-Raft is a protocol with which a cluster of nodes can maintain a replicated state machine.
-The state machine is kept in sync through the use of a replicated log.
-For more details on Raft, see "In Search of an Understandable Consensus Algorithm"
-(https://raft.github.io/raft.pdf) by Diego Ongaro and John Ousterhout.
-
-This Raft library is stable and feature complete. As of 2016, it is **the most widely used** Raft library in production, serving tens of thousands clusters each day. It powers distributed systems such as etcd, Kubernetes, Docker Swarm, Cloud Foundry Diego, CockroachDB, TiDB, Project Calico, Flannel, and more.
-
-Most Raft implementations have a monolithic design, including storage handling, messaging serialization, and network transport. This library instead follows a minimalistic design philosophy by only implementing the core raft algorithm. This minimalism buys flexibility, determinism, and performance.
-
-To keep the codebase small as well as provide flexibility, the library only implements the Raft algorithm; both network and disk IO are left to the user. Library users must implement their own transportation layer for message passing between Raft peers over the wire. Similarly, users must implement their own storage layer to persist the Raft log and state.
-
-In order to easily test the Raft library, its behavior should be deterministic. To achieve this determinism, the library models Raft as a state machine.  The state machine takes a `Message` as input. A message can either be a local timer update or a network message sent from a remote peer. The state machine's output is a 3-tuple `{[]Messages, []LogEntries, NextState}` consisting of an array of `Messages`, `log entries`, and `Raft state changes`. For state machines with the same state, the same state machine input should always generate the same state machine output.
-
-A simple example application, _raftexample_, is also available to help illustrate how to use this package in practice: https://github.com/etcd-io/etcd/tree/master/contrib/raftexample
-
-# Features
-
-This raft implementation is a full feature implementation of Raft protocol. Features includes:
-
-- Leader election
-- Log replication
-- Log compaction
-- Membership changes
-- Leadership transfer extension
-- Efficient linearizable read-only queries served by both the leader and followers
-  - leader checks with quorum and bypasses Raft log before processing read-only queries
-  - followers asks leader to get a safe read index before processing read-only queries
-- More efficient lease-based linearizable read-only queries served by both the leader and followers
-  - leader bypasses Raft log and processing read-only queries locally
-  - followers asks leader to get a safe read index before processing read-only queries
-  - this approach relies on the clock of the all the machines in raft group
-
-This raft implementation also includes a few optional enhancements:
-
-- Optimistic pipelining to reduce log replication latency
-- Flow control for log replication
-- Batching Raft messages to reduce synchronized network I/O calls
-- Batching log entries to reduce disk synchronized I/O
-- Writing to leader's disk in parallel
-- Internal proposal redirection from followers to leader
-- Automatic stepping down when the leader loses quorum
-- Protection against unbounded log growth when quorum is lost
-
-## Notable Users
-
-- [cockroachdb](https://github.com/cockroachdb/cockroach) A Scalable, Survivable, Strongly-Consistent SQL Database
-- [dgraph](https://github.com/dgraph-io/dgraph) A Scalable, Distributed, Low Latency, High Throughput Graph Database
-- [etcd](https://github.com/etcd-io/etcd) A distributed reliable key-value store
-- [tikv](https://github.com/pingcap/tikv) A Distributed transactional key value database powered by Rust and Raft
-- [swarmkit](https://github.com/docker/swarmkit) A toolkit for orchestrating distributed systems at any scale.
-- [chain core](https://github.com/chain/chain) Software for operating permissioned, multi-asset blockchain networks
-
-## Usage
-
-The primary object in raft is a Node. Either start a Node from scratch using raft.StartNode or start a Node from some initial state using raft.RestartNode.
-
-To start a three-node cluster
-```go
-  storage := raft.NewMemoryStorage()
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-  // Set peer list to the other nodes in the cluster.
-  // Note that they need to be started separately as well.
-  n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}})
-```
-
-Start a single node cluster, like so:
-```go
-  // Create storage and config as shown above.
-  // Set peer list to itself, so this node can become the leader of this single-node cluster.
-  peers := []raft.Peer{{ID: 0x01}}
-  n := raft.StartNode(c, peers)
-```
-
-To allow a new node to join this cluster, do not pass in any peers. First, add the node to the existing cluster by calling `ProposeConfChange` on any existing node inside the cluster. Then, start the node with an empty peer list, like so:
-```go
-  // Create storage and config as shown above.
-  n := raft.StartNode(c, nil)
-```
-
-To restart a node from previous state:
-```go
-  storage := raft.NewMemoryStorage()
-
-  // Recover the in-memory storage from persistent snapshot, state and entries.
-  storage.ApplySnapshot(snapshot)
-  storage.SetHardState(state)
-  storage.Append(entries)
-
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-
-  // Restart raft without peer information.
-  // Peer information is already included in the storage.
-  n := raft.RestartNode(c)
-```
-
-After creating a Node, the user has a few responsibilities:
-
-First, read from the Node.Ready() channel and process the updates it contains. These steps may be performed in parallel, except as noted in step 2.
-
-1. Write Entries, HardState and Snapshot to persistent storage in order, i.e. Entries first, then HardState and Snapshot if they are not empty. If persistent storage supports atomic writes then all of them can be written together. Note that when writing an Entry with Index i, any previously-persisted entries with Index >= i must be discarded.
-
-2. Send all Messages to the nodes named in the To field. It is important that no messages be sent until the latest HardState has been persisted to disk, and all Entries written by any previous Ready batch (Messages may be sent while entries from the same batch are being persisted). To reduce the I/O latency, an optimization can be applied to make leader write to disk in parallel with its followers (as explained at section 10.2.1 in Raft thesis). If any Message has type MsgSnap, call Node.ReportSnapshot() after it has been sent (these messages may be large). Note: Marshalling messages is not thread-safe; it is important to make sure that no new entries are persisted while marshalling. The easiest way to achieve this is to serialise the messages directly inside the main raft loop.
-
-3. Apply Snapshot (if any) and CommittedEntries to the state machine. If any committed Entry has Type EntryConfChange, call Node.ApplyConfChange() to apply it to the node. The configuration change may be cancelled at this point by setting the NodeID field to zero before calling ApplyConfChange (but ApplyConfChange must be called one way or the other, and the decision to cancel must be based solely on the state machine and not external information such as the observed health of the node).
-
-4. Call Node.Advance() to signal readiness for the next batch of updates. This may be done at any time after step 1, although all updates must be processed in the order they were returned by Ready.
-
-Second, all persisted log entries must be made available via an implementation of the Storage interface. The provided MemoryStorage type can be used for this (if repopulating its state upon a restart), or a custom disk-backed implementation can be supplied.
-
-Third, after receiving a message from another node, pass it to Node.Step:
-
-```go
-	func recvRaftRPC(ctx context.Context, m raftpb.Message) {
-		n.Step(ctx, m)
-	}
-```
-
-Finally, call `Node.Tick()` at regular intervals (probably via a `time.Ticker`). Raft has two important timeouts: heartbeat and the election timeout. However, internally to the raft package time is represented by an abstract "tick".
-
-The total state machine handling loop will look something like this:
-
-```go
-  for {
-    select {
-    case <-s.Ticker:
-      n.Tick()
-    case rd := <-s.Node.Ready():
-      saveToStorage(rd.HardState, rd.Entries, rd.Snapshot)
-      send(rd.Messages)
-      if !raft.IsEmptySnap(rd.Snapshot) {
-        processSnapshot(rd.Snapshot)
-      }
-      for _, entry := range rd.CommittedEntries {
-        process(entry)
-        if entry.Type == raftpb.EntryConfChange {
-          var cc raftpb.ConfChange
-          cc.Unmarshal(entry.Data)
-          s.Node.ApplyConfChange(cc)
-        }
-      }
-      s.Node.Advance()
-    case <-s.done:
-      return
-    }
-  }
-```
-
-To propose changes to the state machine from the node to take application data, serialize it into a byte slice and call:
-
-```go
-	n.Propose(ctx, data)
-```
-
-If the proposal is committed, data will appear in committed entries with type raftpb.EntryNormal. There is no guarantee that a proposed command will be committed; the command may have to be reproposed after a timeout.
-
-To add or remove node in a cluster, build ConfChange struct 'cc' and call:
-
-```go
-	n.ProposeConfChange(ctx, cc)
-```
-
-After config change is committed, some committed entry with type raftpb.EntryConfChange will be returned. This must be applied to node through:
-
-```go
-	var cc raftpb.ConfChange
-	cc.Unmarshal(data)
-	n.ApplyConfChange(cc)
-```
-
-Note: An ID represents a unique node in a cluster for all time. A
-given ID MUST be used only once even if the old node has been removed.
-This means that for example IP addresses make poor node IDs since they
-may be reused. Node IDs must be non-zero.
-
-## Implementation notes
-
-This implementation is up to date with the final Raft thesis (https://github.com/ongardie/dissertation/blob/master/stanford.pdf), although this implementation of the membership change protocol differs somewhat from that described in chapter 4. The key invariant that membership changes happen one node at a time is preserved, but in our implementation the membership change takes effect when its entry is applied, not when it is added to the log (so the entry is committed under the old membership instead of the new). This is equivalent in terms of safety, since the old and new configurations are guaranteed to overlap.
-
-To ensure there is no attempt to commit two membership changes at once by matching log positions (which would be unsafe since they should have different quorum requirements), any proposed membership change is simply disallowed while any uncommitted change appears in the leader's log.
-
-This approach introduces a problem when removing a member from a two-member cluster: If one of the members dies before the other one receives the commit of the confchange entry, then the member cannot be removed any more since the cluster cannot make progress. For this reason it is highly recommended to use three or more nodes in every cluster.
diff --git a/vendor/go.etcd.io/etcd/raft/bootstrap.go b/vendor/go.etcd.io/etcd/raft/bootstrap.go
deleted file mode 100644
index bd82b20..0000000
--- a/vendor/go.etcd.io/etcd/raft/bootstrap.go
+++ /dev/null
@@ -1,80 +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 raft
-
-import (
-	"errors"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-// Bootstrap initializes the RawNode for first use by appending configuration
-// changes for the supplied peers. This method returns an error if the Storage
-// is nonempty.
-//
-// It is recommended that instead of calling this method, applications bootstrap
-// their state manually by setting up a Storage that has a first index > 1 and
-// which stores the desired ConfState as its InitialState.
-func (rn *RawNode) Bootstrap(peers []Peer) error {
-	if len(peers) == 0 {
-		return errors.New("must provide at least one peer to Bootstrap")
-	}
-	lastIndex, err := rn.raft.raftLog.storage.LastIndex()
-	if err != nil {
-		return err
-	}
-
-	if lastIndex != 0 {
-		return errors.New("can't bootstrap a nonempty Storage")
-	}
-
-	// We've faked out initial entries above, but nothing has been
-	// persisted. Start with an empty HardState (thus the first Ready will
-	// emit a HardState update for the app to persist).
-	rn.prevHardSt = emptyState
-
-	// TODO(tbg): remove StartNode and give the application the right tools to
-	// bootstrap the initial membership in a cleaner way.
-	rn.raft.becomeFollower(1, None)
-	ents := make([]pb.Entry, len(peers))
-	for i, peer := range peers {
-		cc := pb.ConfChange{Type: pb.ConfChangeAddNode, NodeID: peer.ID, Context: peer.Context}
-		data, err := cc.Marshal()
-		if err != nil {
-			return err
-		}
-
-		ents[i] = pb.Entry{Type: pb.EntryConfChange, Term: 1, Index: uint64(i + 1), Data: data}
-	}
-	rn.raft.raftLog.append(ents...)
-
-	// Now apply them, mainly so that the application can call Campaign
-	// immediately after StartNode in tests. Note that these nodes will
-	// be added to raft twice: here and when the application's Ready
-	// loop calls ApplyConfChange. The calls to addNode must come after
-	// all calls to raftLog.append so progress.next is set after these
-	// bootstrapping entries (it is an error if we try to append these
-	// entries since they have already been committed).
-	// We do not set raftLog.applied so the application will be able
-	// to observe all conf changes via Ready.CommittedEntries.
-	//
-	// TODO(bdarnell): These entries are still unstable; do we need to preserve
-	// the invariant that committed < unstable?
-	rn.raft.raftLog.committed = uint64(len(ents))
-	for _, peer := range peers {
-		rn.raft.applyConfChange(pb.ConfChange{NodeID: peer.ID, Type: pb.ConfChangeAddNode}.AsV2())
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/raft/confchange/confchange.go b/vendor/go.etcd.io/etcd/raft/confchange/confchange.go
deleted file mode 100644
index a0dc486..0000000
--- a/vendor/go.etcd.io/etcd/raft/confchange/confchange.go
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright 2019 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 confchange
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"go.etcd.io/etcd/raft/quorum"
-	pb "go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/raft/tracker"
-)
-
-// Changer facilitates configuration changes. It exposes methods to handle
-// simple and joint consensus while performing the proper validation that allows
-// refusing invalid configuration changes before they affect the active
-// configuration.
-type Changer struct {
-	Tracker   tracker.ProgressTracker
-	LastIndex uint64
-}
-
-// EnterJoint verifies that the outgoing (=right) majority config of the joint
-// config is empty and initializes it with a copy of the incoming (=left)
-// majority config. That is, it transitions from
-//
-//     (1 2 3)&&()
-// to
-//     (1 2 3)&&(1 2 3).
-//
-// The supplied changes are then applied to the incoming majority config,
-// resulting in a joint configuration that in terms of the Raft thesis[1]
-// (Section 4.3) corresponds to `C_{new,old}`.
-//
-// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
-func (c Changer) EnterJoint(autoLeave bool, ccs ...pb.ConfChangeSingle) (tracker.Config, tracker.ProgressMap, error) {
-	cfg, prs, err := c.checkAndCopy()
-	if err != nil {
-		return c.err(err)
-	}
-	if joint(cfg) {
-		err := errors.New("config is already joint")
-		return c.err(err)
-	}
-	if len(incoming(cfg.Voters)) == 0 {
-		// We allow adding nodes to an empty config for convenience (testing and
-		// bootstrap), but you can't enter a joint state.
-		err := errors.New("can't make a zero-voter config joint")
-		return c.err(err)
-	}
-	// Clear the outgoing config.
-	*outgoingPtr(&cfg.Voters) = quorum.MajorityConfig{}
-	// Copy incoming to outgoing.
-	for id := range incoming(cfg.Voters) {
-		outgoing(cfg.Voters)[id] = struct{}{}
-	}
-
-	if err := c.apply(&cfg, prs, ccs...); err != nil {
-		return c.err(err)
-	}
-	cfg.AutoLeave = autoLeave
-	return checkAndReturn(cfg, prs)
-}
-
-// LeaveJoint transitions out of a joint configuration. It is an error to call
-// this method if the configuration is not joint, i.e. if the outgoing majority
-// config Voters[1] is empty.
-//
-// The outgoing majority config of the joint configuration will be removed,
-// that is, the incoming config is promoted as the sole decision maker. In the
-// notation of the Raft thesis[1] (Section 4.3), this method transitions from
-// `C_{new,old}` into `C_new`.
-//
-// At the same time, any staged learners (LearnersNext) the addition of which
-// was held back by an overlapping voter in the former outgoing config will be
-// inserted into Learners.
-//
-// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
-func (c Changer) LeaveJoint() (tracker.Config, tracker.ProgressMap, error) {
-	cfg, prs, err := c.checkAndCopy()
-	if err != nil {
-		return c.err(err)
-	}
-	if !joint(cfg) {
-		err := errors.New("can't leave a non-joint config")
-		return c.err(err)
-	}
-	if len(outgoing(cfg.Voters)) == 0 {
-		err := fmt.Errorf("configuration is not joint: %v", cfg)
-		return c.err(err)
-	}
-	for id := range cfg.LearnersNext {
-		nilAwareAdd(&cfg.Learners, id)
-		prs[id].IsLearner = true
-	}
-	cfg.LearnersNext = nil
-
-	for id := range outgoing(cfg.Voters) {
-		_, isVoter := incoming(cfg.Voters)[id]
-		_, isLearner := cfg.Learners[id]
-
-		if !isVoter && !isLearner {
-			delete(prs, id)
-		}
-	}
-	*outgoingPtr(&cfg.Voters) = nil
-	cfg.AutoLeave = false
-
-	return checkAndReturn(cfg, prs)
-}
-
-// Simple carries out a series of configuration changes that (in aggregate)
-// mutates the incoming majority config Voters[0] by at most one. This method
-// will return an error if that is not the case, if the resulting quorum is
-// zero, or if the configuration is in a joint state (i.e. if there is an
-// outgoing configuration).
-func (c Changer) Simple(ccs ...pb.ConfChangeSingle) (tracker.Config, tracker.ProgressMap, error) {
-	cfg, prs, err := c.checkAndCopy()
-	if err != nil {
-		return c.err(err)
-	}
-	if joint(cfg) {
-		err := errors.New("can't apply simple config change in joint config")
-		return c.err(err)
-	}
-	if err := c.apply(&cfg, prs, ccs...); err != nil {
-		return c.err(err)
-	}
-	if n := symdiff(incoming(c.Tracker.Voters), incoming(cfg.Voters)); n > 1 {
-		return tracker.Config{}, nil, errors.New("more than one voter changed without entering joint config")
-	}
-	if err := checkInvariants(cfg, prs); err != nil {
-		return tracker.Config{}, tracker.ProgressMap{}, nil
-	}
-
-	return checkAndReturn(cfg, prs)
-}
-
-// apply a change to the configuration. By convention, changes to voters are
-// always made to the incoming majority config Voters[0]. Voters[1] is either
-// empty or preserves the outgoing majority configuration while in a joint state.
-func (c Changer) apply(cfg *tracker.Config, prs tracker.ProgressMap, ccs ...pb.ConfChangeSingle) error {
-	for _, cc := range ccs {
-		if cc.NodeID == 0 {
-			// etcd replaces the NodeID with zero if it decides (downstream of
-			// raft) to not apply a change, so we have to have explicit code
-			// here to ignore these.
-			continue
-		}
-		switch cc.Type {
-		case pb.ConfChangeAddNode:
-			c.makeVoter(cfg, prs, cc.NodeID)
-		case pb.ConfChangeAddLearnerNode:
-			c.makeLearner(cfg, prs, cc.NodeID)
-		case pb.ConfChangeRemoveNode:
-			c.remove(cfg, prs, cc.NodeID)
-		case pb.ConfChangeUpdateNode:
-		default:
-			return fmt.Errorf("unexpected conf type %d", cc.Type)
-		}
-	}
-	if len(incoming(cfg.Voters)) == 0 {
-		return errors.New("removed all voters")
-	}
-	return nil
-}
-
-// makeVoter adds or promotes the given ID to be a voter in the incoming
-// majority config.
-func (c Changer) makeVoter(cfg *tracker.Config, prs tracker.ProgressMap, id uint64) {
-	pr := prs[id]
-	if pr == nil {
-		c.initProgress(cfg, prs, id, false /* isLearner */)
-		return
-	}
-
-	pr.IsLearner = false
-	nilAwareDelete(&cfg.Learners, id)
-	nilAwareDelete(&cfg.LearnersNext, id)
-	incoming(cfg.Voters)[id] = struct{}{}
-	return
-}
-
-// makeLearner makes the given ID a learner or stages it to be a learner once
-// an active joint configuration is exited.
-//
-// The former happens when the peer is not a part of the outgoing config, in
-// which case we either add a new learner or demote a voter in the incoming
-// config.
-//
-// The latter case occurs when the configuration is joint and the peer is a
-// voter in the outgoing config. In that case, we do not want to add the peer
-// as a learner because then we'd have to track a peer as a voter and learner
-// simultaneously. Instead, we add the learner to LearnersNext, so that it will
-// be added to Learners the moment the outgoing config is removed by
-// LeaveJoint().
-func (c Changer) makeLearner(cfg *tracker.Config, prs tracker.ProgressMap, id uint64) {
-	pr := prs[id]
-	if pr == nil {
-		c.initProgress(cfg, prs, id, true /* isLearner */)
-		return
-	}
-	if pr.IsLearner {
-		return
-	}
-	// Remove any existing voter in the incoming config...
-	c.remove(cfg, prs, id)
-	// ... but save the Progress.
-	prs[id] = pr
-	// Use LearnersNext if we can't add the learner to Learners directly, i.e.
-	// if the peer is still tracked as a voter in the outgoing config. It will
-	// be turned into a learner in LeaveJoint().
-	//
-	// Otherwise, add a regular learner right away.
-	if _, onRight := outgoing(cfg.Voters)[id]; onRight {
-		nilAwareAdd(&cfg.LearnersNext, id)
-	} else {
-		pr.IsLearner = true
-		nilAwareAdd(&cfg.Learners, id)
-	}
-}
-
-// remove this peer as a voter or learner from the incoming config.
-func (c Changer) remove(cfg *tracker.Config, prs tracker.ProgressMap, id uint64) {
-	if _, ok := prs[id]; !ok {
-		return
-	}
-
-	delete(incoming(cfg.Voters), id)
-	nilAwareDelete(&cfg.Learners, id)
-	nilAwareDelete(&cfg.LearnersNext, id)
-
-	// If the peer is still a voter in the outgoing config, keep the Progress.
-	if _, onRight := outgoing(cfg.Voters)[id]; !onRight {
-		delete(prs, id)
-	}
-}
-
-// initProgress initializes a new progress for the given node or learner.
-func (c Changer) initProgress(cfg *tracker.Config, prs tracker.ProgressMap, id uint64, isLearner bool) {
-	if !isLearner {
-		incoming(cfg.Voters)[id] = struct{}{}
-	} else {
-		nilAwareAdd(&cfg.Learners, id)
-	}
-	prs[id] = &tracker.Progress{
-		// Initializing the Progress with the last index means that the follower
-		// can be probed (with the last index).
-		//
-		// TODO(tbg): seems awfully optimistic. Using the first index would be
-		// better. The general expectation here is that the follower has no log
-		// at all (and will thus likely need a snapshot), though the app may
-		// have applied a snapshot out of band before adding the replica (thus
-		// making the first index the better choice).
-		Next:      c.LastIndex,
-		Match:     0,
-		Inflights: tracker.NewInflights(c.Tracker.MaxInflight),
-		IsLearner: isLearner,
-		// When a node is first added, we should mark it as recently active.
-		// Otherwise, CheckQuorum may cause us to step down if it is invoked
-		// before the added node has had a chance to communicate with us.
-		RecentActive: true,
-	}
-}
-
-// checkInvariants makes sure that the config and progress are compatible with
-// each other. This is used to check both what the Changer is initialized with,
-// as well as what it returns.
-func checkInvariants(cfg tracker.Config, prs tracker.ProgressMap) error {
-	// NB: intentionally allow the empty config. In production we'll never see a
-	// non-empty config (we prevent it from being created) but we will need to
-	// be able to *create* an initial config, for example during bootstrap (or
-	// during tests). Instead of having to hand-code this, we allow
-	// transitioning from an empty config into any other legal and non-empty
-	// config.
-	for _, ids := range []map[uint64]struct{}{
-		cfg.Voters.IDs(),
-		cfg.Learners,
-		cfg.LearnersNext,
-	} {
-		for id := range ids {
-			if _, ok := prs[id]; !ok {
-				return fmt.Errorf("no progress for %d", id)
-			}
-		}
-	}
-
-	// Any staged learner was staged because it could not be directly added due
-	// to a conflicting voter in the outgoing config.
-	for id := range cfg.LearnersNext {
-		if _, ok := outgoing(cfg.Voters)[id]; !ok {
-			return fmt.Errorf("%d is in LearnersNext, but not Voters[1]", id)
-		}
-		if prs[id].IsLearner {
-			return fmt.Errorf("%d is in LearnersNext, but is already marked as learner", id)
-		}
-	}
-	// Conversely Learners and Voters doesn't intersect at all.
-	for id := range cfg.Learners {
-		if _, ok := outgoing(cfg.Voters)[id]; ok {
-			return fmt.Errorf("%d is in Learners and Voters[1]", id)
-		}
-		if _, ok := incoming(cfg.Voters)[id]; ok {
-			return fmt.Errorf("%d is in Learners and Voters[0]", id)
-		}
-		if !prs[id].IsLearner {
-			return fmt.Errorf("%d is in Learners, but is not marked as learner", id)
-		}
-	}
-
-	if !joint(cfg) {
-		// We enforce that empty maps are nil instead of zero.
-		if outgoing(cfg.Voters) != nil {
-			return fmt.Errorf("Voters[1] must be nil when not joint")
-		}
-		if cfg.LearnersNext != nil {
-			return fmt.Errorf("LearnersNext must be nil when not joint")
-		}
-		if cfg.AutoLeave {
-			return fmt.Errorf("AutoLeave must be false when not joint")
-		}
-	}
-
-	return nil
-}
-
-// checkAndCopy copies the tracker's config and progress map (deeply enough for
-// the purposes of the Changer) and returns those copies. It returns an error
-// if checkInvariants does.
-func (c Changer) checkAndCopy() (tracker.Config, tracker.ProgressMap, error) {
-	cfg := c.Tracker.Config.Clone()
-	prs := tracker.ProgressMap{}
-
-	for id, pr := range c.Tracker.Progress {
-		// A shallow copy is enough because we only mutate the Learner field.
-		ppr := *pr
-		prs[id] = &ppr
-	}
-	return checkAndReturn(cfg, prs)
-}
-
-// checkAndReturn calls checkInvariants on the input and returns either the
-// resulting error or the input.
-func checkAndReturn(cfg tracker.Config, prs tracker.ProgressMap) (tracker.Config, tracker.ProgressMap, error) {
-	if err := checkInvariants(cfg, prs); err != nil {
-		return tracker.Config{}, tracker.ProgressMap{}, err
-	}
-	return cfg, prs, nil
-}
-
-// err returns zero values and an error.
-func (c Changer) err(err error) (tracker.Config, tracker.ProgressMap, error) {
-	return tracker.Config{}, nil, err
-}
-
-// nilAwareAdd populates a map entry, creating the map if necessary.
-func nilAwareAdd(m *map[uint64]struct{}, id uint64) {
-	if *m == nil {
-		*m = map[uint64]struct{}{}
-	}
-	(*m)[id] = struct{}{}
-}
-
-// nilAwareDelete deletes from a map, nil'ing the map itself if it is empty after.
-func nilAwareDelete(m *map[uint64]struct{}, id uint64) {
-	if *m == nil {
-		return
-	}
-	delete(*m, id)
-	if len(*m) == 0 {
-		*m = nil
-	}
-}
-
-// symdiff returns the count of the symmetric difference between the sets of
-// uint64s, i.e. len( (l - r) \union (r - l)).
-func symdiff(l, r map[uint64]struct{}) int {
-	var n int
-	pairs := [][2]quorum.MajorityConfig{
-		{l, r}, // count elems in l but not in r
-		{r, l}, // count elems in r but not in l
-	}
-	for _, p := range pairs {
-		for id := range p[0] {
-			if _, ok := p[1][id]; !ok {
-				n++
-			}
-		}
-	}
-	return n
-}
-
-func joint(cfg tracker.Config) bool {
-	return len(outgoing(cfg.Voters)) > 0
-}
-
-func incoming(voters quorum.JointConfig) quorum.MajorityConfig      { return voters[0] }
-func outgoing(voters quorum.JointConfig) quorum.MajorityConfig      { return voters[1] }
-func outgoingPtr(voters *quorum.JointConfig) *quorum.MajorityConfig { return &voters[1] }
-
-// Describe prints the type and NodeID of the configuration changes as a
-// space-delimited string.
-func Describe(ccs ...pb.ConfChangeSingle) string {
-	var buf strings.Builder
-	for _, cc := range ccs {
-		if buf.Len() > 0 {
-			buf.WriteByte(' ')
-		}
-		fmt.Fprintf(&buf, "%s(%d)", cc.Type, cc.NodeID)
-	}
-	return buf.String()
-}
diff --git a/vendor/go.etcd.io/etcd/raft/confchange/restore.go b/vendor/go.etcd.io/etcd/raft/confchange/restore.go
deleted file mode 100644
index 724068d..0000000
--- a/vendor/go.etcd.io/etcd/raft/confchange/restore.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2019 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 confchange
-
-import (
-	pb "go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/raft/tracker"
-)
-
-// toConfChangeSingle translates a conf state into 1) a slice of operations creating
-// first the config that will become the outgoing one, and then the incoming one, and
-// b) another slice that, when applied to the config resulted from 1), represents the
-// ConfState.
-func toConfChangeSingle(cs pb.ConfState) (out []pb.ConfChangeSingle, in []pb.ConfChangeSingle) {
-	// Example to follow along this code:
-	// voters=(1 2 3) learners=(5) outgoing=(1 2 4 6) learners_next=(4)
-	//
-	// This means that before entering the joint config, the configuration
-	// had voters (1 2 4) and perhaps some learners that are already gone.
-	// The new set of voters is (1 2 3), i.e. (1 2) were kept around, and (4 6)
-	// are no longer voters; however 4 is poised to become a learner upon leaving
-	// the joint state.
-	// We can't tell whether 5 was a learner before entering the joint config,
-	// but it doesn't matter (we'll pretend that it wasn't).
-	//
-	// The code below will construct
-	// outgoing = add 1; add 2; add 4; add 6
-	// incoming = remove 1; remove 2; remove 4; remove 6
-	//            add 1;    add 2;    add 3;
-	//            add-learner 5;
-	//            add-learner 4;
-	//
-	// So, when starting with an empty config, after applying 'outgoing' we have
-	//
-	//   quorum=(1 2 4 6)
-	//
-	// From which we enter a joint state via 'incoming'
-	//
-	//   quorum=(1 2 3)&&(1 2 4 6) learners=(5) learners_next=(4)
-	//
-	// as desired.
-
-	for _, id := range cs.VotersOutgoing {
-		// If there are outgoing voters, first add them one by one so that the
-		// (non-joint) config has them all.
-		out = append(out, pb.ConfChangeSingle{
-			Type:   pb.ConfChangeAddNode,
-			NodeID: id,
-		})
-
-	}
-
-	// We're done constructing the outgoing slice, now on to the incoming one
-	// (which will apply on top of the config created by the outgoing slice).
-
-	// First, we'll remove all of the outgoing voters.
-	for _, id := range cs.VotersOutgoing {
-		in = append(in, pb.ConfChangeSingle{
-			Type:   pb.ConfChangeRemoveNode,
-			NodeID: id,
-		})
-	}
-	// Then we'll add the incoming voters and learners.
-	for _, id := range cs.Voters {
-		in = append(in, pb.ConfChangeSingle{
-			Type:   pb.ConfChangeAddNode,
-			NodeID: id,
-		})
-	}
-	for _, id := range cs.Learners {
-		in = append(in, pb.ConfChangeSingle{
-			Type:   pb.ConfChangeAddLearnerNode,
-			NodeID: id,
-		})
-	}
-	// Same for LearnersNext; these are nodes we want to be learners but which
-	// are currently voters in the outgoing config.
-	for _, id := range cs.LearnersNext {
-		in = append(in, pb.ConfChangeSingle{
-			Type:   pb.ConfChangeAddLearnerNode,
-			NodeID: id,
-		})
-	}
-	return out, in
-}
-
-func chain(chg Changer, ops ...func(Changer) (tracker.Config, tracker.ProgressMap, error)) (tracker.Config, tracker.ProgressMap, error) {
-	for _, op := range ops {
-		cfg, prs, err := op(chg)
-		if err != nil {
-			return tracker.Config{}, nil, err
-		}
-		chg.Tracker.Config = cfg
-		chg.Tracker.Progress = prs
-	}
-	return chg.Tracker.Config, chg.Tracker.Progress, nil
-}
-
-// Restore takes a Changer (which must represent an empty configuration), and
-// runs a sequence of changes enacting the configuration described in the
-// ConfState.
-//
-// TODO(tbg) it's silly that this takes a Changer. Unravel this by making sure
-// the Changer only needs a ProgressMap (not a whole Tracker) at which point
-// this can just take LastIndex and MaxInflight directly instead and cook up
-// the results from that alone.
-func Restore(chg Changer, cs pb.ConfState) (tracker.Config, tracker.ProgressMap, error) {
-	outgoing, incoming := toConfChangeSingle(cs)
-
-	var ops []func(Changer) (tracker.Config, tracker.ProgressMap, error)
-
-	if len(outgoing) == 0 {
-		// No outgoing config, so just apply the incoming changes one by one.
-		for _, cc := range incoming {
-			cc := cc // loop-local copy
-			ops = append(ops, func(chg Changer) (tracker.Config, tracker.ProgressMap, error) {
-				return chg.Simple(cc)
-			})
-		}
-	} else {
-		// The ConfState describes a joint configuration.
-		//
-		// First, apply all of the changes of the outgoing config one by one, so
-		// that it temporarily becomes the incoming active config. For example,
-		// if the config is (1 2 3)&(2 3 4), this will establish (2 3 4)&().
-		for _, cc := range outgoing {
-			cc := cc // loop-local copy
-			ops = append(ops, func(chg Changer) (tracker.Config, tracker.ProgressMap, error) {
-				return chg.Simple(cc)
-			})
-		}
-		// Now enter the joint state, which rotates the above additions into the
-		// outgoing config, and adds the incoming config in. Continuing the
-		// example above, we'd get (1 2 3)&(2 3 4), i.e. the incoming operations
-		// would be removing 2,3,4 and then adding in 1,2,3 while transitioning
-		// into a joint state.
-		ops = append(ops, func(chg Changer) (tracker.Config, tracker.ProgressMap, error) {
-			return chg.EnterJoint(cs.AutoLeave, incoming...)
-		})
-	}
-
-	return chain(chg, ops...)
-}
diff --git a/vendor/go.etcd.io/etcd/raft/design.md b/vendor/go.etcd.io/etcd/raft/design.md
deleted file mode 100644
index 7bc0531..0000000
--- a/vendor/go.etcd.io/etcd/raft/design.md
+++ /dev/null
@@ -1,57 +0,0 @@
-## Progress
-
-Progress represents a follower’s progress in the view of the leader. Leader maintains progresses of all followers, and sends `replication message` to the follower based on its progress. 
-
-`replication message` is a `msgApp` with log entries.
-
-A progress has two attribute: `match` and `next`. `match` is the index of the highest known matched entry. If leader knows nothing about follower’s replication status, `match` is set to zero. `next` is the index of the first entry that will be replicated to the follower. Leader puts entries from `next` to its latest one in next `replication message`.
-
-A progress is in one of the three state: `probe`, `replicate`, `snapshot`. 
-
-```
-                            +--------------------------------------------------------+          
-                            |                  send snapshot                         |          
-                            |                                                        |          
-                  +---------+----------+                                  +----------v---------+
-              +--->       probe        |                                  |      snapshot      |
-              |   |  max inflight = 1  <----------------------------------+  max inflight = 0  |
-              |   +---------+----------+                                  +--------------------+
-              |             |            1. snapshot success                                    
-              |             |               (next=snapshot.index + 1)                           
-              |             |            2. snapshot failure                                    
-              |             |               (no change)                                         
-              |             |            3. receives msgAppResp(rej=false&&index>lastsnap.index)
-              |             |               (match=m.index,next=match+1)                        
-receives msgAppResp(rej=true)                                                                   
-(next=match+1)|             |                                                                   
-              |             |                                                                   
-              |             |                                                                   
-              |             |   receives msgAppResp(rej=false&&index>match)                     
-              |             |   (match=m.index,next=match+1)                                    
-              |             |                                                                   
-              |             |                                                                   
-              |             |                                                                   
-              |   +---------v----------+                                                        
-              |   |     replicate      |                                                        
-              +---+  max inflight = n  |                                                        
-                  +--------------------+                                                        
-```
-
-When the progress of a follower is in `probe` state, leader sends at most one `replication message` per heartbeat interval. The leader sends `replication message` slowly and probing the actual progress of the follower. A `msgHeartbeatResp` or a `msgAppResp` with reject might trigger the sending of the next `replication message`.
-
-When the progress of a follower is in `replicate` state, leader sends `replication message`, then optimistically increases `next` to the latest entry sent. This is an optimized state for fast replicating log entries to the follower.
-
-When the progress of a follower is in `snapshot` state, leader stops sending any `replication message`.
-
-A newly elected leader sets the progresses of all the followers to `probe` state with `match` = 0 and `next` = last index. The leader slowly (at most once per heartbeat) sends `replication message` to the follower and probes its progress.
-
-A progress changes to `replicate` when the follower replies with a non-rejection `msgAppResp`, which implies that it has matched the index sent. At this point, leader starts to stream log entries to the follower fast. The progress will fall back to `probe` when the follower replies a rejection `msgAppResp` or the link layer reports the follower is unreachable. We aggressively reset `next` to `match`+1 since if we receive any `msgAppResp` soon, both `match` and `next` will increase directly to the `index` in `msgAppResp`. (We might end up with sending some duplicate entries when aggressively reset `next` too low.  see open question)
-
-A progress changes from `probe` to `snapshot` when the follower falls very far behind and requires a snapshot. After sending `msgSnap`, the leader waits until the success, failure or abortion of the previous snapshot sent. The progress will go back to `probe` after the sending result is applied.
-
-### Flow Control
-
-1. limit the max size of message sent per message. Max should be configurable.
-Lower the cost at probing state as we limit the size per message; lower the penalty when aggressively decreased to a too low `next`
-
-2. limit the # of in flight messages < N when in `replicate` state. N should be configurable. Most implementation will have a sending buffer on top of its actual network transport layer (not blocking raft node). We want to make sure raft does not overflow that buffer, which can cause message dropping and triggering a bunch of unnecessary resending repeatedly. 
diff --git a/vendor/go.etcd.io/etcd/raft/doc.go b/vendor/go.etcd.io/etcd/raft/doc.go
deleted file mode 100644
index 68fe6f0..0000000
--- a/vendor/go.etcd.io/etcd/raft/doc.go
+++ /dev/null
@@ -1,300 +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 raft sends and receives messages in the Protocol Buffer format
-defined in the raftpb package.
-
-Raft is a protocol with which a cluster of nodes can maintain a replicated state machine.
-The state machine is kept in sync through the use of a replicated log.
-For more details on Raft, see "In Search of an Understandable Consensus Algorithm"
-(https://raft.github.io/raft.pdf) by Diego Ongaro and John Ousterhout.
-
-A simple example application, _raftexample_, is also available to help illustrate
-how to use this package in practice:
-https://github.com/etcd-io/etcd/tree/master/contrib/raftexample
-
-Usage
-
-The primary object in raft is a Node. You either start a Node from scratch
-using raft.StartNode or start a Node from some initial state using raft.RestartNode.
-
-To start a node from scratch:
-
-  storage := raft.NewMemoryStorage()
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-  n := raft.StartNode(c, []raft.Peer{{ID: 0x02}, {ID: 0x03}})
-
-To restart a node from previous state:
-
-  storage := raft.NewMemoryStorage()
-
-  // recover the in-memory storage from persistent
-  // snapshot, state and entries.
-  storage.ApplySnapshot(snapshot)
-  storage.SetHardState(state)
-  storage.Append(entries)
-
-  c := &Config{
-    ID:              0x01,
-    ElectionTick:    10,
-    HeartbeatTick:   1,
-    Storage:         storage,
-    MaxSizePerMsg:   4096,
-    MaxInflightMsgs: 256,
-  }
-
-  // restart raft without peer information.
-  // peer information is already included in the storage.
-  n := raft.RestartNode(c)
-
-Now that you are holding onto a Node you have a few responsibilities:
-
-First, you must read from the Node.Ready() channel and process the updates
-it contains. These steps may be performed in parallel, except as noted in step
-2.
-
-1. Write HardState, Entries, and Snapshot to persistent storage if they are
-not empty. Note that when writing an Entry with Index i, any
-previously-persisted entries with Index >= i must be discarded.
-
-2. Send all Messages to the nodes named in the To field. It is important that
-no messages be sent until the latest HardState has been persisted to disk,
-and all Entries written by any previous Ready batch (Messages may be sent while
-entries from the same batch are being persisted). To reduce the I/O latency, an
-optimization can be applied to make leader write to disk in parallel with its
-followers (as explained at section 10.2.1 in Raft thesis). If any Message has type
-MsgSnap, call Node.ReportSnapshot() after it has been sent (these messages may be
-large).
-
-Note: Marshalling messages is not thread-safe; it is important that you
-make sure that no new entries are persisted while marshalling.
-The easiest way to achieve this is to serialize the messages directly inside
-your main raft loop.
-
-3. Apply Snapshot (if any) and CommittedEntries to the state machine.
-If any committed Entry has Type EntryConfChange, call Node.ApplyConfChange()
-to apply it to the node. The configuration change may be cancelled at this point
-by setting the NodeID field to zero before calling ApplyConfChange
-(but ApplyConfChange must be called one way or the other, and the decision to cancel
-must be based solely on the state machine and not external information such as
-the observed health of the node).
-
-4. Call Node.Advance() to signal readiness for the next batch of updates.
-This may be done at any time after step 1, although all updates must be processed
-in the order they were returned by Ready.
-
-Second, all persisted log entries must be made available via an
-implementation of the Storage interface. The provided MemoryStorage
-type can be used for this (if you repopulate its state upon a
-restart), or you can supply your own disk-backed implementation.
-
-Third, when you receive a message from another node, pass it to Node.Step:
-
-	func recvRaftRPC(ctx context.Context, m raftpb.Message) {
-		n.Step(ctx, m)
-	}
-
-Finally, you need to call Node.Tick() at regular intervals (probably
-via a time.Ticker). Raft has two important timeouts: heartbeat and the
-election timeout. However, internally to the raft package time is
-represented by an abstract "tick".
-
-The total state machine handling loop will look something like this:
-
-  for {
-    select {
-    case <-s.Ticker:
-      n.Tick()
-    case rd := <-s.Node.Ready():
-      saveToStorage(rd.State, rd.Entries, rd.Snapshot)
-      send(rd.Messages)
-      if !raft.IsEmptySnap(rd.Snapshot) {
-        processSnapshot(rd.Snapshot)
-      }
-      for _, entry := range rd.CommittedEntries {
-        process(entry)
-        if entry.Type == raftpb.EntryConfChange {
-          var cc raftpb.ConfChange
-          cc.Unmarshal(entry.Data)
-          s.Node.ApplyConfChange(cc)
-        }
-      }
-      s.Node.Advance()
-    case <-s.done:
-      return
-    }
-  }
-
-To propose changes to the state machine from your node take your application
-data, serialize it into a byte slice and call:
-
-	n.Propose(ctx, data)
-
-If the proposal is committed, data will appear in committed entries with type
-raftpb.EntryNormal. There is no guarantee that a proposed command will be
-committed; you may have to re-propose after a timeout.
-
-To add or remove a node in a cluster, build ConfChange struct 'cc' and call:
-
-	n.ProposeConfChange(ctx, cc)
-
-After config change is committed, some committed entry with type
-raftpb.EntryConfChange will be returned. You must apply it to node through:
-
-	var cc raftpb.ConfChange
-	cc.Unmarshal(data)
-	n.ApplyConfChange(cc)
-
-Note: An ID represents a unique node in a cluster for all time. A
-given ID MUST be used only once even if the old node has been removed.
-This means that for example IP addresses make poor node IDs since they
-may be reused. Node IDs must be non-zero.
-
-Implementation notes
-
-This implementation is up to date with the final Raft thesis
-(https://github.com/ongardie/dissertation/blob/master/stanford.pdf), although our
-implementation of the membership change protocol differs somewhat from
-that described in chapter 4. The key invariant that membership changes
-happen one node at a time is preserved, but in our implementation the
-membership change takes effect when its entry is applied, not when it
-is added to the log (so the entry is committed under the old
-membership instead of the new). This is equivalent in terms of safety,
-since the old and new configurations are guaranteed to overlap.
-
-To ensure that we do not attempt to commit two membership changes at
-once by matching log positions (which would be unsafe since they
-should have different quorum requirements), we simply disallow any
-proposed membership change while any uncommitted change appears in
-the leader's log.
-
-This approach introduces a problem when you try to remove a member
-from a two-member cluster: If one of the members dies before the
-other one receives the commit of the confchange entry, then the member
-cannot be removed any more since the cluster cannot make progress.
-For this reason it is highly recommended to use three or more nodes in
-every cluster.
-
-MessageType
-
-Package raft sends and receives message in Protocol Buffer format (defined
-in raftpb package). Each state (follower, candidate, leader) implements its
-own 'step' method ('stepFollower', 'stepCandidate', 'stepLeader') when
-advancing with the given raftpb.Message. Each step is determined by its
-raftpb.MessageType. Note that every step is checked by one common method
-'Step' that safety-checks the terms of node and incoming message to prevent
-stale log entries:
-
-	'MsgHup' is used for election. If a node is a follower or candidate, the
-	'tick' function in 'raft' struct is set as 'tickElection'. If a follower or
-	candidate has not received any heartbeat before the election timeout, it
-	passes 'MsgHup' to its Step method and becomes (or remains) a candidate to
-	start a new election.
-
-	'MsgBeat' is an internal type that signals the leader to send a heartbeat of
-	the 'MsgHeartbeat' type. If a node is a leader, the 'tick' function in
-	the 'raft' struct is set as 'tickHeartbeat', and triggers the leader to
-	send periodic 'MsgHeartbeat' messages to its followers.
-
-	'MsgProp' proposes to append data to its log entries. This is a special
-	type to redirect proposals to leader. Therefore, send method overwrites
-	raftpb.Message's term with its HardState's term to avoid attaching its
-	local term to 'MsgProp'. When 'MsgProp' is passed to the leader's 'Step'
-	method, the leader first calls the 'appendEntry' method to append entries
-	to its log, and then calls 'bcastAppend' method to send those entries to
-	its peers. When passed to candidate, 'MsgProp' is dropped. When passed to
-	follower, 'MsgProp' is stored in follower's mailbox(msgs) by the send
-	method. It is stored with sender's ID and later forwarded to leader by
-	rafthttp package.
-
-	'MsgApp' contains log entries to replicate. A leader calls bcastAppend,
-	which calls sendAppend, which sends soon-to-be-replicated logs in 'MsgApp'
-	type. When 'MsgApp' is passed to candidate's Step method, candidate reverts
-	back to follower, because it indicates that there is a valid leader sending
-	'MsgApp' messages. Candidate and follower respond to this message in
-	'MsgAppResp' type.
-
-	'MsgAppResp' is response to log replication request('MsgApp'). When
-	'MsgApp' is passed to candidate or follower's Step method, it responds by
-	calling 'handleAppendEntries' method, which sends 'MsgAppResp' to raft
-	mailbox.
-
-	'MsgVote' requests votes for election. When a node is a follower or
-	candidate and 'MsgHup' is passed to its Step method, then the node calls
-	'campaign' method to campaign itself to become a leader. Once 'campaign'
-	method is called, the node becomes candidate and sends 'MsgVote' to peers
-	in cluster to request votes. When passed to leader or candidate's Step
-	method and the message's Term is lower than leader's or candidate's,
-	'MsgVote' will be rejected ('MsgVoteResp' is returned with Reject true).
-	If leader or candidate receives 'MsgVote' with higher term, it will revert
-	back to follower. When 'MsgVote' is passed to follower, it votes for the
-	sender only when sender's last term is greater than MsgVote's term or
-	sender's last term is equal to MsgVote's term but sender's last committed
-	index is greater than or equal to follower's.
-
-	'MsgVoteResp' contains responses from voting request. When 'MsgVoteResp' is
-	passed to candidate, the candidate calculates how many votes it has won. If
-	it's more than majority (quorum), it becomes leader and calls 'bcastAppend'.
-	If candidate receives majority of votes of denials, it reverts back to
-	follower.
-
-	'MsgPreVote' and 'MsgPreVoteResp' are used in an optional two-phase election
-	protocol. When Config.PreVote is true, a pre-election is carried out first
-	(using the same rules as a regular election), and no node increases its term
-	number unless the pre-election indicates that the campaigning node would win.
-	This minimizes disruption when a partitioned node rejoins the cluster.
-
-	'MsgSnap' requests to install a snapshot message. When a node has just
-	become a leader or the leader receives 'MsgProp' message, it calls
-	'bcastAppend' method, which then calls 'sendAppend' method to each
-	follower. In 'sendAppend', if a leader fails to get term or entries,
-	the leader requests snapshot by sending 'MsgSnap' type message.
-
-	'MsgSnapStatus' tells the result of snapshot install message. When a
-	follower rejected 'MsgSnap', it indicates the snapshot request with
-	'MsgSnap' had failed from network issues which causes the network layer
-	to fail to send out snapshots to its followers. Then leader considers
-	follower's progress as probe. When 'MsgSnap' were not rejected, it
-	indicates that the snapshot succeeded and the leader sets follower's
-	progress to probe and resumes its log replication.
-
-	'MsgHeartbeat' sends heartbeat from leader. When 'MsgHeartbeat' is passed
-	to candidate and message's term is higher than candidate's, the candidate
-	reverts back to follower and updates its committed index from the one in
-	this heartbeat. And it sends the message to its mailbox. When
-	'MsgHeartbeat' is passed to follower's Step method and message's term is
-	higher than follower's, the follower updates its leaderID with the ID
-	from the message.
-
-	'MsgHeartbeatResp' is a response to 'MsgHeartbeat'. When 'MsgHeartbeatResp'
-	is passed to leader's Step method, the leader knows which follower
-	responded. And only when the leader's last committed index is greater than
-	follower's Match index, the leader runs 'sendAppend` method.
-
-	'MsgUnreachable' tells that request(message) wasn't delivered. When
-	'MsgUnreachable' is passed to leader's Step method, the leader discovers
-	that the follower that sent this 'MsgUnreachable' is not reachable, often
-	indicating 'MsgApp' is lost. When follower's progress state is replicate,
-	the leader sets it back to probe.
-
-*/
-package raft
diff --git a/vendor/go.etcd.io/etcd/raft/log.go b/vendor/go.etcd.io/etcd/raft/log.go
deleted file mode 100644
index 77eedfc..0000000
--- a/vendor/go.etcd.io/etcd/raft/log.go
+++ /dev/null
@@ -1,372 +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 raft
-
-import (
-	"fmt"
-	"log"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-type raftLog struct {
-	// storage contains all stable entries since the last snapshot.
-	storage Storage
-
-	// unstable contains all unstable entries and snapshot.
-	// they will be saved into storage.
-	unstable unstable
-
-	// committed is the highest log position that is known to be in
-	// stable storage on a quorum of nodes.
-	committed uint64
-	// applied is the highest log position that the application has
-	// been instructed to apply to its state machine.
-	// Invariant: applied <= committed
-	applied uint64
-
-	logger Logger
-
-	// maxNextEntsSize is the maximum number aggregate byte size of the messages
-	// returned from calls to nextEnts.
-	maxNextEntsSize uint64
-}
-
-// newLog returns log using the given storage and default options. It
-// recovers the log to the state that it just commits and applies the
-// latest snapshot.
-func newLog(storage Storage, logger Logger) *raftLog {
-	return newLogWithSize(storage, logger, noLimit)
-}
-
-// newLogWithSize returns a log using the given storage and max
-// message size.
-func newLogWithSize(storage Storage, logger Logger, maxNextEntsSize uint64) *raftLog {
-	if storage == nil {
-		log.Panic("storage must not be nil")
-	}
-	log := &raftLog{
-		storage:         storage,
-		logger:          logger,
-		maxNextEntsSize: maxNextEntsSize,
-	}
-	firstIndex, err := storage.FirstIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	lastIndex, err := storage.LastIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	log.unstable.offset = lastIndex + 1
-	log.unstable.logger = logger
-	// Initialize our committed and applied pointers to the time of the last compaction.
-	log.committed = firstIndex - 1
-	log.applied = firstIndex - 1
-
-	return log
-}
-
-func (l *raftLog) String() string {
-	return fmt.Sprintf("committed=%d, applied=%d, unstable.offset=%d, len(unstable.Entries)=%d", l.committed, l.applied, l.unstable.offset, len(l.unstable.entries))
-}
-
-// maybeAppend returns (0, false) if the entries cannot be appended. Otherwise,
-// it returns (last index of new entries, true).
-func (l *raftLog) maybeAppend(index, logTerm, committed uint64, ents ...pb.Entry) (lastnewi uint64, ok bool) {
-	if l.matchTerm(index, logTerm) {
-		lastnewi = index + uint64(len(ents))
-		ci := l.findConflict(ents)
-		switch {
-		case ci == 0:
-		case ci <= l.committed:
-			l.logger.Panicf("entry %d conflict with committed entry [committed(%d)]", ci, l.committed)
-		default:
-			offset := index + 1
-			l.append(ents[ci-offset:]...)
-		}
-		l.commitTo(min(committed, lastnewi))
-		return lastnewi, true
-	}
-	return 0, false
-}
-
-func (l *raftLog) append(ents ...pb.Entry) uint64 {
-	if len(ents) == 0 {
-		return l.lastIndex()
-	}
-	if after := ents[0].Index - 1; after < l.committed {
-		l.logger.Panicf("after(%d) is out of range [committed(%d)]", after, l.committed)
-	}
-	l.unstable.truncateAndAppend(ents)
-	return l.lastIndex()
-}
-
-// findConflict finds the index of the conflict.
-// It returns the first pair of conflicting entries between the existing
-// entries and the given entries, if there are any.
-// If there is no conflicting entries, and the existing entries contains
-// all the given entries, zero will be returned.
-// If there is no conflicting entries, but the given entries contains new
-// entries, the index of the first new entry will be returned.
-// An entry is considered to be conflicting if it has the same index but
-// a different term.
-// The first entry MUST have an index equal to the argument 'from'.
-// The index of the given entries MUST be continuously increasing.
-func (l *raftLog) findConflict(ents []pb.Entry) uint64 {
-	for _, ne := range ents {
-		if !l.matchTerm(ne.Index, ne.Term) {
-			if ne.Index <= l.lastIndex() {
-				l.logger.Infof("found conflict at index %d [existing term: %d, conflicting term: %d]",
-					ne.Index, l.zeroTermOnErrCompacted(l.term(ne.Index)), ne.Term)
-			}
-			return ne.Index
-		}
-	}
-	return 0
-}
-
-func (l *raftLog) unstableEntries() []pb.Entry {
-	if len(l.unstable.entries) == 0 {
-		return nil
-	}
-	return l.unstable.entries
-}
-
-// nextEnts returns all the available entries for execution.
-// If applied is smaller than the index of snapshot, it returns all committed
-// entries after the index of snapshot.
-func (l *raftLog) nextEnts() (ents []pb.Entry) {
-	off := max(l.applied+1, l.firstIndex())
-	if l.committed+1 > off {
-		ents, err := l.slice(off, l.committed+1, l.maxNextEntsSize)
-		if err != nil {
-			l.logger.Panicf("unexpected error when getting unapplied entries (%v)", err)
-		}
-		return ents
-	}
-	return nil
-}
-
-// hasNextEnts returns if there is any available entries for execution. This
-// is a fast check without heavy raftLog.slice() in raftLog.nextEnts().
-func (l *raftLog) hasNextEnts() bool {
-	off := max(l.applied+1, l.firstIndex())
-	return l.committed+1 > off
-}
-
-func (l *raftLog) snapshot() (pb.Snapshot, error) {
-	if l.unstable.snapshot != nil {
-		return *l.unstable.snapshot, nil
-	}
-	return l.storage.Snapshot()
-}
-
-func (l *raftLog) firstIndex() uint64 {
-	if i, ok := l.unstable.maybeFirstIndex(); ok {
-		return i
-	}
-	index, err := l.storage.FirstIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	return index
-}
-
-func (l *raftLog) lastIndex() uint64 {
-	if i, ok := l.unstable.maybeLastIndex(); ok {
-		return i
-	}
-	i, err := l.storage.LastIndex()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-	return i
-}
-
-func (l *raftLog) commitTo(tocommit uint64) {
-	// never decrease commit
-	if l.committed < tocommit {
-		if l.lastIndex() < tocommit {
-			l.logger.Panicf("tocommit(%d) is out of range [lastIndex(%d)]. Was the raft log corrupted, truncated, or lost?", tocommit, l.lastIndex())
-		}
-		l.committed = tocommit
-	}
-}
-
-func (l *raftLog) appliedTo(i uint64) {
-	if i == 0 {
-		return
-	}
-	if l.committed < i || i < l.applied {
-		l.logger.Panicf("applied(%d) is out of range [prevApplied(%d), committed(%d)]", i, l.applied, l.committed)
-	}
-	l.applied = i
-}
-
-func (l *raftLog) stableTo(i, t uint64) { l.unstable.stableTo(i, t) }
-
-func (l *raftLog) stableSnapTo(i uint64) { l.unstable.stableSnapTo(i) }
-
-func (l *raftLog) lastTerm() uint64 {
-	t, err := l.term(l.lastIndex())
-	if err != nil {
-		l.logger.Panicf("unexpected error when getting the last term (%v)", err)
-	}
-	return t
-}
-
-func (l *raftLog) term(i uint64) (uint64, error) {
-	// the valid term range is [index of dummy entry, last index]
-	dummyIndex := l.firstIndex() - 1
-	if i < dummyIndex || i > l.lastIndex() {
-		// TODO: return an error instead?
-		return 0, nil
-	}
-
-	if t, ok := l.unstable.maybeTerm(i); ok {
-		return t, nil
-	}
-
-	t, err := l.storage.Term(i)
-	if err == nil {
-		return t, nil
-	}
-	if err == ErrCompacted || err == ErrUnavailable {
-		return 0, err
-	}
-	panic(err) // TODO(bdarnell)
-}
-
-func (l *raftLog) entries(i, maxsize uint64) ([]pb.Entry, error) {
-	if i > l.lastIndex() {
-		return nil, nil
-	}
-	return l.slice(i, l.lastIndex()+1, maxsize)
-}
-
-// allEntries returns all entries in the log.
-func (l *raftLog) allEntries() []pb.Entry {
-	ents, err := l.entries(l.firstIndex(), noLimit)
-	if err == nil {
-		return ents
-	}
-	if err == ErrCompacted { // try again if there was a racing compaction
-		return l.allEntries()
-	}
-	// TODO (xiangli): handle error?
-	panic(err)
-}
-
-// isUpToDate determines if the given (lastIndex,term) log is more up-to-date
-// by comparing the index and term of the last entries in the existing logs.
-// If the logs have last entries with different terms, then the log with the
-// later term is more up-to-date. If the logs end with the same term, then
-// whichever log has the larger lastIndex is more up-to-date. If the logs are
-// the same, the given log is up-to-date.
-func (l *raftLog) isUpToDate(lasti, term uint64) bool {
-	return term > l.lastTerm() || (term == l.lastTerm() && lasti >= l.lastIndex())
-}
-
-func (l *raftLog) matchTerm(i, term uint64) bool {
-	t, err := l.term(i)
-	if err != nil {
-		return false
-	}
-	return t == term
-}
-
-func (l *raftLog) maybeCommit(maxIndex, term uint64) bool {
-	if maxIndex > l.committed && l.zeroTermOnErrCompacted(l.term(maxIndex)) == term {
-		l.commitTo(maxIndex)
-		return true
-	}
-	return false
-}
-
-func (l *raftLog) restore(s pb.Snapshot) {
-	l.logger.Infof("log [%s] starts to restore snapshot [index: %d, term: %d]", l, s.Metadata.Index, s.Metadata.Term)
-	l.committed = s.Metadata.Index
-	l.unstable.restore(s)
-}
-
-// slice returns a slice of log entries from lo through hi-1, inclusive.
-func (l *raftLog) slice(lo, hi, maxSize uint64) ([]pb.Entry, error) {
-	err := l.mustCheckOutOfBounds(lo, hi)
-	if err != nil {
-		return nil, err
-	}
-	if lo == hi {
-		return nil, nil
-	}
-	var ents []pb.Entry
-	if lo < l.unstable.offset {
-		storedEnts, err := l.storage.Entries(lo, min(hi, l.unstable.offset), maxSize)
-		if err == ErrCompacted {
-			return nil, err
-		} else if err == ErrUnavailable {
-			l.logger.Panicf("entries[%d:%d) is unavailable from storage", lo, min(hi, l.unstable.offset))
-		} else if err != nil {
-			panic(err) // TODO(bdarnell)
-		}
-
-		// check if ents has reached the size limitation
-		if uint64(len(storedEnts)) < min(hi, l.unstable.offset)-lo {
-			return storedEnts, nil
-		}
-
-		ents = storedEnts
-	}
-	if hi > l.unstable.offset {
-		unstable := l.unstable.slice(max(lo, l.unstable.offset), hi)
-		if len(ents) > 0 {
-			combined := make([]pb.Entry, len(ents)+len(unstable))
-			n := copy(combined, ents)
-			copy(combined[n:], unstable)
-			ents = combined
-		} else {
-			ents = unstable
-		}
-	}
-	return limitSize(ents, maxSize), nil
-}
-
-// l.firstIndex <= lo <= hi <= l.firstIndex + len(l.entries)
-func (l *raftLog) mustCheckOutOfBounds(lo, hi uint64) error {
-	if lo > hi {
-		l.logger.Panicf("invalid slice %d > %d", lo, hi)
-	}
-	fi := l.firstIndex()
-	if lo < fi {
-		return ErrCompacted
-	}
-
-	length := l.lastIndex() + 1 - fi
-	if lo < fi || hi > fi+length {
-		l.logger.Panicf("slice[%d,%d) out of bound [%d,%d]", lo, hi, fi, l.lastIndex())
-	}
-	return nil
-}
-
-func (l *raftLog) zeroTermOnErrCompacted(t uint64, err error) uint64 {
-	if err == nil {
-		return t
-	}
-	if err == ErrCompacted {
-		return 0
-	}
-	l.logger.Panicf("unexpected error (%v)", err)
-	return 0
-}
diff --git a/vendor/go.etcd.io/etcd/raft/log_unstable.go b/vendor/go.etcd.io/etcd/raft/log_unstable.go
deleted file mode 100644
index 1bff5a7..0000000
--- a/vendor/go.etcd.io/etcd/raft/log_unstable.go
+++ /dev/null
@@ -1,157 +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 raft
-
-import pb "go.etcd.io/etcd/raft/raftpb"
-
-// unstable.entries[i] has raft log position i+unstable.offset.
-// Note that unstable.offset may be less than the highest log
-// position in storage; this means that the next write to storage
-// might need to truncate the log before persisting unstable.entries.
-type unstable struct {
-	// the incoming unstable snapshot, if any.
-	snapshot *pb.Snapshot
-	// all entries that have not yet been written to storage.
-	entries []pb.Entry
-	offset  uint64
-
-	logger Logger
-}
-
-// maybeFirstIndex returns the index of the first possible entry in entries
-// if it has a snapshot.
-func (u *unstable) maybeFirstIndex() (uint64, bool) {
-	if u.snapshot != nil {
-		return u.snapshot.Metadata.Index + 1, true
-	}
-	return 0, false
-}
-
-// maybeLastIndex returns the last index if it has at least one
-// unstable entry or snapshot.
-func (u *unstable) maybeLastIndex() (uint64, bool) {
-	if l := len(u.entries); l != 0 {
-		return u.offset + uint64(l) - 1, true
-	}
-	if u.snapshot != nil {
-		return u.snapshot.Metadata.Index, true
-	}
-	return 0, false
-}
-
-// maybeTerm returns the term of the entry at index i, if there
-// is any.
-func (u *unstable) maybeTerm(i uint64) (uint64, bool) {
-	if i < u.offset {
-		if u.snapshot != nil && u.snapshot.Metadata.Index == i {
-			return u.snapshot.Metadata.Term, true
-		}
-		return 0, false
-	}
-
-	last, ok := u.maybeLastIndex()
-	if !ok {
-		return 0, false
-	}
-	if i > last {
-		return 0, false
-	}
-
-	return u.entries[i-u.offset].Term, true
-}
-
-func (u *unstable) stableTo(i, t uint64) {
-	gt, ok := u.maybeTerm(i)
-	if !ok {
-		return
-	}
-	// if i < offset, term is matched with the snapshot
-	// only update the unstable entries if term is matched with
-	// an unstable entry.
-	if gt == t && i >= u.offset {
-		u.entries = u.entries[i+1-u.offset:]
-		u.offset = i + 1
-		u.shrinkEntriesArray()
-	}
-}
-
-// shrinkEntriesArray discards the underlying array used by the entries slice
-// if most of it isn't being used. This avoids holding references to a bunch of
-// potentially large entries that aren't needed anymore. Simply clearing the
-// entries wouldn't be safe because clients might still be using them.
-func (u *unstable) shrinkEntriesArray() {
-	// We replace the array if we're using less than half of the space in
-	// it. This number is fairly arbitrary, chosen as an attempt to balance
-	// memory usage vs number of allocations. It could probably be improved
-	// with some focused tuning.
-	const lenMultiple = 2
-	if len(u.entries) == 0 {
-		u.entries = nil
-	} else if len(u.entries)*lenMultiple < cap(u.entries) {
-		newEntries := make([]pb.Entry, len(u.entries))
-		copy(newEntries, u.entries)
-		u.entries = newEntries
-	}
-}
-
-func (u *unstable) stableSnapTo(i uint64) {
-	if u.snapshot != nil && u.snapshot.Metadata.Index == i {
-		u.snapshot = nil
-	}
-}
-
-func (u *unstable) restore(s pb.Snapshot) {
-	u.offset = s.Metadata.Index + 1
-	u.entries = nil
-	u.snapshot = &s
-}
-
-func (u *unstable) truncateAndAppend(ents []pb.Entry) {
-	after := ents[0].Index
-	switch {
-	case after == u.offset+uint64(len(u.entries)):
-		// after is the next index in the u.entries
-		// directly append
-		u.entries = append(u.entries, ents...)
-	case after <= u.offset:
-		u.logger.Infof("replace the unstable entries from index %d", after)
-		// The log is being truncated to before our current offset
-		// portion, so set the offset and replace the entries
-		u.offset = after
-		u.entries = ents
-	default:
-		// truncate to after and copy to u.entries
-		// then append
-		u.logger.Infof("truncate the unstable entries before index %d", after)
-		u.entries = append([]pb.Entry{}, u.slice(u.offset, after)...)
-		u.entries = append(u.entries, ents...)
-	}
-}
-
-func (u *unstable) slice(lo uint64, hi uint64) []pb.Entry {
-	u.mustCheckOutOfBounds(lo, hi)
-	return u.entries[lo-u.offset : hi-u.offset]
-}
-
-// u.offset <= lo <= hi <= u.offset+len(u.entries)
-func (u *unstable) mustCheckOutOfBounds(lo, hi uint64) {
-	if lo > hi {
-		u.logger.Panicf("invalid unstable.slice %d > %d", lo, hi)
-	}
-	upper := u.offset + uint64(len(u.entries))
-	if lo < u.offset || hi > upper {
-		u.logger.Panicf("unstable.slice[%d,%d) out of bound [%d,%d]", lo, hi, u.offset, upper)
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/raft/logger.go b/vendor/go.etcd.io/etcd/raft/logger.go
deleted file mode 100644
index 6d89629..0000000
--- a/vendor/go.etcd.io/etcd/raft/logger.go
+++ /dev/null
@@ -1,132 +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 raft
-
-import (
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-	"sync"
-)
-
-type Logger interface {
-	Debug(v ...interface{})
-	Debugf(format string, v ...interface{})
-
-	Error(v ...interface{})
-	Errorf(format string, v ...interface{})
-
-	Info(v ...interface{})
-	Infof(format string, v ...interface{})
-
-	Warning(v ...interface{})
-	Warningf(format string, v ...interface{})
-
-	Fatal(v ...interface{})
-	Fatalf(format string, v ...interface{})
-
-	Panic(v ...interface{})
-	Panicf(format string, v ...interface{})
-}
-
-func SetLogger(l Logger) {
-	raftLoggerMu.Lock()
-	raftLogger = l
-	raftLoggerMu.Unlock()
-}
-
-var (
-	defaultLogger = &DefaultLogger{Logger: log.New(os.Stderr, "raft", log.LstdFlags)}
-	discardLogger = &DefaultLogger{Logger: log.New(ioutil.Discard, "", 0)}
-	raftLoggerMu  sync.Mutex
-	raftLogger    = Logger(defaultLogger)
-)
-
-const (
-	calldepth = 2
-)
-
-// DefaultLogger is a default implementation of the Logger interface.
-type DefaultLogger struct {
-	*log.Logger
-	debug bool
-}
-
-func (l *DefaultLogger) EnableTimestamps() {
-	l.SetFlags(l.Flags() | log.Ldate | log.Ltime)
-}
-
-func (l *DefaultLogger) EnableDebug() {
-	l.debug = true
-}
-
-func (l *DefaultLogger) Debug(v ...interface{}) {
-	if l.debug {
-		l.Output(calldepth, header("DEBUG", fmt.Sprint(v...)))
-	}
-}
-
-func (l *DefaultLogger) Debugf(format string, v ...interface{}) {
-	if l.debug {
-		l.Output(calldepth, header("DEBUG", fmt.Sprintf(format, v...)))
-	}
-}
-
-func (l *DefaultLogger) Info(v ...interface{}) {
-	l.Output(calldepth, header("INFO", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Infof(format string, v ...interface{}) {
-	l.Output(calldepth, header("INFO", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Error(v ...interface{}) {
-	l.Output(calldepth, header("ERROR", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Errorf(format string, v ...interface{}) {
-	l.Output(calldepth, header("ERROR", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Warning(v ...interface{}) {
-	l.Output(calldepth, header("WARN", fmt.Sprint(v...)))
-}
-
-func (l *DefaultLogger) Warningf(format string, v ...interface{}) {
-	l.Output(calldepth, header("WARN", fmt.Sprintf(format, v...)))
-}
-
-func (l *DefaultLogger) Fatal(v ...interface{}) {
-	l.Output(calldepth, header("FATAL", fmt.Sprint(v...)))
-	os.Exit(1)
-}
-
-func (l *DefaultLogger) Fatalf(format string, v ...interface{}) {
-	l.Output(calldepth, header("FATAL", fmt.Sprintf(format, v...)))
-	os.Exit(1)
-}
-
-func (l *DefaultLogger) Panic(v ...interface{}) {
-	l.Logger.Panic(v...)
-}
-
-func (l *DefaultLogger) Panicf(format string, v ...interface{}) {
-	l.Logger.Panicf(format, v...)
-}
-
-func header(lvl, msg string) string {
-	return fmt.Sprintf("%s: %s", lvl, msg)
-}
diff --git a/vendor/go.etcd.io/etcd/raft/node.go b/vendor/go.etcd.io/etcd/raft/node.go
deleted file mode 100644
index ab6185b..0000000
--- a/vendor/go.etcd.io/etcd/raft/node.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 raft
-
-import (
-	"context"
-	"errors"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-type SnapshotStatus int
-
-const (
-	SnapshotFinish  SnapshotStatus = 1
-	SnapshotFailure SnapshotStatus = 2
-)
-
-var (
-	emptyState = pb.HardState{}
-
-	// ErrStopped is returned by methods on Nodes that have been stopped.
-	ErrStopped = errors.New("raft: stopped")
-)
-
-// SoftState provides state that is useful for logging and debugging.
-// The state is volatile and does not need to be persisted to the WAL.
-type SoftState struct {
-	Lead      uint64 // must use atomic operations to access; keep 64-bit aligned.
-	RaftState StateType
-}
-
-func (a *SoftState) equal(b *SoftState) bool {
-	return a.Lead == b.Lead && a.RaftState == b.RaftState
-}
-
-// Ready encapsulates the entries and messages that are ready to read,
-// be saved to stable storage, committed or sent to other peers.
-// All fields in Ready are read-only.
-type Ready struct {
-	// The current volatile state of a Node.
-	// SoftState will be nil if there is no update.
-	// It is not required to consume or store SoftState.
-	*SoftState
-
-	// The current state of a Node to be saved to stable storage BEFORE
-	// Messages are sent.
-	// HardState will be equal to empty state if there is no update.
-	pb.HardState
-
-	// ReadStates can be used for node to serve linearizable read requests locally
-	// when its applied index is greater than the index in ReadState.
-	// Note that the readState will be returned when raft receives msgReadIndex.
-	// The returned is only valid for the request that requested to read.
-	ReadStates []ReadState
-
-	// Entries specifies entries to be saved to stable storage BEFORE
-	// Messages are sent.
-	Entries []pb.Entry
-
-	// Snapshot specifies the snapshot to be saved to stable storage.
-	Snapshot pb.Snapshot
-
-	// CommittedEntries specifies entries to be committed to a
-	// store/state-machine. These have previously been committed to stable
-	// store.
-	CommittedEntries []pb.Entry
-
-	// Messages specifies outbound messages to be sent AFTER Entries are
-	// committed to stable storage.
-	// If it contains a MsgSnap message, the application MUST report back to raft
-	// when the snapshot has been received or has failed by calling ReportSnapshot.
-	Messages []pb.Message
-
-	// MustSync indicates whether the HardState and Entries must be synchronously
-	// written to disk or if an asynchronous write is permissible.
-	MustSync bool
-}
-
-func isHardStateEqual(a, b pb.HardState) bool {
-	return a.Term == b.Term && a.Vote == b.Vote && a.Commit == b.Commit
-}
-
-// IsEmptyHardState returns true if the given HardState is empty.
-func IsEmptyHardState(st pb.HardState) bool {
-	return isHardStateEqual(st, emptyState)
-}
-
-// IsEmptySnap returns true if the given Snapshot is empty.
-func IsEmptySnap(sp pb.Snapshot) bool {
-	return sp.Metadata.Index == 0
-}
-
-func (rd Ready) containsUpdates() bool {
-	return rd.SoftState != nil || !IsEmptyHardState(rd.HardState) ||
-		!IsEmptySnap(rd.Snapshot) || len(rd.Entries) > 0 ||
-		len(rd.CommittedEntries) > 0 || len(rd.Messages) > 0 || len(rd.ReadStates) != 0
-}
-
-// appliedCursor extracts from the Ready the highest index the client has
-// applied (once the Ready is confirmed via Advance). If no information is
-// contained in the Ready, returns zero.
-func (rd Ready) appliedCursor() uint64 {
-	if n := len(rd.CommittedEntries); n > 0 {
-		return rd.CommittedEntries[n-1].Index
-	}
-	if index := rd.Snapshot.Metadata.Index; index > 0 {
-		return index
-	}
-	return 0
-}
-
-// Node represents a node in a raft cluster.
-type Node interface {
-	// Tick increments the internal logical clock for the Node by a single tick. Election
-	// timeouts and heartbeat timeouts are in units of ticks.
-	Tick()
-	// Campaign causes the Node to transition to candidate state and start campaigning to become leader.
-	Campaign(ctx context.Context) error
-	// Propose proposes that data be appended to the log. Note that proposals can be lost without
-	// notice, therefore it is user's job to ensure proposal retries.
-	Propose(ctx context.Context, data []byte) error
-	// ProposeConfChange proposes a configuration change. Like any proposal, the
-	// configuration change may be dropped with or without an error being
-	// returned. In particular, configuration changes are dropped unless the
-	// leader has certainty that there is no prior unapplied configuration
-	// change in its log.
-	//
-	// The method accepts either a pb.ConfChange (deprecated) or pb.ConfChangeV2
-	// message. The latter allows arbitrary configuration changes via joint
-	// consensus, notably including replacing a voter. Passing a ConfChangeV2
-	// message is only allowed if all Nodes participating in the cluster run a
-	// version of this library aware of the V2 API. See pb.ConfChangeV2 for
-	// usage details and semantics.
-	ProposeConfChange(ctx context.Context, cc pb.ConfChangeI) error
-
-	// Step advances the state machine using the given message. ctx.Err() will be returned, if any.
-	Step(ctx context.Context, msg pb.Message) error
-
-	// Ready returns a channel that returns the current point-in-time state.
-	// Users of the Node must call Advance after retrieving the state returned by Ready.
-	//
-	// NOTE: No committed entries from the next Ready may be applied until all committed entries
-	// and snapshots from the previous one have finished.
-	Ready() <-chan Ready
-
-	// Advance notifies the Node that the application has saved progress up to the last Ready.
-	// It prepares the node to return the next available Ready.
-	//
-	// The application should generally call Advance after it applies the entries in last Ready.
-	//
-	// However, as an optimization, the application may call Advance while it is applying the
-	// commands. For example. when the last Ready contains a snapshot, the application might take
-	// a long time to apply the snapshot data. To continue receiving Ready without blocking raft
-	// progress, it can call Advance before finishing applying the last ready.
-	Advance()
-	// ApplyConfChange applies a config change (previously passed to
-	// ProposeConfChange) to the node. This must be called whenever a config
-	// change is observed in Ready.CommittedEntries.
-	//
-	// Returns an opaque non-nil ConfState protobuf which must be recorded in
-	// snapshots.
-	ApplyConfChange(cc pb.ConfChangeI) *pb.ConfState
-
-	// TransferLeadership attempts to transfer leadership to the given transferee.
-	TransferLeadership(ctx context.Context, lead, transferee uint64)
-
-	// ReadIndex request a read state. The read state will be set in the ready.
-	// Read state has a read index. Once the application advances further than the read
-	// index, any linearizable read requests issued before the read request can be
-	// processed safely. The read state will have the same rctx attached.
-	ReadIndex(ctx context.Context, rctx []byte) error
-
-	// Status returns the current status of the raft state machine.
-	Status() Status
-	// ReportUnreachable reports the given node is not reachable for the last send.
-	ReportUnreachable(id uint64)
-	// ReportSnapshot reports the status of the sent snapshot. The id is the raft ID of the follower
-	// who is meant to receive the snapshot, and the status is SnapshotFinish or SnapshotFailure.
-	// Calling ReportSnapshot with SnapshotFinish is a no-op. But, any failure in applying a
-	// snapshot (for e.g., while streaming it from leader to follower), should be reported to the
-	// leader with SnapshotFailure. When leader sends a snapshot to a follower, it pauses any raft
-	// log probes until the follower can apply the snapshot and advance its state. If the follower
-	// can't do that, for e.g., due to a crash, it could end up in a limbo, never getting any
-	// updates from the leader. Therefore, it is crucial that the application ensures that any
-	// failure in snapshot sending is caught and reported back to the leader; so it can resume raft
-	// log probing in the follower.
-	ReportSnapshot(id uint64, status SnapshotStatus)
-	// Stop performs any necessary termination of the Node.
-	Stop()
-}
-
-type Peer struct {
-	ID      uint64
-	Context []byte
-}
-
-// StartNode returns a new Node given configuration and a list of raft peers.
-// It appends a ConfChangeAddNode entry for each given peer to the initial log.
-//
-// Peers must not be zero length; call RestartNode in that case.
-func StartNode(c *Config, peers []Peer) Node {
-	if len(peers) == 0 {
-		panic("no peers given; use RestartNode instead")
-	}
-	rn, err := NewRawNode(c)
-	if err != nil {
-		panic(err)
-	}
-	rn.Bootstrap(peers)
-
-	n := newNode(rn)
-
-	go n.run()
-	return &n
-}
-
-// RestartNode is similar to StartNode but does not take a list of peers.
-// The current membership of the cluster will be restored from the Storage.
-// If the caller has an existing state machine, pass in the last log index that
-// has been applied to it; otherwise use zero.
-func RestartNode(c *Config) Node {
-	rn, err := NewRawNode(c)
-	if err != nil {
-		panic(err)
-	}
-	n := newNode(rn)
-	go n.run()
-	return &n
-}
-
-type msgWithResult struct {
-	m      pb.Message
-	result chan error
-}
-
-// node is the canonical implementation of the Node interface
-type node struct {
-	propc      chan msgWithResult
-	recvc      chan pb.Message
-	confc      chan pb.ConfChangeV2
-	confstatec chan pb.ConfState
-	readyc     chan Ready
-	advancec   chan struct{}
-	tickc      chan struct{}
-	done       chan struct{}
-	stop       chan struct{}
-	status     chan chan Status
-
-	rn *RawNode
-}
-
-func newNode(rn *RawNode) node {
-	return node{
-		propc:      make(chan msgWithResult),
-		recvc:      make(chan pb.Message),
-		confc:      make(chan pb.ConfChangeV2),
-		confstatec: make(chan pb.ConfState),
-		readyc:     make(chan Ready),
-		advancec:   make(chan struct{}),
-		// make tickc a buffered chan, so raft node can buffer some ticks when the node
-		// is busy processing raft messages. Raft node will resume process buffered
-		// ticks when it becomes idle.
-		tickc:  make(chan struct{}, 128),
-		done:   make(chan struct{}),
-		stop:   make(chan struct{}),
-		status: make(chan chan Status),
-		rn:     rn,
-	}
-}
-
-func (n *node) Stop() {
-	select {
-	case n.stop <- struct{}{}:
-		// Not already stopped, so trigger it
-	case <-n.done:
-		// Node has already been stopped - no need to do anything
-		return
-	}
-	// Block until the stop has been acknowledged by run()
-	<-n.done
-}
-
-func (n *node) run() {
-	var propc chan msgWithResult
-	var readyc chan Ready
-	var advancec chan struct{}
-	var rd Ready
-
-	r := n.rn.raft
-
-	lead := None
-
-	for {
-		if advancec != nil {
-			readyc = nil
-		} else if n.rn.HasReady() {
-			// Populate a Ready. Note that this Ready is not guaranteed to
-			// actually be handled. We will arm readyc, but there's no guarantee
-			// that we will actually send on it. It's possible that we will
-			// service another channel instead, loop around, and then populate
-			// the Ready again. We could instead force the previous Ready to be
-			// handled first, but it's generally good to emit larger Readys plus
-			// it simplifies testing (by emitting less frequently and more
-			// predictably).
-			rd = n.rn.readyWithoutAccept()
-			readyc = n.readyc
-		}
-
-		if lead != r.lead {
-			if r.hasLeader() {
-				if lead == None {
-					r.logger.Infof("raft.node: %x elected leader %x at term %d", r.id, r.lead, r.Term)
-				} else {
-					r.logger.Infof("raft.node: %x changed leader from %x to %x at term %d", r.id, lead, r.lead, r.Term)
-				}
-				propc = n.propc
-			} else {
-				r.logger.Infof("raft.node: %x lost leader %x at term %d", r.id, lead, r.Term)
-				propc = nil
-			}
-			lead = r.lead
-		}
-
-		select {
-		// TODO: maybe buffer the config propose if there exists one (the way
-		// described in raft dissertation)
-		// Currently it is dropped in Step silently.
-		case pm := <-propc:
-			m := pm.m
-			m.From = r.id
-			err := r.Step(m)
-			if pm.result != nil {
-				pm.result <- err
-				close(pm.result)
-			}
-		case m := <-n.recvc:
-			// filter out response message from unknown From.
-			if pr := r.prs.Progress[m.From]; pr != nil || !IsResponseMsg(m.Type) {
-				r.Step(m)
-			}
-		case cc := <-n.confc:
-			_, okBefore := r.prs.Progress[r.id]
-			cs := r.applyConfChange(cc)
-			// If the node was removed, block incoming proposals. Note that we
-			// only do this if the node was in the config before. Nodes may be
-			// a member of the group without knowing this (when they're catching
-			// up on the log and don't have the latest config) and we don't want
-			// to block the proposal channel in that case.
-			//
-			// NB: propc is reset when the leader changes, which, if we learn
-			// about it, sort of implies that we got readded, maybe? This isn't
-			// very sound and likely has bugs.
-			if _, okAfter := r.prs.Progress[r.id]; okBefore && !okAfter {
-				var found bool
-				for _, sl := range [][]uint64{cs.Voters, cs.VotersOutgoing} {
-					for _, id := range sl {
-						if id == r.id {
-							found = true
-						}
-					}
-				}
-				if !found {
-					propc = nil
-				}
-			}
-			select {
-			case n.confstatec <- cs:
-			case <-n.done:
-			}
-		case <-n.tickc:
-			n.rn.Tick()
-		case readyc <- rd:
-			n.rn.acceptReady(rd)
-			advancec = n.advancec
-		case <-advancec:
-			n.rn.Advance(rd)
-			rd = Ready{}
-			advancec = nil
-		case c := <-n.status:
-			c <- getStatus(r)
-		case <-n.stop:
-			close(n.done)
-			return
-		}
-	}
-}
-
-// Tick increments the internal logical clock for this Node. Election timeouts
-// and heartbeat timeouts are in units of ticks.
-func (n *node) Tick() {
-	select {
-	case n.tickc <- struct{}{}:
-	case <-n.done:
-	default:
-		n.rn.raft.logger.Warningf("%x (leader %v) A tick missed to fire. Node blocks too long!", n.rn.raft.id, n.rn.raft.id == n.rn.raft.lead)
-	}
-}
-
-func (n *node) Campaign(ctx context.Context) error { return n.step(ctx, pb.Message{Type: pb.MsgHup}) }
-
-func (n *node) Propose(ctx context.Context, data []byte) error {
-	return n.stepWait(ctx, pb.Message{Type: pb.MsgProp, Entries: []pb.Entry{{Data: data}}})
-}
-
-func (n *node) Step(ctx context.Context, m pb.Message) error {
-	// ignore unexpected local messages receiving over network
-	if IsLocalMsg(m.Type) {
-		// TODO: return an error?
-		return nil
-	}
-	return n.step(ctx, m)
-}
-
-func confChangeToMsg(c pb.ConfChangeI) (pb.Message, error) {
-	typ, data, err := pb.MarshalConfChange(c)
-	if err != nil {
-		return pb.Message{}, err
-	}
-	return pb.Message{Type: pb.MsgProp, Entries: []pb.Entry{{Type: typ, Data: data}}}, nil
-}
-
-func (n *node) ProposeConfChange(ctx context.Context, cc pb.ConfChangeI) error {
-	msg, err := confChangeToMsg(cc)
-	if err != nil {
-		return err
-	}
-	return n.Step(ctx, msg)
-}
-
-func (n *node) step(ctx context.Context, m pb.Message) error {
-	return n.stepWithWaitOption(ctx, m, false)
-}
-
-func (n *node) stepWait(ctx context.Context, m pb.Message) error {
-	return n.stepWithWaitOption(ctx, m, true)
-}
-
-// Step advances the state machine using msgs. The ctx.Err() will be returned,
-// if any.
-func (n *node) stepWithWaitOption(ctx context.Context, m pb.Message, wait bool) error {
-	if m.Type != pb.MsgProp {
-		select {
-		case n.recvc <- m:
-			return nil
-		case <-ctx.Done():
-			return ctx.Err()
-		case <-n.done:
-			return ErrStopped
-		}
-	}
-	ch := n.propc
-	pm := msgWithResult{m: m}
-	if wait {
-		pm.result = make(chan error, 1)
-	}
-	select {
-	case ch <- pm:
-		if !wait {
-			return nil
-		}
-	case <-ctx.Done():
-		return ctx.Err()
-	case <-n.done:
-		return ErrStopped
-	}
-	select {
-	case err := <-pm.result:
-		if err != nil {
-			return err
-		}
-	case <-ctx.Done():
-		return ctx.Err()
-	case <-n.done:
-		return ErrStopped
-	}
-	return nil
-}
-
-func (n *node) Ready() <-chan Ready { return n.readyc }
-
-func (n *node) Advance() {
-	select {
-	case n.advancec <- struct{}{}:
-	case <-n.done:
-	}
-}
-
-func (n *node) ApplyConfChange(cc pb.ConfChangeI) *pb.ConfState {
-	var cs pb.ConfState
-	select {
-	case n.confc <- cc.AsV2():
-	case <-n.done:
-	}
-	select {
-	case cs = <-n.confstatec:
-	case <-n.done:
-	}
-	return &cs
-}
-
-func (n *node) Status() Status {
-	c := make(chan Status)
-	select {
-	case n.status <- c:
-		return <-c
-	case <-n.done:
-		return Status{}
-	}
-}
-
-func (n *node) ReportUnreachable(id uint64) {
-	select {
-	case n.recvc <- pb.Message{Type: pb.MsgUnreachable, From: id}:
-	case <-n.done:
-	}
-}
-
-func (n *node) ReportSnapshot(id uint64, status SnapshotStatus) {
-	rej := status == SnapshotFailure
-
-	select {
-	case n.recvc <- pb.Message{Type: pb.MsgSnapStatus, From: id, Reject: rej}:
-	case <-n.done:
-	}
-}
-
-func (n *node) TransferLeadership(ctx context.Context, lead, transferee uint64) {
-	select {
-	// manually set 'from' and 'to', so that leader can voluntarily transfers its leadership
-	case n.recvc <- pb.Message{Type: pb.MsgTransferLeader, From: transferee, To: lead}:
-	case <-n.done:
-	case <-ctx.Done():
-	}
-}
-
-func (n *node) ReadIndex(ctx context.Context, rctx []byte) error {
-	return n.step(ctx, pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}})
-}
-
-func newReady(r *raft, prevSoftSt *SoftState, prevHardSt pb.HardState) Ready {
-	rd := Ready{
-		Entries:          r.raftLog.unstableEntries(),
-		CommittedEntries: r.raftLog.nextEnts(),
-		Messages:         r.msgs,
-	}
-	if softSt := r.softState(); !softSt.equal(prevSoftSt) {
-		rd.SoftState = softSt
-	}
-	if hardSt := r.hardState(); !isHardStateEqual(hardSt, prevHardSt) {
-		rd.HardState = hardSt
-	}
-	if r.raftLog.unstable.snapshot != nil {
-		rd.Snapshot = *r.raftLog.unstable.snapshot
-	}
-	if len(r.readStates) != 0 {
-		rd.ReadStates = r.readStates
-	}
-	rd.MustSync = MustSync(r.hardState(), prevHardSt, len(rd.Entries))
-	return rd
-}
-
-// MustSync returns true if the hard state and count of Raft entries indicate
-// that a synchronous write to persistent storage is required.
-func MustSync(st, prevst pb.HardState, entsnum int) bool {
-	// Persistent state on all servers:
-	// (Updated on stable storage before responding to RPCs)
-	// currentTerm
-	// votedFor
-	// log entries[]
-	return entsnum != 0 || st.Vote != prevst.Vote || st.Term != prevst.Term
-}
diff --git a/vendor/go.etcd.io/etcd/raft/quorum/joint.go b/vendor/go.etcd.io/etcd/raft/quorum/joint.go
deleted file mode 100644
index e3741e0..0000000
--- a/vendor/go.etcd.io/etcd/raft/quorum/joint.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2019 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 quorum
-
-// JointConfig is a configuration of two groups of (possibly overlapping)
-// majority configurations. Decisions require the support of both majorities.
-type JointConfig [2]MajorityConfig
-
-func (c JointConfig) String() string {
-	if len(c[1]) > 0 {
-		return c[0].String() + "&&" + c[1].String()
-	}
-	return c[0].String()
-}
-
-// IDs returns a newly initialized map representing the set of voters present
-// in the joint configuration.
-func (c JointConfig) IDs() map[uint64]struct{} {
-	m := map[uint64]struct{}{}
-	for _, cc := range c {
-		for id := range cc {
-			m[id] = struct{}{}
-		}
-	}
-	return m
-}
-
-// Describe returns a (multi-line) representation of the commit indexes for the
-// given lookuper.
-func (c JointConfig) Describe(l AckedIndexer) string {
-	return MajorityConfig(c.IDs()).Describe(l)
-}
-
-// CommittedIndex returns the largest committed index for the given joint
-// quorum. An index is jointly committed if it is committed in both constituent
-// majorities.
-func (c JointConfig) CommittedIndex(l AckedIndexer) Index {
-	idx0 := c[0].CommittedIndex(l)
-	idx1 := c[1].CommittedIndex(l)
-	if idx0 < idx1 {
-		return idx0
-	}
-	return idx1
-}
-
-// VoteResult takes a mapping of voters to yes/no (true/false) votes and returns
-// a result indicating whether the vote is pending, lost, or won. A joint quorum
-// requires both majority quorums to vote in favor.
-func (c JointConfig) VoteResult(votes map[uint64]bool) VoteResult {
-	r1 := c[0].VoteResult(votes)
-	r2 := c[1].VoteResult(votes)
-
-	if r1 == r2 {
-		// If they agree, return the agreed state.
-		return r1
-	}
-	if r1 == VoteLost || r2 == VoteLost {
-		// If either config has lost, loss is the only possible outcome.
-		return VoteLost
-	}
-	// One side won, the other one is pending, so the whole outcome is.
-	return VotePending
-}
diff --git a/vendor/go.etcd.io/etcd/raft/quorum/majority.go b/vendor/go.etcd.io/etcd/raft/quorum/majority.go
deleted file mode 100644
index 8858a36..0000000
--- a/vendor/go.etcd.io/etcd/raft/quorum/majority.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2019 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 quorum
-
-import (
-	"fmt"
-	"math"
-	"sort"
-	"strings"
-)
-
-// MajorityConfig is a set of IDs that uses majority quorums to make decisions.
-type MajorityConfig map[uint64]struct{}
-
-func (c MajorityConfig) String() string {
-	sl := make([]uint64, 0, len(c))
-	for id := range c {
-		sl = append(sl, id)
-	}
-	sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
-	var buf strings.Builder
-	buf.WriteByte('(')
-	for i := range sl {
-		if i > 0 {
-			buf.WriteByte(' ')
-		}
-		fmt.Fprint(&buf, sl[i])
-	}
-	buf.WriteByte(')')
-	return buf.String()
-}
-
-// Describe returns a (multi-line) representation of the commit indexes for the
-// given lookuper.
-func (c MajorityConfig) Describe(l AckedIndexer) string {
-	if len(c) == 0 {
-		return "<empty majority quorum>"
-	}
-	type tup struct {
-		id  uint64
-		idx Index
-		ok  bool // idx found?
-		bar int  // length of bar displayed for this tup
-	}
-
-	// Below, populate .bar so that the i-th largest commit index has bar i (we
-	// plot this as sort of a progress bar). The actual code is a bit more
-	// complicated and also makes sure that equal index => equal bar.
-
-	n := len(c)
-	info := make([]tup, 0, n)
-	for id := range c {
-		idx, ok := l.AckedIndex(id)
-		info = append(info, tup{id: id, idx: idx, ok: ok})
-	}
-
-	// Sort by index
-	sort.Slice(info, func(i, j int) bool {
-		if info[i].idx == info[j].idx {
-			return info[i].id < info[j].id
-		}
-		return info[i].idx < info[j].idx
-	})
-
-	// Populate .bar.
-	for i := range info {
-		if i > 0 && info[i-1].idx < info[i].idx {
-			info[i].bar = i
-		}
-	}
-
-	// Sort by ID.
-	sort.Slice(info, func(i, j int) bool {
-		return info[i].id < info[j].id
-	})
-
-	var buf strings.Builder
-
-	// Print.
-	fmt.Fprint(&buf, strings.Repeat(" ", n)+"    idx\n")
-	for i := range info {
-		bar := info[i].bar
-		if !info[i].ok {
-			fmt.Fprint(&buf, "?"+strings.Repeat(" ", n))
-		} else {
-			fmt.Fprint(&buf, strings.Repeat("x", bar)+">"+strings.Repeat(" ", n-bar))
-		}
-		fmt.Fprintf(&buf, " %5d    (id=%d)\n", info[i].idx, info[i].id)
-	}
-	return buf.String()
-}
-
-// Slice returns the MajorityConfig as a sorted slice.
-func (c MajorityConfig) Slice() []uint64 {
-	var sl []uint64
-	for id := range c {
-		sl = append(sl, id)
-	}
-	sort.Slice(sl, func(i, j int) bool { return sl[i] < sl[j] })
-	return sl
-}
-
-func insertionSort(sl []uint64) {
-	a, b := 0, len(sl)
-	for i := a + 1; i < b; i++ {
-		for j := i; j > a && sl[j] < sl[j-1]; j-- {
-			sl[j], sl[j-1] = sl[j-1], sl[j]
-		}
-	}
-}
-
-// CommittedIndex computes the committed index from those supplied via the
-// provided AckedIndexer (for the active config).
-func (c MajorityConfig) CommittedIndex(l AckedIndexer) Index {
-	n := len(c)
-	if n == 0 {
-		// This plays well with joint quorums which, when one half is the zero
-		// MajorityConfig, should behave like the other half.
-		return math.MaxUint64
-	}
-
-	// Use an on-stack slice to collect the committed indexes when n <= 7
-	// (otherwise we alloc). The alternative is to stash a slice on
-	// MajorityConfig, but this impairs usability (as is, MajorityConfig is just
-	// a map, and that's nice). The assumption is that running with a
-	// replication factor of >7 is rare, and in cases in which it happens
-	// performance is a lesser concern (additionally the performance
-	// implications of an allocation here are far from drastic).
-	var stk [7]uint64
-	var srt []uint64
-	if len(stk) >= n {
-		srt = stk[:n]
-	} else {
-		srt = make([]uint64, n)
-	}
-
-	{
-		// Fill the slice with the indexes observed. Any unused slots will be
-		// left as zero; these correspond to voters that may report in, but
-		// haven't yet. We fill from the right (since the zeroes will end up on
-		// the left after sorting below anyway).
-		i := n - 1
-		for id := range c {
-			if idx, ok := l.AckedIndex(id); ok {
-				srt[i] = uint64(idx)
-				i--
-			}
-		}
-	}
-
-	// Sort by index. Use a bespoke algorithm (copied from the stdlib's sort
-	// package) to keep srt on the stack.
-	insertionSort(srt)
-
-	// The smallest index into the array for which the value is acked by a
-	// quorum. In other words, from the end of the slice, move n/2+1 to the
-	// left (accounting for zero-indexing).
-	pos := n - (n/2 + 1)
-	return Index(srt[pos])
-}
-
-// VoteResult takes a mapping of voters to yes/no (true/false) votes and returns
-// a result indicating whether the vote is pending (i.e. neither a quorum of
-// yes/no has been reached), won (a quorum of yes has been reached), or lost (a
-// quorum of no has been reached).
-func (c MajorityConfig) VoteResult(votes map[uint64]bool) VoteResult {
-	if len(c) == 0 {
-		// By convention, the elections on an empty config win. This comes in
-		// handy with joint quorums because it'll make a half-populated joint
-		// quorum behave like a majority quorum.
-		return VoteWon
-	}
-
-	ny := [2]int{} // vote counts for no and yes, respectively
-
-	var missing int
-	for id := range c {
-		v, ok := votes[id]
-		if !ok {
-			missing++
-			continue
-		}
-		if v {
-			ny[1]++
-		} else {
-			ny[0]++
-		}
-	}
-
-	q := len(c)/2 + 1
-	if ny[1] >= q {
-		return VoteWon
-	}
-	if ny[1]+missing >= q {
-		return VotePending
-	}
-	return VoteLost
-}
diff --git a/vendor/go.etcd.io/etcd/raft/quorum/quorum.go b/vendor/go.etcd.io/etcd/raft/quorum/quorum.go
deleted file mode 100644
index 2899e46..0000000
--- a/vendor/go.etcd.io/etcd/raft/quorum/quorum.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2019 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 quorum
-
-import (
-	"math"
-	"strconv"
-)
-
-// Index is a Raft log position.
-type Index uint64
-
-func (i Index) String() string {
-	if i == math.MaxUint64 {
-		return "∞"
-	}
-	return strconv.FormatUint(uint64(i), 10)
-}
-
-// AckedIndexer allows looking up a commit index for a given ID of a voter
-// from a corresponding MajorityConfig.
-type AckedIndexer interface {
-	AckedIndex(voterID uint64) (idx Index, found bool)
-}
-
-type mapAckIndexer map[uint64]Index
-
-func (m mapAckIndexer) AckedIndex(id uint64) (Index, bool) {
-	idx, ok := m[id]
-	return idx, ok
-}
-
-// VoteResult indicates the outcome of a vote.
-//
-//go:generate stringer -type=VoteResult
-type VoteResult uint8
-
-const (
-	// VotePending indicates that the decision of the vote depends on future
-	// votes, i.e. neither "yes" or "no" has reached quorum yet.
-	VotePending VoteResult = 1 + iota
-	// VoteLost indicates that the quorum has voted "no".
-	VoteLost
-	// VoteWon indicates that the quorum has voted "yes".
-	VoteWon
-)
diff --git a/vendor/go.etcd.io/etcd/raft/quorum/voteresult_string.go b/vendor/go.etcd.io/etcd/raft/quorum/voteresult_string.go
deleted file mode 100644
index 9eca8fd..0000000
--- a/vendor/go.etcd.io/etcd/raft/quorum/voteresult_string.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Code generated by "stringer -type=VoteResult"; DO NOT EDIT.
-
-package quorum
-
-import "strconv"
-
-func _() {
-	// An "invalid array index" compiler error signifies that the constant values have changed.
-	// Re-run the stringer command to generate them again.
-	var x [1]struct{}
-	_ = x[VotePending-1]
-	_ = x[VoteLost-2]
-	_ = x[VoteWon-3]
-}
-
-const _VoteResult_name = "VotePendingVoteLostVoteWon"
-
-var _VoteResult_index = [...]uint8{0, 11, 19, 26}
-
-func (i VoteResult) String() string {
-	i -= 1
-	if i >= VoteResult(len(_VoteResult_index)-1) {
-		return "VoteResult(" + strconv.FormatInt(int64(i+1), 10) + ")"
-	}
-	return _VoteResult_name[_VoteResult_index[i]:_VoteResult_index[i+1]]
-}
diff --git a/vendor/go.etcd.io/etcd/raft/raft.go b/vendor/go.etcd.io/etcd/raft/raft.go
deleted file mode 100644
index cdcb43d..0000000
--- a/vendor/go.etcd.io/etcd/raft/raft.go
+++ /dev/null
@@ -1,1656 +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 raft
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"math"
-	"math/rand"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/raft/confchange"
-	"go.etcd.io/etcd/raft/quorum"
-	pb "go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/raft/tracker"
-)
-
-// None is a placeholder node ID used when there is no leader.
-const None uint64 = 0
-const noLimit = math.MaxUint64
-
-// Possible values for StateType.
-const (
-	StateFollower StateType = iota
-	StateCandidate
-	StateLeader
-	StatePreCandidate
-	numStates
-)
-
-type ReadOnlyOption int
-
-const (
-	// ReadOnlySafe guarantees the linearizability of the read only request by
-	// communicating with the quorum. It is the default and suggested option.
-	ReadOnlySafe ReadOnlyOption = iota
-	// ReadOnlyLeaseBased ensures linearizability of the read only request by
-	// relying on the leader lease. It can be affected by clock drift.
-	// If the clock drift is unbounded, leader might keep the lease longer than it
-	// should (clock can move backward/pause without any bound). ReadIndex is not safe
-	// in that case.
-	ReadOnlyLeaseBased
-)
-
-// Possible values for CampaignType
-const (
-	// campaignPreElection represents the first phase of a normal election when
-	// Config.PreVote is true.
-	campaignPreElection CampaignType = "CampaignPreElection"
-	// campaignElection represents a normal (time-based) election (the second phase
-	// of the election when Config.PreVote is true).
-	campaignElection CampaignType = "CampaignElection"
-	// campaignTransfer represents the type of leader transfer
-	campaignTransfer CampaignType = "CampaignTransfer"
-)
-
-// ErrProposalDropped is returned when the proposal is ignored by some cases,
-// so that the proposer can be notified and fail fast.
-var ErrProposalDropped = errors.New("raft proposal dropped")
-
-// lockedRand is a small wrapper around rand.Rand to provide
-// synchronization among multiple raft groups. Only the methods needed
-// by the code are exposed (e.g. Intn).
-type lockedRand struct {
-	mu   sync.Mutex
-	rand *rand.Rand
-}
-
-func (r *lockedRand) Intn(n int) int {
-	r.mu.Lock()
-	v := r.rand.Intn(n)
-	r.mu.Unlock()
-	return v
-}
-
-var globalRand = &lockedRand{
-	rand: rand.New(rand.NewSource(time.Now().UnixNano())),
-}
-
-// CampaignType represents the type of campaigning
-// the reason we use the type of string instead of uint64
-// is because it's simpler to compare and fill in raft entries
-type CampaignType string
-
-// StateType represents the role of a node in a cluster.
-type StateType uint64
-
-var stmap = [...]string{
-	"StateFollower",
-	"StateCandidate",
-	"StateLeader",
-	"StatePreCandidate",
-}
-
-func (st StateType) String() string {
-	return stmap[uint64(st)]
-}
-
-// Config contains the parameters to start a raft.
-type Config struct {
-	// ID is the identity of the local raft. ID cannot be 0.
-	ID uint64
-
-	// peers contains the IDs of all nodes (including self) in the raft cluster. It
-	// should only be set when starting a new raft cluster. Restarting raft from
-	// previous configuration will panic if peers is set. peer is private and only
-	// used for testing right now.
-	peers []uint64
-
-	// learners contains the IDs of all learner nodes (including self if the
-	// local node is a learner) in the raft cluster. learners only receives
-	// entries from the leader node. It does not vote or promote itself.
-	learners []uint64
-
-	// ElectionTick is the number of Node.Tick invocations that must pass between
-	// elections. That is, if a follower does not receive any message from the
-	// leader of current term before ElectionTick has elapsed, it will become
-	// candidate and start an election. ElectionTick must be greater than
-	// HeartbeatTick. We suggest ElectionTick = 10 * HeartbeatTick to avoid
-	// unnecessary leader switching.
-	ElectionTick int
-	// HeartbeatTick is the number of Node.Tick invocations that must pass between
-	// heartbeats. That is, a leader sends heartbeat messages to maintain its
-	// leadership every HeartbeatTick ticks.
-	HeartbeatTick int
-
-	// Storage is the storage for raft. raft generates entries and states to be
-	// stored in storage. raft reads the persisted entries and states out of
-	// Storage when it needs. raft reads out the previous state and configuration
-	// out of storage when restarting.
-	Storage Storage
-	// Applied is the last applied index. It should only be set when restarting
-	// raft. raft will not return entries to the application smaller or equal to
-	// Applied. If Applied is unset when restarting, raft might return previous
-	// applied entries. This is a very application dependent configuration.
-	Applied uint64
-
-	// MaxSizePerMsg limits the max byte size of each append message. Smaller
-	// value lowers the raft recovery cost(initial probing and message lost
-	// during normal operation). On the other side, it might affect the
-	// throughput during normal replication. Note: math.MaxUint64 for unlimited,
-	// 0 for at most one entry per message.
-	MaxSizePerMsg uint64
-	// MaxCommittedSizePerReady limits the size of the committed entries which
-	// can be applied.
-	MaxCommittedSizePerReady uint64
-	// MaxUncommittedEntriesSize limits the aggregate byte size of the
-	// uncommitted entries that may be appended to a leader's log. Once this
-	// limit is exceeded, proposals will begin to return ErrProposalDropped
-	// errors. Note: 0 for no limit.
-	MaxUncommittedEntriesSize uint64
-	// MaxInflightMsgs limits the max number of in-flight append messages during
-	// optimistic replication phase. The application transportation layer usually
-	// has its own sending buffer over TCP/UDP. Setting MaxInflightMsgs to avoid
-	// overflowing that sending buffer. TODO (xiangli): feedback to application to
-	// limit the proposal rate?
-	MaxInflightMsgs int
-
-	// CheckQuorum specifies if the leader should check quorum activity. Leader
-	// steps down when quorum is not active for an electionTimeout.
-	CheckQuorum bool
-
-	// PreVote enables the Pre-Vote algorithm described in raft thesis section
-	// 9.6. This prevents disruption when a node that has been partitioned away
-	// rejoins the cluster.
-	PreVote bool
-
-	// ReadOnlyOption specifies how the read only request is processed.
-	//
-	// ReadOnlySafe guarantees the linearizability of the read only request by
-	// communicating with the quorum. It is the default and suggested option.
-	//
-	// ReadOnlyLeaseBased ensures linearizability of the read only request by
-	// relying on the leader lease. It can be affected by clock drift.
-	// If the clock drift is unbounded, leader might keep the lease longer than it
-	// should (clock can move backward/pause without any bound). ReadIndex is not safe
-	// in that case.
-	// CheckQuorum MUST be enabled if ReadOnlyOption is ReadOnlyLeaseBased.
-	ReadOnlyOption ReadOnlyOption
-
-	// Logger is the logger used for raft log. For multinode which can host
-	// multiple raft group, each raft group can have its own logger
-	Logger Logger
-
-	// DisableProposalForwarding set to true means that followers will drop
-	// proposals, rather than forwarding them to the leader. One use case for
-	// this feature would be in a situation where the Raft leader is used to
-	// compute the data of a proposal, for example, adding a timestamp from a
-	// hybrid logical clock to data in a monotonically increasing way. Forwarding
-	// should be disabled to prevent a follower with an inaccurate hybrid
-	// logical clock from assigning the timestamp and then forwarding the data
-	// to the leader.
-	DisableProposalForwarding bool
-}
-
-func (c *Config) validate() error {
-	if c.ID == None {
-		return errors.New("cannot use none as id")
-	}
-
-	if c.HeartbeatTick <= 0 {
-		return errors.New("heartbeat tick must be greater than 0")
-	}
-
-	if c.ElectionTick <= c.HeartbeatTick {
-		return errors.New("election tick must be greater than heartbeat tick")
-	}
-
-	if c.Storage == nil {
-		return errors.New("storage cannot be nil")
-	}
-
-	if c.MaxUncommittedEntriesSize == 0 {
-		c.MaxUncommittedEntriesSize = noLimit
-	}
-
-	// default MaxCommittedSizePerReady to MaxSizePerMsg because they were
-	// previously the same parameter.
-	if c.MaxCommittedSizePerReady == 0 {
-		c.MaxCommittedSizePerReady = c.MaxSizePerMsg
-	}
-
-	if c.MaxInflightMsgs <= 0 {
-		return errors.New("max inflight messages must be greater than 0")
-	}
-
-	if c.Logger == nil {
-		c.Logger = raftLogger
-	}
-
-	if c.ReadOnlyOption == ReadOnlyLeaseBased && !c.CheckQuorum {
-		return errors.New("CheckQuorum must be enabled when ReadOnlyOption is ReadOnlyLeaseBased")
-	}
-
-	return nil
-}
-
-type raft struct {
-	id uint64
-
-	Term uint64
-	Vote uint64
-
-	readStates []ReadState
-
-	// the log
-	raftLog *raftLog
-
-	maxMsgSize         uint64
-	maxUncommittedSize uint64
-	// TODO(tbg): rename to trk.
-	prs tracker.ProgressTracker
-
-	state StateType
-
-	// isLearner is true if the local raft node is a learner.
-	isLearner bool
-
-	msgs []pb.Message
-
-	// the leader id
-	lead uint64
-	// leadTransferee is id of the leader transfer target when its value is not zero.
-	// Follow the procedure defined in raft thesis 3.10.
-	leadTransferee uint64
-	// Only one conf change may be pending (in the log, but not yet
-	// applied) at a time. This is enforced via pendingConfIndex, which
-	// is set to a value >= the log index of the latest pending
-	// configuration change (if any). Config changes are only allowed to
-	// be proposed if the leader's applied index is greater than this
-	// value.
-	pendingConfIndex uint64
-	// an estimate of the size of the uncommitted tail of the Raft log. Used to
-	// prevent unbounded log growth. Only maintained by the leader. Reset on
-	// term changes.
-	uncommittedSize uint64
-
-	readOnly *readOnly
-
-	// number of ticks since it reached last electionTimeout when it is leader
-	// or candidate.
-	// number of ticks since it reached last electionTimeout or received a
-	// valid message from current leader when it is a follower.
-	electionElapsed int
-
-	// number of ticks since it reached last heartbeatTimeout.
-	// only leader keeps heartbeatElapsed.
-	heartbeatElapsed int
-
-	checkQuorum bool
-	preVote     bool
-
-	heartbeatTimeout int
-	electionTimeout  int
-	// randomizedElectionTimeout is a random number between
-	// [electiontimeout, 2 * electiontimeout - 1]. It gets reset
-	// when raft changes its state to follower or candidate.
-	randomizedElectionTimeout int
-	disableProposalForwarding bool
-
-	tick func()
-	step stepFunc
-
-	logger Logger
-}
-
-func newRaft(c *Config) *raft {
-	if err := c.validate(); err != nil {
-		panic(err.Error())
-	}
-	raftlog := newLogWithSize(c.Storage, c.Logger, c.MaxCommittedSizePerReady)
-	hs, cs, err := c.Storage.InitialState()
-	if err != nil {
-		panic(err) // TODO(bdarnell)
-	}
-
-	if len(c.peers) > 0 || len(c.learners) > 0 {
-		if len(cs.Voters) > 0 || len(cs.Learners) > 0 {
-			// TODO(bdarnell): the peers argument is always nil except in
-			// tests; the argument should be removed and these tests should be
-			// updated to specify their nodes through a snapshot.
-			panic("cannot specify both newRaft(peers, learners) and ConfState.(Voters, Learners)")
-		}
-		cs.Voters = c.peers
-		cs.Learners = c.learners
-	}
-
-	r := &raft{
-		id:                        c.ID,
-		lead:                      None,
-		isLearner:                 false,
-		raftLog:                   raftlog,
-		maxMsgSize:                c.MaxSizePerMsg,
-		maxUncommittedSize:        c.MaxUncommittedEntriesSize,
-		prs:                       tracker.MakeProgressTracker(c.MaxInflightMsgs),
-		electionTimeout:           c.ElectionTick,
-		heartbeatTimeout:          c.HeartbeatTick,
-		logger:                    c.Logger,
-		checkQuorum:               c.CheckQuorum,
-		preVote:                   c.PreVote,
-		readOnly:                  newReadOnly(c.ReadOnlyOption),
-		disableProposalForwarding: c.DisableProposalForwarding,
-	}
-
-	cfg, prs, err := confchange.Restore(confchange.Changer{
-		Tracker:   r.prs,
-		LastIndex: raftlog.lastIndex(),
-	}, cs)
-	if err != nil {
-		panic(err)
-	}
-	assertConfStatesEquivalent(r.logger, cs, r.switchToConfig(cfg, prs))
-
-	if !IsEmptyHardState(hs) {
-		r.loadState(hs)
-	}
-	if c.Applied > 0 {
-		raftlog.appliedTo(c.Applied)
-	}
-	r.becomeFollower(r.Term, None)
-
-	var nodesStrs []string
-	for _, n := range r.prs.VoterNodes() {
-		nodesStrs = append(nodesStrs, fmt.Sprintf("%x", n))
-	}
-
-	r.logger.Infof("newRaft %x [peers: [%s], term: %d, commit: %d, applied: %d, lastindex: %d, lastterm: %d]",
-		r.id, strings.Join(nodesStrs, ","), r.Term, r.raftLog.committed, r.raftLog.applied, r.raftLog.lastIndex(), r.raftLog.lastTerm())
-	return r
-}
-
-func (r *raft) hasLeader() bool { return r.lead != None }
-
-func (r *raft) softState() *SoftState { return &SoftState{Lead: r.lead, RaftState: r.state} }
-
-func (r *raft) hardState() pb.HardState {
-	return pb.HardState{
-		Term:   r.Term,
-		Vote:   r.Vote,
-		Commit: r.raftLog.committed,
-	}
-}
-
-// send persists state to stable storage and then sends to its mailbox.
-func (r *raft) send(m pb.Message) {
-	m.From = r.id
-	if m.Type == pb.MsgVote || m.Type == pb.MsgVoteResp || m.Type == pb.MsgPreVote || m.Type == pb.MsgPreVoteResp {
-		if m.Term == 0 {
-			// All {pre-,}campaign messages need to have the term set when
-			// sending.
-			// - MsgVote: m.Term is the term the node is campaigning for,
-			//   non-zero as we increment the term when campaigning.
-			// - MsgVoteResp: m.Term is the new r.Term if the MsgVote was
-			//   granted, non-zero for the same reason MsgVote is
-			// - MsgPreVote: m.Term is the term the node will campaign,
-			//   non-zero as we use m.Term to indicate the next term we'll be
-			//   campaigning for
-			// - MsgPreVoteResp: m.Term is the term received in the original
-			//   MsgPreVote if the pre-vote was granted, non-zero for the
-			//   same reasons MsgPreVote is
-			panic(fmt.Sprintf("term should be set when sending %s", m.Type))
-		}
-	} else {
-		if m.Term != 0 {
-			panic(fmt.Sprintf("term should not be set when sending %s (was %d)", m.Type, m.Term))
-		}
-		// do not attach term to MsgProp, MsgReadIndex
-		// proposals are a way to forward to the leader and
-		// should be treated as local message.
-		// MsgReadIndex is also forwarded to leader.
-		if m.Type != pb.MsgProp && m.Type != pb.MsgReadIndex {
-			m.Term = r.Term
-		}
-	}
-	r.msgs = append(r.msgs, m)
-}
-
-// sendAppend sends an append RPC with new entries (if any) and the
-// current commit index to the given peer.
-func (r *raft) sendAppend(to uint64) {
-	r.maybeSendAppend(to, true)
-}
-
-// maybeSendAppend sends an append RPC with new entries to the given peer,
-// if necessary. Returns true if a message was sent. The sendIfEmpty
-// argument controls whether messages with no entries will be sent
-// ("empty" messages are useful to convey updated Commit indexes, but
-// are undesirable when we're sending multiple messages in a batch).
-func (r *raft) maybeSendAppend(to uint64, sendIfEmpty bool) bool {
-	pr := r.prs.Progress[to]
-	if pr.IsPaused() {
-		return false
-	}
-	m := pb.Message{}
-	m.To = to
-
-	term, errt := r.raftLog.term(pr.Next - 1)
-	ents, erre := r.raftLog.entries(pr.Next, r.maxMsgSize)
-	if len(ents) == 0 && !sendIfEmpty {
-		return false
-	}
-
-	if errt != nil || erre != nil { // send snapshot if we failed to get term or entries
-		if !pr.RecentActive {
-			r.logger.Debugf("ignore sending snapshot to %x since it is not recently active", to)
-			return false
-		}
-
-		m.Type = pb.MsgSnap
-		snapshot, err := r.raftLog.snapshot()
-		if err != nil {
-			if err == ErrSnapshotTemporarilyUnavailable {
-				r.logger.Debugf("%x failed to send snapshot to %x because snapshot is temporarily unavailable", r.id, to)
-				return false
-			}
-			panic(err) // TODO(bdarnell)
-		}
-		if IsEmptySnap(snapshot) {
-			panic("need non-empty snapshot")
-		}
-		m.Snapshot = snapshot
-		sindex, sterm := snapshot.Metadata.Index, snapshot.Metadata.Term
-		r.logger.Debugf("%x [firstindex: %d, commit: %d] sent snapshot[index: %d, term: %d] to %x [%s]",
-			r.id, r.raftLog.firstIndex(), r.raftLog.committed, sindex, sterm, to, pr)
-		pr.BecomeSnapshot(sindex)
-		r.logger.Debugf("%x paused sending replication messages to %x [%s]", r.id, to, pr)
-	} else {
-		m.Type = pb.MsgApp
-		m.Index = pr.Next - 1
-		m.LogTerm = term
-		m.Entries = ents
-		m.Commit = r.raftLog.committed
-		if n := len(m.Entries); n != 0 {
-			switch pr.State {
-			// optimistically increase the next when in StateReplicate
-			case tracker.StateReplicate:
-				last := m.Entries[n-1].Index
-				pr.OptimisticUpdate(last)
-				pr.Inflights.Add(last)
-			case tracker.StateProbe:
-				pr.ProbeSent = true
-			default:
-				r.logger.Panicf("%x is sending append in unhandled state %s", r.id, pr.State)
-			}
-		}
-	}
-	r.send(m)
-	return true
-}
-
-// sendHeartbeat sends a heartbeat RPC to the given peer.
-func (r *raft) sendHeartbeat(to uint64, ctx []byte) {
-	// Attach the commit as min(to.matched, r.committed).
-	// When the leader sends out heartbeat message,
-	// the receiver(follower) might not be matched with the leader
-	// or it might not have all the committed entries.
-	// The leader MUST NOT forward the follower's commit to
-	// an unmatched index.
-	commit := min(r.prs.Progress[to].Match, r.raftLog.committed)
-	m := pb.Message{
-		To:      to,
-		Type:    pb.MsgHeartbeat,
-		Commit:  commit,
-		Context: ctx,
-	}
-
-	r.send(m)
-}
-
-// bcastAppend sends RPC, with entries to all peers that are not up-to-date
-// according to the progress recorded in r.prs.
-func (r *raft) bcastAppend() {
-	r.prs.Visit(func(id uint64, _ *tracker.Progress) {
-		if id == r.id {
-			return
-		}
-		r.sendAppend(id)
-	})
-}
-
-// bcastHeartbeat sends RPC, without entries to all the peers.
-func (r *raft) bcastHeartbeat() {
-	lastCtx := r.readOnly.lastPendingRequestCtx()
-	if len(lastCtx) == 0 {
-		r.bcastHeartbeatWithCtx(nil)
-	} else {
-		r.bcastHeartbeatWithCtx([]byte(lastCtx))
-	}
-}
-
-func (r *raft) bcastHeartbeatWithCtx(ctx []byte) {
-	r.prs.Visit(func(id uint64, _ *tracker.Progress) {
-		if id == r.id {
-			return
-		}
-		r.sendHeartbeat(id, ctx)
-	})
-}
-
-func (r *raft) advance(rd Ready) {
-	// If entries were applied (or a snapshot), update our cursor for
-	// the next Ready. Note that if the current HardState contains a
-	// new Commit index, this does not mean that we're also applying
-	// all of the new entries due to commit pagination by size.
-	if index := rd.appliedCursor(); index > 0 {
-		r.raftLog.appliedTo(index)
-		if r.prs.Config.AutoLeave && index >= r.pendingConfIndex && r.state == StateLeader {
-			// If the current (and most recent, at least for this leader's term)
-			// configuration should be auto-left, initiate that now.
-			ccdata, err := (&pb.ConfChangeV2{}).Marshal()
-			if err != nil {
-				panic(err)
-			}
-			ent := pb.Entry{
-				Type: pb.EntryConfChangeV2,
-				Data: ccdata,
-			}
-			if !r.appendEntry(ent) {
-				// If we could not append the entry, bump the pending conf index
-				// so that we'll try again later.
-				//
-				// TODO(tbg): test this case.
-				r.pendingConfIndex = r.raftLog.lastIndex()
-			} else {
-				r.logger.Infof("initiating automatic transition out of joint configuration %s", r.prs.Config)
-			}
-		}
-	}
-	r.reduceUncommittedSize(rd.CommittedEntries)
-
-	if len(rd.Entries) > 0 {
-		e := rd.Entries[len(rd.Entries)-1]
-		r.raftLog.stableTo(e.Index, e.Term)
-	}
-	if !IsEmptySnap(rd.Snapshot) {
-		r.raftLog.stableSnapTo(rd.Snapshot.Metadata.Index)
-	}
-}
-
-// maybeCommit attempts to advance the commit index. Returns true if
-// the commit index changed (in which case the caller should call
-// r.bcastAppend).
-func (r *raft) maybeCommit() bool {
-	mci := r.prs.Committed()
-	return r.raftLog.maybeCommit(mci, r.Term)
-}
-
-func (r *raft) reset(term uint64) {
-	if r.Term != term {
-		r.Term = term
-		r.Vote = None
-	}
-	r.lead = None
-
-	r.electionElapsed = 0
-	r.heartbeatElapsed = 0
-	r.resetRandomizedElectionTimeout()
-
-	r.abortLeaderTransfer()
-
-	r.prs.ResetVotes()
-	r.prs.Visit(func(id uint64, pr *tracker.Progress) {
-		*pr = tracker.Progress{
-			Match:     0,
-			Next:      r.raftLog.lastIndex() + 1,
-			Inflights: tracker.NewInflights(r.prs.MaxInflight),
-			IsLearner: pr.IsLearner,
-		}
-		if id == r.id {
-			pr.Match = r.raftLog.lastIndex()
-		}
-	})
-
-	r.pendingConfIndex = 0
-	r.uncommittedSize = 0
-	r.readOnly = newReadOnly(r.readOnly.option)
-}
-
-func (r *raft) appendEntry(es ...pb.Entry) (accepted bool) {
-	li := r.raftLog.lastIndex()
-	for i := range es {
-		es[i].Term = r.Term
-		es[i].Index = li + 1 + uint64(i)
-	}
-	// Track the size of this uncommitted proposal.
-	if !r.increaseUncommittedSize(es) {
-		r.logger.Debugf(
-			"%x appending new entries to log would exceed uncommitted entry size limit; dropping proposal",
-			r.id,
-		)
-		// Drop the proposal.
-		return false
-	}
-	// use latest "last" index after truncate/append
-	li = r.raftLog.append(es...)
-	r.prs.Progress[r.id].MaybeUpdate(li)
-	// Regardless of maybeCommit's return, our caller will call bcastAppend.
-	r.maybeCommit()
-	return true
-}
-
-// tickElection is run by followers and candidates after r.electionTimeout.
-func (r *raft) tickElection() {
-	r.electionElapsed++
-
-	if r.promotable() && r.pastElectionTimeout() {
-		r.electionElapsed = 0
-		r.Step(pb.Message{From: r.id, Type: pb.MsgHup})
-	}
-}
-
-// tickHeartbeat is run by leaders to send a MsgBeat after r.heartbeatTimeout.
-func (r *raft) tickHeartbeat() {
-	r.heartbeatElapsed++
-	r.electionElapsed++
-
-	if r.electionElapsed >= r.electionTimeout {
-		r.electionElapsed = 0
-		if r.checkQuorum {
-			r.Step(pb.Message{From: r.id, Type: pb.MsgCheckQuorum})
-		}
-		// If current leader cannot transfer leadership in electionTimeout, it becomes leader again.
-		if r.state == StateLeader && r.leadTransferee != None {
-			r.abortLeaderTransfer()
-		}
-	}
-
-	if r.state != StateLeader {
-		return
-	}
-
-	if r.heartbeatElapsed >= r.heartbeatTimeout {
-		r.heartbeatElapsed = 0
-		r.Step(pb.Message{From: r.id, Type: pb.MsgBeat})
-	}
-}
-
-func (r *raft) becomeFollower(term uint64, lead uint64) {
-	r.step = stepFollower
-	r.reset(term)
-	r.tick = r.tickElection
-	r.lead = lead
-	r.state = StateFollower
-	r.logger.Infof("%x became follower at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomeCandidate() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateLeader {
-		panic("invalid transition [leader -> candidate]")
-	}
-	r.step = stepCandidate
-	r.reset(r.Term + 1)
-	r.tick = r.tickElection
-	r.Vote = r.id
-	r.state = StateCandidate
-	r.logger.Infof("%x became candidate at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomePreCandidate() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateLeader {
-		panic("invalid transition [leader -> pre-candidate]")
-	}
-	// Becoming a pre-candidate changes our step functions and state,
-	// but doesn't change anything else. In particular it does not increase
-	// r.Term or change r.Vote.
-	r.step = stepCandidate
-	r.prs.ResetVotes()
-	r.tick = r.tickElection
-	r.lead = None
-	r.state = StatePreCandidate
-	r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term)
-}
-
-func (r *raft) becomeLeader() {
-	// TODO(xiangli) remove the panic when the raft implementation is stable
-	if r.state == StateFollower {
-		panic("invalid transition [follower -> leader]")
-	}
-	r.step = stepLeader
-	r.reset(r.Term)
-	r.tick = r.tickHeartbeat
-	r.lead = r.id
-	r.state = StateLeader
-	// Followers enter replicate mode when they've been successfully probed
-	// (perhaps after having received a snapshot as a result). The leader is
-	// trivially in this state. Note that r.reset() has initialized this
-	// progress with the last index already.
-	r.prs.Progress[r.id].BecomeReplicate()
-
-	// Conservatively set the pendingConfIndex to the last index in the
-	// log. There may or may not be a pending config change, but it's
-	// safe to delay any future proposals until we commit all our
-	// pending log entries, and scanning the entire tail of the log
-	// could be expensive.
-	r.pendingConfIndex = r.raftLog.lastIndex()
-
-	emptyEnt := pb.Entry{Data: nil}
-	if !r.appendEntry(emptyEnt) {
-		// This won't happen because we just called reset() above.
-		r.logger.Panic("empty entry was dropped")
-	}
-	// As a special case, don't count the initial empty entry towards the
-	// uncommitted log quota. This is because we want to preserve the
-	// behavior of allowing one entry larger than quota if the current
-	// usage is zero.
-	r.reduceUncommittedSize([]pb.Entry{emptyEnt})
-	r.logger.Infof("%x became leader at term %d", r.id, r.Term)
-}
-
-// campaign transitions the raft instance to candidate state. This must only be
-// called after verifying that this is a legitimate transition.
-func (r *raft) campaign(t CampaignType) {
-	if !r.promotable() {
-		// This path should not be hit (callers are supposed to check), but
-		// better safe than sorry.
-		r.logger.Warningf("%x is unpromotable; campaign() should have been called", r.id)
-	}
-	var term uint64
-	var voteMsg pb.MessageType
-	if t == campaignPreElection {
-		r.becomePreCandidate()
-		voteMsg = pb.MsgPreVote
-		// PreVote RPCs are sent for the next term before we've incremented r.Term.
-		term = r.Term + 1
-	} else {
-		r.becomeCandidate()
-		voteMsg = pb.MsgVote
-		term = r.Term
-	}
-	if _, _, res := r.poll(r.id, voteRespMsgType(voteMsg), true); res == quorum.VoteWon {
-		// We won the election after voting for ourselves (which must mean that
-		// this is a single-node cluster). Advance to the next state.
-		if t == campaignPreElection {
-			r.campaign(campaignElection)
-		} else {
-			r.becomeLeader()
-		}
-		return
-	}
-	var ids []uint64
-	{
-		idMap := r.prs.Voters.IDs()
-		ids = make([]uint64, 0, len(idMap))
-		for id := range idMap {
-			ids = append(ids, id)
-		}
-		sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
-	}
-	for _, id := range ids {
-		if id == r.id {
-			continue
-		}
-		r.logger.Infof("%x [logterm: %d, index: %d] sent %s request to %x at term %d",
-			r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), voteMsg, id, r.Term)
-
-		var ctx []byte
-		if t == campaignTransfer {
-			ctx = []byte(t)
-		}
-		r.send(pb.Message{Term: term, To: id, Type: voteMsg, Index: r.raftLog.lastIndex(), LogTerm: r.raftLog.lastTerm(), Context: ctx})
-	}
-}
-
-func (r *raft) poll(id uint64, t pb.MessageType, v bool) (granted int, rejected int, result quorum.VoteResult) {
-	if v {
-		r.logger.Infof("%x received %s from %x at term %d", r.id, t, id, r.Term)
-	} else {
-		r.logger.Infof("%x received %s rejection from %x at term %d", r.id, t, id, r.Term)
-	}
-	r.prs.RecordVote(id, v)
-	return r.prs.TallyVotes()
-}
-
-func (r *raft) Step(m pb.Message) error {
-	// Handle the message term, which may result in our stepping down to a follower.
-	switch {
-	case m.Term == 0:
-		// local message
-	case m.Term > r.Term:
-		if m.Type == pb.MsgVote || m.Type == pb.MsgPreVote {
-			force := bytes.Equal(m.Context, []byte(campaignTransfer))
-			inLease := r.checkQuorum && r.lead != None && r.electionElapsed < r.electionTimeout
-			if !force && inLease {
-				// If a server receives a RequestVote request within the minimum election timeout
-				// of hearing from a current leader, it does not update its term or grant its vote
-				r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] ignored %s from %x [logterm: %d, index: %d] at term %d: lease is not expired (remaining ticks: %d)",
-					r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term, r.electionTimeout-r.electionElapsed)
-				return nil
-			}
-		}
-		switch {
-		case m.Type == pb.MsgPreVote:
-			// Never change our term in response to a PreVote
-		case m.Type == pb.MsgPreVoteResp && !m.Reject:
-			// We send pre-vote requests with a term in our future. If the
-			// pre-vote is granted, we will increment our term when we get a
-			// quorum. If it is not, the term comes from the node that
-			// rejected our vote so we should become a follower at the new
-			// term.
-		default:
-			r.logger.Infof("%x [term: %d] received a %s message with higher term from %x [term: %d]",
-				r.id, r.Term, m.Type, m.From, m.Term)
-			if m.Type == pb.MsgApp || m.Type == pb.MsgHeartbeat || m.Type == pb.MsgSnap {
-				r.becomeFollower(m.Term, m.From)
-			} else {
-				r.becomeFollower(m.Term, None)
-			}
-		}
-
-	case m.Term < r.Term:
-		if (r.checkQuorum || r.preVote) && (m.Type == pb.MsgHeartbeat || m.Type == pb.MsgApp) {
-			// We have received messages from a leader at a lower term. It is possible
-			// that these messages were simply delayed in the network, but this could
-			// also mean that this node has advanced its term number during a network
-			// partition, and it is now unable to either win an election or to rejoin
-			// the majority on the old term. If checkQuorum is false, this will be
-			// handled by incrementing term numbers in response to MsgVote with a
-			// higher term, but if checkQuorum is true we may not advance the term on
-			// MsgVote and must generate other messages to advance the term. The net
-			// result of these two features is to minimize the disruption caused by
-			// nodes that have been removed from the cluster's configuration: a
-			// removed node will send MsgVotes (or MsgPreVotes) which will be ignored,
-			// but it will not receive MsgApp or MsgHeartbeat, so it will not create
-			// disruptive term increases, by notifying leader of this node's activeness.
-			// The above comments also true for Pre-Vote
-			//
-			// When follower gets isolated, it soon starts an election ending
-			// up with a higher term than leader, although it won't receive enough
-			// votes to win the election. When it regains connectivity, this response
-			// with "pb.MsgAppResp" of higher term would force leader to step down.
-			// However, this disruption is inevitable to free this stuck node with
-			// fresh election. This can be prevented with Pre-Vote phase.
-			r.send(pb.Message{To: m.From, Type: pb.MsgAppResp})
-		} else if m.Type == pb.MsgPreVote {
-			// Before Pre-Vote enable, there may have candidate with higher term,
-			// but less log. After update to Pre-Vote, the cluster may deadlock if
-			// we drop messages with a lower term.
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected %s from %x [logterm: %d, index: %d] at term %d",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			r.send(pb.Message{To: m.From, Term: r.Term, Type: pb.MsgPreVoteResp, Reject: true})
-		} else {
-			// ignore other cases
-			r.logger.Infof("%x [term: %d] ignored a %s message with lower term from %x [term: %d]",
-				r.id, r.Term, m.Type, m.From, m.Term)
-		}
-		return nil
-	}
-
-	switch m.Type {
-	case pb.MsgHup:
-		if r.state != StateLeader {
-			if !r.promotable() {
-				r.logger.Warningf("%x is unpromotable and can not campaign; ignoring MsgHup", r.id)
-				return nil
-			}
-			ents, err := r.raftLog.slice(r.raftLog.applied+1, r.raftLog.committed+1, noLimit)
-			if err != nil {
-				r.logger.Panicf("unexpected error getting unapplied entries (%v)", err)
-			}
-			if n := numOfPendingConf(ents); n != 0 && r.raftLog.committed > r.raftLog.applied {
-				r.logger.Warningf("%x cannot campaign at term %d since there are still %d pending configuration changes to apply", r.id, r.Term, n)
-				return nil
-			}
-
-			r.logger.Infof("%x is starting a new election at term %d", r.id, r.Term)
-			if r.preVote {
-				r.campaign(campaignPreElection)
-			} else {
-				r.campaign(campaignElection)
-			}
-		} else {
-			r.logger.Debugf("%x ignoring MsgHup because already leader", r.id)
-		}
-
-	case pb.MsgVote, pb.MsgPreVote:
-		// We can vote if this is a repeat of a vote we've already cast...
-		canVote := r.Vote == m.From ||
-			// ...we haven't voted and we don't think there's a leader yet in this term...
-			(r.Vote == None && r.lead == None) ||
-			// ...or this is a PreVote for a future term...
-			(m.Type == pb.MsgPreVote && m.Term > r.Term)
-		// ...and we believe the candidate is up to date.
-		if canVote && r.raftLog.isUpToDate(m.Index, m.LogTerm) {
-			// Note: it turns out that that learners must be allowed to cast votes.
-			// This seems counter- intuitive but is necessary in the situation in which
-			// a learner has been promoted (i.e. is now a voter) but has not learned
-			// about this yet.
-			// For example, consider a group in which id=1 is a learner and id=2 and
-			// id=3 are voters. A configuration change promoting 1 can be committed on
-			// the quorum `{2,3}` without the config change being appended to the
-			// learner's log. If the leader (say 2) fails, there are de facto two
-			// voters remaining. Only 3 can win an election (due to its log containing
-			// all committed entries), but to do so it will need 1 to vote. But 1
-			// considers itself a learner and will continue to do so until 3 has
-			// stepped up as leader, replicates the conf change to 1, and 1 applies it.
-			// Ultimately, by receiving a request to vote, the learner realizes that
-			// the candidate believes it to be a voter, and that it should act
-			// accordingly. The candidate's config may be stale, too; but in that case
-			// it won't win the election, at least in the absence of the bug discussed
-			// in:
-			// https://github.com/etcd-io/etcd/issues/7625#issuecomment-488798263.
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] cast %s for %x [logterm: %d, index: %d] at term %d",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			// When responding to Msg{Pre,}Vote messages we include the term
-			// from the message, not the local term. To see why, consider the
-			// case where a single node was previously partitioned away and
-			// it's local term is now out of date. If we include the local term
-			// (recall that for pre-votes we don't update the local term), the
-			// (pre-)campaigning node on the other end will proceed to ignore
-			// the message (it ignores all out of date messages).
-			// The term in the original message and current local term are the
-			// same in the case of regular votes, but different for pre-votes.
-			r.send(pb.Message{To: m.From, Term: m.Term, Type: voteRespMsgType(m.Type)})
-			if m.Type == pb.MsgVote {
-				// Only record real votes.
-				r.electionElapsed = 0
-				r.Vote = m.From
-			}
-		} else {
-			r.logger.Infof("%x [logterm: %d, index: %d, vote: %x] rejected %s from %x [logterm: %d, index: %d] at term %d",
-				r.id, r.raftLog.lastTerm(), r.raftLog.lastIndex(), r.Vote, m.Type, m.From, m.LogTerm, m.Index, r.Term)
-			r.send(pb.Message{To: m.From, Term: r.Term, Type: voteRespMsgType(m.Type), Reject: true})
-		}
-
-	default:
-		err := r.step(r, m)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-type stepFunc func(r *raft, m pb.Message) error
-
-func stepLeader(r *raft, m pb.Message) error {
-	// These message types do not require any progress for m.From.
-	switch m.Type {
-	case pb.MsgBeat:
-		r.bcastHeartbeat()
-		return nil
-	case pb.MsgCheckQuorum:
-		// The leader should always see itself as active. As a precaution, handle
-		// the case in which the leader isn't in the configuration any more (for
-		// example if it just removed itself).
-		//
-		// TODO(tbg): I added a TODO in removeNode, it doesn't seem that the
-		// leader steps down when removing itself. I might be missing something.
-		if pr := r.prs.Progress[r.id]; pr != nil {
-			pr.RecentActive = true
-		}
-		if !r.prs.QuorumActive() {
-			r.logger.Warningf("%x stepped down to follower since quorum is not active", r.id)
-			r.becomeFollower(r.Term, None)
-		}
-		// Mark everyone (but ourselves) as inactive in preparation for the next
-		// CheckQuorum.
-		r.prs.Visit(func(id uint64, pr *tracker.Progress) {
-			if id != r.id {
-				pr.RecentActive = false
-			}
-		})
-		return nil
-	case pb.MsgProp:
-		if len(m.Entries) == 0 {
-			r.logger.Panicf("%x stepped empty MsgProp", r.id)
-		}
-		if r.prs.Progress[r.id] == nil {
-			// If we are not currently a member of the range (i.e. this node
-			// was removed from the configuration while serving as leader),
-			// drop any new proposals.
-			return ErrProposalDropped
-		}
-		if r.leadTransferee != None {
-			r.logger.Debugf("%x [term %d] transfer leadership to %x is in progress; dropping proposal", r.id, r.Term, r.leadTransferee)
-			return ErrProposalDropped
-		}
-
-		for i := range m.Entries {
-			e := &m.Entries[i]
-			var cc pb.ConfChangeI
-			if e.Type == pb.EntryConfChange {
-				var ccc pb.ConfChange
-				if err := ccc.Unmarshal(e.Data); err != nil {
-					panic(err)
-				}
-				cc = ccc
-			} else if e.Type == pb.EntryConfChangeV2 {
-				var ccc pb.ConfChangeV2
-				if err := ccc.Unmarshal(e.Data); err != nil {
-					panic(err)
-				}
-				cc = ccc
-			}
-			if cc != nil {
-				alreadyPending := r.pendingConfIndex > r.raftLog.applied
-				alreadyJoint := len(r.prs.Config.Voters[1]) > 0
-				wantsLeaveJoint := len(cc.AsV2().Changes) == 0
-
-				var refused string
-				if alreadyPending {
-					refused = fmt.Sprintf("possible unapplied conf change at index %d (applied to %d)", r.pendingConfIndex, r.raftLog.applied)
-				} else if alreadyJoint && !wantsLeaveJoint {
-					refused = "must transition out of joint config first"
-				} else if !alreadyJoint && wantsLeaveJoint {
-					refused = "not in joint state; refusing empty conf change"
-				}
-
-				if refused != "" {
-					r.logger.Infof("%x ignoring conf change %v at config %s: %s", r.id, cc, r.prs.Config, refused)
-					m.Entries[i] = pb.Entry{Type: pb.EntryNormal}
-				} else {
-					r.pendingConfIndex = r.raftLog.lastIndex() + uint64(i) + 1
-				}
-			}
-		}
-
-		if !r.appendEntry(m.Entries...) {
-			return ErrProposalDropped
-		}
-		r.bcastAppend()
-		return nil
-	case pb.MsgReadIndex:
-		// If more than the local vote is needed, go through a full broadcast,
-		// otherwise optimize.
-		if !r.prs.IsSingleton() {
-			if r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(r.raftLog.committed)) != r.Term {
-				// Reject read only request when this leader has not committed any log entry at its term.
-				return nil
-			}
-
-			// thinking: use an interally defined context instead of the user given context.
-			// We can express this in terms of the term and index instead of a user-supplied value.
-			// This would allow multiple reads to piggyback on the same message.
-			switch r.readOnly.option {
-			case ReadOnlySafe:
-				r.readOnly.addRequest(r.raftLog.committed, m)
-				// The local node automatically acks the request.
-				r.readOnly.recvAck(r.id, m.Entries[0].Data)
-				r.bcastHeartbeatWithCtx(m.Entries[0].Data)
-			case ReadOnlyLeaseBased:
-				ri := r.raftLog.committed
-				if m.From == None || m.From == r.id { // from local member
-					r.readStates = append(r.readStates, ReadState{Index: ri, RequestCtx: m.Entries[0].Data})
-				} else {
-					r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: ri, Entries: m.Entries})
-				}
-			}
-		} else { // only one voting member (the leader) in the cluster
-			if m.From == None || m.From == r.id { // from leader itself
-				r.readStates = append(r.readStates, ReadState{Index: r.raftLog.committed, RequestCtx: m.Entries[0].Data})
-			} else { // from learner member
-				r.send(pb.Message{To: m.From, Type: pb.MsgReadIndexResp, Index: r.raftLog.committed, Entries: m.Entries})
-			}
-		}
-
-		return nil
-	}
-
-	// All other message types require a progress for m.From (pr).
-	pr := r.prs.Progress[m.From]
-	if pr == nil {
-		r.logger.Debugf("%x no progress available for %x", r.id, m.From)
-		return nil
-	}
-	switch m.Type {
-	case pb.MsgAppResp:
-		pr.RecentActive = true
-
-		if m.Reject {
-			r.logger.Debugf("%x received MsgAppResp(MsgApp was rejected, lastindex: %d) from %x for index %d",
-				r.id, m.RejectHint, m.From, m.Index)
-			if pr.MaybeDecrTo(m.Index, m.RejectHint) {
-				r.logger.Debugf("%x decreased progress of %x to [%s]", r.id, m.From, pr)
-				if pr.State == tracker.StateReplicate {
-					pr.BecomeProbe()
-				}
-				r.sendAppend(m.From)
-			}
-		} else {
-			oldPaused := pr.IsPaused()
-			if pr.MaybeUpdate(m.Index) {
-				switch {
-				case pr.State == tracker.StateProbe:
-					pr.BecomeReplicate()
-				case pr.State == tracker.StateSnapshot && pr.Match >= pr.PendingSnapshot:
-					// TODO(tbg): we should also enter this branch if a snapshot is
-					// received that is below pr.PendingSnapshot but which makes it
-					// possible to use the log again.
-					r.logger.Debugf("%x recovered from needing snapshot, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-					// Transition back to replicating state via probing state
-					// (which takes the snapshot into account). If we didn't
-					// move to replicating state, that would only happen with
-					// the next round of appends (but there may not be a next
-					// round for a while, exposing an inconsistent RaftStatus).
-					pr.BecomeProbe()
-					pr.BecomeReplicate()
-				case pr.State == tracker.StateReplicate:
-					pr.Inflights.FreeLE(m.Index)
-				}
-
-				if r.maybeCommit() {
-					r.bcastAppend()
-				} else if oldPaused {
-					// If we were paused before, this node may be missing the
-					// latest commit index, so send it.
-					r.sendAppend(m.From)
-				}
-				// We've updated flow control information above, which may
-				// allow us to send multiple (size-limited) in-flight messages
-				// at once (such as when transitioning from probe to
-				// replicate, or when freeTo() covers multiple messages). If
-				// we have more entries to send, send as many messages as we
-				// can (without sending empty messages for the commit index)
-				for r.maybeSendAppend(m.From, false) {
-				}
-				// Transfer leadership is in progress.
-				if m.From == r.leadTransferee && pr.Match == r.raftLog.lastIndex() {
-					r.logger.Infof("%x sent MsgTimeoutNow to %x after received MsgAppResp", r.id, m.From)
-					r.sendTimeoutNow(m.From)
-				}
-			}
-		}
-	case pb.MsgHeartbeatResp:
-		pr.RecentActive = true
-		pr.ProbeSent = false
-
-		// free one slot for the full inflights window to allow progress.
-		if pr.State == tracker.StateReplicate && pr.Inflights.Full() {
-			pr.Inflights.FreeFirstOne()
-		}
-		if pr.Match < r.raftLog.lastIndex() {
-			r.sendAppend(m.From)
-		}
-
-		if r.readOnly.option != ReadOnlySafe || len(m.Context) == 0 {
-			return nil
-		}
-
-		if r.prs.Voters.VoteResult(r.readOnly.recvAck(m.From, m.Context)) != quorum.VoteWon {
-			return nil
-		}
-
-		rss := r.readOnly.advance(m)
-		for _, rs := range rss {
-			req := rs.req
-			if req.From == None || req.From == r.id { // from local member
-				r.readStates = append(r.readStates, ReadState{Index: rs.index, RequestCtx: req.Entries[0].Data})
-			} else {
-				r.send(pb.Message{To: req.From, Type: pb.MsgReadIndexResp, Index: rs.index, Entries: req.Entries})
-			}
-		}
-	case pb.MsgSnapStatus:
-		if pr.State != tracker.StateSnapshot {
-			return nil
-		}
-		// TODO(tbg): this code is very similar to the snapshot handling in
-		// MsgAppResp above. In fact, the code there is more correct than the
-		// code here and should likely be updated to match (or even better, the
-		// logic pulled into a newly created Progress state machine handler).
-		if !m.Reject {
-			pr.BecomeProbe()
-			r.logger.Debugf("%x snapshot succeeded, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-		} else {
-			// NB: the order here matters or we'll be probing erroneously from
-			// the snapshot index, but the snapshot never applied.
-			pr.PendingSnapshot = 0
-			pr.BecomeProbe()
-			r.logger.Debugf("%x snapshot failed, resumed sending replication messages to %x [%s]", r.id, m.From, pr)
-		}
-		// If snapshot finish, wait for the MsgAppResp from the remote node before sending
-		// out the next MsgApp.
-		// If snapshot failure, wait for a heartbeat interval before next try
-		pr.ProbeSent = true
-	case pb.MsgUnreachable:
-		// During optimistic replication, if the remote becomes unreachable,
-		// there is huge probability that a MsgApp is lost.
-		if pr.State == tracker.StateReplicate {
-			pr.BecomeProbe()
-		}
-		r.logger.Debugf("%x failed to send message to %x because it is unreachable [%s]", r.id, m.From, pr)
-	case pb.MsgTransferLeader:
-		if pr.IsLearner {
-			r.logger.Debugf("%x is learner. Ignored transferring leadership", r.id)
-			return nil
-		}
-		leadTransferee := m.From
-		lastLeadTransferee := r.leadTransferee
-		if lastLeadTransferee != None {
-			if lastLeadTransferee == leadTransferee {
-				r.logger.Infof("%x [term %d] transfer leadership to %x is in progress, ignores request to same node %x",
-					r.id, r.Term, leadTransferee, leadTransferee)
-				return nil
-			}
-			r.abortLeaderTransfer()
-			r.logger.Infof("%x [term %d] abort previous transferring leadership to %x", r.id, r.Term, lastLeadTransferee)
-		}
-		if leadTransferee == r.id {
-			r.logger.Debugf("%x is already leader. Ignored transferring leadership to self", r.id)
-			return nil
-		}
-		// Transfer leadership to third party.
-		r.logger.Infof("%x [term %d] starts to transfer leadership to %x", r.id, r.Term, leadTransferee)
-		// Transfer leadership should be finished in one electionTimeout, so reset r.electionElapsed.
-		r.electionElapsed = 0
-		r.leadTransferee = leadTransferee
-		if pr.Match == r.raftLog.lastIndex() {
-			r.sendTimeoutNow(leadTransferee)
-			r.logger.Infof("%x sends MsgTimeoutNow to %x immediately as %x already has up-to-date log", r.id, leadTransferee, leadTransferee)
-		} else {
-			r.sendAppend(leadTransferee)
-		}
-	}
-	return nil
-}
-
-// stepCandidate is shared by StateCandidate and StatePreCandidate; the difference is
-// whether they respond to MsgVoteResp or MsgPreVoteResp.
-func stepCandidate(r *raft, m pb.Message) error {
-	// Only handle vote responses corresponding to our candidacy (while in
-	// StateCandidate, we may get stale MsgPreVoteResp messages in this term from
-	// our pre-candidate state).
-	var myVoteRespType pb.MessageType
-	if r.state == StatePreCandidate {
-		myVoteRespType = pb.MsgPreVoteResp
-	} else {
-		myVoteRespType = pb.MsgVoteResp
-	}
-	switch m.Type {
-	case pb.MsgProp:
-		r.logger.Infof("%x no leader at term %d; dropping proposal", r.id, r.Term)
-		return ErrProposalDropped
-	case pb.MsgApp:
-		r.becomeFollower(m.Term, m.From) // always m.Term == r.Term
-		r.handleAppendEntries(m)
-	case pb.MsgHeartbeat:
-		r.becomeFollower(m.Term, m.From) // always m.Term == r.Term
-		r.handleHeartbeat(m)
-	case pb.MsgSnap:
-		r.becomeFollower(m.Term, m.From) // always m.Term == r.Term
-		r.handleSnapshot(m)
-	case myVoteRespType:
-		gr, rj, res := r.poll(m.From, m.Type, !m.Reject)
-		r.logger.Infof("%x has received %d %s votes and %d vote rejections", r.id, gr, m.Type, rj)
-		switch res {
-		case quorum.VoteWon:
-			if r.state == StatePreCandidate {
-				r.campaign(campaignElection)
-			} else {
-				r.becomeLeader()
-				r.bcastAppend()
-			}
-		case quorum.VoteLost:
-			// pb.MsgPreVoteResp contains future term of pre-candidate
-			// m.Term > r.Term; reuse r.Term
-			r.becomeFollower(r.Term, None)
-		}
-	case pb.MsgTimeoutNow:
-		r.logger.Debugf("%x [term %d state %v] ignored MsgTimeoutNow from %x", r.id, r.Term, r.state, m.From)
-	}
-	return nil
-}
-
-func stepFollower(r *raft, m pb.Message) error {
-	switch m.Type {
-	case pb.MsgProp:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping proposal", r.id, r.Term)
-			return ErrProposalDropped
-		} else if r.disableProposalForwarding {
-			r.logger.Infof("%x not forwarding to leader %x at term %d; dropping proposal", r.id, r.lead, r.Term)
-			return ErrProposalDropped
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgApp:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleAppendEntries(m)
-	case pb.MsgHeartbeat:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleHeartbeat(m)
-	case pb.MsgSnap:
-		r.electionElapsed = 0
-		r.lead = m.From
-		r.handleSnapshot(m)
-	case pb.MsgTransferLeader:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping leader transfer msg", r.id, r.Term)
-			return nil
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgTimeoutNow:
-		if r.promotable() {
-			r.logger.Infof("%x [term %d] received MsgTimeoutNow from %x and starts an election to get leadership.", r.id, r.Term, m.From)
-			// Leadership transfers never use pre-vote even if r.preVote is true; we
-			// know we are not recovering from a partition so there is no need for the
-			// extra round trip.
-			r.campaign(campaignTransfer)
-		} else {
-			r.logger.Infof("%x received MsgTimeoutNow from %x but is not promotable", r.id, m.From)
-		}
-	case pb.MsgReadIndex:
-		if r.lead == None {
-			r.logger.Infof("%x no leader at term %d; dropping index reading msg", r.id, r.Term)
-			return nil
-		}
-		m.To = r.lead
-		r.send(m)
-	case pb.MsgReadIndexResp:
-		if len(m.Entries) != 1 {
-			r.logger.Errorf("%x invalid format of MsgReadIndexResp from %x, entries count: %d", r.id, m.From, len(m.Entries))
-			return nil
-		}
-		r.readStates = append(r.readStates, ReadState{Index: m.Index, RequestCtx: m.Entries[0].Data})
-	}
-	return nil
-}
-
-func (r *raft) handleAppendEntries(m pb.Message) {
-	if m.Index < r.raftLog.committed {
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.committed})
-		return
-	}
-
-	if mlastIndex, ok := r.raftLog.maybeAppend(m.Index, m.LogTerm, m.Commit, m.Entries...); ok {
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: mlastIndex})
-	} else {
-		r.logger.Debugf("%x [logterm: %d, index: %d] rejected MsgApp [logterm: %d, index: %d] from %x",
-			r.id, r.raftLog.zeroTermOnErrCompacted(r.raftLog.term(m.Index)), m.Index, m.LogTerm, m.Index, m.From)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: m.Index, Reject: true, RejectHint: r.raftLog.lastIndex()})
-	}
-}
-
-func (r *raft) handleHeartbeat(m pb.Message) {
-	r.raftLog.commitTo(m.Commit)
-	r.send(pb.Message{To: m.From, Type: pb.MsgHeartbeatResp, Context: m.Context})
-}
-
-func (r *raft) handleSnapshot(m pb.Message) {
-	sindex, sterm := m.Snapshot.Metadata.Index, m.Snapshot.Metadata.Term
-	if r.restore(m.Snapshot) {
-		r.logger.Infof("%x [commit: %d] restored snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, sindex, sterm)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.lastIndex()})
-	} else {
-		r.logger.Infof("%x [commit: %d] ignored snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, sindex, sterm)
-		r.send(pb.Message{To: m.From, Type: pb.MsgAppResp, Index: r.raftLog.committed})
-	}
-}
-
-// restore recovers the state machine from a snapshot. It restores the log and the
-// configuration of state machine. If this method returns false, the snapshot was
-// ignored, either because it was obsolete or because of an error.
-func (r *raft) restore(s pb.Snapshot) bool {
-	if s.Metadata.Index <= r.raftLog.committed {
-		return false
-	}
-	if r.state != StateFollower {
-		// This is defense-in-depth: if the leader somehow ended up applying a
-		// snapshot, it could move into a new term without moving into a
-		// follower state. This should never fire, but if it did, we'd have
-		// prevented damage by returning early, so log only a loud warning.
-		//
-		// At the time of writing, the instance is guaranteed to be in follower
-		// state when this method is called.
-		r.logger.Warningf("%x attempted to restore snapshot as leader; should never happen", r.id)
-		r.becomeFollower(r.Term+1, None)
-		return false
-	}
-
-	// More defense-in-depth: throw away snapshot if recipient is not in the
-	// config. This shouldn't ever happen (at the time of writing) but lots of
-	// code here and there assumes that r.id is in the progress tracker.
-	found := false
-	cs := s.Metadata.ConfState
-	for _, set := range [][]uint64{
-		cs.Voters,
-		cs.Learners,
-	} {
-		for _, id := range set {
-			if id == r.id {
-				found = true
-				break
-			}
-		}
-	}
-	if !found {
-		r.logger.Warningf(
-			"%x attempted to restore snapshot but it is not in the ConfState %v; should never happen",
-			r.id, cs,
-		)
-		return false
-	}
-
-	// Now go ahead and actually restore.
-
-	if r.raftLog.matchTerm(s.Metadata.Index, s.Metadata.Term) {
-		r.logger.Infof("%x [commit: %d, lastindex: %d, lastterm: %d] fast-forwarded commit to snapshot [index: %d, term: %d]",
-			r.id, r.raftLog.committed, r.raftLog.lastIndex(), r.raftLog.lastTerm(), s.Metadata.Index, s.Metadata.Term)
-		r.raftLog.commitTo(s.Metadata.Index)
-		return false
-	}
-
-	r.raftLog.restore(s)
-
-	// Reset the configuration and add the (potentially updated) peers in anew.
-	r.prs = tracker.MakeProgressTracker(r.prs.MaxInflight)
-	cfg, prs, err := confchange.Restore(confchange.Changer{
-		Tracker:   r.prs,
-		LastIndex: r.raftLog.lastIndex(),
-	}, cs)
-
-	if err != nil {
-		// This should never happen. Either there's a bug in our config change
-		// handling or the client corrupted the conf change.
-		panic(fmt.Sprintf("unable to restore config %+v: %s", cs, err))
-	}
-
-	assertConfStatesEquivalent(r.logger, cs, r.switchToConfig(cfg, prs))
-
-	pr := r.prs.Progress[r.id]
-	pr.MaybeUpdate(pr.Next - 1) // TODO(tbg): this is untested and likely unneeded
-
-	r.logger.Infof("%x [commit: %d, lastindex: %d, lastterm: %d] restored snapshot [index: %d, term: %d]",
-		r.id, r.raftLog.committed, r.raftLog.lastIndex(), r.raftLog.lastTerm(), s.Metadata.Index, s.Metadata.Term)
-	return true
-}
-
-// promotable indicates whether state machine can be promoted to leader,
-// which is true when its own id is in progress list.
-func (r *raft) promotable() bool {
-	pr := r.prs.Progress[r.id]
-	return pr != nil && !pr.IsLearner
-}
-
-func (r *raft) applyConfChange(cc pb.ConfChangeV2) pb.ConfState {
-	cfg, prs, err := func() (tracker.Config, tracker.ProgressMap, error) {
-		changer := confchange.Changer{
-			Tracker:   r.prs,
-			LastIndex: r.raftLog.lastIndex(),
-		}
-		if cc.LeaveJoint() {
-			return changer.LeaveJoint()
-		} else if autoLeave, ok := cc.EnterJoint(); ok {
-			return changer.EnterJoint(autoLeave, cc.Changes...)
-		}
-		return changer.Simple(cc.Changes...)
-	}()
-
-	if err != nil {
-		// TODO(tbg): return the error to the caller.
-		panic(err)
-	}
-
-	return r.switchToConfig(cfg, prs)
-}
-
-// switchToConfig reconfigures this node to use the provided configuration. It
-// updates the in-memory state and, when necessary, carries out additional
-// actions such as reacting to the removal of nodes or changed quorum
-// requirements.
-//
-// The inputs usually result from restoring a ConfState or applying a ConfChange.
-func (r *raft) switchToConfig(cfg tracker.Config, prs tracker.ProgressMap) pb.ConfState {
-	r.prs.Config = cfg
-	r.prs.Progress = prs
-
-	r.logger.Infof("%x switched to configuration %s", r.id, r.prs.Config)
-	cs := r.prs.ConfState()
-	pr, ok := r.prs.Progress[r.id]
-
-	// Update whether the node itself is a learner, resetting to false when the
-	// node is removed.
-	r.isLearner = ok && pr.IsLearner
-
-	if (!ok || r.isLearner) && r.state == StateLeader {
-		// This node is leader and was removed or demoted. We prevent demotions
-		// at the time writing but hypothetically we handle them the same way as
-		// removing the leader: stepping down into the next Term.
-		//
-		// TODO(tbg): step down (for sanity) and ask follower with largest Match
-		// to TimeoutNow (to avoid interruption). This might still drop some
-		// proposals but it's better than nothing.
-		//
-		// TODO(tbg): test this branch. It is untested at the time of writing.
-		return cs
-	}
-
-	// The remaining steps only make sense if this node is the leader and there
-	// are other nodes.
-	if r.state != StateLeader || len(cs.Voters) == 0 {
-		return cs
-	}
-
-	if r.maybeCommit() {
-		// If the configuration change means that more entries are committed now,
-		// broadcast/append to everyone in the updated config.
-		r.bcastAppend()
-	} else {
-		// Otherwise, still probe the newly added replicas; there's no reason to
-		// let them wait out a heartbeat interval (or the next incoming
-		// proposal).
-		r.prs.Visit(func(id uint64, pr *tracker.Progress) {
-			r.maybeSendAppend(id, false /* sendIfEmpty */)
-		})
-	}
-	// If the the leadTransferee was removed, abort the leadership transfer.
-	if _, tOK := r.prs.Progress[r.leadTransferee]; !tOK && r.leadTransferee != 0 {
-		r.abortLeaderTransfer()
-	}
-
-	return cs
-}
-
-func (r *raft) loadState(state pb.HardState) {
-	if state.Commit < r.raftLog.committed || state.Commit > r.raftLog.lastIndex() {
-		r.logger.Panicf("%x state.commit %d is out of range [%d, %d]", r.id, state.Commit, r.raftLog.committed, r.raftLog.lastIndex())
-	}
-	r.raftLog.committed = state.Commit
-	r.Term = state.Term
-	r.Vote = state.Vote
-}
-
-// pastElectionTimeout returns true iff r.electionElapsed is greater
-// than or equal to the randomized election timeout in
-// [electiontimeout, 2 * electiontimeout - 1].
-func (r *raft) pastElectionTimeout() bool {
-	return r.electionElapsed >= r.randomizedElectionTimeout
-}
-
-func (r *raft) resetRandomizedElectionTimeout() {
-	r.randomizedElectionTimeout = r.electionTimeout + globalRand.Intn(r.electionTimeout)
-}
-
-func (r *raft) sendTimeoutNow(to uint64) {
-	r.send(pb.Message{To: to, Type: pb.MsgTimeoutNow})
-}
-
-func (r *raft) abortLeaderTransfer() {
-	r.leadTransferee = None
-}
-
-// increaseUncommittedSize computes the size of the proposed entries and
-// determines whether they would push leader over its maxUncommittedSize limit.
-// If the new entries would exceed the limit, the method returns false. If not,
-// the increase in uncommitted entry size is recorded and the method returns
-// true.
-func (r *raft) increaseUncommittedSize(ents []pb.Entry) bool {
-	var s uint64
-	for _, e := range ents {
-		s += uint64(PayloadSize(e))
-	}
-
-	if r.uncommittedSize > 0 && r.uncommittedSize+s > r.maxUncommittedSize {
-		// If the uncommitted tail of the Raft log is empty, allow any size
-		// proposal. Otherwise, limit the size of the uncommitted tail of the
-		// log and drop any proposal that would push the size over the limit.
-		return false
-	}
-	r.uncommittedSize += s
-	return true
-}
-
-// reduceUncommittedSize accounts for the newly committed entries by decreasing
-// the uncommitted entry size limit.
-func (r *raft) reduceUncommittedSize(ents []pb.Entry) {
-	if r.uncommittedSize == 0 {
-		// Fast-path for followers, who do not track or enforce the limit.
-		return
-	}
-
-	var s uint64
-	for _, e := range ents {
-		s += uint64(PayloadSize(e))
-	}
-	if s > r.uncommittedSize {
-		// uncommittedSize may underestimate the size of the uncommitted Raft
-		// log tail but will never overestimate it. Saturate at 0 instead of
-		// allowing overflow.
-		r.uncommittedSize = 0
-	} else {
-		r.uncommittedSize -= s
-	}
-}
-
-func numOfPendingConf(ents []pb.Entry) int {
-	n := 0
-	for i := range ents {
-		if ents[i].Type == pb.EntryConfChange {
-			n++
-		}
-	}
-	return n
-}
diff --git a/vendor/go.etcd.io/etcd/raft/raftpb/confchange.go b/vendor/go.etcd.io/etcd/raft/raftpb/confchange.go
deleted file mode 100644
index 46a7a70..0000000
--- a/vendor/go.etcd.io/etcd/raft/raftpb/confchange.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2019 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 raftpb
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-
-	"github.com/gogo/protobuf/proto"
-)
-
-// ConfChangeI abstracts over ConfChangeV2 and (legacy) ConfChange to allow
-// treating them in a unified manner.
-type ConfChangeI interface {
-	AsV2() ConfChangeV2
-	AsV1() (ConfChange, bool)
-}
-
-// MarshalConfChange calls Marshal on the underlying ConfChange or ConfChangeV2
-// and returns the result along with the corresponding EntryType.
-func MarshalConfChange(c ConfChangeI) (EntryType, []byte, error) {
-	var typ EntryType
-	var ccdata []byte
-	var err error
-	if ccv1, ok := c.AsV1(); ok {
-		typ = EntryConfChange
-		ccdata, err = ccv1.Marshal()
-	} else {
-		ccv2 := c.AsV2()
-		typ = EntryConfChangeV2
-		ccdata, err = ccv2.Marshal()
-	}
-	return typ, ccdata, err
-}
-
-// AsV2 returns a V2 configuration change carrying out the same operation.
-func (c ConfChange) AsV2() ConfChangeV2 {
-	return ConfChangeV2{
-		Changes: []ConfChangeSingle{{
-			Type:   c.Type,
-			NodeID: c.NodeID,
-		}},
-		Context: c.Context,
-	}
-}
-
-// AsV1 returns the ConfChange and true.
-func (c ConfChange) AsV1() (ConfChange, bool) {
-	return c, true
-}
-
-// AsV2 is the identity.
-func (c ConfChangeV2) AsV2() ConfChangeV2 { return c }
-
-// AsV1 returns ConfChange{} and false.
-func (c ConfChangeV2) AsV1() (ConfChange, bool) { return ConfChange{}, false }
-
-// EnterJoint returns two bools. The second bool is true if and only if this
-// config change will use Joint Consensus, which is the case if it contains more
-// than one change or if the use of Joint Consensus was requested explicitly.
-// The first bool can only be true if second one is, and indicates whether the
-// Joint State will be left automatically.
-func (c *ConfChangeV2) EnterJoint() (autoLeave bool, ok bool) {
-	// NB: in theory, more config changes could qualify for the "simple"
-	// protocol but it depends on the config on top of which the changes apply.
-	// For example, adding two learners is not OK if both nodes are part of the
-	// base config (i.e. two voters are turned into learners in the process of
-	// applying the conf change). In practice, these distinctions should not
-	// matter, so we keep it simple and use Joint Consensus liberally.
-	if c.Transition != ConfChangeTransitionAuto || len(c.Changes) > 1 {
-		// Use Joint Consensus.
-		var autoLeave bool
-		switch c.Transition {
-		case ConfChangeTransitionAuto:
-			autoLeave = true
-		case ConfChangeTransitionJointImplicit:
-			autoLeave = true
-		case ConfChangeTransitionJointExplicit:
-		default:
-			panic(fmt.Sprintf("unknown transition: %+v", c))
-		}
-		return autoLeave, true
-	}
-	return false, false
-}
-
-// LeaveJoint is true if the configuration change leaves a joint configuration.
-// This is the case if the ConfChangeV2 is zero, with the possible exception of
-// the Context field.
-func (c *ConfChangeV2) LeaveJoint() bool {
-	cpy := *c
-	cpy.Context = nil
-	return proto.Equal(&cpy, &ConfChangeV2{})
-}
-
-// ConfChangesFromString parses a Space-delimited sequence of operations into a
-// slice of ConfChangeSingle. The supported operations are:
-// - vn: make n a voter,
-// - ln: make n a learner,
-// - rn: remove n, and
-// - un: update n.
-func ConfChangesFromString(s string) ([]ConfChangeSingle, error) {
-	var ccs []ConfChangeSingle
-	toks := strings.Split(strings.TrimSpace(s), " ")
-	if toks[0] == "" {
-		toks = nil
-	}
-	for _, tok := range toks {
-		if len(tok) < 2 {
-			return nil, fmt.Errorf("unknown token %s", tok)
-		}
-		var cc ConfChangeSingle
-		switch tok[0] {
-		case 'v':
-			cc.Type = ConfChangeAddNode
-		case 'l':
-			cc.Type = ConfChangeAddLearnerNode
-		case 'r':
-			cc.Type = ConfChangeRemoveNode
-		case 'u':
-			cc.Type = ConfChangeUpdateNode
-		default:
-			return nil, fmt.Errorf("unknown input: %s", tok)
-		}
-		id, err := strconv.ParseUint(tok[1:], 10, 64)
-		if err != nil {
-			return nil, err
-		}
-		cc.NodeID = id
-		ccs = append(ccs, cc)
-	}
-	return ccs, nil
-}
-
-// ConfChangesToString is the inverse to ConfChangesFromString.
-func ConfChangesToString(ccs []ConfChangeSingle) string {
-	var buf strings.Builder
-	for i, cc := range ccs {
-		if i > 0 {
-			buf.WriteByte(' ')
-		}
-		switch cc.Type {
-		case ConfChangeAddNode:
-			buf.WriteByte('v')
-		case ConfChangeAddLearnerNode:
-			buf.WriteByte('l')
-		case ConfChangeRemoveNode:
-			buf.WriteByte('r')
-		case ConfChangeUpdateNode:
-			buf.WriteByte('u')
-		default:
-			buf.WriteString("unknown")
-		}
-		fmt.Fprintf(&buf, "%d", cc.NodeID)
-	}
-	return buf.String()
-}
diff --git a/vendor/go.etcd.io/etcd/raft/raftpb/confstate.go b/vendor/go.etcd.io/etcd/raft/raftpb/confstate.go
deleted file mode 100644
index 4bda932..0000000
--- a/vendor/go.etcd.io/etcd/raft/raftpb/confstate.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2019 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 raftpb
-
-import (
-	"fmt"
-	"reflect"
-	"sort"
-)
-
-// Equivalent returns a nil error if the inputs describe the same configuration.
-// On mismatch, returns a descriptive error showing the differences.
-func (cs ConfState) Equivalent(cs2 ConfState) error {
-	cs1 := cs
-	orig1, orig2 := cs1, cs2
-	s := func(sl *[]uint64) {
-		*sl = append([]uint64(nil), *sl...)
-		sort.Slice(*sl, func(i, j int) bool { return (*sl)[i] < (*sl)[j] })
-	}
-
-	for _, cs := range []*ConfState{&cs1, &cs2} {
-		s(&cs.Voters)
-		s(&cs.Learners)
-		s(&cs.VotersOutgoing)
-		s(&cs.LearnersNext)
-		cs.XXX_unrecognized = nil
-	}
-
-	if !reflect.DeepEqual(cs1, cs2) {
-		return fmt.Errorf("ConfStates not equivalent after sorting:\n%+#v\n%+#v\nInputs were:\n%+#v\n%+#v", cs1, cs2, orig1, orig2)
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/raft/raftpb/raft.pb.go b/vendor/go.etcd.io/etcd/raft/raftpb/raft.pb.go
deleted file mode 100644
index fcf259c..0000000
--- a/vendor/go.etcd.io/etcd/raft/raftpb/raft.pb.go
+++ /dev/null
@@ -1,2646 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: raft.proto
-
-/*
-	Package raftpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		raft.proto
-
-	It has these top-level messages:
-		Entry
-		SnapshotMetadata
-		Snapshot
-		Message
-		HardState
-		ConfState
-		ConfChange
-		ConfChangeSingle
-		ConfChangeV2
-*/
-package raftpb
-
-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 EntryType int32
-
-const (
-	EntryNormal       EntryType = 0
-	EntryConfChange   EntryType = 1
-	EntryConfChangeV2 EntryType = 2
-)
-
-var EntryType_name = map[int32]string{
-	0: "EntryNormal",
-	1: "EntryConfChange",
-	2: "EntryConfChangeV2",
-}
-var EntryType_value = map[string]int32{
-	"EntryNormal":       0,
-	"EntryConfChange":   1,
-	"EntryConfChangeV2": 2,
-}
-
-func (x EntryType) Enum() *EntryType {
-	p := new(EntryType)
-	*p = x
-	return p
-}
-func (x EntryType) String() string {
-	return proto.EnumName(EntryType_name, int32(x))
-}
-func (x *EntryType) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(EntryType_value, data, "EntryType")
-	if err != nil {
-		return err
-	}
-	*x = EntryType(value)
-	return nil
-}
-func (EntryType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{0} }
-
-type MessageType int32
-
-const (
-	MsgHup            MessageType = 0
-	MsgBeat           MessageType = 1
-	MsgProp           MessageType = 2
-	MsgApp            MessageType = 3
-	MsgAppResp        MessageType = 4
-	MsgVote           MessageType = 5
-	MsgVoteResp       MessageType = 6
-	MsgSnap           MessageType = 7
-	MsgHeartbeat      MessageType = 8
-	MsgHeartbeatResp  MessageType = 9
-	MsgUnreachable    MessageType = 10
-	MsgSnapStatus     MessageType = 11
-	MsgCheckQuorum    MessageType = 12
-	MsgTransferLeader MessageType = 13
-	MsgTimeoutNow     MessageType = 14
-	MsgReadIndex      MessageType = 15
-	MsgReadIndexResp  MessageType = 16
-	MsgPreVote        MessageType = 17
-	MsgPreVoteResp    MessageType = 18
-)
-
-var MessageType_name = map[int32]string{
-	0:  "MsgHup",
-	1:  "MsgBeat",
-	2:  "MsgProp",
-	3:  "MsgApp",
-	4:  "MsgAppResp",
-	5:  "MsgVote",
-	6:  "MsgVoteResp",
-	7:  "MsgSnap",
-	8:  "MsgHeartbeat",
-	9:  "MsgHeartbeatResp",
-	10: "MsgUnreachable",
-	11: "MsgSnapStatus",
-	12: "MsgCheckQuorum",
-	13: "MsgTransferLeader",
-	14: "MsgTimeoutNow",
-	15: "MsgReadIndex",
-	16: "MsgReadIndexResp",
-	17: "MsgPreVote",
-	18: "MsgPreVoteResp",
-}
-var MessageType_value = map[string]int32{
-	"MsgHup":            0,
-	"MsgBeat":           1,
-	"MsgProp":           2,
-	"MsgApp":            3,
-	"MsgAppResp":        4,
-	"MsgVote":           5,
-	"MsgVoteResp":       6,
-	"MsgSnap":           7,
-	"MsgHeartbeat":      8,
-	"MsgHeartbeatResp":  9,
-	"MsgUnreachable":    10,
-	"MsgSnapStatus":     11,
-	"MsgCheckQuorum":    12,
-	"MsgTransferLeader": 13,
-	"MsgTimeoutNow":     14,
-	"MsgReadIndex":      15,
-	"MsgReadIndexResp":  16,
-	"MsgPreVote":        17,
-	"MsgPreVoteResp":    18,
-}
-
-func (x MessageType) Enum() *MessageType {
-	p := new(MessageType)
-	*p = x
-	return p
-}
-func (x MessageType) String() string {
-	return proto.EnumName(MessageType_name, int32(x))
-}
-func (x *MessageType) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType")
-	if err != nil {
-		return err
-	}
-	*x = MessageType(value)
-	return nil
-}
-func (MessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{1} }
-
-// ConfChangeTransition specifies the behavior of a configuration change with
-// respect to joint consensus.
-type ConfChangeTransition int32
-
-const (
-	// Automatically use the simple protocol if possible, otherwise fall back
-	// to ConfChangeJointImplicit. Most applications will want to use this.
-	ConfChangeTransitionAuto ConfChangeTransition = 0
-	// Use joint consensus unconditionally, and transition out of them
-	// automatically (by proposing a zero configuration change).
-	//
-	// This option is suitable for applications that want to minimize the time
-	// spent in the joint configuration and do not store the joint configuration
-	// in the state machine (outside of InitialState).
-	ConfChangeTransitionJointImplicit ConfChangeTransition = 1
-	// Use joint consensus and remain in the joint configuration until the
-	// application proposes a no-op configuration change. This is suitable for
-	// applications that want to explicitly control the transitions, for example
-	// to use a custom payload (via the Context field).
-	ConfChangeTransitionJointExplicit ConfChangeTransition = 2
-)
-
-var ConfChangeTransition_name = map[int32]string{
-	0: "ConfChangeTransitionAuto",
-	1: "ConfChangeTransitionJointImplicit",
-	2: "ConfChangeTransitionJointExplicit",
-}
-var ConfChangeTransition_value = map[string]int32{
-	"ConfChangeTransitionAuto":          0,
-	"ConfChangeTransitionJointImplicit": 1,
-	"ConfChangeTransitionJointExplicit": 2,
-}
-
-func (x ConfChangeTransition) Enum() *ConfChangeTransition {
-	p := new(ConfChangeTransition)
-	*p = x
-	return p
-}
-func (x ConfChangeTransition) String() string {
-	return proto.EnumName(ConfChangeTransition_name, int32(x))
-}
-func (x *ConfChangeTransition) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(ConfChangeTransition_value, data, "ConfChangeTransition")
-	if err != nil {
-		return err
-	}
-	*x = ConfChangeTransition(value)
-	return nil
-}
-func (ConfChangeTransition) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{2} }
-
-type ConfChangeType int32
-
-const (
-	ConfChangeAddNode        ConfChangeType = 0
-	ConfChangeRemoveNode     ConfChangeType = 1
-	ConfChangeUpdateNode     ConfChangeType = 2
-	ConfChangeAddLearnerNode ConfChangeType = 3
-)
-
-var ConfChangeType_name = map[int32]string{
-	0: "ConfChangeAddNode",
-	1: "ConfChangeRemoveNode",
-	2: "ConfChangeUpdateNode",
-	3: "ConfChangeAddLearnerNode",
-}
-var ConfChangeType_value = map[string]int32{
-	"ConfChangeAddNode":        0,
-	"ConfChangeRemoveNode":     1,
-	"ConfChangeUpdateNode":     2,
-	"ConfChangeAddLearnerNode": 3,
-}
-
-func (x ConfChangeType) Enum() *ConfChangeType {
-	p := new(ConfChangeType)
-	*p = x
-	return p
-}
-func (x ConfChangeType) String() string {
-	return proto.EnumName(ConfChangeType_name, int32(x))
-}
-func (x *ConfChangeType) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(ConfChangeType_value, data, "ConfChangeType")
-	if err != nil {
-		return err
-	}
-	*x = ConfChangeType(value)
-	return nil
-}
-func (ConfChangeType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRaft, []int{3} }
-
-type Entry struct {
-	Term             uint64    `protobuf:"varint,2,opt,name=Term" json:"Term"`
-	Index            uint64    `protobuf:"varint,3,opt,name=Index" json:"Index"`
-	Type             EntryType `protobuf:"varint,1,opt,name=Type,enum=raftpb.EntryType" json:"Type"`
-	Data             []byte    `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"`
-	XXX_unrecognized []byte    `json:"-"`
-}
-
-func (m *Entry) Reset()                    { *m = Entry{} }
-func (m *Entry) String() string            { return proto.CompactTextString(m) }
-func (*Entry) ProtoMessage()               {}
-func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{0} }
-
-type SnapshotMetadata struct {
-	ConfState        ConfState `protobuf:"bytes,1,opt,name=conf_state,json=confState" json:"conf_state"`
-	Index            uint64    `protobuf:"varint,2,opt,name=index" json:"index"`
-	Term             uint64    `protobuf:"varint,3,opt,name=term" json:"term"`
-	XXX_unrecognized []byte    `json:"-"`
-}
-
-func (m *SnapshotMetadata) Reset()                    { *m = SnapshotMetadata{} }
-func (m *SnapshotMetadata) String() string            { return proto.CompactTextString(m) }
-func (*SnapshotMetadata) ProtoMessage()               {}
-func (*SnapshotMetadata) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{1} }
-
-type Snapshot struct {
-	Data             []byte           `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
-	Metadata         SnapshotMetadata `protobuf:"bytes,2,opt,name=metadata" json:"metadata"`
-	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 fileDescriptorRaft, []int{2} }
-
-type Message struct {
-	Type             MessageType `protobuf:"varint,1,opt,name=type,enum=raftpb.MessageType" json:"type"`
-	To               uint64      `protobuf:"varint,2,opt,name=to" json:"to"`
-	From             uint64      `protobuf:"varint,3,opt,name=from" json:"from"`
-	Term             uint64      `protobuf:"varint,4,opt,name=term" json:"term"`
-	LogTerm          uint64      `protobuf:"varint,5,opt,name=logTerm" json:"logTerm"`
-	Index            uint64      `protobuf:"varint,6,opt,name=index" json:"index"`
-	Entries          []Entry     `protobuf:"bytes,7,rep,name=entries" json:"entries"`
-	Commit           uint64      `protobuf:"varint,8,opt,name=commit" json:"commit"`
-	Snapshot         Snapshot    `protobuf:"bytes,9,opt,name=snapshot" json:"snapshot"`
-	Reject           bool        `protobuf:"varint,10,opt,name=reject" json:"reject"`
-	RejectHint       uint64      `protobuf:"varint,11,opt,name=rejectHint" json:"rejectHint"`
-	Context          []byte      `protobuf:"bytes,12,opt,name=context" json:"context,omitempty"`
-	XXX_unrecognized []byte      `json:"-"`
-}
-
-func (m *Message) Reset()                    { *m = Message{} }
-func (m *Message) String() string            { return proto.CompactTextString(m) }
-func (*Message) ProtoMessage()               {}
-func (*Message) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{3} }
-
-type HardState struct {
-	Term             uint64 `protobuf:"varint,1,opt,name=term" json:"term"`
-	Vote             uint64 `protobuf:"varint,2,opt,name=vote" json:"vote"`
-	Commit           uint64 `protobuf:"varint,3,opt,name=commit" json:"commit"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *HardState) Reset()                    { *m = HardState{} }
-func (m *HardState) String() string            { return proto.CompactTextString(m) }
-func (*HardState) ProtoMessage()               {}
-func (*HardState) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{4} }
-
-type ConfState struct {
-	// The voters in the incoming config. (If the configuration is not joint,
-	// then the outgoing config is empty).
-	Voters []uint64 `protobuf:"varint,1,rep,name=voters" json:"voters,omitempty"`
-	// The learners in the incoming config.
-	Learners []uint64 `protobuf:"varint,2,rep,name=learners" json:"learners,omitempty"`
-	// The voters in the outgoing config.
-	VotersOutgoing []uint64 `protobuf:"varint,3,rep,name=voters_outgoing,json=votersOutgoing" json:"voters_outgoing,omitempty"`
-	// The nodes that will become learners when the outgoing config is removed.
-	// These nodes are necessarily currently in nodes_joint (or they would have
-	// been added to the incoming config right away).
-	LearnersNext []uint64 `protobuf:"varint,4,rep,name=learners_next,json=learnersNext" json:"learners_next,omitempty"`
-	// If set, the config is joint and Raft will automatically transition into
-	// the final config (i.e. remove the outgoing config) when this is safe.
-	AutoLeave        bool   `protobuf:"varint,5,opt,name=auto_leave,json=autoLeave" json:"auto_leave"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *ConfState) Reset()                    { *m = ConfState{} }
-func (m *ConfState) String() string            { return proto.CompactTextString(m) }
-func (*ConfState) ProtoMessage()               {}
-func (*ConfState) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{5} }
-
-type ConfChange struct {
-	Type    ConfChangeType `protobuf:"varint,2,opt,name=type,enum=raftpb.ConfChangeType" json:"type"`
-	NodeID  uint64         `protobuf:"varint,3,opt,name=node_id,json=nodeId" json:"node_id"`
-	Context []byte         `protobuf:"bytes,4,opt,name=context" json:"context,omitempty"`
-	// NB: this is used only by etcd to thread through a unique identifier.
-	// Ideally it should really use the Context instead. No counterpart to
-	// this field exists in ConfChangeV2.
-	ID               uint64 `protobuf:"varint,1,opt,name=id" json:"id"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *ConfChange) Reset()                    { *m = ConfChange{} }
-func (m *ConfChange) String() string            { return proto.CompactTextString(m) }
-func (*ConfChange) ProtoMessage()               {}
-func (*ConfChange) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{6} }
-
-// ConfChangeSingle is an individual configuration change operation. Multiple
-// such operations can be carried out atomically via a ConfChangeV2.
-type ConfChangeSingle struct {
-	Type             ConfChangeType `protobuf:"varint,1,opt,name=type,enum=raftpb.ConfChangeType" json:"type"`
-	NodeID           uint64         `protobuf:"varint,2,opt,name=node_id,json=nodeId" json:"node_id"`
-	XXX_unrecognized []byte         `json:"-"`
-}
-
-func (m *ConfChangeSingle) Reset()                    { *m = ConfChangeSingle{} }
-func (m *ConfChangeSingle) String() string            { return proto.CompactTextString(m) }
-func (*ConfChangeSingle) ProtoMessage()               {}
-func (*ConfChangeSingle) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{7} }
-
-// ConfChangeV2 messages initiate configuration changes. They support both the
-// simple "one at a time" membership change protocol and full Joint Consensus
-// allowing for arbitrary changes in membership.
-//
-// The supplied context is treated as an opaque payload and can be used to
-// attach an action on the state machine to the application of the config change
-// proposal. Note that contrary to Joint Consensus as outlined in the Raft
-// paper[1], configuration changes become active when they are *applied* to the
-// state machine (not when they are appended to the log).
-//
-// The simple protocol can be used whenever only a single change is made.
-//
-// Non-simple changes require the use of Joint Consensus, for which two
-// configuration changes are run. The first configuration change specifies the
-// desired changes and transitions the Raft group into the joint configuration,
-// in which quorum requires a majority of both the pre-changes and post-changes
-// configuration. Joint Consensus avoids entering fragile intermediate
-// configurations that could compromise survivability. For example, without the
-// use of Joint Consensus and running across three availability zones with a
-// replication factor of three, it is not possible to replace a voter without
-// entering an intermediate configuration that does not survive the outage of
-// one availability zone.
-//
-// The provided ConfChangeTransition specifies how (and whether) Joint Consensus
-// is used, and assigns the task of leaving the joint configuration either to
-// Raft or the application. Leaving the joint configuration is accomplished by
-// proposing a ConfChangeV2 with only and optionally the Context field
-// populated.
-//
-// For details on Raft membership changes, see:
-//
-// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
-type ConfChangeV2 struct {
-	Transition       ConfChangeTransition `protobuf:"varint,1,opt,name=transition,enum=raftpb.ConfChangeTransition" json:"transition"`
-	Changes          []ConfChangeSingle   `protobuf:"bytes,2,rep,name=changes" json:"changes"`
-	Context          []byte               `protobuf:"bytes,3,opt,name=context" json:"context,omitempty"`
-	XXX_unrecognized []byte               `json:"-"`
-}
-
-func (m *ConfChangeV2) Reset()                    { *m = ConfChangeV2{} }
-func (m *ConfChangeV2) String() string            { return proto.CompactTextString(m) }
-func (*ConfChangeV2) ProtoMessage()               {}
-func (*ConfChangeV2) Descriptor() ([]byte, []int) { return fileDescriptorRaft, []int{8} }
-
-func init() {
-	proto.RegisterType((*Entry)(nil), "raftpb.Entry")
-	proto.RegisterType((*SnapshotMetadata)(nil), "raftpb.SnapshotMetadata")
-	proto.RegisterType((*Snapshot)(nil), "raftpb.Snapshot")
-	proto.RegisterType((*Message)(nil), "raftpb.Message")
-	proto.RegisterType((*HardState)(nil), "raftpb.HardState")
-	proto.RegisterType((*ConfState)(nil), "raftpb.ConfState")
-	proto.RegisterType((*ConfChange)(nil), "raftpb.ConfChange")
-	proto.RegisterType((*ConfChangeSingle)(nil), "raftpb.ConfChangeSingle")
-	proto.RegisterType((*ConfChangeV2)(nil), "raftpb.ConfChangeV2")
-	proto.RegisterEnum("raftpb.EntryType", EntryType_name, EntryType_value)
-	proto.RegisterEnum("raftpb.MessageType", MessageType_name, MessageType_value)
-	proto.RegisterEnum("raftpb.ConfChangeTransition", ConfChangeTransition_name, ConfChangeTransition_value)
-	proto.RegisterEnum("raftpb.ConfChangeType", ConfChangeType_name, ConfChangeType_value)
-}
-func (m *Entry) 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 *Entry) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Type))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Term))
-	dAtA[i] = 0x18
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Index))
-	if m.Data != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRaft(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 (m *SnapshotMetadata) 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 *SnapshotMetadata) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0xa
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.ConfState.Size()))
-	n1, err := m.ConfState.MarshalTo(dAtA[i:])
-	if err != nil {
-		return 0, err
-	}
-	i += n1
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Index))
-	dAtA[i] = 0x18
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Term))
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-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
-	if m.Data != nil {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintRaft(dAtA, i, uint64(len(m.Data)))
-		i += copy(dAtA[i:], m.Data)
-	}
-	dAtA[i] = 0x12
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Metadata.Size()))
-	n2, err := m.Metadata.MarshalTo(dAtA[i:])
-	if err != nil {
-		return 0, err
-	}
-	i += n2
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *Message) 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 *Message) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Type))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.To))
-	dAtA[i] = 0x18
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.From))
-	dAtA[i] = 0x20
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Term))
-	dAtA[i] = 0x28
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.LogTerm))
-	dAtA[i] = 0x30
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Index))
-	if len(m.Entries) > 0 {
-		for _, msg := range m.Entries {
-			dAtA[i] = 0x3a
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	dAtA[i] = 0x40
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Commit))
-	dAtA[i] = 0x4a
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Snapshot.Size()))
-	n3, err := m.Snapshot.MarshalTo(dAtA[i:])
-	if err != nil {
-		return 0, err
-	}
-	i += n3
-	dAtA[i] = 0x50
-	i++
-	if m.Reject {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	dAtA[i] = 0x58
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.RejectHint))
-	if m.Context != nil {
-		dAtA[i] = 0x62
-		i++
-		i = encodeVarintRaft(dAtA, i, uint64(len(m.Context)))
-		i += copy(dAtA[i:], m.Context)
-	}
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *HardState) 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 *HardState) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Term))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Vote))
-	dAtA[i] = 0x18
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Commit))
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *ConfState) 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 *ConfState) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	if len(m.Voters) > 0 {
-		for _, num := range m.Voters {
-			dAtA[i] = 0x8
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(num))
-		}
-	}
-	if len(m.Learners) > 0 {
-		for _, num := range m.Learners {
-			dAtA[i] = 0x10
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(num))
-		}
-	}
-	if len(m.VotersOutgoing) > 0 {
-		for _, num := range m.VotersOutgoing {
-			dAtA[i] = 0x18
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(num))
-		}
-	}
-	if len(m.LearnersNext) > 0 {
-		for _, num := range m.LearnersNext {
-			dAtA[i] = 0x20
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(num))
-		}
-	}
-	dAtA[i] = 0x28
-	i++
-	if m.AutoLeave {
-		dAtA[i] = 1
-	} else {
-		dAtA[i] = 0
-	}
-	i++
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *ConfChange) 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 *ConfChange) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.ID))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Type))
-	dAtA[i] = 0x18
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.NodeID))
-	if m.Context != nil {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintRaft(dAtA, i, uint64(len(m.Context)))
-		i += copy(dAtA[i:], m.Context)
-	}
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *ConfChangeSingle) 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 *ConfChangeSingle) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Type))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.NodeID))
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func (m *ConfChangeV2) 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 *ConfChangeV2) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRaft(dAtA, i, uint64(m.Transition))
-	if len(m.Changes) > 0 {
-		for _, msg := range m.Changes {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintRaft(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
-	}
-	if m.Context != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRaft(dAtA, i, uint64(len(m.Context)))
-		i += copy(dAtA[i:], m.Context)
-	}
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func encodeVarintRaft(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 *Entry) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.Type))
-	n += 1 + sovRaft(uint64(m.Term))
-	n += 1 + sovRaft(uint64(m.Index))
-	if m.Data != nil {
-		l = len(m.Data)
-		n += 1 + l + sovRaft(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *SnapshotMetadata) Size() (n int) {
-	var l int
-	_ = l
-	l = m.ConfState.Size()
-	n += 1 + l + sovRaft(uint64(l))
-	n += 1 + sovRaft(uint64(m.Index))
-	n += 1 + sovRaft(uint64(m.Term))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *Snapshot) Size() (n int) {
-	var l int
-	_ = l
-	if m.Data != nil {
-		l = len(m.Data)
-		n += 1 + l + sovRaft(uint64(l))
-	}
-	l = m.Metadata.Size()
-	n += 1 + l + sovRaft(uint64(l))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *Message) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.Type))
-	n += 1 + sovRaft(uint64(m.To))
-	n += 1 + sovRaft(uint64(m.From))
-	n += 1 + sovRaft(uint64(m.Term))
-	n += 1 + sovRaft(uint64(m.LogTerm))
-	n += 1 + sovRaft(uint64(m.Index))
-	if len(m.Entries) > 0 {
-		for _, e := range m.Entries {
-			l = e.Size()
-			n += 1 + l + sovRaft(uint64(l))
-		}
-	}
-	n += 1 + sovRaft(uint64(m.Commit))
-	l = m.Snapshot.Size()
-	n += 1 + l + sovRaft(uint64(l))
-	n += 2
-	n += 1 + sovRaft(uint64(m.RejectHint))
-	if m.Context != nil {
-		l = len(m.Context)
-		n += 1 + l + sovRaft(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *HardState) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.Term))
-	n += 1 + sovRaft(uint64(m.Vote))
-	n += 1 + sovRaft(uint64(m.Commit))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *ConfState) Size() (n int) {
-	var l int
-	_ = l
-	if len(m.Voters) > 0 {
-		for _, e := range m.Voters {
-			n += 1 + sovRaft(uint64(e))
-		}
-	}
-	if len(m.Learners) > 0 {
-		for _, e := range m.Learners {
-			n += 1 + sovRaft(uint64(e))
-		}
-	}
-	if len(m.VotersOutgoing) > 0 {
-		for _, e := range m.VotersOutgoing {
-			n += 1 + sovRaft(uint64(e))
-		}
-	}
-	if len(m.LearnersNext) > 0 {
-		for _, e := range m.LearnersNext {
-			n += 1 + sovRaft(uint64(e))
-		}
-	}
-	n += 2
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *ConfChange) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.ID))
-	n += 1 + sovRaft(uint64(m.Type))
-	n += 1 + sovRaft(uint64(m.NodeID))
-	if m.Context != nil {
-		l = len(m.Context)
-		n += 1 + l + sovRaft(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *ConfChangeSingle) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.Type))
-	n += 1 + sovRaft(uint64(m.NodeID))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *ConfChangeV2) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRaft(uint64(m.Transition))
-	if len(m.Changes) > 0 {
-		for _, e := range m.Changes {
-			l = e.Size()
-			n += 1 + l + sovRaft(uint64(l))
-		}
-	}
-	if m.Context != nil {
-		l = len(m.Context)
-		n += 1 + l + sovRaft(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func sovRaft(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozRaft(x uint64) (n int) {
-	return sovRaft(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *Entry) 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 ErrIntOverflowRaft
-			}
-			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: Entry: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (EntryType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
-			}
-			m.Term = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Term |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
-			}
-			m.Index = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Index |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			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 ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *SnapshotMetadata) 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 ErrIntOverflowRaft
-			}
-			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: SnapshotMetadata: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: SnapshotMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ConfState", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if err := m.ConfState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
-			}
-			m.Index = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Index |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
-			}
-			m.Term = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Term |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (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 ErrIntOverflowRaft
-			}
-			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 != 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 ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *Message) 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 ErrIntOverflowRaft
-			}
-			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: Message: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (MessageType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field To", wireType)
-			}
-			m.To = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.To |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field From", wireType)
-			}
-			m.From = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.From |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
-			}
-			m.Term = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Term |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field LogTerm", wireType)
-			}
-			m.LogTerm = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.LogTerm |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 6:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
-			}
-			m.Index = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Index |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 7:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Entries = append(m.Entries, Entry{})
-			if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 8:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType)
-			}
-			m.Commit = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Commit |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 9:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Snapshot", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			if err := m.Snapshot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 10:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Reject", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.Reject = bool(v != 0)
-		case 11:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field RejectHint", wireType)
-			}
-			m.RejectHint = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.RejectHint |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 12:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Context", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Context = append(m.Context[:0], dAtA[iNdEx:postIndex]...)
-			if m.Context == nil {
-				m.Context = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *HardState) 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 ErrIntOverflowRaft
-			}
-			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: HardState: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: HardState: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
-			}
-			m.Term = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Term |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Vote", wireType)
-			}
-			m.Vote = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Vote |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType)
-			}
-			m.Commit = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Commit |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *ConfState) 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 ErrIntOverflowRaft
-			}
-			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: ConfState: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ConfState: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType == 0 {
-				var v uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					v |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				m.Voters = append(m.Voters, v)
-			} else if wireType == 2 {
-				var packedLen int
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					packedLen |= (int(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				if packedLen < 0 {
-					return ErrInvalidLengthRaft
-				}
-				postIndex := iNdEx + packedLen
-				if postIndex > l {
-					return io.ErrUnexpectedEOF
-				}
-				for iNdEx < postIndex {
-					var v uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowRaft
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						v |= (uint64(b) & 0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					m.Voters = append(m.Voters, v)
-				}
-			} else {
-				return fmt.Errorf("proto: wrong wireType = %d for field Voters", wireType)
-			}
-		case 2:
-			if wireType == 0 {
-				var v uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					v |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				m.Learners = append(m.Learners, v)
-			} else if wireType == 2 {
-				var packedLen int
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					packedLen |= (int(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				if packedLen < 0 {
-					return ErrInvalidLengthRaft
-				}
-				postIndex := iNdEx + packedLen
-				if postIndex > l {
-					return io.ErrUnexpectedEOF
-				}
-				for iNdEx < postIndex {
-					var v uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowRaft
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						v |= (uint64(b) & 0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					m.Learners = append(m.Learners, v)
-				}
-			} else {
-				return fmt.Errorf("proto: wrong wireType = %d for field Learners", wireType)
-			}
-		case 3:
-			if wireType == 0 {
-				var v uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					v |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				m.VotersOutgoing = append(m.VotersOutgoing, v)
-			} else if wireType == 2 {
-				var packedLen int
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					packedLen |= (int(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				if packedLen < 0 {
-					return ErrInvalidLengthRaft
-				}
-				postIndex := iNdEx + packedLen
-				if postIndex > l {
-					return io.ErrUnexpectedEOF
-				}
-				for iNdEx < postIndex {
-					var v uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowRaft
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						v |= (uint64(b) & 0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					m.VotersOutgoing = append(m.VotersOutgoing, v)
-				}
-			} else {
-				return fmt.Errorf("proto: wrong wireType = %d for field VotersOutgoing", wireType)
-			}
-		case 4:
-			if wireType == 0 {
-				var v uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					v |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				m.LearnersNext = append(m.LearnersNext, v)
-			} else if wireType == 2 {
-				var packedLen int
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowRaft
-					}
-					if iNdEx >= l {
-						return io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					packedLen |= (int(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				if packedLen < 0 {
-					return ErrInvalidLengthRaft
-				}
-				postIndex := iNdEx + packedLen
-				if postIndex > l {
-					return io.ErrUnexpectedEOF
-				}
-				for iNdEx < postIndex {
-					var v uint64
-					for shift := uint(0); ; shift += 7 {
-						if shift >= 64 {
-							return ErrIntOverflowRaft
-						}
-						if iNdEx >= l {
-							return io.ErrUnexpectedEOF
-						}
-						b := dAtA[iNdEx]
-						iNdEx++
-						v |= (uint64(b) & 0x7F) << shift
-						if b < 0x80 {
-							break
-						}
-					}
-					m.LearnersNext = append(m.LearnersNext, v)
-				}
-			} else {
-				return fmt.Errorf("proto: wrong wireType = %d for field LearnersNext", wireType)
-			}
-		case 5:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field AutoLeave", wireType)
-			}
-			var v int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				v |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			m.AutoLeave = bool(v != 0)
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *ConfChange) 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 ErrIntOverflowRaft
-			}
-			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: ConfChange: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ConfChange: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
-			}
-			m.ID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.ID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (ConfChangeType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NodeID", wireType)
-			}
-			m.NodeID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.NodeID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 4:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Context", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Context = append(m.Context[:0], dAtA[iNdEx:postIndex]...)
-			if m.Context == nil {
-				m.Context = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *ConfChangeSingle) 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 ErrIntOverflowRaft
-			}
-			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: ConfChangeSingle: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ConfChangeSingle: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (ConfChangeType(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field NodeID", wireType)
-			}
-			m.NodeID = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.NodeID |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 (m *ConfChangeV2) 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 ErrIntOverflowRaft
-			}
-			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: ConfChangeV2: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: ConfChangeV2: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Transition", wireType)
-			}
-			m.Transition = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Transition |= (ConfChangeTransition(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType)
-			}
-			var msglen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if msglen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Changes = append(m.Changes, ConfChangeSingle{})
-			if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
-				return err
-			}
-			iNdEx = postIndex
-		case 3:
-			if wireType != 2 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Context", wireType)
-			}
-			var byteLen int
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRaft
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRaft
-			}
-			postIndex := iNdEx + byteLen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			m.Context = append(m.Context[:0], dAtA[iNdEx:postIndex]...)
-			if m.Context == nil {
-				m.Context = []byte{}
-			}
-			iNdEx = postIndex
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRaft(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRaft
-			}
-			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 skipRaft(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, ErrIntOverflowRaft
-			}
-			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, ErrIntOverflowRaft
-				}
-				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, ErrIntOverflowRaft
-				}
-				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, ErrInvalidLengthRaft
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowRaft
-					}
-					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 := skipRaft(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 (
-	ErrInvalidLengthRaft = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowRaft   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("raft.proto", fileDescriptorRaft) }
-
-var fileDescriptorRaft = []byte{
-	// 1009 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x6e, 0xe3, 0x36,
-	0x17, 0xb5, 0x64, 0xc5, 0x3f, 0xd7, 0x8e, 0xc3, 0xdc, 0xc9, 0x37, 0x20, 0x82, 0xc0, 0xe3, 0xcf,
-	0xd3, 0x62, 0x8c, 0x14, 0x93, 0x16, 0x5e, 0x14, 0x45, 0x77, 0xf9, 0x19, 0x20, 0x29, 0xe2, 0x74,
-	0xea, 0x64, 0xb2, 0x28, 0x50, 0x04, 0x8c, 0x45, 0x2b, 0x6a, 0x2d, 0x51, 0xa0, 0xe8, 0x34, 0xd9,
-	0x14, 0x45, 0x9f, 0xa2, 0x9b, 0xd9, 0xf6, 0x01, 0xfa, 0x14, 0x59, 0x0e, 0xd0, 0xfd, 0xa0, 0x93,
-	0xbe, 0x48, 0x41, 0x8a, 0xb2, 0x65, 0x27, 0x98, 0x45, 0x77, 0xe4, 0x39, 0x87, 0xf7, 0x9e, 0x7b,
-	0x79, 0x45, 0x01, 0x48, 0x36, 0x56, 0x3b, 0x89, 0x14, 0x4a, 0x60, 0x45, 0xaf, 0x93, 0xcb, 0xcd,
-	0x8d, 0x40, 0x04, 0xc2, 0x40, 0x9f, 0xeb, 0x55, 0xc6, 0x76, 0x7f, 0x81, 0x95, 0x57, 0xb1, 0x92,
-	0xb7, 0xf8, 0x19, 0x78, 0x67, 0xb7, 0x09, 0xa7, 0x4e, 0xc7, 0xe9, 0xb5, 0xfa, 0xeb, 0x3b, 0xd9,
-	0xa9, 0x1d, 0x43, 0x6a, 0x62, 0xcf, 0xbb, 0x7b, 0xff, 0xac, 0x34, 0x34, 0x22, 0xa4, 0xe0, 0x9d,
-	0x71, 0x19, 0x51, 0xb7, 0xe3, 0xf4, 0xbc, 0x19, 0xc3, 0x65, 0x84, 0x9b, 0xb0, 0x72, 0x14, 0xfb,
-	0xfc, 0x86, 0x96, 0x0b, 0x54, 0x06, 0x21, 0x82, 0x77, 0xc0, 0x14, 0xa3, 0x5e, 0xc7, 0xe9, 0x35,
-	0x87, 0x66, 0xdd, 0xfd, 0xd5, 0x01, 0x72, 0x1a, 0xb3, 0x24, 0xbd, 0x12, 0x6a, 0xc0, 0x15, 0xf3,
-	0x99, 0x62, 0xf8, 0x25, 0xc0, 0x48, 0xc4, 0xe3, 0x8b, 0x54, 0x31, 0x95, 0x39, 0x6a, 0xcc, 0x1d,
-	0xed, 0x8b, 0x78, 0x7c, 0xaa, 0x09, 0x1b, 0xbc, 0x3e, 0xca, 0x01, 0x9d, 0x3c, 0x34, 0xc9, 0x8b,
-	0xbe, 0x32, 0x48, 0x5b, 0x56, 0xda, 0x72, 0xd1, 0x97, 0x41, 0xba, 0xdf, 0x43, 0x2d, 0x77, 0xa0,
-	0x2d, 0x6a, 0x07, 0x26, 0x67, 0x73, 0x68, 0xd6, 0xf8, 0x35, 0xd4, 0x22, 0xeb, 0xcc, 0x04, 0x6e,
-	0xf4, 0x69, 0xee, 0x65, 0xd9, 0xb9, 0x8d, 0x3b, 0xd3, 0x77, 0xdf, 0x96, 0xa1, 0x3a, 0xe0, 0x69,
-	0xca, 0x02, 0x8e, 0x2f, 0xc1, 0x53, 0xf3, 0x0e, 0x3f, 0xc9, 0x63, 0x58, 0xba, 0xd8, 0x63, 0x2d,
-	0xc3, 0x0d, 0x70, 0x95, 0x58, 0xa8, 0xc4, 0x55, 0x42, 0x97, 0x31, 0x96, 0x62, 0xa9, 0x0c, 0x8d,
-	0xcc, 0x0a, 0xf4, 0x96, 0x0b, 0xc4, 0x36, 0x54, 0x27, 0x22, 0x30, 0x17, 0xb6, 0x52, 0x20, 0x73,
-	0x70, 0xde, 0xb6, 0xca, 0xc3, 0xb6, 0xbd, 0x84, 0x2a, 0x8f, 0x95, 0x0c, 0x79, 0x4a, 0xab, 0x9d,
-	0x72, 0xaf, 0xd1, 0x5f, 0x5d, 0x98, 0x8c, 0x3c, 0x94, 0xd5, 0xe0, 0x16, 0x54, 0x46, 0x22, 0x8a,
-	0x42, 0x45, 0x6b, 0x85, 0x58, 0x16, 0xc3, 0x3e, 0xd4, 0x52, 0xdb, 0x31, 0x5a, 0x37, 0x9d, 0x24,
-	0xcb, 0x9d, 0xcc, 0x3b, 0x98, 0xeb, 0x74, 0x44, 0xc9, 0x7f, 0xe4, 0x23, 0x45, 0xa1, 0xe3, 0xf4,
-	0x6a, 0x79, 0xc4, 0x0c, 0xc3, 0x4f, 0x00, 0xb2, 0xd5, 0x61, 0x18, 0x2b, 0xda, 0x28, 0xe4, 0x2c,
-	0xe0, 0x48, 0xa1, 0x3a, 0x12, 0xb1, 0xe2, 0x37, 0x8a, 0x36, 0xcd, 0xc5, 0xe6, 0xdb, 0xee, 0x0f,
-	0x50, 0x3f, 0x64, 0xd2, 0xcf, 0xc6, 0x27, 0xef, 0xa0, 0xf3, 0xa0, 0x83, 0x14, 0xbc, 0x6b, 0xa1,
-	0xf8, 0xe2, 0xbc, 0x6b, 0xa4, 0x50, 0x70, 0xf9, 0x61, 0xc1, 0xdd, 0x3f, 0x1d, 0xa8, 0xcf, 0xe6,
-	0x15, 0x9f, 0x42, 0x45, 0x9f, 0x91, 0x29, 0x75, 0x3a, 0xe5, 0x9e, 0x37, 0xb4, 0x3b, 0xdc, 0x84,
-	0xda, 0x84, 0x33, 0x19, 0x6b, 0xc6, 0x35, 0xcc, 0x6c, 0x8f, 0x2f, 0x60, 0x2d, 0x53, 0x5d, 0x88,
-	0xa9, 0x0a, 0x44, 0x18, 0x07, 0xb4, 0x6c, 0x24, 0xad, 0x0c, 0xfe, 0xd6, 0xa2, 0xf8, 0x1c, 0x56,
-	0xf3, 0x43, 0x17, 0xb1, 0xae, 0xd4, 0x33, 0xb2, 0x66, 0x0e, 0x9e, 0xf0, 0x1b, 0x85, 0xcf, 0x01,
-	0xd8, 0x54, 0x89, 0x8b, 0x09, 0x67, 0xd7, 0xdc, 0x0c, 0x43, 0xde, 0xd0, 0xba, 0xc6, 0x8f, 0x35,
-	0xdc, 0x7d, 0xeb, 0x00, 0x68, 0xd3, 0xfb, 0x57, 0x2c, 0x0e, 0xf4, 0x47, 0xe5, 0x86, 0xbe, 0xed,
-	0x09, 0x68, 0xed, 0xfd, 0xfb, 0x67, 0xee, 0xd1, 0xc1, 0xd0, 0x0d, 0x7d, 0xfc, 0xc2, 0x8e, 0xb4,
-	0x6b, 0x46, 0xfa, 0x69, 0xf1, 0x13, 0xcd, 0x4e, 0x3f, 0x98, 0xea, 0x17, 0x50, 0x8d, 0x85, 0xcf,
-	0x2f, 0x42, 0xdf, 0x36, 0xac, 0x65, 0x43, 0x56, 0x4e, 0x84, 0xcf, 0x8f, 0x0e, 0x86, 0x15, 0x4d,
-	0x1f, 0xf9, 0xc5, 0x3b, 0xf3, 0x16, 0xef, 0x2c, 0x02, 0x32, 0x4f, 0x70, 0x1a, 0xc6, 0xc1, 0x84,
-	0xcf, 0x8c, 0x38, 0xff, 0xc5, 0x88, 0xfb, 0x31, 0x23, 0xdd, 0x3f, 0x1c, 0x68, 0xce, 0xe3, 0x9c,
-	0xf7, 0x71, 0x0f, 0x40, 0x49, 0x16, 0xa7, 0xa1, 0x0a, 0x45, 0x6c, 0x33, 0x6e, 0x3d, 0x92, 0x71,
-	0xa6, 0xc9, 0x27, 0x72, 0x7e, 0x0a, 0xbf, 0x82, 0xea, 0xc8, 0xa8, 0xb2, 0x1b, 0x2f, 0x3c, 0x29,
-	0xcb, 0xa5, 0xe5, 0x5f, 0x98, 0x95, 0x17, 0xfb, 0x52, 0x5e, 0xe8, 0xcb, 0xf6, 0x21, 0xd4, 0x67,
-	0xaf, 0x35, 0xae, 0x41, 0xc3, 0x6c, 0x4e, 0x84, 0x8c, 0xd8, 0x84, 0x94, 0xf0, 0x09, 0xac, 0x19,
-	0x60, 0x1e, 0x9f, 0x38, 0xf8, 0x3f, 0x58, 0x5f, 0x02, 0xcf, 0xfb, 0xc4, 0xdd, 0xfe, 0xcb, 0x85,
-	0x46, 0xe1, 0x59, 0x42, 0x80, 0xca, 0x20, 0x0d, 0x0e, 0xa7, 0x09, 0x29, 0x61, 0x03, 0xaa, 0x83,
-	0x34, 0xd8, 0xe3, 0x4c, 0x11, 0xc7, 0x6e, 0x5e, 0x4b, 0x91, 0x10, 0xd7, 0xaa, 0x76, 0x93, 0x84,
-	0x94, 0xb1, 0x05, 0x90, 0xad, 0x87, 0x3c, 0x4d, 0x88, 0x67, 0x85, 0xe7, 0x42, 0x71, 0xb2, 0xa2,
-	0xbd, 0xd9, 0x8d, 0x61, 0x2b, 0x96, 0xd5, 0x4f, 0x00, 0xa9, 0x22, 0x81, 0xa6, 0x4e, 0xc6, 0x99,
-	0x54, 0x97, 0x3a, 0x4b, 0x0d, 0x37, 0x80, 0x14, 0x11, 0x73, 0xa8, 0x8e, 0x08, 0xad, 0x41, 0x1a,
-	0xbc, 0x89, 0x25, 0x67, 0xa3, 0x2b, 0x76, 0x39, 0xe1, 0x04, 0x70, 0x1d, 0x56, 0x6d, 0x20, 0xfd,
-	0xc5, 0x4d, 0x53, 0xd2, 0xb0, 0xb2, 0xfd, 0x2b, 0x3e, 0xfa, 0xe9, 0xbb, 0xa9, 0x90, 0xd3, 0x88,
-	0x34, 0x75, 0xd9, 0x83, 0x34, 0x30, 0x17, 0x34, 0xe6, 0xf2, 0x98, 0x33, 0x9f, 0x4b, 0xb2, 0x6a,
-	0x4f, 0x9f, 0x85, 0x11, 0x17, 0x53, 0x75, 0x22, 0x7e, 0x26, 0x2d, 0x6b, 0x66, 0xc8, 0x99, 0x6f,
-	0x7e, 0x61, 0x64, 0xcd, 0x9a, 0x99, 0x21, 0xc6, 0x0c, 0xb1, 0xf5, 0xbe, 0x96, 0xdc, 0x94, 0xb8,
-	0x6e, 0xb3, 0xda, 0xbd, 0xd1, 0xe0, 0xf6, 0x6f, 0x0e, 0x6c, 0x3c, 0x36, 0x1e, 0xb8, 0x05, 0xf4,
-	0x31, 0x7c, 0x77, 0xaa, 0x04, 0x29, 0xe1, 0xa7, 0xf0, 0xff, 0xc7, 0xd8, 0x6f, 0x44, 0x18, 0xab,
-	0xa3, 0x28, 0x99, 0x84, 0xa3, 0x50, 0x5f, 0xc5, 0xc7, 0x64, 0xaf, 0x6e, 0xac, 0xcc, 0xdd, 0xbe,
-	0x85, 0xd6, 0xe2, 0x47, 0xa1, 0x9b, 0x31, 0x47, 0x76, 0x7d, 0x5f, 0x8f, 0x3f, 0x29, 0x21, 0x2d,
-	0x9a, 0x1d, 0xf2, 0x48, 0x5c, 0x73, 0xc3, 0x38, 0x8b, 0xcc, 0x9b, 0xc4, 0x67, 0x2a, 0x63, 0xdc,
-	0xc5, 0x42, 0x76, 0x7d, 0xff, 0x38, 0x7b, 0x7b, 0x0c, 0x5b, 0xde, 0xa3, 0x77, 0x1f, 0xda, 0xa5,
-	0x77, 0x1f, 0xda, 0xa5, 0xbb, 0xfb, 0xb6, 0xf3, 0xee, 0xbe, 0xed, 0xfc, 0x7d, 0xdf, 0x76, 0x7e,
-	0xff, 0xa7, 0x5d, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0x87, 0x11, 0x6d, 0xd6, 0xaf, 0x08, 0x00,
-	0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/raft/raftpb/raft.proto b/vendor/go.etcd.io/etcd/raft/raftpb/raft.proto
deleted file mode 100644
index 23d62ec..0000000
--- a/vendor/go.etcd.io/etcd/raft/raftpb/raft.proto
+++ /dev/null
@@ -1,177 +0,0 @@
-syntax = "proto2";
-package raftpb;
-
-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;
-option (gogoproto.goproto_enum_prefix_all) = false;
-
-enum EntryType {
-	EntryNormal       = 0;
-	EntryConfChange   = 1; // corresponds to pb.ConfChange
-	EntryConfChangeV2 = 2; // corresponds to pb.ConfChangeV2
-}
-
-message Entry {
-	optional uint64     Term  = 2 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
-	optional uint64     Index = 3 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
-	optional EntryType  Type  = 1 [(gogoproto.nullable) = false];
-	optional bytes      Data  = 4;
-}
-
-message SnapshotMetadata {
-	optional ConfState conf_state = 1 [(gogoproto.nullable) = false];
-	optional uint64    index      = 2 [(gogoproto.nullable) = false];
-	optional uint64    term       = 3 [(gogoproto.nullable) = false];
-}
-
-message Snapshot {
-	optional bytes            data     = 1;
-	optional SnapshotMetadata metadata = 2 [(gogoproto.nullable) = false];
-}
-
-enum MessageType {
-	MsgHup             = 0;
-	MsgBeat            = 1;
-	MsgProp            = 2;
-	MsgApp             = 3;
-	MsgAppResp         = 4;
-	MsgVote            = 5;
-	MsgVoteResp        = 6;
-	MsgSnap            = 7;
-	MsgHeartbeat       = 8;
-	MsgHeartbeatResp   = 9;
-	MsgUnreachable     = 10;
-	MsgSnapStatus      = 11;
-	MsgCheckQuorum     = 12;
-	MsgTransferLeader  = 13;
-	MsgTimeoutNow      = 14;
-	MsgReadIndex       = 15;
-	MsgReadIndexResp   = 16;
-	MsgPreVote         = 17;
-	MsgPreVoteResp     = 18;
-}
-
-message Message {
-	optional MessageType type        = 1  [(gogoproto.nullable) = false];
-	optional uint64      to          = 2  [(gogoproto.nullable) = false];
-	optional uint64      from        = 3  [(gogoproto.nullable) = false];
-	optional uint64      term        = 4  [(gogoproto.nullable) = false];
-	optional uint64      logTerm     = 5  [(gogoproto.nullable) = false];
-	optional uint64      index       = 6  [(gogoproto.nullable) = false];
-	repeated Entry       entries     = 7  [(gogoproto.nullable) = false];
-	optional uint64      commit      = 8  [(gogoproto.nullable) = false];
-	optional Snapshot    snapshot    = 9  [(gogoproto.nullable) = false];
-	optional bool        reject      = 10 [(gogoproto.nullable) = false];
-	optional uint64      rejectHint  = 11 [(gogoproto.nullable) = false];
-	optional bytes       context     = 12;
-}
-
-message HardState {
-	optional uint64 term   = 1 [(gogoproto.nullable) = false];
-	optional uint64 vote   = 2 [(gogoproto.nullable) = false];
-	optional uint64 commit = 3 [(gogoproto.nullable) = false];
-}
-
-// ConfChangeTransition specifies the behavior of a configuration change with
-// respect to joint consensus.
-enum ConfChangeTransition {
-	// Automatically use the simple protocol if possible, otherwise fall back
-	// to ConfChangeJointImplicit. Most applications will want to use this.
-	ConfChangeTransitionAuto          = 0;
-	// Use joint consensus unconditionally, and transition out of them
-	// automatically (by proposing a zero configuration change).
-	//
-	// This option is suitable for applications that want to minimize the time
-	// spent in the joint configuration and do not store the joint configuration
-	// in the state machine (outside of InitialState).
-	ConfChangeTransitionJointImplicit = 1;
-	// Use joint consensus and remain in the joint configuration until the
-	// application proposes a no-op configuration change. This is suitable for
-	// applications that want to explicitly control the transitions, for example
-	// to use a custom payload (via the Context field).
-	ConfChangeTransitionJointExplicit = 2;
-}
-
-message ConfState {
-	// The voters in the incoming config. (If the configuration is not joint,
-	// then the outgoing config is empty).
-	repeated uint64 voters = 1;
-	// The learners in the incoming config.
-	repeated uint64 learners          = 2;
-	// The voters in the outgoing config.
-	repeated uint64 voters_outgoing   = 3;
-	// The nodes that will become learners when the outgoing config is removed.
-	// These nodes are necessarily currently in nodes_joint (or they would have
-	// been added to the incoming config right away).
-	repeated uint64 learners_next     = 4;
-	// If set, the config is joint and Raft will automatically transition into
-	// the final config (i.e. remove the outgoing config) when this is safe.
-	optional bool   auto_leave        = 5 [(gogoproto.nullable) = false];
-}
-
-enum ConfChangeType {
-	ConfChangeAddNode        = 0;
-	ConfChangeRemoveNode     = 1;
-	ConfChangeUpdateNode     = 2;
-	ConfChangeAddLearnerNode = 3;
-}
-
-message ConfChange {
-	optional ConfChangeType  type    = 2 [(gogoproto.nullable) = false];
-	optional uint64          node_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeID" ];
-	optional bytes           context = 4;
-
-	// NB: this is used only by etcd to thread through a unique identifier.
-	// Ideally it should really use the Context instead. No counterpart to
-	// this field exists in ConfChangeV2.
-	optional uint64          id      = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ID" ];
-}
-
-// ConfChangeSingle is an individual configuration change operation. Multiple
-// such operations can be carried out atomically via a ConfChangeV2.
-message ConfChangeSingle {
-	optional ConfChangeType  type    = 1 [(gogoproto.nullable) = false];
-	optional uint64          node_id = 2 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeID"];
-}
-
-// ConfChangeV2 messages initiate configuration changes. They support both the
-// simple "one at a time" membership change protocol and full Joint Consensus
-// allowing for arbitrary changes in membership.
-//
-// The supplied context is treated as an opaque payload and can be used to
-// attach an action on the state machine to the application of the config change
-// proposal. Note that contrary to Joint Consensus as outlined in the Raft
-// paper[1], configuration changes become active when they are *applied* to the
-// state machine (not when they are appended to the log).
-//
-// The simple protocol can be used whenever only a single change is made.
-//
-// Non-simple changes require the use of Joint Consensus, for which two
-// configuration changes are run. The first configuration change specifies the
-// desired changes and transitions the Raft group into the joint configuration,
-// in which quorum requires a majority of both the pre-changes and post-changes
-// configuration. Joint Consensus avoids entering fragile intermediate
-// configurations that could compromise survivability. For example, without the
-// use of Joint Consensus and running across three availability zones with a
-// replication factor of three, it is not possible to replace a voter without
-// entering an intermediate configuration that does not survive the outage of
-// one availability zone.
-//
-// The provided ConfChangeTransition specifies how (and whether) Joint Consensus
-// is used, and assigns the task of leaving the joint configuration either to
-// Raft or the application. Leaving the joint configuration is accomplished by
-// proposing a ConfChangeV2 with only and optionally the Context field
-// populated.
-//
-// For details on Raft membership changes, see:
-//
-// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
-message ConfChangeV2 {
-	optional ConfChangeTransition transition = 1 [(gogoproto.nullable) = false];
-	repeated ConfChangeSingle     changes =    2 [(gogoproto.nullable) = false];
-	optional bytes                context =    3;
-}
diff --git a/vendor/go.etcd.io/etcd/raft/rawnode.go b/vendor/go.etcd.io/etcd/raft/rawnode.go
deleted file mode 100644
index 90eb694..0000000
--- a/vendor/go.etcd.io/etcd/raft/rawnode.go
+++ /dev/null
@@ -1,239 +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 raft
-
-import (
-	"errors"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/raft/tracker"
-)
-
-// ErrStepLocalMsg is returned when try to step a local raft message
-var ErrStepLocalMsg = errors.New("raft: cannot step raft local message")
-
-// ErrStepPeerNotFound is returned when try to step a response message
-// but there is no peer found in raft.prs for that node.
-var ErrStepPeerNotFound = errors.New("raft: cannot step as peer not found")
-
-// RawNode is a thread-unsafe Node.
-// The methods of this struct correspond to the methods of Node and are described
-// more fully there.
-type RawNode struct {
-	raft       *raft
-	prevSoftSt *SoftState
-	prevHardSt pb.HardState
-}
-
-// NewRawNode instantiates a RawNode from the given configuration.
-//
-// See Bootstrap() for bootstrapping an initial state; this replaces the former
-// 'peers' argument to this method (with identical behavior). However, It is
-// recommended that instead of calling Bootstrap, applications bootstrap their
-// state manually by setting up a Storage that has a first index > 1 and which
-// stores the desired ConfState as its InitialState.
-func NewRawNode(config *Config) (*RawNode, error) {
-	r := newRaft(config)
-	rn := &RawNode{
-		raft: r,
-	}
-	rn.prevSoftSt = r.softState()
-	rn.prevHardSt = r.hardState()
-	return rn, nil
-}
-
-// Tick advances the internal logical clock by a single tick.
-func (rn *RawNode) Tick() {
-	rn.raft.tick()
-}
-
-// TickQuiesced advances the internal logical clock by a single tick without
-// performing any other state machine processing. It allows the caller to avoid
-// periodic heartbeats and elections when all of the peers in a Raft group are
-// known to be at the same state. Expected usage is to periodically invoke Tick
-// or TickQuiesced depending on whether the group is "active" or "quiesced".
-//
-// WARNING: Be very careful about using this method as it subverts the Raft
-// state machine. You should probably be using Tick instead.
-func (rn *RawNode) TickQuiesced() {
-	rn.raft.electionElapsed++
-}
-
-// Campaign causes this RawNode to transition to candidate state.
-func (rn *RawNode) Campaign() error {
-	return rn.raft.Step(pb.Message{
-		Type: pb.MsgHup,
-	})
-}
-
-// Propose proposes data be appended to the raft log.
-func (rn *RawNode) Propose(data []byte) error {
-	return rn.raft.Step(pb.Message{
-		Type: pb.MsgProp,
-		From: rn.raft.id,
-		Entries: []pb.Entry{
-			{Data: data},
-		}})
-}
-
-// ProposeConfChange proposes a config change. See (Node).ProposeConfChange for
-// details.
-func (rn *RawNode) ProposeConfChange(cc pb.ConfChangeI) error {
-	m, err := confChangeToMsg(cc)
-	if err != nil {
-		return err
-	}
-	return rn.raft.Step(m)
-}
-
-// ApplyConfChange applies a config change to the local node.
-func (rn *RawNode) ApplyConfChange(cc pb.ConfChangeI) *pb.ConfState {
-	cs := rn.raft.applyConfChange(cc.AsV2())
-	return &cs
-}
-
-// Step advances the state machine using the given message.
-func (rn *RawNode) Step(m pb.Message) error {
-	// ignore unexpected local messages receiving over network
-	if IsLocalMsg(m.Type) {
-		return ErrStepLocalMsg
-	}
-	if pr := rn.raft.prs.Progress[m.From]; pr != nil || !IsResponseMsg(m.Type) {
-		return rn.raft.Step(m)
-	}
-	return ErrStepPeerNotFound
-}
-
-// Ready returns the outstanding work that the application needs to handle. This
-// includes appending and applying entries or a snapshot, updating the HardState,
-// and sending messages. The returned Ready() *must* be handled and subsequently
-// passed back via Advance().
-func (rn *RawNode) Ready() Ready {
-	rd := rn.readyWithoutAccept()
-	rn.acceptReady(rd)
-	return rd
-}
-
-// readyWithoutAccept returns a Ready. This is a read-only operation, i.e. there
-// is no obligation that the Ready must be handled.
-func (rn *RawNode) readyWithoutAccept() Ready {
-	return newReady(rn.raft, rn.prevSoftSt, rn.prevHardSt)
-}
-
-// acceptReady is called when the consumer of the RawNode has decided to go
-// ahead and handle a Ready. Nothing must alter the state of the RawNode between
-// this call and the prior call to Ready().
-func (rn *RawNode) acceptReady(rd Ready) {
-	if rd.SoftState != nil {
-		rn.prevSoftSt = rd.SoftState
-	}
-	if len(rd.ReadStates) != 0 {
-		rn.raft.readStates = nil
-	}
-	rn.raft.msgs = nil
-}
-
-// HasReady called when RawNode user need to check if any Ready pending.
-// Checking logic in this method should be consistent with Ready.containsUpdates().
-func (rn *RawNode) HasReady() bool {
-	r := rn.raft
-	if !r.softState().equal(rn.prevSoftSt) {
-		return true
-	}
-	if hardSt := r.hardState(); !IsEmptyHardState(hardSt) && !isHardStateEqual(hardSt, rn.prevHardSt) {
-		return true
-	}
-	if r.raftLog.unstable.snapshot != nil && !IsEmptySnap(*r.raftLog.unstable.snapshot) {
-		return true
-	}
-	if len(r.msgs) > 0 || len(r.raftLog.unstableEntries()) > 0 || r.raftLog.hasNextEnts() {
-		return true
-	}
-	if len(r.readStates) != 0 {
-		return true
-	}
-	return false
-}
-
-// Advance notifies the RawNode that the application has applied and saved progress in the
-// last Ready results.
-func (rn *RawNode) Advance(rd Ready) {
-	if !IsEmptyHardState(rd.HardState) {
-		rn.prevHardSt = rd.HardState
-	}
-	rn.raft.advance(rd)
-}
-
-// Status returns the current status of the given group. This allocates, see
-// BasicStatus and WithProgress for allocation-friendlier choices.
-func (rn *RawNode) Status() Status {
-	status := getStatus(rn.raft)
-	return status
-}
-
-// BasicStatus returns a BasicStatus. Notably this does not contain the
-// Progress map; see WithProgress for an allocation-free way to inspect it.
-func (rn *RawNode) BasicStatus() BasicStatus {
-	return getBasicStatus(rn.raft)
-}
-
-// ProgressType indicates the type of replica a Progress corresponds to.
-type ProgressType byte
-
-const (
-	// ProgressTypePeer accompanies a Progress for a regular peer replica.
-	ProgressTypePeer ProgressType = iota
-	// ProgressTypeLearner accompanies a Progress for a learner replica.
-	ProgressTypeLearner
-)
-
-// WithProgress is a helper to introspect the Progress for this node and its
-// peers.
-func (rn *RawNode) WithProgress(visitor func(id uint64, typ ProgressType, pr tracker.Progress)) {
-	rn.raft.prs.Visit(func(id uint64, pr *tracker.Progress) {
-		typ := ProgressTypePeer
-		if pr.IsLearner {
-			typ = ProgressTypeLearner
-		}
-		p := *pr
-		p.Inflights = nil
-		visitor(id, typ, p)
-	})
-}
-
-// ReportUnreachable reports the given node is not reachable for the last send.
-func (rn *RawNode) ReportUnreachable(id uint64) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgUnreachable, From: id})
-}
-
-// ReportSnapshot reports the status of the sent snapshot.
-func (rn *RawNode) ReportSnapshot(id uint64, status SnapshotStatus) {
-	rej := status == SnapshotFailure
-
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgSnapStatus, From: id, Reject: rej})
-}
-
-// TransferLeader tries to transfer leadership to the given transferee.
-func (rn *RawNode) TransferLeader(transferee uint64) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgTransferLeader, From: transferee})
-}
-
-// ReadIndex requests a read state. The read state will be set in ready.
-// Read State has a read index. Once the application advances further than the read
-// index, any linearizable read requests issued before the read request can be
-// processed safely. The read state will have the same rctx attached.
-func (rn *RawNode) ReadIndex(rctx []byte) {
-	_ = rn.raft.Step(pb.Message{Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: rctx}}})
-}
diff --git a/vendor/go.etcd.io/etcd/raft/read_only.go b/vendor/go.etcd.io/etcd/raft/read_only.go
deleted file mode 100644
index 6987f1b..0000000
--- a/vendor/go.etcd.io/etcd/raft/read_only.go
+++ /dev/null
@@ -1,121 +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 raft
-
-import pb "go.etcd.io/etcd/raft/raftpb"
-
-// ReadState provides state for read only query.
-// It's caller's responsibility to call ReadIndex first before getting
-// this state from ready, it's also caller's duty to differentiate if this
-// state is what it requests through RequestCtx, eg. given a unique id as
-// RequestCtx
-type ReadState struct {
-	Index      uint64
-	RequestCtx []byte
-}
-
-type readIndexStatus struct {
-	req   pb.Message
-	index uint64
-	// NB: this never records 'false', but it's more convenient to use this
-	// instead of a map[uint64]struct{} due to the API of quorum.VoteResult. If
-	// this becomes performance sensitive enough (doubtful), quorum.VoteResult
-	// can change to an API that is closer to that of CommittedIndex.
-	acks map[uint64]bool
-}
-
-type readOnly struct {
-	option           ReadOnlyOption
-	pendingReadIndex map[string]*readIndexStatus
-	readIndexQueue   []string
-}
-
-func newReadOnly(option ReadOnlyOption) *readOnly {
-	return &readOnly{
-		option:           option,
-		pendingReadIndex: make(map[string]*readIndexStatus),
-	}
-}
-
-// addRequest adds a read only reuqest into readonly struct.
-// `index` is the commit index of the raft state machine when it received
-// the read only request.
-// `m` is the original read only request message from the local or remote node.
-func (ro *readOnly) addRequest(index uint64, m pb.Message) {
-	s := string(m.Entries[0].Data)
-	if _, ok := ro.pendingReadIndex[s]; ok {
-		return
-	}
-	ro.pendingReadIndex[s] = &readIndexStatus{index: index, req: m, acks: make(map[uint64]bool)}
-	ro.readIndexQueue = append(ro.readIndexQueue, s)
-}
-
-// recvAck notifies the readonly struct that the raft state machine received
-// an acknowledgment of the heartbeat that attached with the read only request
-// context.
-func (ro *readOnly) recvAck(id uint64, context []byte) map[uint64]bool {
-	rs, ok := ro.pendingReadIndex[string(context)]
-	if !ok {
-		return nil
-	}
-
-	rs.acks[id] = true
-	return rs.acks
-}
-
-// advance advances the read only request queue kept by the readonly struct.
-// It dequeues the requests until it finds the read only request that has
-// the same context as the given `m`.
-func (ro *readOnly) advance(m pb.Message) []*readIndexStatus {
-	var (
-		i     int
-		found bool
-	)
-
-	ctx := string(m.Context)
-	rss := []*readIndexStatus{}
-
-	for _, okctx := range ro.readIndexQueue {
-		i++
-		rs, ok := ro.pendingReadIndex[okctx]
-		if !ok {
-			panic("cannot find corresponding read state from pending map")
-		}
-		rss = append(rss, rs)
-		if okctx == ctx {
-			found = true
-			break
-		}
-	}
-
-	if found {
-		ro.readIndexQueue = ro.readIndexQueue[i:]
-		for _, rs := range rss {
-			delete(ro.pendingReadIndex, string(rs.req.Entries[0].Data))
-		}
-		return rss
-	}
-
-	return nil
-}
-
-// lastPendingRequestCtx returns the context of the last pending read only
-// request in readonly struct.
-func (ro *readOnly) lastPendingRequestCtx() string {
-	if len(ro.readIndexQueue) == 0 {
-		return ""
-	}
-	return ro.readIndexQueue[len(ro.readIndexQueue)-1]
-}
diff --git a/vendor/go.etcd.io/etcd/raft/status.go b/vendor/go.etcd.io/etcd/raft/status.go
deleted file mode 100644
index adc6048..0000000
--- a/vendor/go.etcd.io/etcd/raft/status.go
+++ /dev/null
@@ -1,106 +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 raft
-
-import (
-	"fmt"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/raft/tracker"
-)
-
-// Status contains information about this Raft peer and its view of the system.
-// The Progress is only populated on the leader.
-type Status struct {
-	BasicStatus
-	Config   tracker.Config
-	Progress map[uint64]tracker.Progress
-}
-
-// BasicStatus contains basic information about the Raft peer. It does not allocate.
-type BasicStatus struct {
-	ID uint64
-
-	pb.HardState
-	SoftState
-
-	Applied uint64
-
-	LeadTransferee uint64
-}
-
-func getProgressCopy(r *raft) map[uint64]tracker.Progress {
-	m := make(map[uint64]tracker.Progress)
-	r.prs.Visit(func(id uint64, pr *tracker.Progress) {
-		var p tracker.Progress
-		p = *pr
-		p.Inflights = pr.Inflights.Clone()
-		pr = nil
-
-		m[id] = p
-	})
-	return m
-}
-
-func getBasicStatus(r *raft) BasicStatus {
-	s := BasicStatus{
-		ID:             r.id,
-		LeadTransferee: r.leadTransferee,
-	}
-	s.HardState = r.hardState()
-	s.SoftState = *r.softState()
-	s.Applied = r.raftLog.applied
-	return s
-}
-
-// getStatus gets a copy of the current raft status.
-func getStatus(r *raft) Status {
-	var s Status
-	s.BasicStatus = getBasicStatus(r)
-	if s.RaftState == StateLeader {
-		s.Progress = getProgressCopy(r)
-	}
-	s.Config = r.prs.Config.Clone()
-	return s
-}
-
-// MarshalJSON translates the raft status into JSON.
-// TODO: try to simplify this by introducing ID type into raft
-func (s Status) MarshalJSON() ([]byte, error) {
-	j := fmt.Sprintf(`{"id":"%x","term":%d,"vote":"%x","commit":%d,"lead":"%x","raftState":%q,"applied":%d,"progress":{`,
-		s.ID, s.Term, s.Vote, s.Commit, s.Lead, s.RaftState, s.Applied)
-
-	if len(s.Progress) == 0 {
-		j += "},"
-	} else {
-		for k, v := range s.Progress {
-			subj := fmt.Sprintf(`"%x":{"match":%d,"next":%d,"state":%q},`, k, v.Match, v.Next, v.State)
-			j += subj
-		}
-		// remove the trailing ","
-		j = j[:len(j)-1] + "},"
-	}
-
-	j += fmt.Sprintf(`"leadtransferee":"%x"}`, s.LeadTransferee)
-	return []byte(j), nil
-}
-
-func (s Status) String() string {
-	b, err := s.MarshalJSON()
-	if err != nil {
-		raftLogger.Panicf("unexpected error: %v", err)
-	}
-	return string(b)
-}
diff --git a/vendor/go.etcd.io/etcd/raft/storage.go b/vendor/go.etcd.io/etcd/raft/storage.go
deleted file mode 100644
index 6be5745..0000000
--- a/vendor/go.etcd.io/etcd/raft/storage.go
+++ /dev/null
@@ -1,273 +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 raft
-
-import (
-	"errors"
-	"sync"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-// ErrCompacted is returned by Storage.Entries/Compact when a requested
-// index is unavailable because it predates the last snapshot.
-var ErrCompacted = errors.New("requested index is unavailable due to compaction")
-
-// ErrSnapOutOfDate is returned by Storage.CreateSnapshot when a requested
-// index is older than the existing snapshot.
-var ErrSnapOutOfDate = errors.New("requested index is older than the existing snapshot")
-
-// ErrUnavailable is returned by Storage interface when the requested log entries
-// are unavailable.
-var ErrUnavailable = errors.New("requested entry at index is unavailable")
-
-// ErrSnapshotTemporarilyUnavailable is returned by the Storage interface when the required
-// snapshot is temporarily unavailable.
-var ErrSnapshotTemporarilyUnavailable = errors.New("snapshot is temporarily unavailable")
-
-// Storage is an interface that may be implemented by the application
-// to retrieve log entries from storage.
-//
-// If any Storage method returns an error, the raft instance will
-// become inoperable and refuse to participate in elections; the
-// application is responsible for cleanup and recovery in this case.
-type Storage interface {
-	// TODO(tbg): split this into two interfaces, LogStorage and StateStorage.
-
-	// InitialState returns the saved HardState and ConfState information.
-	InitialState() (pb.HardState, pb.ConfState, error)
-	// Entries returns a slice of log entries in the range [lo,hi).
-	// MaxSize limits the total size of the log entries returned, but
-	// Entries returns at least one entry if any.
-	Entries(lo, hi, maxSize uint64) ([]pb.Entry, error)
-	// Term returns the term of entry i, which must be in the range
-	// [FirstIndex()-1, LastIndex()]. The term of the entry before
-	// FirstIndex is retained for matching purposes even though the
-	// rest of that entry may not be available.
-	Term(i uint64) (uint64, error)
-	// LastIndex returns the index of the last entry in the log.
-	LastIndex() (uint64, error)
-	// FirstIndex returns the index of the first log entry that is
-	// possibly available via Entries (older entries have been incorporated
-	// into the latest Snapshot; if storage only contains the dummy entry the
-	// first log entry is not available).
-	FirstIndex() (uint64, error)
-	// Snapshot returns the most recent snapshot.
-	// If snapshot is temporarily unavailable, it should return ErrSnapshotTemporarilyUnavailable,
-	// so raft state machine could know that Storage needs some time to prepare
-	// snapshot and call Snapshot later.
-	Snapshot() (pb.Snapshot, error)
-}
-
-// MemoryStorage implements the Storage interface backed by an
-// in-memory array.
-type MemoryStorage struct {
-	// Protects access to all fields. Most methods of MemoryStorage are
-	// run on the raft goroutine, but Append() is run on an application
-	// goroutine.
-	sync.Mutex
-
-	hardState pb.HardState
-	snapshot  pb.Snapshot
-	// ents[i] has raft log position i+snapshot.Metadata.Index
-	ents []pb.Entry
-}
-
-// NewMemoryStorage creates an empty MemoryStorage.
-func NewMemoryStorage() *MemoryStorage {
-	return &MemoryStorage{
-		// When starting from scratch populate the list with a dummy entry at term zero.
-		ents: make([]pb.Entry, 1),
-	}
-}
-
-// InitialState implements the Storage interface.
-func (ms *MemoryStorage) InitialState() (pb.HardState, pb.ConfState, error) {
-	return ms.hardState, ms.snapshot.Metadata.ConfState, nil
-}
-
-// SetHardState saves the current HardState.
-func (ms *MemoryStorage) SetHardState(st pb.HardState) error {
-	ms.Lock()
-	defer ms.Unlock()
-	ms.hardState = st
-	return nil
-}
-
-// Entries implements the Storage interface.
-func (ms *MemoryStorage) Entries(lo, hi, maxSize uint64) ([]pb.Entry, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if lo <= offset {
-		return nil, ErrCompacted
-	}
-	if hi > ms.lastIndex()+1 {
-		raftLogger.Panicf("entries' hi(%d) is out of bound lastindex(%d)", hi, ms.lastIndex())
-	}
-	// only contains dummy entries.
-	if len(ms.ents) == 1 {
-		return nil, ErrUnavailable
-	}
-
-	ents := ms.ents[lo-offset : hi-offset]
-	return limitSize(ents, maxSize), nil
-}
-
-// Term implements the Storage interface.
-func (ms *MemoryStorage) Term(i uint64) (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if i < offset {
-		return 0, ErrCompacted
-	}
-	if int(i-offset) >= len(ms.ents) {
-		return 0, ErrUnavailable
-	}
-	return ms.ents[i-offset].Term, nil
-}
-
-// LastIndex implements the Storage interface.
-func (ms *MemoryStorage) LastIndex() (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.lastIndex(), nil
-}
-
-func (ms *MemoryStorage) lastIndex() uint64 {
-	return ms.ents[0].Index + uint64(len(ms.ents)) - 1
-}
-
-// FirstIndex implements the Storage interface.
-func (ms *MemoryStorage) FirstIndex() (uint64, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.firstIndex(), nil
-}
-
-func (ms *MemoryStorage) firstIndex() uint64 {
-	return ms.ents[0].Index + 1
-}
-
-// Snapshot implements the Storage interface.
-func (ms *MemoryStorage) Snapshot() (pb.Snapshot, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	return ms.snapshot, nil
-}
-
-// ApplySnapshot overwrites the contents of this Storage object with
-// those of the given snapshot.
-func (ms *MemoryStorage) ApplySnapshot(snap pb.Snapshot) error {
-	ms.Lock()
-	defer ms.Unlock()
-
-	//handle check for old snapshot being applied
-	msIndex := ms.snapshot.Metadata.Index
-	snapIndex := snap.Metadata.Index
-	if msIndex >= snapIndex {
-		return ErrSnapOutOfDate
-	}
-
-	ms.snapshot = snap
-	ms.ents = []pb.Entry{{Term: snap.Metadata.Term, Index: snap.Metadata.Index}}
-	return nil
-}
-
-// CreateSnapshot makes a snapshot which can be retrieved with Snapshot() and
-// can be used to reconstruct the state at that point.
-// If any configuration changes have been made since the last compaction,
-// the result of the last ApplyConfChange must be passed in.
-func (ms *MemoryStorage) CreateSnapshot(i uint64, cs *pb.ConfState, data []byte) (pb.Snapshot, error) {
-	ms.Lock()
-	defer ms.Unlock()
-	if i <= ms.snapshot.Metadata.Index {
-		return pb.Snapshot{}, ErrSnapOutOfDate
-	}
-
-	offset := ms.ents[0].Index
-	if i > ms.lastIndex() {
-		raftLogger.Panicf("snapshot %d is out of bound lastindex(%d)", i, ms.lastIndex())
-	}
-
-	ms.snapshot.Metadata.Index = i
-	ms.snapshot.Metadata.Term = ms.ents[i-offset].Term
-	if cs != nil {
-		ms.snapshot.Metadata.ConfState = *cs
-	}
-	ms.snapshot.Data = data
-	return ms.snapshot, nil
-}
-
-// Compact discards all log entries prior to compactIndex.
-// It is the application's responsibility to not attempt to compact an index
-// greater than raftLog.applied.
-func (ms *MemoryStorage) Compact(compactIndex uint64) error {
-	ms.Lock()
-	defer ms.Unlock()
-	offset := ms.ents[0].Index
-	if compactIndex <= offset {
-		return ErrCompacted
-	}
-	if compactIndex > ms.lastIndex() {
-		raftLogger.Panicf("compact %d is out of bound lastindex(%d)", compactIndex, ms.lastIndex())
-	}
-
-	i := compactIndex - offset
-	ents := make([]pb.Entry, 1, 1+uint64(len(ms.ents))-i)
-	ents[0].Index = ms.ents[i].Index
-	ents[0].Term = ms.ents[i].Term
-	ents = append(ents, ms.ents[i+1:]...)
-	ms.ents = ents
-	return nil
-}
-
-// Append the new entries to storage.
-// TODO (xiangli): ensure the entries are continuous and
-// entries[0].Index > ms.entries[0].Index
-func (ms *MemoryStorage) Append(entries []pb.Entry) error {
-	if len(entries) == 0 {
-		return nil
-	}
-
-	ms.Lock()
-	defer ms.Unlock()
-
-	first := ms.firstIndex()
-	last := entries[0].Index + uint64(len(entries)) - 1
-
-	// shortcut if there is no new entry.
-	if last < first {
-		return nil
-	}
-	// truncate compacted entries
-	if first > entries[0].Index {
-		entries = entries[first-entries[0].Index:]
-	}
-
-	offset := entries[0].Index - ms.ents[0].Index
-	switch {
-	case uint64(len(ms.ents)) > offset:
-		ms.ents = append([]pb.Entry{}, ms.ents[:offset]...)
-		ms.ents = append(ms.ents, entries...)
-	case uint64(len(ms.ents)) == offset:
-		ms.ents = append(ms.ents, entries...)
-	default:
-		raftLogger.Panicf("missing log entry [last: %d, append at: %d]",
-			ms.lastIndex(), entries[0].Index)
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/raft/tracker/inflights.go b/vendor/go.etcd.io/etcd/raft/tracker/inflights.go
deleted file mode 100644
index 1a05634..0000000
--- a/vendor/go.etcd.io/etcd/raft/tracker/inflights.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2019 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 tracker
-
-// Inflights limits the number of MsgApp (represented by the largest index
-// contained within) sent to followers but not yet acknowledged by them. Callers
-// use Full() to check whether more messages can be sent, call Add() whenever
-// they are sending a new append, and release "quota" via FreeLE() whenever an
-// ack is received.
-type Inflights struct {
-	// the starting index in the buffer
-	start int
-	// number of inflights in the buffer
-	count int
-
-	// the size of the buffer
-	size int
-
-	// buffer contains the index of the last entry
-	// inside one message.
-	buffer []uint64
-}
-
-// NewInflights sets up an Inflights that allows up to 'size' inflight messages.
-func NewInflights(size int) *Inflights {
-	return &Inflights{
-		size: size,
-	}
-}
-
-// Clone returns an *Inflights that is identical to but shares no memory with
-// the receiver.
-func (in *Inflights) Clone() *Inflights {
-	ins := *in
-	ins.buffer = append([]uint64(nil), in.buffer...)
-	return &ins
-}
-
-// Add notifies the Inflights that a new message with the given index is being
-// dispatched. Full() must be called prior to Add() to verify that there is room
-// for one more message, and consecutive calls to add Add() must provide a
-// monotonic sequence of indexes.
-func (in *Inflights) Add(inflight uint64) {
-	if in.Full() {
-		panic("cannot add into a Full inflights")
-	}
-	next := in.start + in.count
-	size := in.size
-	if next >= size {
-		next -= size
-	}
-	if next >= len(in.buffer) {
-		in.grow()
-	}
-	in.buffer[next] = inflight
-	in.count++
-}
-
-// grow the inflight buffer by doubling up to inflights.size. We grow on demand
-// instead of preallocating to inflights.size to handle systems which have
-// thousands of Raft groups per process.
-func (in *Inflights) grow() {
-	newSize := len(in.buffer) * 2
-	if newSize == 0 {
-		newSize = 1
-	} else if newSize > in.size {
-		newSize = in.size
-	}
-	newBuffer := make([]uint64, newSize)
-	copy(newBuffer, in.buffer)
-	in.buffer = newBuffer
-}
-
-// FreeLE frees the inflights smaller or equal to the given `to` flight.
-func (in *Inflights) FreeLE(to uint64) {
-	if in.count == 0 || to < in.buffer[in.start] {
-		// out of the left side of the window
-		return
-	}
-
-	idx := in.start
-	var i int
-	for i = 0; i < in.count; i++ {
-		if to < in.buffer[idx] { // found the first large inflight
-			break
-		}
-
-		// increase index and maybe rotate
-		size := in.size
-		if idx++; idx >= size {
-			idx -= size
-		}
-	}
-	// free i inflights and set new start index
-	in.count -= i
-	in.start = idx
-	if in.count == 0 {
-		// inflights is empty, reset the start index so that we don't grow the
-		// buffer unnecessarily.
-		in.start = 0
-	}
-}
-
-// FreeFirstOne releases the first inflight. This is a no-op if nothing is
-// inflight.
-func (in *Inflights) FreeFirstOne() { in.FreeLE(in.buffer[in.start]) }
-
-// Full returns true if no more messages can be sent at the moment.
-func (in *Inflights) Full() bool {
-	return in.count == in.size
-}
-
-// Count returns the number of inflight messages.
-func (in *Inflights) Count() int { return in.count }
-
-// reset frees all inflights.
-func (in *Inflights) reset() {
-	in.count = 0
-	in.start = 0
-}
diff --git a/vendor/go.etcd.io/etcd/raft/tracker/progress.go b/vendor/go.etcd.io/etcd/raft/tracker/progress.go
deleted file mode 100644
index 62c81f4..0000000
--- a/vendor/go.etcd.io/etcd/raft/tracker/progress.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2019 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 tracker
-
-import (
-	"fmt"
-	"sort"
-	"strings"
-)
-
-// Progress represents a follower’s progress in the view of the leader. Leader
-// maintains progresses of all followers, and sends entries to the follower
-// based on its progress.
-//
-// NB(tbg): Progress is basically a state machine whose transitions are mostly
-// strewn around `*raft.raft`. Additionally, some fields are only used when in a
-// certain State. All of this isn't ideal.
-type Progress struct {
-	Match, Next uint64
-	// State defines how the leader should interact with the follower.
-	//
-	// When in StateProbe, leader sends at most one replication message
-	// per heartbeat interval. It also probes actual progress of the follower.
-	//
-	// When in StateReplicate, leader optimistically increases next
-	// to the latest entry sent after sending replication message. This is
-	// an optimized state for fast replicating log entries to the follower.
-	//
-	// When in StateSnapshot, leader should have sent out snapshot
-	// before and stops sending any replication message.
-	State StateType
-
-	// PendingSnapshot is used in StateSnapshot.
-	// If there is a pending snapshot, the pendingSnapshot will be set to the
-	// index of the snapshot. If pendingSnapshot is set, the replication process of
-	// this Progress will be paused. raft will not resend snapshot until the pending one
-	// is reported to be failed.
-	PendingSnapshot uint64
-
-	// RecentActive is true if the progress is recently active. Receiving any messages
-	// from the corresponding follower indicates the progress is active.
-	// RecentActive can be reset to false after an election timeout.
-	//
-	// TODO(tbg): the leader should always have this set to true.
-	RecentActive bool
-
-	// ProbeSent is used while this follower is in StateProbe. When ProbeSent is
-	// true, raft should pause sending replication message to this peer until
-	// ProbeSent is reset. See ProbeAcked() and IsPaused().
-	ProbeSent bool
-
-	// Inflights is a sliding window for the inflight messages.
-	// Each inflight message contains one or more log entries.
-	// The max number of entries per message is defined in raft config as MaxSizePerMsg.
-	// Thus inflight effectively limits both the number of inflight messages
-	// and the bandwidth each Progress can use.
-	// When inflights is Full, no more message should be sent.
-	// When a leader sends out a message, the index of the last
-	// entry should be added to inflights. The index MUST be added
-	// into inflights in order.
-	// When a leader receives a reply, the previous inflights should
-	// be freed by calling inflights.FreeLE with the index of the last
-	// received entry.
-	Inflights *Inflights
-
-	// IsLearner is true if this progress is tracked for a learner.
-	IsLearner bool
-}
-
-// ResetState moves the Progress into the specified State, resetting ProbeSent,
-// PendingSnapshot, and Inflights.
-func (pr *Progress) ResetState(state StateType) {
-	pr.ProbeSent = false
-	pr.PendingSnapshot = 0
-	pr.State = state
-	pr.Inflights.reset()
-}
-
-func max(a, b uint64) uint64 {
-	if a > b {
-		return a
-	}
-	return b
-}
-
-func min(a, b uint64) uint64 {
-	if a > b {
-		return b
-	}
-	return a
-}
-
-// ProbeAcked is called when this peer has accepted an append. It resets
-// ProbeSent to signal that additional append messages should be sent without
-// further delay.
-func (pr *Progress) ProbeAcked() {
-	pr.ProbeSent = false
-}
-
-// BecomeProbe transitions into StateProbe. Next is reset to Match+1 or,
-// optionally and if larger, the index of the pending snapshot.
-func (pr *Progress) BecomeProbe() {
-	// If the original state is StateSnapshot, progress knows that
-	// the pending snapshot has been sent to this peer successfully, then
-	// probes from pendingSnapshot + 1.
-	if pr.State == StateSnapshot {
-		pendingSnapshot := pr.PendingSnapshot
-		pr.ResetState(StateProbe)
-		pr.Next = max(pr.Match+1, pendingSnapshot+1)
-	} else {
-		pr.ResetState(StateProbe)
-		pr.Next = pr.Match + 1
-	}
-}
-
-// BecomeReplicate transitions into StateReplicate, resetting Next to Match+1.
-func (pr *Progress) BecomeReplicate() {
-	pr.ResetState(StateReplicate)
-	pr.Next = pr.Match + 1
-}
-
-// BecomeSnapshot moves the Progress to StateSnapshot with the specified pending
-// snapshot index.
-func (pr *Progress) BecomeSnapshot(snapshoti uint64) {
-	pr.ResetState(StateSnapshot)
-	pr.PendingSnapshot = snapshoti
-}
-
-// MaybeUpdate is called when an MsgAppResp arrives from the follower, with the
-// index acked by it. The method returns false if the given n index comes from
-// an outdated message. Otherwise it updates the progress and returns true.
-func (pr *Progress) MaybeUpdate(n uint64) bool {
-	var updated bool
-	if pr.Match < n {
-		pr.Match = n
-		updated = true
-		pr.ProbeAcked()
-	}
-	if pr.Next < n+1 {
-		pr.Next = n + 1
-	}
-	return updated
-}
-
-// OptimisticUpdate signals that appends all the way up to and including index n
-// are in-flight. As a result, Next is increased to n+1.
-func (pr *Progress) OptimisticUpdate(n uint64) { pr.Next = n + 1 }
-
-// MaybeDecrTo adjusts the Progress to the receipt of a MsgApp rejection. The
-// arguments are the index the follower rejected to append to its log, and its
-// last index.
-//
-// Rejections can happen spuriously as messages are sent out of order or
-// duplicated. In such cases, the rejection pertains to an index that the
-// Progress already knows were previously acknowledged, and false is returned
-// without changing the Progress.
-//
-// If the rejection is genuine, Next is lowered sensibly, and the Progress is
-// cleared for sending log entries.
-func (pr *Progress) MaybeDecrTo(rejected, last uint64) bool {
-	if pr.State == StateReplicate {
-		// The rejection must be stale if the progress has matched and "rejected"
-		// is smaller than "match".
-		if rejected <= pr.Match {
-			return false
-		}
-		// Directly decrease next to match + 1.
-		//
-		// TODO(tbg): why not use last if it's larger?
-		pr.Next = pr.Match + 1
-		return true
-	}
-
-	// The rejection must be stale if "rejected" does not match next - 1. This
-	// is because non-replicating followers are probed one entry at a time.
-	if pr.Next-1 != rejected {
-		return false
-	}
-
-	if pr.Next = min(rejected, last+1); pr.Next < 1 {
-		pr.Next = 1
-	}
-	pr.ProbeSent = false
-	return true
-}
-
-// IsPaused returns whether sending log entries to this node has been throttled.
-// This is done when a node has rejected recent MsgApps, is currently waiting
-// for a snapshot, or has reached the MaxInflightMsgs limit. In normal
-// operation, this is false. A throttled node will be contacted less frequently
-// until it has reached a state in which it's able to accept a steady stream of
-// log entries again.
-func (pr *Progress) IsPaused() bool {
-	switch pr.State {
-	case StateProbe:
-		return pr.ProbeSent
-	case StateReplicate:
-		return pr.Inflights.Full()
-	case StateSnapshot:
-		return true
-	default:
-		panic("unexpected state")
-	}
-}
-
-func (pr *Progress) String() string {
-	var buf strings.Builder
-	fmt.Fprintf(&buf, "%s match=%d next=%d", pr.State, pr.Match, pr.Next)
-	if pr.IsLearner {
-		fmt.Fprint(&buf, " learner")
-	}
-	if pr.IsPaused() {
-		fmt.Fprint(&buf, " paused")
-	}
-	if pr.PendingSnapshot > 0 {
-		fmt.Fprintf(&buf, " pendingSnap=%d", pr.PendingSnapshot)
-	}
-	if !pr.RecentActive {
-		fmt.Fprintf(&buf, " inactive")
-	}
-	if n := pr.Inflights.Count(); n > 0 {
-		fmt.Fprintf(&buf, " inflight=%d", n)
-		if pr.Inflights.Full() {
-			fmt.Fprint(&buf, "[full]")
-		}
-	}
-	return buf.String()
-}
-
-// ProgressMap is a map of *Progress.
-type ProgressMap map[uint64]*Progress
-
-// String prints the ProgressMap in sorted key order, one Progress per line.
-func (m ProgressMap) String() string {
-	ids := make([]uint64, 0, len(m))
-	for k := range m {
-		ids = append(ids, k)
-	}
-	sort.Slice(ids, func(i, j int) bool {
-		return ids[i] < ids[j]
-	})
-	var buf strings.Builder
-	for _, id := range ids {
-		fmt.Fprintf(&buf, "%d: %s\n", id, m[id])
-	}
-	return buf.String()
-}
diff --git a/vendor/go.etcd.io/etcd/raft/tracker/state.go b/vendor/go.etcd.io/etcd/raft/tracker/state.go
deleted file mode 100644
index 285b4b8..0000000
--- a/vendor/go.etcd.io/etcd/raft/tracker/state.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 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 tracker
-
-// StateType is the state of a tracked follower.
-type StateType uint64
-
-const (
-	// StateProbe indicates a follower whose last index isn't known. Such a
-	// follower is "probed" (i.e. an append sent periodically) to narrow down
-	// its last index. In the ideal (and common) case, only one round of probing
-	// is necessary as the follower will react with a hint. Followers that are
-	// probed over extended periods of time are often offline.
-	StateProbe StateType = iota
-	// StateReplicate is the state steady in which a follower eagerly receives
-	// log entries to append to its log.
-	StateReplicate
-	// StateSnapshot indicates a follower that needs log entries not available
-	// from the leader's Raft log. Such a follower needs a full snapshot to
-	// return to StateReplicate.
-	StateSnapshot
-)
-
-var prstmap = [...]string{
-	"StateProbe",
-	"StateReplicate",
-	"StateSnapshot",
-}
-
-func (st StateType) String() string { return prstmap[uint64(st)] }
diff --git a/vendor/go.etcd.io/etcd/raft/tracker/tracker.go b/vendor/go.etcd.io/etcd/raft/tracker/tracker.go
deleted file mode 100644
index a458114..0000000
--- a/vendor/go.etcd.io/etcd/raft/tracker/tracker.go
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2019 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 tracker
-
-import (
-	"fmt"
-	"sort"
-	"strings"
-
-	"go.etcd.io/etcd/raft/quorum"
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-// Config reflects the configuration tracked in a ProgressTracker.
-type Config struct {
-	Voters quorum.JointConfig
-	// AutoLeave is true if the configuration is joint and a transition to the
-	// incoming configuration should be carried out automatically by Raft when
-	// this is possible. If false, the configuration will be joint until the
-	// application initiates the transition manually.
-	AutoLeave bool
-	// Learners is a set of IDs corresponding to the learners active in the
-	// current configuration.
-	//
-	// Invariant: Learners and Voters does not intersect, i.e. if a peer is in
-	// either half of the joint config, it can't be a learner; if it is a
-	// learner it can't be in either half of the joint config. This invariant
-	// simplifies the implementation since it allows peers to have clarity about
-	// its current role without taking into account joint consensus.
-	Learners map[uint64]struct{}
-	// When we turn a voter into a learner during a joint consensus transition,
-	// we cannot add the learner directly when entering the joint state. This is
-	// because this would violate the invariant that the intersection of
-	// voters and learners is empty. For example, assume a Voter is removed and
-	// immediately re-added as a learner (or in other words, it is demoted):
-	//
-	// Initially, the configuration will be
-	//
-	//   voters:   {1 2 3}
-	//   learners: {}
-	//
-	// and we want to demote 3. Entering the joint configuration, we naively get
-	//
-	//   voters:   {1 2} & {1 2 3}
-	//   learners: {3}
-	//
-	// but this violates the invariant (3 is both voter and learner). Instead,
-	// we get
-	//
-	//   voters:   {1 2} & {1 2 3}
-	//   learners: {}
-	//   next_learners: {3}
-	//
-	// Where 3 is now still purely a voter, but we are remembering the intention
-	// to make it a learner upon transitioning into the final configuration:
-	//
-	//   voters:   {1 2}
-	//   learners: {3}
-	//   next_learners: {}
-	//
-	// Note that next_learners is not used while adding a learner that is not
-	// also a voter in the joint config. In this case, the learner is added
-	// right away when entering the joint configuration, so that it is caught up
-	// as soon as possible.
-	LearnersNext map[uint64]struct{}
-}
-
-func (c Config) String() string {
-	var buf strings.Builder
-	fmt.Fprintf(&buf, "voters=%s", c.Voters)
-	if c.Learners != nil {
-		fmt.Fprintf(&buf, " learners=%s", quorum.MajorityConfig(c.Learners).String())
-	}
-	if c.LearnersNext != nil {
-		fmt.Fprintf(&buf, " learners_next=%s", quorum.MajorityConfig(c.LearnersNext).String())
-	}
-	if c.AutoLeave {
-		fmt.Fprintf(&buf, " autoleave")
-	}
-	return buf.String()
-}
-
-// Clone returns a copy of the Config that shares no memory with the original.
-func (c *Config) Clone() Config {
-	clone := func(m map[uint64]struct{}) map[uint64]struct{} {
-		if m == nil {
-			return nil
-		}
-		mm := make(map[uint64]struct{}, len(m))
-		for k := range m {
-			mm[k] = struct{}{}
-		}
-		return mm
-	}
-	return Config{
-		Voters:       quorum.JointConfig{clone(c.Voters[0]), clone(c.Voters[1])},
-		Learners:     clone(c.Learners),
-		LearnersNext: clone(c.LearnersNext),
-	}
-}
-
-// ProgressTracker tracks the currently active configuration and the information
-// known about the nodes and learners in it. In particular, it tracks the match
-// index for each peer which in turn allows reasoning about the committed index.
-type ProgressTracker struct {
-	Config
-
-	Progress ProgressMap
-
-	Votes map[uint64]bool
-
-	MaxInflight int
-}
-
-// MakeProgressTracker initializes a ProgressTracker.
-func MakeProgressTracker(maxInflight int) ProgressTracker {
-	p := ProgressTracker{
-		MaxInflight: maxInflight,
-		Config: Config{
-			Voters: quorum.JointConfig{
-				quorum.MajorityConfig{},
-				nil, // only populated when used
-			},
-			Learners:     nil, // only populated when used
-			LearnersNext: nil, // only populated when used
-		},
-		Votes:    map[uint64]bool{},
-		Progress: map[uint64]*Progress{},
-	}
-	return p
-}
-
-// ConfState returns a ConfState representing the active configuration.
-func (p *ProgressTracker) ConfState() pb.ConfState {
-	return pb.ConfState{
-		Voters:         p.Voters[0].Slice(),
-		VotersOutgoing: p.Voters[1].Slice(),
-		Learners:       quorum.MajorityConfig(p.Learners).Slice(),
-		LearnersNext:   quorum.MajorityConfig(p.LearnersNext).Slice(),
-		AutoLeave:      p.AutoLeave,
-	}
-}
-
-// IsSingleton returns true if (and only if) there is only one voting member
-// (i.e. the leader) in the current configuration.
-func (p *ProgressTracker) IsSingleton() bool {
-	return len(p.Voters[0]) == 1 && len(p.Voters[1]) == 0
-}
-
-type matchAckIndexer map[uint64]*Progress
-
-var _ quorum.AckedIndexer = matchAckIndexer(nil)
-
-// AckedIndex implements IndexLookuper.
-func (l matchAckIndexer) AckedIndex(id uint64) (quorum.Index, bool) {
-	pr, ok := l[id]
-	if !ok {
-		return 0, false
-	}
-	return quorum.Index(pr.Match), true
-}
-
-// Committed returns the largest log index known to be committed based on what
-// the voting members of the group have acknowledged.
-func (p *ProgressTracker) Committed() uint64 {
-	return uint64(p.Voters.CommittedIndex(matchAckIndexer(p.Progress)))
-}
-
-func insertionSort(sl []uint64) {
-	a, b := 0, len(sl)
-	for i := a + 1; i < b; i++ {
-		for j := i; j > a && sl[j] < sl[j-1]; j-- {
-			sl[j], sl[j-1] = sl[j-1], sl[j]
-		}
-	}
-}
-
-// Visit invokes the supplied closure for all tracked progresses in stable order.
-func (p *ProgressTracker) Visit(f func(id uint64, pr *Progress)) {
-	n := len(p.Progress)
-	// We need to sort the IDs and don't want to allocate since this is hot code.
-	// The optimization here mirrors that in `(MajorityConfig).CommittedIndex`,
-	// see there for details.
-	var sl [7]uint64
-	ids := sl[:]
-	if len(sl) >= n {
-		ids = sl[:n]
-	} else {
-		ids = make([]uint64, n)
-	}
-	for id := range p.Progress {
-		n--
-		ids[n] = id
-	}
-	insertionSort(ids)
-	for _, id := range ids {
-		f(id, p.Progress[id])
-	}
-}
-
-// QuorumActive returns true if the quorum is active from the view of the local
-// raft state machine. Otherwise, it returns false.
-func (p *ProgressTracker) QuorumActive() bool {
-	votes := map[uint64]bool{}
-	p.Visit(func(id uint64, pr *Progress) {
-		if pr.IsLearner {
-			return
-		}
-		votes[id] = pr.RecentActive
-	})
-
-	return p.Voters.VoteResult(votes) == quorum.VoteWon
-}
-
-// VoterNodes returns a sorted slice of voters.
-func (p *ProgressTracker) VoterNodes() []uint64 {
-	m := p.Voters.IDs()
-	nodes := make([]uint64, 0, len(m))
-	for id := range m {
-		nodes = append(nodes, id)
-	}
-	sort.Slice(nodes, func(i, j int) bool { return nodes[i] < nodes[j] })
-	return nodes
-}
-
-// LearnerNodes returns a sorted slice of learners.
-func (p *ProgressTracker) LearnerNodes() []uint64 {
-	if len(p.Learners) == 0 {
-		return nil
-	}
-	nodes := make([]uint64, 0, len(p.Learners))
-	for id := range p.Learners {
-		nodes = append(nodes, id)
-	}
-	sort.Slice(nodes, func(i, j int) bool { return nodes[i] < nodes[j] })
-	return nodes
-}
-
-// ResetVotes prepares for a new round of vote counting via recordVote.
-func (p *ProgressTracker) ResetVotes() {
-	p.Votes = map[uint64]bool{}
-}
-
-// RecordVote records that the node with the given id voted for this Raft
-// instance if v == true (and declined it otherwise).
-func (p *ProgressTracker) RecordVote(id uint64, v bool) {
-	_, ok := p.Votes[id]
-	if !ok {
-		p.Votes[id] = v
-	}
-}
-
-// TallyVotes returns the number of granted and rejected Votes, and whether the
-// election outcome is known.
-func (p *ProgressTracker) TallyVotes() (granted int, rejected int, _ quorum.VoteResult) {
-	// Make sure to populate granted/rejected correctly even if the Votes slice
-	// contains members no longer part of the configuration. This doesn't really
-	// matter in the way the numbers are used (they're informational), but might
-	// as well get it right.
-	for id, pr := range p.Progress {
-		if pr.IsLearner {
-			continue
-		}
-		v, voted := p.Votes[id]
-		if !voted {
-			continue
-		}
-		if v {
-			granted++
-		} else {
-			rejected++
-		}
-	}
-	result := p.Voters.VoteResult(p.Votes)
-	return granted, rejected, result
-}
diff --git a/vendor/go.etcd.io/etcd/raft/util.go b/vendor/go.etcd.io/etcd/raft/util.go
deleted file mode 100644
index 785cf73..0000000
--- a/vendor/go.etcd.io/etcd/raft/util.go
+++ /dev/null
@@ -1,233 +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 raft
-
-import (
-	"bytes"
-	"fmt"
-	"strings"
-
-	pb "go.etcd.io/etcd/raft/raftpb"
-)
-
-func (st StateType) MarshalJSON() ([]byte, error) {
-	return []byte(fmt.Sprintf("%q", st.String())), nil
-}
-
-func min(a, b uint64) uint64 {
-	if a > b {
-		return b
-	}
-	return a
-}
-
-func max(a, b uint64) uint64 {
-	if a > b {
-		return a
-	}
-	return b
-}
-
-func IsLocalMsg(msgt pb.MessageType) bool {
-	return msgt == pb.MsgHup || msgt == pb.MsgBeat || msgt == pb.MsgUnreachable ||
-		msgt == pb.MsgSnapStatus || msgt == pb.MsgCheckQuorum
-}
-
-func IsResponseMsg(msgt pb.MessageType) bool {
-	return msgt == pb.MsgAppResp || msgt == pb.MsgVoteResp || msgt == pb.MsgHeartbeatResp || msgt == pb.MsgUnreachable || msgt == pb.MsgPreVoteResp
-}
-
-// voteResponseType maps vote and prevote message types to their corresponding responses.
-func voteRespMsgType(msgt pb.MessageType) pb.MessageType {
-	switch msgt {
-	case pb.MsgVote:
-		return pb.MsgVoteResp
-	case pb.MsgPreVote:
-		return pb.MsgPreVoteResp
-	default:
-		panic(fmt.Sprintf("not a vote message: %s", msgt))
-	}
-}
-
-func DescribeHardState(hs pb.HardState) string {
-	var buf strings.Builder
-	fmt.Fprintf(&buf, "Term:%d", hs.Term)
-	if hs.Vote != 0 {
-		fmt.Fprintf(&buf, " Vote:%d", hs.Vote)
-	}
-	fmt.Fprintf(&buf, " Commit:%d", hs.Commit)
-	return buf.String()
-}
-
-func DescribeSoftState(ss SoftState) string {
-	return fmt.Sprintf("Lead:%d State:%s", ss.Lead, ss.RaftState)
-}
-
-func DescribeConfState(state pb.ConfState) string {
-	return fmt.Sprintf(
-		"Voters:%v VotersOutgoing:%v Learners:%v LearnersNext:%v AutoLeave:%v",
-		state.Voters, state.VotersOutgoing, state.Learners, state.LearnersNext, state.AutoLeave,
-	)
-}
-
-func DescribeSnapshot(snap pb.Snapshot) string {
-	m := snap.Metadata
-	return fmt.Sprintf("Index:%d Term:%d ConfState:%s", m.Index, m.Term, DescribeConfState(m.ConfState))
-}
-
-func DescribeReady(rd Ready, f EntryFormatter) string {
-	var buf strings.Builder
-	if rd.SoftState != nil {
-		fmt.Fprint(&buf, DescribeSoftState(*rd.SoftState))
-		buf.WriteByte('\n')
-	}
-	if !IsEmptyHardState(rd.HardState) {
-		fmt.Fprintf(&buf, "HardState %s", DescribeHardState(rd.HardState))
-		buf.WriteByte('\n')
-	}
-	if len(rd.ReadStates) > 0 {
-		fmt.Fprintf(&buf, "ReadStates %v\n", rd.ReadStates)
-	}
-	if len(rd.Entries) > 0 {
-		buf.WriteString("Entries:\n")
-		fmt.Fprint(&buf, DescribeEntries(rd.Entries, f))
-	}
-	if !IsEmptySnap(rd.Snapshot) {
-		fmt.Fprintf(&buf, "Snapshot %s\n", DescribeSnapshot(rd.Snapshot))
-	}
-	if len(rd.CommittedEntries) > 0 {
-		buf.WriteString("CommittedEntries:\n")
-		fmt.Fprint(&buf, DescribeEntries(rd.CommittedEntries, f))
-	}
-	if len(rd.Messages) > 0 {
-		buf.WriteString("Messages:\n")
-		for _, msg := range rd.Messages {
-			fmt.Fprint(&buf, DescribeMessage(msg, f))
-			buf.WriteByte('\n')
-		}
-	}
-	if buf.Len() > 0 {
-		return fmt.Sprintf("Ready MustSync=%t:\n%s", rd.MustSync, buf.String())
-	}
-	return "<empty Ready>"
-}
-
-// EntryFormatter can be implemented by the application to provide human-readable formatting
-// of entry data. Nil is a valid EntryFormatter and will use a default format.
-type EntryFormatter func([]byte) string
-
-// DescribeMessage returns a concise human-readable description of a
-// Message for debugging.
-func DescribeMessage(m pb.Message, f EntryFormatter) string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%x->%x %v Term:%d Log:%d/%d", m.From, m.To, m.Type, m.Term, m.LogTerm, m.Index)
-	if m.Reject {
-		fmt.Fprintf(&buf, " Rejected (Hint: %d)", m.RejectHint)
-	}
-	if m.Commit != 0 {
-		fmt.Fprintf(&buf, " Commit:%d", m.Commit)
-	}
-	if len(m.Entries) > 0 {
-		fmt.Fprintf(&buf, " Entries:[")
-		for i, e := range m.Entries {
-			if i != 0 {
-				buf.WriteString(", ")
-			}
-			buf.WriteString(DescribeEntry(e, f))
-		}
-		fmt.Fprintf(&buf, "]")
-	}
-	if !IsEmptySnap(m.Snapshot) {
-		fmt.Fprintf(&buf, " Snapshot: %s", DescribeSnapshot(m.Snapshot))
-	}
-	return buf.String()
-}
-
-// PayloadSize is the size of the payload of this Entry. Notably, it does not
-// depend on its Index or Term.
-func PayloadSize(e pb.Entry) int {
-	return len(e.Data)
-}
-
-// DescribeEntry returns a concise human-readable description of an
-// Entry for debugging.
-func DescribeEntry(e pb.Entry, f EntryFormatter) string {
-	if f == nil {
-		f = func(data []byte) string { return fmt.Sprintf("%q", data) }
-	}
-
-	formatConfChange := func(cc pb.ConfChangeI) string {
-		// TODO(tbg): give the EntryFormatter a type argument so that it gets
-		// a chance to expose the Context.
-		return pb.ConfChangesToString(cc.AsV2().Changes)
-	}
-
-	var formatted string
-	switch e.Type {
-	case pb.EntryNormal:
-		formatted = f(e.Data)
-	case pb.EntryConfChange:
-		var cc pb.ConfChange
-		if err := cc.Unmarshal(e.Data); err != nil {
-			formatted = err.Error()
-		} else {
-			formatted = formatConfChange(cc)
-		}
-	case pb.EntryConfChangeV2:
-		var cc pb.ConfChangeV2
-		if err := cc.Unmarshal(e.Data); err != nil {
-			formatted = err.Error()
-		} else {
-			formatted = formatConfChange(cc)
-		}
-	}
-	if formatted != "" {
-		formatted = " " + formatted
-	}
-	return fmt.Sprintf("%d/%d %s%s", e.Term, e.Index, e.Type, formatted)
-}
-
-// DescribeEntries calls DescribeEntry for each Entry, adding a newline to
-// each.
-func DescribeEntries(ents []pb.Entry, f EntryFormatter) string {
-	var buf bytes.Buffer
-	for _, e := range ents {
-		_, _ = buf.WriteString(DescribeEntry(e, f) + "\n")
-	}
-	return buf.String()
-}
-
-func limitSize(ents []pb.Entry, maxSize uint64) []pb.Entry {
-	if len(ents) == 0 {
-		return ents
-	}
-	size := ents[0].Size()
-	var limit int
-	for limit = 1; limit < len(ents); limit++ {
-		size += ents[limit].Size()
-		if uint64(size) > maxSize {
-			break
-		}
-	}
-	return ents[:limit]
-}
-
-func assertConfStatesEquivalent(l Logger, cs1, cs2 pb.ConfState) {
-	err := cs1.Equivalent(cs2)
-	if err == nil {
-		return
-	}
-	l.Panic(err)
-}
diff --git a/vendor/go.etcd.io/etcd/version/version.go b/vendor/go.etcd.io/etcd/version/version.go
deleted file mode 100644
index 622e751..0000000
--- a/vendor/go.etcd.io/etcd/version/version.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 version implements etcd version parsing and contains latest version
-// information.
-package version
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/coreos/go-semver/semver"
-)
-
-var (
-	// MinClusterVersion is the min cluster version this etcd binary is compatible with.
-	MinClusterVersion = "3.0.0"
-	Version           = "3.5.0-pre"
-	APIVersion        = "unknown"
-
-	// Git SHA Value will be set during build
-	GitSHA = "Not provided (use ./build instead of go build)"
-)
-
-func init() {
-	ver, err := semver.NewVersion(Version)
-	if err == nil {
-		APIVersion = fmt.Sprintf("%d.%d", ver.Major, ver.Minor)
-	}
-}
-
-type Versions struct {
-	Server  string `json:"etcdserver"`
-	Cluster string `json:"etcdcluster"`
-	// TODO: raft state machine version
-}
-
-// Cluster only keeps the major.minor.
-func Cluster(v string) string {
-	vs := strings.Split(v, ".")
-	if len(vs) <= 2 {
-		return v
-	}
-	return fmt.Sprintf("%s.%s", vs[0], vs[1])
-}
diff --git a/vendor/go.etcd.io/etcd/wal/decoder.go b/vendor/go.etcd.io/etcd/wal/decoder.go
deleted file mode 100644
index f2f01fd..0000000
--- a/vendor/go.etcd.io/etcd/wal/decoder.go
+++ /dev/null
@@ -1,188 +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 wal
-
-import (
-	"bufio"
-	"encoding/binary"
-	"hash"
-	"io"
-	"sync"
-
-	"go.etcd.io/etcd/pkg/crc"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/wal/walpb"
-)
-
-const minSectorSize = 512
-
-// frameSizeBytes is frame size in bytes, including record size and padding size.
-const frameSizeBytes = 8
-
-type decoder struct {
-	mu  sync.Mutex
-	brs []*bufio.Reader
-
-	// lastValidOff file offset following the last valid decoded record
-	lastValidOff int64
-	crc          hash.Hash32
-}
-
-func newDecoder(r ...io.Reader) *decoder {
-	readers := make([]*bufio.Reader, len(r))
-	for i := range r {
-		readers[i] = bufio.NewReader(r[i])
-	}
-	return &decoder{
-		brs: readers,
-		crc: crc.New(0, crcTable),
-	}
-}
-
-func (d *decoder) decode(rec *walpb.Record) error {
-	rec.Reset()
-	d.mu.Lock()
-	defer d.mu.Unlock()
-	return d.decodeRecord(rec)
-}
-
-func (d *decoder) decodeRecord(rec *walpb.Record) error {
-	if len(d.brs) == 0 {
-		return io.EOF
-	}
-
-	l, err := readInt64(d.brs[0])
-	if err == io.EOF || (err == nil && l == 0) {
-		// hit end of file or preallocated space
-		d.brs = d.brs[1:]
-		if len(d.brs) == 0 {
-			return io.EOF
-		}
-		d.lastValidOff = 0
-		return d.decodeRecord(rec)
-	}
-	if err != nil {
-		return err
-	}
-
-	recBytes, padBytes := decodeFrameSize(l)
-
-	data := make([]byte, recBytes+padBytes)
-	if _, err = io.ReadFull(d.brs[0], data); err != nil {
-		// ReadFull returns io.EOF only if no bytes were read
-		// the decoder should treat this as an ErrUnexpectedEOF instead.
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return err
-	}
-	if err := rec.Unmarshal(data[:recBytes]); err != nil {
-		if d.isTornEntry(data) {
-			return io.ErrUnexpectedEOF
-		}
-		return err
-	}
-
-	// skip crc checking if the record type is crcType
-	if rec.Type != crcType {
-		d.crc.Write(rec.Data)
-		if err := rec.Validate(d.crc.Sum32()); err != nil {
-			if d.isTornEntry(data) {
-				return io.ErrUnexpectedEOF
-			}
-			return err
-		}
-	}
-	// record decoded as valid; point last valid offset to end of record
-	d.lastValidOff += frameSizeBytes + recBytes + padBytes
-	return nil
-}
-
-func decodeFrameSize(lenField int64) (recBytes int64, padBytes int64) {
-	// the record size is stored in the lower 56 bits of the 64-bit length
-	recBytes = int64(uint64(lenField) & ^(uint64(0xff) << 56))
-	// non-zero padding is indicated by set MSb / a negative length
-	if lenField < 0 {
-		// padding is stored in lower 3 bits of length MSB
-		padBytes = int64((uint64(lenField) >> 56) & 0x7)
-	}
-	return recBytes, padBytes
-}
-
-// isTornEntry determines whether the last entry of the WAL was partially written
-// and corrupted because of a torn write.
-func (d *decoder) isTornEntry(data []byte) bool {
-	if len(d.brs) != 1 {
-		return false
-	}
-
-	fileOff := d.lastValidOff + frameSizeBytes
-	curOff := 0
-	chunks := [][]byte{}
-	// split data on sector boundaries
-	for curOff < len(data) {
-		chunkLen := int(minSectorSize - (fileOff % minSectorSize))
-		if chunkLen > len(data)-curOff {
-			chunkLen = len(data) - curOff
-		}
-		chunks = append(chunks, data[curOff:curOff+chunkLen])
-		fileOff += int64(chunkLen)
-		curOff += chunkLen
-	}
-
-	// if any data for a sector chunk is all 0, it's a torn write
-	for _, sect := range chunks {
-		isZero := true
-		for _, v := range sect {
-			if v != 0 {
-				isZero = false
-				break
-			}
-		}
-		if isZero {
-			return true
-		}
-	}
-	return false
-}
-
-func (d *decoder) updateCRC(prevCrc uint32) {
-	d.crc = crc.New(prevCrc, crcTable)
-}
-
-func (d *decoder) lastCRC() uint32 {
-	return d.crc.Sum32()
-}
-
-func (d *decoder) lastOffset() int64 { return d.lastValidOff }
-
-func mustUnmarshalEntry(d []byte) raftpb.Entry {
-	var e raftpb.Entry
-	pbutil.MustUnmarshal(&e, d)
-	return e
-}
-
-func mustUnmarshalState(d []byte) raftpb.HardState {
-	var s raftpb.HardState
-	pbutil.MustUnmarshal(&s, d)
-	return s
-}
-
-func readInt64(r io.Reader) (int64, error) {
-	var n int64
-	err := binary.Read(r, binary.LittleEndian, &n)
-	return n, err
-}
diff --git a/vendor/go.etcd.io/etcd/wal/doc.go b/vendor/go.etcd.io/etcd/wal/doc.go
deleted file mode 100644
index 7ea348e..0000000
--- a/vendor/go.etcd.io/etcd/wal/doc.go
+++ /dev/null
@@ -1,75 +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 wal provides an implementation of a write ahead log that is used by
-etcd.
-
-A WAL is created at a particular directory and is made up of a number of
-segmented WAL files. Inside of each file the raft state and entries are appended
-to it with the Save method:
-
-	metadata := []byte{}
-	w, err := wal.Create(zap.NewExample(), "/var/lib/etcd", metadata)
-	...
-	err := w.Save(s, ents)
-
-After saving a raft snapshot to disk, SaveSnapshot method should be called to
-record it. So WAL can match with the saved snapshot when restarting.
-
-	err := w.SaveSnapshot(walpb.Snapshot{Index: 10, Term: 2})
-
-When a user has finished using a WAL it must be closed:
-
-	w.Close()
-
-Each WAL file is a stream of WAL records. A WAL record is a length field and a wal record
-protobuf. The record protobuf contains a CRC, a type, and a data payload. The length field is a
-64-bit packed structure holding the length of the remaining logical record data in its lower
-56 bits and its physical padding in the first three bits of the most significant byte. Each
-record is 8-byte aligned so that the length field is never torn. The CRC contains the CRC32
-value of all record protobufs preceding the current record.
-
-WAL files are placed inside of the directory in the following format:
-$seq-$index.wal
-
-The first WAL file to be created will be 0000000000000000-0000000000000000.wal
-indicating an initial sequence of 0 and an initial raft index of 0. The first
-entry written to WAL MUST have raft index 0.
-
-WAL will cut its current tail wal file if its size exceeds 64MB. This will increment an internal
-sequence number and cause a new file to be created. If the last raft index saved
-was 0x20 and this is the first time cut has been called on this WAL then the sequence will
-increment from 0x0 to 0x1. The new file will be: 0000000000000001-0000000000000021.wal.
-If a second cut issues 0x10 entries with incremental index later then the file will be called:
-0000000000000002-0000000000000031.wal.
-
-At a later time a WAL can be opened at a particular snapshot. If there is no
-snapshot, an empty snapshot should be passed in.
-
-	w, err := wal.Open("/var/lib/etcd", walpb.Snapshot{Index: 10, Term: 2})
-	...
-
-The snapshot must have been written to the WAL.
-
-Additional items cannot be Saved to this WAL until all of the items from the given
-snapshot to the end of the WAL are read first:
-
-	metadata, state, ents, err := w.ReadAll()
-
-This will give you the metadata, the last raft.State and the slice of
-raft.Entry items in the log.
-
-*/
-package wal
diff --git a/vendor/go.etcd.io/etcd/wal/encoder.go b/vendor/go.etcd.io/etcd/wal/encoder.go
deleted file mode 100644
index d3877ed..0000000
--- a/vendor/go.etcd.io/etcd/wal/encoder.go
+++ /dev/null
@@ -1,120 +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 wal
-
-import (
-	"encoding/binary"
-	"hash"
-	"io"
-	"os"
-	"sync"
-
-	"go.etcd.io/etcd/pkg/crc"
-	"go.etcd.io/etcd/pkg/ioutil"
-	"go.etcd.io/etcd/wal/walpb"
-)
-
-// walPageBytes is the alignment for flushing records to the backing Writer.
-// It should be a multiple of the minimum sector size so that WAL can safely
-// distinguish between torn writes and ordinary data corruption.
-const walPageBytes = 8 * minSectorSize
-
-type encoder struct {
-	mu sync.Mutex
-	bw *ioutil.PageWriter
-
-	crc       hash.Hash32
-	buf       []byte
-	uint64buf []byte
-}
-
-func newEncoder(w io.Writer, prevCrc uint32, pageOffset int) *encoder {
-	return &encoder{
-		bw:  ioutil.NewPageWriter(w, walPageBytes, pageOffset),
-		crc: crc.New(prevCrc, crcTable),
-		// 1MB buffer
-		buf:       make([]byte, 1024*1024),
-		uint64buf: make([]byte, 8),
-	}
-}
-
-// newFileEncoder creates a new encoder with current file offset for the page writer.
-func newFileEncoder(f *os.File, prevCrc uint32) (*encoder, error) {
-	offset, err := f.Seek(0, io.SeekCurrent)
-	if err != nil {
-		return nil, err
-	}
-	return newEncoder(f, prevCrc, int(offset)), nil
-}
-
-func (e *encoder) encode(rec *walpb.Record) error {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-
-	e.crc.Write(rec.Data)
-	rec.Crc = e.crc.Sum32()
-	var (
-		data []byte
-		err  error
-		n    int
-	)
-
-	if rec.Size() > len(e.buf) {
-		data, err = rec.Marshal()
-		if err != nil {
-			return err
-		}
-	} else {
-		n, err = rec.MarshalTo(e.buf)
-		if err != nil {
-			return err
-		}
-		data = e.buf[:n]
-	}
-
-	lenField, padBytes := encodeFrameSize(len(data))
-	if err = writeUint64(e.bw, lenField, e.uint64buf); err != nil {
-		return err
-	}
-
-	if padBytes != 0 {
-		data = append(data, make([]byte, padBytes)...)
-	}
-	_, err = e.bw.Write(data)
-	return err
-}
-
-func encodeFrameSize(dataBytes int) (lenField uint64, padBytes int) {
-	lenField = uint64(dataBytes)
-	// force 8 byte alignment so length never gets a torn write
-	padBytes = (8 - (dataBytes % 8)) % 8
-	if padBytes != 0 {
-		lenField |= uint64(0x80|padBytes) << 56
-	}
-	return lenField, padBytes
-}
-
-func (e *encoder) flush() error {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-	return e.bw.Flush()
-}
-
-func writeUint64(w io.Writer, n uint64, buf []byte) error {
-	// http://golang.org/src/encoding/binary/binary.go
-	binary.LittleEndian.PutUint64(buf, n)
-	_, err := w.Write(buf)
-	return err
-}
diff --git a/vendor/go.etcd.io/etcd/wal/file_pipeline.go b/vendor/go.etcd.io/etcd/wal/file_pipeline.go
deleted file mode 100644
index e1e1c55..0000000
--- a/vendor/go.etcd.io/etcd/wal/file_pipeline.go
+++ /dev/null
@@ -1,106 +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 wal
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-
-	"go.uber.org/zap"
-)
-
-// filePipeline pipelines allocating disk space
-type filePipeline struct {
-	lg *zap.Logger
-
-	// dir to put files
-	dir string
-	// size of files to make, in bytes
-	size int64
-	// count number of files generated
-	count int
-
-	filec chan *fileutil.LockedFile
-	errc  chan error
-	donec chan struct{}
-}
-
-func newFilePipeline(lg *zap.Logger, dir string, fileSize int64) *filePipeline {
-	fp := &filePipeline{
-		lg:    lg,
-		dir:   dir,
-		size:  fileSize,
-		filec: make(chan *fileutil.LockedFile),
-		errc:  make(chan error, 1),
-		donec: make(chan struct{}),
-	}
-	go fp.run()
-	return fp
-}
-
-// Open returns a fresh file for writing. Rename the file before calling
-// Open again or there will be file collisions.
-func (fp *filePipeline) Open() (f *fileutil.LockedFile, err error) {
-	select {
-	case f = <-fp.filec:
-	case err = <-fp.errc:
-	}
-	return f, err
-}
-
-func (fp *filePipeline) Close() error {
-	close(fp.donec)
-	return <-fp.errc
-}
-
-func (fp *filePipeline) alloc() (f *fileutil.LockedFile, err error) {
-	// count % 2 so this file isn't the same as the one last published
-	fpath := filepath.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count%2))
-	if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
-		return nil, err
-	}
-	if err = fileutil.Preallocate(f.File, fp.size, true); err != nil {
-		if fp.lg != nil {
-			fp.lg.Warn("failed to preallocate space when creating a new WAL", zap.Int64("size", fp.size), zap.Error(err))
-		} else {
-			plog.Errorf("failed to allocate space when creating new wal file (%v)", err)
-		}
-		f.Close()
-		return nil, err
-	}
-	fp.count++
-	return f, nil
-}
-
-func (fp *filePipeline) run() {
-	defer close(fp.errc)
-	for {
-		f, err := fp.alloc()
-		if err != nil {
-			fp.errc <- err
-			return
-		}
-		select {
-		case fp.filec <- f:
-		case <-fp.donec:
-			os.Remove(f.Name())
-			f.Close()
-			return
-		}
-	}
-}
diff --git a/vendor/go.etcd.io/etcd/wal/metrics.go b/vendor/go.etcd.io/etcd/wal/metrics.go
deleted file mode 100644
index 22cb800..0000000
--- a/vendor/go.etcd.io/etcd/wal/metrics.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 wal
-
-import "github.com/prometheus/client_golang/prometheus"
-
-var (
-	walFsyncSec = prometheus.NewHistogram(prometheus.HistogramOpts{
-		Namespace: "etcd",
-		Subsystem: "disk",
-		Name:      "wal_fsync_duration_seconds",
-		Help:      "The latency distributions of fsync called by WAL.",
-
-		// 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(walFsyncSec)
-}
diff --git a/vendor/go.etcd.io/etcd/wal/repair.go b/vendor/go.etcd.io/etcd/wal/repair.go
deleted file mode 100644
index 15afed0..0000000
--- a/vendor/go.etcd.io/etcd/wal/repair.go
+++ /dev/null
@@ -1,141 +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 wal
-
-import (
-	"io"
-	"os"
-	"path/filepath"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-	"go.etcd.io/etcd/wal/walpb"
-
-	"go.uber.org/zap"
-)
-
-// Repair tries to repair ErrUnexpectedEOF in the
-// last wal file by truncating.
-func Repair(lg *zap.Logger, dirpath string) bool {
-	f, err := openLast(lg, dirpath)
-	if err != nil {
-		return false
-	}
-	defer f.Close()
-
-	if lg != nil {
-		lg.Info("repairing", zap.String("path", f.Name()))
-	} else {
-		plog.Noticef("repairing %v", f.Name())
-	}
-
-	rec := &walpb.Record{}
-	decoder := newDecoder(f)
-	for {
-		lastOffset := decoder.lastOffset()
-		err := decoder.decode(rec)
-		switch err {
-		case nil:
-			// update crc of the decoder when necessary
-			switch rec.Type {
-			case crcType:
-				crc := decoder.crc.Sum32()
-				// current crc of decoder must match the crc of the record.
-				// do no need to match 0 crc, since the decoder is a new one at this case.
-				if crc != 0 && rec.Validate(crc) != nil {
-					return false
-				}
-				decoder.updateCRC(rec.Crc)
-			}
-			continue
-
-		case io.EOF:
-			if lg != nil {
-				lg.Info("repaired", zap.String("path", f.Name()), zap.Error(io.EOF))
-			}
-			return true
-
-		case io.ErrUnexpectedEOF:
-			bf, bferr := os.Create(f.Name() + ".broken")
-			if bferr != nil {
-				if lg != nil {
-					lg.Warn("failed to create backup file", zap.String("path", f.Name()+".broken"), zap.Error(bferr))
-				} else {
-					plog.Errorf("could not repair %v, failed to create backup file", f.Name())
-				}
-				return false
-			}
-			defer bf.Close()
-
-			if _, err = f.Seek(0, io.SeekStart); err != nil {
-				if lg != nil {
-					lg.Warn("failed to read file", zap.String("path", f.Name()), zap.Error(err))
-				} else {
-					plog.Errorf("could not repair %v, failed to read file", f.Name())
-				}
-				return false
-			}
-
-			if _, err = io.Copy(bf, f); err != nil {
-				if lg != nil {
-					lg.Warn("failed to copy", zap.String("from", f.Name()+".broken"), zap.String("to", f.Name()), zap.Error(err))
-				} else {
-					plog.Errorf("could not repair %v, failed to copy file", f.Name())
-				}
-				return false
-			}
-
-			if err = f.Truncate(lastOffset); err != nil {
-				if lg != nil {
-					lg.Warn("failed to truncate", zap.String("path", f.Name()), zap.Error(err))
-				} else {
-					plog.Errorf("could not repair %v, failed to truncate file", f.Name())
-				}
-				return false
-			}
-
-			if err = fileutil.Fsync(f.File); err != nil {
-				if lg != nil {
-					lg.Warn("failed to fsync", zap.String("path", f.Name()), zap.Error(err))
-				} else {
-					plog.Errorf("could not repair %v, failed to sync file", f.Name())
-				}
-				return false
-			}
-
-			if lg != nil {
-				lg.Info("repaired", zap.String("path", f.Name()), zap.Error(io.ErrUnexpectedEOF))
-			}
-			return true
-
-		default:
-			if lg != nil {
-				lg.Warn("failed to repair", zap.String("path", f.Name()), zap.Error(err))
-			} else {
-				plog.Errorf("could not repair error (%v)", err)
-			}
-			return false
-		}
-	}
-}
-
-// openLast opens the last wal file for read and write.
-func openLast(lg *zap.Logger, dirpath string) (*fileutil.LockedFile, error) {
-	names, err := readWALNames(lg, dirpath)
-	if err != nil {
-		return nil, err
-	}
-	last := filepath.Join(dirpath, names[len(names)-1])
-	return fileutil.LockFile(last, os.O_RDWR, fileutil.PrivateFileMode)
-}
diff --git a/vendor/go.etcd.io/etcd/wal/util.go b/vendor/go.etcd.io/etcd/wal/util.go
deleted file mode 100644
index a3f314b..0000000
--- a/vendor/go.etcd.io/etcd/wal/util.go
+++ /dev/null
@@ -1,124 +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 wal
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-
-	"go.uber.org/zap"
-)
-
-var errBadWALName = errors.New("bad wal name")
-
-// Exist returns true if there are any files in a given directory.
-func Exist(dir string) bool {
-	names, err := fileutil.ReadDir(dir, fileutil.WithExt(".wal"))
-	if err != nil {
-		return false
-	}
-	return len(names) != 0
-}
-
-// searchIndex returns the last array index of names whose raft index section is
-// equal to or smaller than the given index.
-// The given names MUST be sorted.
-func searchIndex(lg *zap.Logger, names []string, index uint64) (int, bool) {
-	for i := len(names) - 1; i >= 0; i-- {
-		name := names[i]
-		_, curIndex, err := parseWALName(name)
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to parse WAL file name", zap.String("path", name), zap.Error(err))
-			} else {
-				plog.Panicf("parse correct name should never fail: %v", err)
-			}
-		}
-		if index >= curIndex {
-			return i, true
-		}
-	}
-	return -1, false
-}
-
-// names should have been sorted based on sequence number.
-// isValidSeq checks whether seq increases continuously.
-func isValidSeq(lg *zap.Logger, names []string) bool {
-	var lastSeq uint64
-	for _, name := range names {
-		curSeq, _, err := parseWALName(name)
-		if err != nil {
-			if lg != nil {
-				lg.Panic("failed to parse WAL file name", zap.String("path", name), zap.Error(err))
-			} else {
-				plog.Panicf("parse correct name should never fail: %v", err)
-			}
-		}
-		if lastSeq != 0 && lastSeq != curSeq-1 {
-			return false
-		}
-		lastSeq = curSeq
-	}
-	return true
-}
-
-func readWALNames(lg *zap.Logger, dirpath string) ([]string, error) {
-	names, err := fileutil.ReadDir(dirpath)
-	if err != nil {
-		return nil, err
-	}
-	wnames := checkWalNames(lg, names)
-	if len(wnames) == 0 {
-		return nil, ErrFileNotFound
-	}
-	return wnames, nil
-}
-
-func checkWalNames(lg *zap.Logger, names []string) []string {
-	wnames := make([]string, 0)
-	for _, name := range names {
-		if _, _, err := parseWALName(name); err != nil {
-			// don't complain about left over tmp files
-			if !strings.HasSuffix(name, ".tmp") {
-				if lg != nil {
-					lg.Warn(
-						"ignored file in WAL directory",
-						zap.String("path", name),
-					)
-				} else {
-					plog.Warningf("ignored file %v in wal", name)
-				}
-			}
-			continue
-		}
-		wnames = append(wnames, name)
-	}
-	return wnames
-}
-
-func parseWALName(str string) (seq, index uint64, err error) {
-	if !strings.HasSuffix(str, ".wal") {
-		return 0, 0, errBadWALName
-	}
-	_, err = fmt.Sscanf(str, "%016x-%016x.wal", &seq, &index)
-	return seq, index, err
-}
-
-func walName(seq, index uint64) string {
-	return fmt.Sprintf("%016x-%016x.wal", seq, index)
-}
diff --git a/vendor/go.etcd.io/etcd/wal/wal.go b/vendor/go.etcd.io/etcd/wal/wal.go
deleted file mode 100644
index e177c8e..0000000
--- a/vendor/go.etcd.io/etcd/wal/wal.go
+++ /dev/null
@@ -1,912 +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 wal
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"hash/crc32"
-	"io"
-	"os"
-	"path/filepath"
-	"sync"
-	"time"
-
-	"go.etcd.io/etcd/pkg/fileutil"
-	"go.etcd.io/etcd/pkg/pbutil"
-	"go.etcd.io/etcd/raft"
-	"go.etcd.io/etcd/raft/raftpb"
-	"go.etcd.io/etcd/wal/walpb"
-
-	"github.com/coreos/pkg/capnslog"
-	"go.uber.org/zap"
-)
-
-const (
-	metadataType int64 = iota + 1
-	entryType
-	stateType
-	crcType
-	snapshotType
-
-	// warnSyncDuration is the amount of time allotted to an fsync before
-	// logging a warning
-	warnSyncDuration = time.Second
-)
-
-var (
-	// SegmentSizeBytes is the preallocated size of each wal segment file.
-	// The actual size might be larger than this. In general, the default
-	// value should be used, but this is defined as an exported variable
-	// so that tests can set a different segment size.
-	SegmentSizeBytes int64 = 64 * 1000 * 1000 // 64MB
-
-	plog = capnslog.NewPackageLogger("go.etcd.io/etcd", "wal")
-
-	ErrMetadataConflict = errors.New("wal: conflicting metadata found")
-	ErrFileNotFound     = errors.New("wal: file not found")
-	ErrCRCMismatch      = errors.New("wal: crc mismatch")
-	ErrSnapshotMismatch = errors.New("wal: snapshot mismatch")
-	ErrSnapshotNotFound = errors.New("wal: snapshot not found")
-	crcTable            = crc32.MakeTable(crc32.Castagnoli)
-)
-
-// WAL is a logical representation of the stable storage.
-// WAL is either in read mode or append mode but not both.
-// A newly created WAL is in append mode, and ready for appending records.
-// A just opened WAL is in read mode, and ready for reading records.
-// The WAL will be ready for appending after reading out all the previous records.
-type WAL struct {
-	lg *zap.Logger
-
-	dir string // the living directory of the underlay files
-
-	// dirFile is a fd for the wal directory for syncing on Rename
-	dirFile *os.File
-
-	metadata []byte           // metadata recorded at the head of each WAL
-	state    raftpb.HardState // hardstate recorded at the head of WAL
-
-	start     walpb.Snapshot // snapshot to start reading
-	decoder   *decoder       // decoder to decode records
-	readClose func() error   // closer for decode reader
-
-	mu      sync.Mutex
-	enti    uint64   // index of the last entry saved to the wal
-	encoder *encoder // encoder to encode records
-
-	locks []*fileutil.LockedFile // the locked files the WAL holds (the name is increasing)
-	fp    *filePipeline
-}
-
-// Create creates a WAL ready for appending records. The given metadata is
-// recorded at the head of each WAL file, and can be retrieved with ReadAll.
-func Create(lg *zap.Logger, dirpath string, metadata []byte) (*WAL, error) {
-	if Exist(dirpath) {
-		return nil, os.ErrExist
-	}
-
-	// keep temporary wal directory so WAL initialization appears atomic
-	tmpdirpath := filepath.Clean(dirpath) + ".tmp"
-	if fileutil.Exist(tmpdirpath) {
-		if err := os.RemoveAll(tmpdirpath); err != nil {
-			return nil, err
-		}
-	}
-	if err := fileutil.CreateDirAll(tmpdirpath); err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to create a temporary WAL directory",
-				zap.String("tmp-dir-path", tmpdirpath),
-				zap.String("dir-path", dirpath),
-				zap.Error(err),
-			)
-		}
-		return nil, err
-	}
-
-	p := filepath.Join(tmpdirpath, walName(0, 0))
-	f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, fileutil.PrivateFileMode)
-	if err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to flock an initial WAL file",
-				zap.String("path", p),
-				zap.Error(err),
-			)
-		}
-		return nil, err
-	}
-	if _, err = f.Seek(0, io.SeekEnd); err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to seek an initial WAL file",
-				zap.String("path", p),
-				zap.Error(err),
-			)
-		}
-		return nil, err
-	}
-	if err = fileutil.Preallocate(f.File, SegmentSizeBytes, true); err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to preallocate an initial WAL file",
-				zap.String("path", p),
-				zap.Int64("segment-bytes", SegmentSizeBytes),
-				zap.Error(err),
-			)
-		}
-		return nil, err
-	}
-
-	w := &WAL{
-		lg:       lg,
-		dir:      dirpath,
-		metadata: metadata,
-	}
-	w.encoder, err = newFileEncoder(f.File, 0)
-	if err != nil {
-		return nil, err
-	}
-	w.locks = append(w.locks, f)
-	if err = w.saveCrc(0); err != nil {
-		return nil, err
-	}
-	if err = w.encoder.encode(&walpb.Record{Type: metadataType, Data: metadata}); err != nil {
-		return nil, err
-	}
-	if err = w.SaveSnapshot(walpb.Snapshot{}); err != nil {
-		return nil, err
-	}
-
-	if w, err = w.renameWAL(tmpdirpath); err != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to rename the temporary WAL directory",
-				zap.String("tmp-dir-path", tmpdirpath),
-				zap.String("dir-path", w.dir),
-				zap.Error(err),
-			)
-		}
-		return nil, err
-	}
-
-	var perr error
-	defer func() {
-		if perr != nil {
-			w.cleanupWAL(lg)
-		}
-	}()
-
-	// directory was renamed; sync parent dir to persist rename
-	pdir, perr := fileutil.OpenDir(filepath.Dir(w.dir))
-	if perr != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to open the parent data directory",
-				zap.String("parent-dir-path", filepath.Dir(w.dir)),
-				zap.String("dir-path", w.dir),
-				zap.Error(perr),
-			)
-		}
-		return nil, perr
-	}
-	if perr = fileutil.Fsync(pdir); perr != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to fsync the parent data directory file",
-				zap.String("parent-dir-path", filepath.Dir(w.dir)),
-				zap.String("dir-path", w.dir),
-				zap.Error(perr),
-			)
-		}
-		return nil, perr
-	}
-	if perr = pdir.Close(); perr != nil {
-		if lg != nil {
-			lg.Warn(
-				"failed to close the parent data directory file",
-				zap.String("parent-dir-path", filepath.Dir(w.dir)),
-				zap.String("dir-path", w.dir),
-				zap.Error(perr),
-			)
-		}
-		return nil, perr
-	}
-
-	return w, nil
-}
-
-func (w *WAL) cleanupWAL(lg *zap.Logger) {
-	var err error
-	if err = w.Close(); err != nil {
-		if lg != nil {
-			lg.Panic("failed to close WAL during cleanup", zap.Error(err))
-		} else {
-			plog.Panicf("failed to close WAL during cleanup: %v", err)
-		}
-	}
-	brokenDirName := fmt.Sprintf("%s.broken.%v", w.dir, time.Now().Format("20060102.150405.999999"))
-	if err = os.Rename(w.dir, brokenDirName); err != nil {
-		if lg != nil {
-			lg.Panic(
-				"failed to rename WAL during cleanup",
-				zap.Error(err),
-				zap.String("source-path", w.dir),
-				zap.String("rename-path", brokenDirName),
-			)
-		} else {
-			plog.Panicf("failed to rename WAL during cleanup: %v", err)
-		}
-	}
-}
-
-func (w *WAL) renameWAL(tmpdirpath string) (*WAL, error) {
-	if err := os.RemoveAll(w.dir); err != nil {
-		return nil, err
-	}
-	// On non-Windows platforms, hold the lock while renaming. Releasing
-	// the lock and trying to reacquire it quickly can be flaky because
-	// it's possible the process will fork to spawn a process while this is
-	// happening. The fds are set up as close-on-exec by the Go runtime,
-	// but there is a window between the fork and the exec where another
-	// process holds the lock.
-	if err := os.Rename(tmpdirpath, w.dir); err != nil {
-		if _, ok := err.(*os.LinkError); ok {
-			return w.renameWALUnlock(tmpdirpath)
-		}
-		return nil, err
-	}
-	w.fp = newFilePipeline(w.lg, w.dir, SegmentSizeBytes)
-	df, err := fileutil.OpenDir(w.dir)
-	w.dirFile = df
-	return w, err
-}
-
-func (w *WAL) renameWALUnlock(tmpdirpath string) (*WAL, error) {
-	// rename of directory with locked files doesn't work on windows/cifs;
-	// close the WAL to release the locks so the directory can be renamed.
-	if w.lg != nil {
-		w.lg.Info(
-			"closing WAL to release flock and retry directory renaming",
-			zap.String("from", tmpdirpath),
-			zap.String("to", w.dir),
-		)
-	} else {
-		plog.Infof("releasing file lock to rename %q to %q", tmpdirpath, w.dir)
-	}
-	w.Close()
-
-	if err := os.Rename(tmpdirpath, w.dir); err != nil {
-		return nil, err
-	}
-
-	// reopen and relock
-	newWAL, oerr := Open(w.lg, w.dir, walpb.Snapshot{})
-	if oerr != nil {
-		return nil, oerr
-	}
-	if _, _, _, err := newWAL.ReadAll(); err != nil {
-		newWAL.Close()
-		return nil, err
-	}
-	return newWAL, nil
-}
-
-// Open opens the WAL at the given snap.
-// The snap SHOULD have been previously saved to the WAL, or the following
-// ReadAll will fail.
-// The returned WAL is ready to read and the first record will be the one after
-// the given snap. The WAL cannot be appended to before reading out all of its
-// previous records.
-func Open(lg *zap.Logger, dirpath string, snap walpb.Snapshot) (*WAL, error) {
-	w, err := openAtIndex(lg, dirpath, snap, true)
-	if err != nil {
-		return nil, err
-	}
-	if w.dirFile, err = fileutil.OpenDir(w.dir); err != nil {
-		return nil, err
-	}
-	return w, nil
-}
-
-// OpenForRead only opens the wal files for read.
-// Write on a read only wal panics.
-func OpenForRead(lg *zap.Logger, dirpath string, snap walpb.Snapshot) (*WAL, error) {
-	return openAtIndex(lg, dirpath, snap, false)
-}
-
-func openAtIndex(lg *zap.Logger, dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) {
-	names, nameIndex, err := selectWALFiles(lg, dirpath, snap)
-	if err != nil {
-		return nil, err
-	}
-
-	rs, ls, closer, err := openWALFiles(lg, dirpath, names, nameIndex, write)
-	if err != nil {
-		return nil, err
-	}
-
-	// create a WAL ready for reading
-	w := &WAL{
-		lg:        lg,
-		dir:       dirpath,
-		start:     snap,
-		decoder:   newDecoder(rs...),
-		readClose: closer,
-		locks:     ls,
-	}
-
-	if write {
-		// write reuses the file descriptors from read; don't close so
-		// WAL can append without dropping the file lock
-		w.readClose = nil
-		if _, _, err := parseWALName(filepath.Base(w.tail().Name())); err != nil {
-			closer()
-			return nil, err
-		}
-		w.fp = newFilePipeline(lg, w.dir, SegmentSizeBytes)
-	}
-
-	return w, nil
-}
-
-func selectWALFiles(lg *zap.Logger, dirpath string, snap walpb.Snapshot) ([]string, int, error) {
-	names, err := readWALNames(lg, dirpath)
-	if err != nil {
-		return nil, -1, err
-	}
-
-	nameIndex, ok := searchIndex(lg, names, snap.Index)
-	if !ok || !isValidSeq(lg, names[nameIndex:]) {
-		err = ErrFileNotFound
-		return nil, -1, err
-	}
-
-	return names, nameIndex, nil
-}
-
-func openWALFiles(lg *zap.Logger, dirpath string, names []string, nameIndex int, write bool) ([]io.Reader, []*fileutil.LockedFile, func() error, error) {
-	rcs := make([]io.ReadCloser, 0)
-	rs := make([]io.Reader, 0)
-	ls := make([]*fileutil.LockedFile, 0)
-	for _, name := range names[nameIndex:] {
-		p := filepath.Join(dirpath, name)
-		if write {
-			l, err := fileutil.TryLockFile(p, os.O_RDWR, fileutil.PrivateFileMode)
-			if err != nil {
-				closeAll(rcs...)
-				return nil, nil, nil, err
-			}
-			ls = append(ls, l)
-			rcs = append(rcs, l)
-		} else {
-			rf, err := os.OpenFile(p, os.O_RDONLY, fileutil.PrivateFileMode)
-			if err != nil {
-				closeAll(rcs...)
-				return nil, nil, nil, err
-			}
-			ls = append(ls, nil)
-			rcs = append(rcs, rf)
-		}
-		rs = append(rs, rcs[len(rcs)-1])
-	}
-
-	closer := func() error { return closeAll(rcs...) }
-
-	return rs, ls, closer, nil
-}
-
-// ReadAll reads out records of the current WAL.
-// If opened in write mode, it must read out all records until EOF. Or an error
-// will be returned.
-// If opened in read mode, it will try to read all records if possible.
-// If it cannot read out the expected snap, it will return ErrSnapshotNotFound.
-// If loaded snap doesn't match with the expected one, it will return
-// all the records and error ErrSnapshotMismatch.
-// TODO: detect not-last-snap error.
-// TODO: maybe loose the checking of match.
-// After ReadAll, the WAL will be ready for appending new records.
-func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.Entry, err error) {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	rec := &walpb.Record{}
-	decoder := w.decoder
-
-	var match bool
-	for err = decoder.decode(rec); err == nil; err = decoder.decode(rec) {
-		switch rec.Type {
-		case entryType:
-			e := mustUnmarshalEntry(rec.Data)
-			if e.Index > w.start.Index {
-				ents = append(ents[:e.Index-w.start.Index-1], e)
-			}
-			w.enti = e.Index
-
-		case stateType:
-			state = mustUnmarshalState(rec.Data)
-
-		case metadataType:
-			if metadata != nil && !bytes.Equal(metadata, rec.Data) {
-				state.Reset()
-				return nil, state, nil, ErrMetadataConflict
-			}
-			metadata = rec.Data
-
-		case crcType:
-			crc := decoder.crc.Sum32()
-			// current crc of decoder must match the crc of the record.
-			// do no need to match 0 crc, since the decoder is a new one at this case.
-			if crc != 0 && rec.Validate(crc) != nil {
-				state.Reset()
-				return nil, state, nil, ErrCRCMismatch
-			}
-			decoder.updateCRC(rec.Crc)
-
-		case snapshotType:
-			var snap walpb.Snapshot
-			pbutil.MustUnmarshal(&snap, rec.Data)
-			if snap.Index == w.start.Index {
-				if snap.Term != w.start.Term {
-					state.Reset()
-					return nil, state, nil, ErrSnapshotMismatch
-				}
-				match = true
-			}
-
-		default:
-			state.Reset()
-			return nil, state, nil, fmt.Errorf("unexpected block type %d", rec.Type)
-		}
-	}
-
-	switch w.tail() {
-	case nil:
-		// We do not have to read out all entries in read mode.
-		// The last record maybe a partial written one, so
-		// ErrunexpectedEOF might be returned.
-		if err != io.EOF && err != io.ErrUnexpectedEOF {
-			state.Reset()
-			return nil, state, nil, err
-		}
-	default:
-		// We must read all of the entries if WAL is opened in write mode.
-		if err != io.EOF {
-			state.Reset()
-			return nil, state, nil, err
-		}
-		// decodeRecord() will return io.EOF if it detects a zero record,
-		// but this zero record may be followed by non-zero records from
-		// a torn write. Overwriting some of these non-zero records, but
-		// not all, will cause CRC errors on WAL open. Since the records
-		// were never fully synced to disk in the first place, it's safe
-		// to zero them out to avoid any CRC errors from new writes.
-		if _, err = w.tail().Seek(w.decoder.lastOffset(), io.SeekStart); err != nil {
-			return nil, state, nil, err
-		}
-		if err = fileutil.ZeroToEnd(w.tail().File); err != nil {
-			return nil, state, nil, err
-		}
-	}
-
-	err = nil
-	if !match {
-		err = ErrSnapshotNotFound
-	}
-
-	// close decoder, disable reading
-	if w.readClose != nil {
-		w.readClose()
-		w.readClose = nil
-	}
-	w.start = walpb.Snapshot{}
-
-	w.metadata = metadata
-
-	if w.tail() != nil {
-		// create encoder (chain crc with the decoder), enable appending
-		w.encoder, err = newFileEncoder(w.tail().File, w.decoder.lastCRC())
-		if err != nil {
-			return
-		}
-	}
-	w.decoder = nil
-
-	return metadata, state, ents, err
-}
-
-// Verify reads through the given WAL and verifies that it is not corrupted.
-// It creates a new decoder to read through the records of the given WAL.
-// It does not conflict with any open WAL, but it is recommended not to
-// call this function after opening the WAL for writing.
-// If it cannot read out the expected snap, it will return ErrSnapshotNotFound.
-// If the loaded snap doesn't match with the expected one, it will
-// return error ErrSnapshotMismatch.
-func Verify(lg *zap.Logger, walDir string, snap walpb.Snapshot) error {
-	var metadata []byte
-	var err error
-	var match bool
-
-	rec := &walpb.Record{}
-
-	names, nameIndex, err := selectWALFiles(lg, walDir, snap)
-	if err != nil {
-		return err
-	}
-
-	// open wal files in read mode, so that there is no conflict
-	// when the same WAL is opened elsewhere in write mode
-	rs, _, closer, err := openWALFiles(lg, walDir, names, nameIndex, false)
-	if err != nil {
-		return err
-	}
-	defer func() {
-		if closer != nil {
-			closer()
-		}
-	}()
-
-	// create a new decoder from the readers on the WAL files
-	decoder := newDecoder(rs...)
-
-	for err = decoder.decode(rec); err == nil; err = decoder.decode(rec) {
-		switch rec.Type {
-		case metadataType:
-			if metadata != nil && !bytes.Equal(metadata, rec.Data) {
-				return ErrMetadataConflict
-			}
-			metadata = rec.Data
-		case crcType:
-			crc := decoder.crc.Sum32()
-			// Current crc of decoder must match the crc of the record.
-			// We need not match 0 crc, since the decoder is a new one at this point.
-			if crc != 0 && rec.Validate(crc) != nil {
-				return ErrCRCMismatch
-			}
-			decoder.updateCRC(rec.Crc)
-		case snapshotType:
-			var loadedSnap walpb.Snapshot
-			pbutil.MustUnmarshal(&loadedSnap, rec.Data)
-			if loadedSnap.Index == snap.Index {
-				if loadedSnap.Term != snap.Term {
-					return ErrSnapshotMismatch
-				}
-				match = true
-			}
-		// We ignore all entry and state type records as these
-		// are not necessary for validating the WAL contents
-		case entryType:
-		case stateType:
-		default:
-			return fmt.Errorf("unexpected block type %d", rec.Type)
-		}
-	}
-
-	// We do not have to read out all the WAL entries
-	// as the decoder is opened in read mode.
-	if err != io.EOF && err != io.ErrUnexpectedEOF {
-		return err
-	}
-
-	if !match {
-		return ErrSnapshotNotFound
-	}
-
-	return nil
-}
-
-// cut closes current file written and creates a new one ready to append.
-// cut first creates a temp wal file and writes necessary headers into it.
-// Then cut atomically rename temp wal file to a wal file.
-func (w *WAL) cut() error {
-	// close old wal file; truncate to avoid wasting space if an early cut
-	off, serr := w.tail().Seek(0, io.SeekCurrent)
-	if serr != nil {
-		return serr
-	}
-
-	if err := w.tail().Truncate(off); err != nil {
-		return err
-	}
-
-	if err := w.sync(); err != nil {
-		return err
-	}
-
-	fpath := filepath.Join(w.dir, walName(w.seq()+1, w.enti+1))
-
-	// create a temp wal file with name sequence + 1, or truncate the existing one
-	newTail, err := w.fp.Open()
-	if err != nil {
-		return err
-	}
-
-	// update writer and save the previous crc
-	w.locks = append(w.locks, newTail)
-	prevCrc := w.encoder.crc.Sum32()
-	w.encoder, err = newFileEncoder(w.tail().File, prevCrc)
-	if err != nil {
-		return err
-	}
-
-	if err = w.saveCrc(prevCrc); err != nil {
-		return err
-	}
-
-	if err = w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.metadata}); err != nil {
-		return err
-	}
-
-	if err = w.saveState(&w.state); err != nil {
-		return err
-	}
-
-	// atomically move temp wal file to wal file
-	if err = w.sync(); err != nil {
-		return err
-	}
-
-	off, err = w.tail().Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-
-	if err = os.Rename(newTail.Name(), fpath); err != nil {
-		return err
-	}
-	if err = fileutil.Fsync(w.dirFile); err != nil {
-		return err
-	}
-
-	// reopen newTail with its new path so calls to Name() match the wal filename format
-	newTail.Close()
-
-	if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, fileutil.PrivateFileMode); err != nil {
-		return err
-	}
-	if _, err = newTail.Seek(off, io.SeekStart); err != nil {
-		return err
-	}
-
-	w.locks[len(w.locks)-1] = newTail
-
-	prevCrc = w.encoder.crc.Sum32()
-	w.encoder, err = newFileEncoder(w.tail().File, prevCrc)
-	if err != nil {
-		return err
-	}
-
-	if w.lg != nil {
-		w.lg.Info("created a new WAL segment", zap.String("path", fpath))
-	} else {
-		plog.Infof("segmented wal file %v is created", fpath)
-	}
-	return nil
-}
-
-func (w *WAL) sync() error {
-	if w.encoder != nil {
-		if err := w.encoder.flush(); err != nil {
-			return err
-		}
-	}
-	start := time.Now()
-	err := fileutil.Fdatasync(w.tail().File)
-
-	took := time.Since(start)
-	if took > warnSyncDuration {
-		if w.lg != nil {
-			w.lg.Warn(
-				"slow fdatasync",
-				zap.Duration("took", took),
-				zap.Duration("expected-duration", warnSyncDuration),
-			)
-		} else {
-			plog.Warningf("sync duration of %v, expected less than %v", took, warnSyncDuration)
-		}
-	}
-	walFsyncSec.Observe(took.Seconds())
-
-	return err
-}
-
-// ReleaseLockTo releases the locks, which has smaller index than the given index
-// except the largest one among them.
-// For example, if WAL is holding lock 1,2,3,4,5,6, ReleaseLockTo(4) will release
-// lock 1,2 but keep 3. ReleaseLockTo(5) will release 1,2,3 but keep 4.
-func (w *WAL) ReleaseLockTo(index uint64) error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	if len(w.locks) == 0 {
-		return nil
-	}
-
-	var smaller int
-	found := false
-	for i, l := range w.locks {
-		_, lockIndex, err := parseWALName(filepath.Base(l.Name()))
-		if err != nil {
-			return err
-		}
-		if lockIndex >= index {
-			smaller = i - 1
-			found = true
-			break
-		}
-	}
-
-	// if no lock index is greater than the release index, we can
-	// release lock up to the last one(excluding).
-	if !found {
-		smaller = len(w.locks) - 1
-	}
-
-	if smaller <= 0 {
-		return nil
-	}
-
-	for i := 0; i < smaller; i++ {
-		if w.locks[i] == nil {
-			continue
-		}
-		w.locks[i].Close()
-	}
-	w.locks = w.locks[smaller:]
-
-	return nil
-}
-
-// Close closes the current WAL file and directory.
-func (w *WAL) Close() error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	if w.fp != nil {
-		w.fp.Close()
-		w.fp = nil
-	}
-
-	if w.tail() != nil {
-		if err := w.sync(); err != nil {
-			return err
-		}
-	}
-	for _, l := range w.locks {
-		if l == nil {
-			continue
-		}
-		if err := l.Close(); err != nil {
-			if w.lg != nil {
-				w.lg.Warn("failed to close WAL", zap.Error(err))
-			} else {
-				plog.Errorf("failed to unlock during closing wal: %s", err)
-			}
-		}
-	}
-
-	return w.dirFile.Close()
-}
-
-func (w *WAL) saveEntry(e *raftpb.Entry) error {
-	// TODO: add MustMarshalTo to reduce one allocation.
-	b := pbutil.MustMarshal(e)
-	rec := &walpb.Record{Type: entryType, Data: b}
-	if err := w.encoder.encode(rec); err != nil {
-		return err
-	}
-	w.enti = e.Index
-	return nil
-}
-
-func (w *WAL) saveState(s *raftpb.HardState) error {
-	if raft.IsEmptyHardState(*s) {
-		return nil
-	}
-	w.state = *s
-	b := pbutil.MustMarshal(s)
-	rec := &walpb.Record{Type: stateType, Data: b}
-	return w.encoder.encode(rec)
-}
-
-func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) error {
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	// short cut, do not call sync
-	if raft.IsEmptyHardState(st) && len(ents) == 0 {
-		return nil
-	}
-
-	mustSync := raft.MustSync(st, w.state, len(ents))
-
-	// TODO(xiangli): no more reference operator
-	for i := range ents {
-		if err := w.saveEntry(&ents[i]); err != nil {
-			return err
-		}
-	}
-	if err := w.saveState(&st); err != nil {
-		return err
-	}
-
-	curOff, err := w.tail().Seek(0, io.SeekCurrent)
-	if err != nil {
-		return err
-	}
-	if curOff < SegmentSizeBytes {
-		if mustSync {
-			return w.sync()
-		}
-		return nil
-	}
-
-	return w.cut()
-}
-
-func (w *WAL) SaveSnapshot(e walpb.Snapshot) error {
-	b := pbutil.MustMarshal(&e)
-
-	w.mu.Lock()
-	defer w.mu.Unlock()
-
-	rec := &walpb.Record{Type: snapshotType, Data: b}
-	if err := w.encoder.encode(rec); err != nil {
-		return err
-	}
-	// update enti only when snapshot is ahead of last index
-	if w.enti < e.Index {
-		w.enti = e.Index
-	}
-	return w.sync()
-}
-
-func (w *WAL) saveCrc(prevCrc uint32) error {
-	return w.encoder.encode(&walpb.Record{Type: crcType, Crc: prevCrc})
-}
-
-func (w *WAL) tail() *fileutil.LockedFile {
-	if len(w.locks) > 0 {
-		return w.locks[len(w.locks)-1]
-	}
-	return nil
-}
-
-func (w *WAL) seq() uint64 {
-	t := w.tail()
-	if t == nil {
-		return 0
-	}
-	seq, _, err := parseWALName(filepath.Base(t.Name()))
-	if err != nil {
-		if w.lg != nil {
-			w.lg.Fatal("failed to parse WAL name", zap.String("name", t.Name()), zap.Error(err))
-		} else {
-			plog.Fatalf("bad wal name %s (%v)", t.Name(), err)
-		}
-	}
-	return seq
-}
-
-func closeAll(rcs ...io.ReadCloser) error {
-	for _, f := range rcs {
-		if err := f.Close(); err != nil {
-			return err
-		}
-	}
-	return nil
-}
diff --git a/vendor/go.etcd.io/etcd/wal/walpb/record.go b/vendor/go.etcd.io/etcd/wal/walpb/record.go
deleted file mode 100644
index 30a05e0..0000000
--- a/vendor/go.etcd.io/etcd/wal/walpb/record.go
+++ /dev/null
@@ -1,29 +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 walpb
-
-import "errors"
-
-var (
-	ErrCRCMismatch = errors.New("walpb: crc mismatch")
-)
-
-func (rec *Record) Validate(crc uint32) error {
-	if rec.Crc == crc {
-		return nil
-	}
-	rec.Reset()
-	return ErrCRCMismatch
-}
diff --git a/vendor/go.etcd.io/etcd/wal/walpb/record.pb.go b/vendor/go.etcd.io/etcd/wal/walpb/record.pb.go
deleted file mode 100644
index 3ce63dd..0000000
--- a/vendor/go.etcd.io/etcd/wal/walpb/record.pb.go
+++ /dev/null
@@ -1,504 +0,0 @@
-// Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: record.proto
-
-/*
-	Package walpb is a generated protocol buffer package.
-
-	It is generated from these files:
-		record.proto
-
-	It has these top-level messages:
-		Record
-		Snapshot
-*/
-package walpb
-
-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 Record struct {
-	Type             int64  `protobuf:"varint,1,opt,name=type" json:"type"`
-	Crc              uint32 `protobuf:"varint,2,opt,name=crc" json:"crc"`
-	Data             []byte `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Record) Reset()                    { *m = Record{} }
-func (m *Record) String() string            { return proto.CompactTextString(m) }
-func (*Record) ProtoMessage()               {}
-func (*Record) Descriptor() ([]byte, []int) { return fileDescriptorRecord, []int{0} }
-
-type Snapshot struct {
-	Index            uint64 `protobuf:"varint,1,opt,name=index" json:"index"`
-	Term             uint64 `protobuf:"varint,2,opt,name=term" json:"term"`
-	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 fileDescriptorRecord, []int{1} }
-
-func init() {
-	proto.RegisterType((*Record)(nil), "walpb.Record")
-	proto.RegisterType((*Snapshot)(nil), "walpb.Snapshot")
-}
-func (m *Record) 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 *Record) MarshalTo(dAtA []byte) (int, error) {
-	var i int
-	_ = i
-	var l int
-	_ = l
-	dAtA[i] = 0x8
-	i++
-	i = encodeVarintRecord(dAtA, i, uint64(m.Type))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRecord(dAtA, i, uint64(m.Crc))
-	if m.Data != nil {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintRecord(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 (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 = encodeVarintRecord(dAtA, i, uint64(m.Index))
-	dAtA[i] = 0x10
-	i++
-	i = encodeVarintRecord(dAtA, i, uint64(m.Term))
-	if m.XXX_unrecognized != nil {
-		i += copy(dAtA[i:], m.XXX_unrecognized)
-	}
-	return i, nil
-}
-
-func encodeVarintRecord(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 *Record) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRecord(uint64(m.Type))
-	n += 1 + sovRecord(uint64(m.Crc))
-	if m.Data != nil {
-		l = len(m.Data)
-		n += 1 + l + sovRecord(uint64(l))
-	}
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func (m *Snapshot) Size() (n int) {
-	var l int
-	_ = l
-	n += 1 + sovRecord(uint64(m.Index))
-	n += 1 + sovRecord(uint64(m.Term))
-	if m.XXX_unrecognized != nil {
-		n += len(m.XXX_unrecognized)
-	}
-	return n
-}
-
-func sovRecord(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
-}
-func sozRecord(x uint64) (n int) {
-	return sovRecord(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (m *Record) 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 ErrIntOverflowRecord
-			}
-			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: Record: wiretype end group for non-group")
-		}
-		if fieldNum <= 0 {
-			return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire)
-		}
-		switch fieldNum {
-		case 1:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
-			}
-			m.Type = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRecord
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Type |= (int64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			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 ErrIntOverflowRecord
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Crc |= (uint32(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 3:
-			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 ErrIntOverflowRecord
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			if byteLen < 0 {
-				return ErrInvalidLengthRecord
-			}
-			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 := skipRecord(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRecord
-			}
-			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 (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 ErrIntOverflowRecord
-			}
-			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 Index", wireType)
-			}
-			m.Index = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRecord
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Index |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		case 2:
-			if wireType != 0 {
-				return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
-			}
-			m.Term = 0
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowRecord
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				m.Term |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-		default:
-			iNdEx = preIndex
-			skippy, err := skipRecord(dAtA[iNdEx:])
-			if err != nil {
-				return err
-			}
-			if skippy < 0 {
-				return ErrInvalidLengthRecord
-			}
-			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 skipRecord(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, ErrIntOverflowRecord
-			}
-			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, ErrIntOverflowRecord
-				}
-				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, ErrIntOverflowRecord
-				}
-				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, ErrInvalidLengthRecord
-			}
-			return iNdEx, nil
-		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowRecord
-					}
-					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 := skipRecord(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 (
-	ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowRecord   = fmt.Errorf("proto: integer overflow")
-)
-
-func init() { proto.RegisterFile("record.proto", fileDescriptorRecord) }
-
-var fileDescriptorRecord = []byte{
-	// 186 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0x4d, 0xce,
-	0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2d, 0x4f, 0xcc, 0x29, 0x48, 0x92,
-	0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x8b, 0xe8, 0x83, 0x58, 0x10, 0x49, 0x25, 0x3f, 0x2e, 0xb6,
-	0x20, 0xb0, 0x62, 0x21, 0x09, 0x2e, 0x96, 0x92, 0xca, 0x82, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d,
-	0x66, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xc0, 0x22, 0x42, 0x62, 0x5c, 0xcc, 0xc9, 0x45,
-	0xc9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xbc, 0x50, 0x09, 0x90, 0x80, 0x90, 0x10, 0x17, 0x4b, 0x4a,
-	0x62, 0x49, 0xa2, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x98, 0xad, 0xe4, 0xc0, 0xc5, 0x11,
-	0x9c, 0x97, 0x58, 0x50, 0x9c, 0x91, 0x5f, 0x22, 0x24, 0xc5, 0xc5, 0x9a, 0x99, 0x97, 0x92, 0x5a,
-	0x01, 0x36, 0x92, 0x05, 0xaa, 0x13, 0x22, 0x04, 0xb6, 0x2d, 0xb5, 0x28, 0x17, 0x6c, 0x28, 0x0b,
-	0xdc, 0xb6, 0xd4, 0xa2, 0x5c, 0x27, 0x91, 0x13, 0x0f, 0xe5, 0x18, 0x4e, 0x3c, 0x92, 0x63, 0xbc,
-	0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x19, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, 0x00,
-	0xff, 0xff, 0x7f, 0x5e, 0x5c, 0x46, 0xd3, 0x00, 0x00, 0x00,
-}
diff --git a/vendor/go.etcd.io/etcd/wal/walpb/record.proto b/vendor/go.etcd.io/etcd/wal/walpb/record.proto
deleted file mode 100644
index b694cb2..0000000
--- a/vendor/go.etcd.io/etcd/wal/walpb/record.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-syntax = "proto2";
-package walpb;
-
-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 Record {
-	optional int64 type  = 1 [(gogoproto.nullable) = false];
-	optional uint32 crc  = 2 [(gogoproto.nullable) = false];
-	optional bytes data  = 3;
-}
-
-message Snapshot {
-	optional uint64 index = 1 [(gogoproto.nullable) = false];
-	optional uint64 term  = 2 [(gogoproto.nullable) = false];
-}
