Browse Source

main: add grpc-gateway support

Now etcd can serve HTTP json request at /v3alpha/
Xiang Li 9 years ago
parent
commit
5a7b7f7595

+ 62 - 3
etcdmain/serve.go

@@ -23,10 +23,15 @@ import (
 	"strings"
 	"time"
 
-	"github.com/cockroachdb/cmux"
 	"github.com/coreos/etcd/etcdserver"
 	"github.com/coreos/etcd/etcdserver/api/v3rpc"
+	pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
+
+	"github.com/cockroachdb/cmux"
+	gw "github.com/gengo/grpc-gateway/runtime"
+	"golang.org/x/net/context"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
 )
 
 type serveCtx struct {
@@ -52,8 +57,19 @@ func serve(sctx *serveCtx, s *etcdserver.EtcdServer, tlscfg *tls.Config, handler
 		grpcl := m.Match(cmux.HTTP2())
 		go func() { plog.Fatal(gs.Serve(grpcl)) }()
 
+		opts := []grpc.DialOption{
+			grpc.WithInsecure(),
+		}
+		gwmux, err := registerGateway(sctx.l.Addr().String(), opts)
+		if err != nil {
+			return err
+		}
+
+		httpmux := http.NewServeMux()
+		httpmux.Handle("/v3alpha/", gwmux)
+		httpmux.Handle("/", handler)
 		srvhttp := &http.Server{
-			Handler:  handler,
+			Handler:  httpmux,
 			ErrorLog: logger, // do not log user error
 		}
 		httpl := m.Match(cmux.HTTP1())
@@ -65,10 +81,23 @@ func serve(sctx *serveCtx, s *etcdserver.EtcdServer, tlscfg *tls.Config, handler
 		gs := v3rpc.Server(s, tlscfg)
 		handler = grpcHandlerFunc(gs, handler)
 
+		dtls := *tlscfg
+		// trust local server
+		dtls.InsecureSkipVerify = true
+		creds := credentials.NewTLS(&dtls)
+		opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}
+		gwmux, err := registerGateway(sctx.l.Addr().String(), opts)
+		if err != nil {
+			return err
+		}
+
 		tlsl := tls.NewListener(m.Match(cmux.Any()), tlscfg)
 		// TODO: add debug flag; enable logging when debug flag is set
+		httpmux := http.NewServeMux()
+		httpmux.Handle("/v3alpha/", gwmux)
+		httpmux.Handle("/", handler)
 		srv := &http.Server{
-			Handler:   handler,
+			Handler:   httpmux,
 			TLSConfig: tlscfg,
 			ErrorLog:  logger, // do not log user error
 		}
@@ -102,3 +131,33 @@ func servePeerHTTP(l net.Listener, handler http.Handler) error {
 	}
 	return srv.Serve(l)
 }
+
+func registerGateway(addr string, opts []grpc.DialOption) (*gw.ServeMux, error) {
+	gwmux := gw.NewServeMux()
+
+	err := pb.RegisterKVHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	err = pb.RegisterWatchHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	err = pb.RegisterLeaseHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	err = pb.RegisterClusterHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	err = pb.RegisterMaintenanceHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	err = pb.RegisterAuthHandlerFromEndpoint(context.Background(), gwmux, addr, opts)
+	if err != nil {
+		return nil, err
+	}
+	return gwmux, nil
+}

+ 188 - 168
etcdserver/etcdserverpb/rpc.pb.go

@@ -14405,172 +14405,192 @@ var (
 )
 
 var fileDescriptorRpc = []byte{
-	// 2657 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0x4b, 0x6f, 0x1b, 0xc9,
-	0xf1, 0xd7, 0x90, 0x14, 0x29, 0x16, 0x1f, 0x96, 0x5b, 0xb2, 0xff, 0xf4, 0xec, 0xfa, 0xb1, 0xe3,
-	0xe7, 0x3f, 0xeb, 0xa5, 0x63, 0x65, 0x93, 0x4b, 0x16, 0x1b, 0x50, 0x22, 0xd7, 0xd6, 0x4a, 0x96,
-	0xec, 0x11, 0x2d, 0xef, 0x02, 0x01, 0x84, 0x21, 0xd9, 0x96, 0x08, 0xf3, 0xb5, 0x33, 0x43, 0xd9,
-	0x32, 0x90, 0x4b, 0x80, 0x7c, 0x82, 0xcd, 0x25, 0xb9, 0xe6, 0x23, 0x04, 0xf9, 0x0e, 0x41, 0x2e,
-	0xc9, 0x27, 0x08, 0x82, 0x9c, 0x82, 0x20, 0xf7, 0x1c, 0x72, 0x49, 0xf5, 0x6b, 0xa6, 0x67, 0x38,
-	0x23, 0x7b, 0x33, 0xc9, 0xc1, 0xf6, 0x74, 0x75, 0xd5, 0xaf, 0xab, 0xab, 0xab, 0xab, 0xab, 0x8a,
-	0x86, 0xb2, 0x3b, 0xeb, 0x37, 0x67, 0xee, 0xd4, 0x9f, 0x92, 0x2a, 0xf5, 0xfb, 0x03, 0x8f, 0xba,
-	0xa7, 0xd4, 0x9d, 0xf5, 0xcc, 0xf5, 0xe3, 0xe9, 0xf1, 0x94, 0x4f, 0x3c, 0x60, 0x5f, 0x82, 0xc7,
-	0xbc, 0xc2, 0x78, 0x1e, 0x8c, 0x4f, 0xfb, 0x7d, 0xfe, 0xd7, 0xac, 0xf7, 0xe0, 0xd5, 0xa9, 0x9c,
-	0xfa, 0x80, 0x4f, 0x39, 0x73, 0xff, 0x84, 0xff, 0x85, 0x53, 0xec, 0x1f, 0x31, 0x69, 0xfd, 0xc2,
-	0x80, 0xba, 0x4d, 0xbd, 0xd9, 0x74, 0xe2, 0xd1, 0xc7, 0xd4, 0x19, 0x50, 0x97, 0x5c, 0x05, 0xe8,
-	0x8f, 0xe6, 0x9e, 0x4f, 0xdd, 0xa3, 0xe1, 0xa0, 0x61, 0xdc, 0x30, 0xee, 0x15, 0xec, 0xb2, 0xa4,
-	0x6c, 0x0f, 0xc8, 0x07, 0x50, 0x1e, 0xd3, 0x71, 0x4f, 0xcc, 0xe6, 0xf8, 0xec, 0x8a, 0x20, 0xe0,
-	0xa4, 0x09, 0x2b, 0x2e, 0x3d, 0x1d, 0x7a, 0xc3, 0xe9, 0xa4, 0x91, 0xc7, 0xb9, 0xbc, 0x1d, 0x8c,
-	0x99, 0xa0, 0xeb, 0xbc, 0xf4, 0x8f, 0x10, 0x66, 0xdc, 0x28, 0x08, 0x41, 0x46, 0xe8, 0xe2, 0xd8,
-	0xfa, 0x65, 0x1e, 0xaa, 0xb6, 0x33, 0x39, 0xa6, 0x36, 0xfd, 0x66, 0x4e, 0x3d, 0x9f, 0xac, 0x42,
-	0xfe, 0x15, 0x3d, 0xe3, 0xcb, 0x57, 0x6d, 0xf6, 0x29, 0xe4, 0x91, 0xe3, 0x88, 0x4e, 0xc4, 0xc2,
-	0x55, 0x26, 0x8f, 0x84, 0xce, 0x64, 0x40, 0xd6, 0x61, 0x79, 0x34, 0x1c, 0x0f, 0x7d, 0xb9, 0xaa,
-	0x18, 0x44, 0xd4, 0x29, 0xc4, 0xd4, 0xd9, 0x02, 0xf0, 0xa6, 0xae, 0x7f, 0x34, 0x75, 0x71, 0xd3,
-	0x8d, 0x65, 0x9c, 0xad, 0x6f, 0xdc, 0x6a, 0xea, 0xa6, 0x6e, 0xea, 0x0a, 0x35, 0x0f, 0x90, 0x79,
-	0x9f, 0xf1, 0xda, 0x65, 0x4f, 0x7d, 0x92, 0x2f, 0xa0, 0xc2, 0x41, 0x7c, 0xc7, 0x3d, 0xa6, 0x7e,
-	0xa3, 0xc8, 0x51, 0x6e, 0xbf, 0x03, 0xa5, 0xcb, 0x99, 0x6d, 0xbe, 0xbc, 0xf8, 0x26, 0x16, 0x54,
-	0x91, 0x7f, 0xe8, 0x8c, 0x86, 0x6f, 0x9d, 0xde, 0x88, 0x36, 0x4a, 0x08, 0xb4, 0x62, 0x47, 0x68,
-	0x56, 0x13, 0xca, 0x81, 0x0e, 0x64, 0x05, 0x0a, 0x7b, 0xfb, 0x7b, 0x9d, 0xd5, 0x25, 0x02, 0x50,
-	0x6c, 0x1d, 0x6c, 0x75, 0xf6, 0xda, 0xab, 0x06, 0xa9, 0x40, 0xa9, 0xdd, 0x11, 0x83, 0x9c, 0xb5,
-	0x09, 0x10, 0xae, 0x46, 0x4a, 0x90, 0xdf, 0xe9, 0x7c, 0x8d, 0xfc, 0xc8, 0x73, 0xd8, 0xb1, 0x0f,
-	0xb6, 0xf7, 0xf7, 0x50, 0x00, 0x85, 0xb7, 0xec, 0x4e, 0xab, 0xdb, 0x59, 0xcd, 0x31, 0x8e, 0x27,
-	0xfb, 0xed, 0xd5, 0x3c, 0x29, 0xc3, 0xf2, 0x61, 0x6b, 0xf7, 0x79, 0x67, 0xb5, 0x60, 0xfd, 0x0c,
-	0x6a, 0x52, 0x7d, 0xe1, 0x22, 0xe4, 0x53, 0x28, 0x9e, 0x70, 0x37, 0xe1, 0x27, 0x53, 0xd9, 0xf8,
-	0x30, 0xb6, 0xd7, 0x88, 0x2b, 0xd9, 0x92, 0x17, 0xb7, 0x97, 0x7f, 0x75, 0xea, 0xe1, 0xa1, 0xe5,
-	0x51, 0x64, 0xb5, 0x29, 0x3c, 0xb4, 0xb9, 0x43, 0xcf, 0x0e, 0x9d, 0xd1, 0x9c, 0xda, 0x6c, 0x92,
-	0x10, 0x28, 0x8c, 0xa7, 0x2e, 0xe5, 0x07, 0xb8, 0x62, 0xf3, 0x6f, 0xeb, 0x4b, 0x80, 0xa7, 0x73,
-	0x3f, 0xdd, 0x25, 0xf0, 0xd4, 0x4f, 0x19, 0x82, 0x74, 0x07, 0x31, 0xe0, 0xbe, 0x40, 0x1d, 0x8f,
-	0x06, 0xbe, 0xc0, 0x06, 0xd6, 0x16, 0x54, 0x38, 0x56, 0x96, 0x8d, 0x20, 0x08, 0x69, 0xd3, 0x11,
-	0xf5, 0x69, 0x06, 0x5f, 0xb5, 0x28, 0xac, 0x45, 0x40, 0x32, 0x99, 0xb6, 0x01, 0xa5, 0x01, 0x07,
-	0x13, 0xeb, 0xe4, 0x6d, 0x35, 0xb4, 0xfe, 0x61, 0x40, 0x59, 0x6a, 0xb8, 0x3f, 0x23, 0x2d, 0xa8,
-	0xb9, 0x62, 0x70, 0xc4, 0x15, 0x91, 0x8b, 0x98, 0xe9, 0xbe, 0xfa, 0x78, 0xc9, 0xae, 0x4a, 0x11,
-	0x4e, 0x26, 0x3f, 0x86, 0x8a, 0x82, 0x98, 0xcd, 0x7d, 0xbe, 0x5c, 0x65, 0xa3, 0x11, 0x05, 0x08,
-	0x8f, 0x0b, 0xc5, 0x41, 0xb2, 0x23, 0x91, 0x74, 0x61, 0x5d, 0x09, 0x0b, 0x05, 0xa5, 0x1a, 0x79,
-	0x8e, 0x72, 0x23, 0x8a, 0xb2, 0x68, 0x63, 0x44, 0x23, 0x52, 0x5e, 0x9b, 0xdc, 0x2c, 0x43, 0x49,
-	0x52, 0xad, 0x7f, 0x1a, 0x00, 0xca, 0x46, 0xb8, 0xdf, 0x36, 0xd4, 0x5d, 0x39, 0x8a, 0x6c, 0xf8,
-	0x83, 0xc4, 0x0d, 0x4b, 0xd3, 0x2e, 0xd9, 0x35, 0x25, 0x24, 0xb6, 0xfc, 0x39, 0x54, 0x03, 0x94,
-	0x70, 0xcf, 0x57, 0x12, 0xf6, 0x1c, 0x20, 0x54, 0x94, 0x00, 0xdb, 0xf5, 0x0b, 0xb8, 0x14, 0xc8,
-	0x27, 0x6c, 0xfb, 0xa3, 0x73, 0xb6, 0x1d, 0x00, 0xae, 0x29, 0x04, 0x7d, 0xe3, 0xc0, 0x22, 0x9b,
-	0x20, 0x5b, 0xbf, 0xce, 0x43, 0x69, 0x6b, 0x3a, 0x9e, 0x39, 0x2e, 0x3b, 0xa3, 0x22, 0xd2, 0xe7,
-	0x23, 0x9f, 0x6f, 0xb7, 0xbe, 0x71, 0x33, 0xba, 0x82, 0x64, 0x53, 0xff, 0xda, 0x9c, 0xd5, 0x96,
-	0x22, 0x4c, 0x58, 0x06, 0xb2, 0xdc, 0x7b, 0x08, 0xcb, 0x30, 0x26, 0x45, 0xd4, 0x25, 0xc8, 0x87,
-	0x97, 0xc0, 0x84, 0x12, 0x0a, 0x86, 0xc1, 0x17, 0xf7, 0xa2, 0x08, 0xe4, 0xff, 0xe1, 0x42, 0xdf,
-	0xa5, 0x0e, 0xb3, 0x87, 0x0a, 0xd0, 0xcb, 0x92, 0xa7, 0x2e, 0x26, 0x6c, 0x15, 0xa8, 0x6f, 0x42,
-	0x75, 0x3c, 0x1d, 0x84, 0x7c, 0x45, 0xc9, 0x57, 0x41, 0x6a, 0xc0, 0x74, 0x59, 0x45, 0x02, 0x16,
-	0x39, 0xab, 0x38, 0x2b, 0x86, 0xd6, 0x43, 0xa8, 0x45, 0xf6, 0xca, 0x82, 0x5b, 0xe7, 0xd9, 0xf3,
-	0xd6, 0xae, 0x88, 0x84, 0x8f, 0x78, 0xf0, 0xb3, 0x31, 0x12, 0x62, 0x40, 0xdd, 0xed, 0x1c, 0x1c,
-	0x60, 0xdc, 0xfc, 0x2c, 0x10, 0x91, 0xa1, 0x53, 0x8b, 0x98, 0x4b, 0x5a, 0xc4, 0x34, 0x54, 0xc4,
-	0xcc, 0x85, 0x11, 0x33, 0xbf, 0x59, 0x87, 0xaa, 0x30, 0xc8, 0xd1, 0x7c, 0x82, 0x8a, 0x59, 0xbf,
-	0x41, 0xb7, 0xec, 0xbe, 0x99, 0xa8, 0x50, 0xf1, 0x00, 0x4a, 0x7d, 0x01, 0x8e, 0x07, 0xc4, 0xa2,
-	0xe1, 0xa5, 0x44, 0x1b, 0xdb, 0x8a, 0x8b, 0x3c, 0x84, 0x92, 0x37, 0xef, 0xf7, 0xa9, 0xa7, 0xc2,
-	0xe7, 0xff, 0xc5, 0xc3, 0x82, 0xbc, 0xe1, 0xb6, 0xe2, 0x63, 0x22, 0x2f, 0x9d, 0xe1, 0x68, 0xce,
-	0x83, 0xe9, 0xf9, 0x22, 0x92, 0xcf, 0xfa, 0x95, 0x01, 0x15, 0xae, 0x65, 0xa6, 0x58, 0xf4, 0x21,
-	0x94, 0xb9, 0x0e, 0x74, 0x20, 0xa3, 0xd1, 0x8a, 0x1d, 0x12, 0xc8, 0x8f, 0x30, 0x26, 0x4a, 0x39,
-	0x4f, 0x2a, 0xd6, 0x48, 0x86, 0x45, 0xcd, 0x42, 0x56, 0x6b, 0x07, 0x2e, 0x72, 0xab, 0xf4, 0x7d,
-	0xb4, 0xa7, 0xb2, 0xa3, 0xfe, 0xb2, 0x1b, 0xb1, 0x97, 0x1d, 0xe7, 0x66, 0x27, 0x67, 0xde, 0xb0,
-	0xef, 0x8c, 0xa4, 0x16, 0xc1, 0x18, 0x5f, 0x14, 0xa2, 0x83, 0x65, 0x7a, 0x0c, 0x6a, 0x50, 0x79,
-	0xec, 0x78, 0x27, 0x52, 0x25, 0xeb, 0x2b, 0xa8, 0x8a, 0x61, 0x26, 0x1b, 0xe2, 0x33, 0x78, 0x82,
-	0x28, 0x5c, 0xf1, 0x9a, 0xcd, 0xbf, 0xad, 0x8b, 0x70, 0xe1, 0x60, 0xe2, 0xcc, 0xbc, 0x93, 0xa9,
-	0x0a, 0xae, 0x2c, 0x6f, 0x5b, 0x0d, 0x69, 0x99, 0x56, 0xbc, 0x0b, 0x17, 0x5c, 0x3a, 0x76, 0x86,
-	0x93, 0xe1, 0xe4, 0xf8, 0xa8, 0x77, 0xe6, 0x53, 0x4f, 0xa6, 0x75, 0xf5, 0x80, 0xbc, 0xc9, 0xa8,
-	0x4c, 0xb5, 0xde, 0x68, 0xda, 0x93, 0x57, 0x9c, 0x7f, 0x5b, 0xbf, 0x33, 0xa0, 0xfa, 0xc2, 0xf1,
-	0xfb, 0xca, 0x0a, 0x64, 0x1b, 0xea, 0xc1, 0xc5, 0xe6, 0x14, 0xa9, 0x4b, 0x2c, 0xc2, 0x73, 0x99,
-	0x2d, 0x79, 0xd1, 0x55, 0x84, 0xaf, 0xf5, 0x75, 0x02, 0x87, 0x72, 0x26, 0x7d, 0x3a, 0x0a, 0xa0,
-	0x72, 0xe9, 0x50, 0x9c, 0x51, 0x87, 0xd2, 0x09, 0x9b, 0x17, 0xc2, 0xd7, 0x4f, 0x5c, 0xcb, 0x6f,
-	0x0d, 0x20, 0x8b, 0x3a, 0x7c, 0xd7, 0xac, 0xf3, 0x36, 0xd4, 0x3d, 0xbc, 0xed, 0xfe, 0x51, 0x2c,
-	0xe9, 0xad, 0x71, 0x6a, 0x10, 0x9c, 0xd0, 0xc2, 0x98, 0x6d, 0x1f, 0xa3, 0x4b, 0x7b, 0x47, 0x93,
-	0xa9, 0x3f, 0x7c, 0x79, 0xc6, 0x03, 0xe2, 0x8a, 0x5d, 0x57, 0xe4, 0x3d, 0x4e, 0xb5, 0x1e, 0x28,
-	0xa5, 0x74, 0xe5, 0xc9, 0x15, 0x58, 0x79, 0xcd, 0xa8, 0x2a, 0x1d, 0xc7, 0x37, 0x9e, 0x8f, 0xb7,
-	0x07, 0xd6, 0xdf, 0x0c, 0xa8, 0x49, 0xf3, 0x67, 0xf2, 0x01, 0x7d, 0x89, 0x5c, 0x64, 0x09, 0x96,
-	0x60, 0x88, 0x63, 0x19, 0xc8, 0xd4, 0x4c, 0x0d, 0xd9, 0x3d, 0x13, 0x56, 0xc6, 0x29, 0xb1, 0x9f,
-	0x60, 0x8c, 0xf1, 0x7d, 0xb5, 0x2f, 0xee, 0x59, 0x2c, 0xc0, 0xdb, 0x17, 0x24, 0x3d, 0xb0, 0xce,
-	0x6d, 0x28, 0xd2, 0x53, 0x3a, 0xf1, 0xbd, 0x46, 0x85, 0x07, 0x85, 0x9a, 0xca, 0x0f, 0x3b, 0x8c,
-	0x6a, 0xcb, 0x49, 0xeb, 0x87, 0x70, 0x71, 0x97, 0x25, 0x72, 0x8f, 0xd0, 0xfa, 0x7a, 0x4a, 0xd8,
-	0xed, 0xee, 0x4a, 0xab, 0xe4, 0xfd, 0xee, 0x2e, 0xa9, 0x43, 0x6e, 0xbb, 0x2d, 0xf7, 0x90, 0x1b,
-	0xb6, 0xad, 0x9f, 0xe3, 0x41, 0xeb, 0x72, 0x99, 0xcc, 0x14, 0x03, 0x57, 0xcb, 0xe7, 0xc3, 0xe5,
-	0x31, 0xf7, 0xa4, 0xae, 0x3b, 0x75, 0xb9, 0x41, 0xca, 0xb6, 0x18, 0x58, 0xb7, 0xa4, 0x0e, 0xb8,
-	0xe7, 0xe9, 0xab, 0xc0, 0xd9, 0x04, 0x9a, 0x11, 0xa8, 0xba, 0x03, 0x6b, 0x11, 0xae, 0x4c, 0xc1,
-	0xe9, 0x2e, 0x5c, 0xe2, 0x60, 0x3b, 0x94, 0xce, 0x5a, 0xa3, 0xe1, 0x69, 0xea, 0xaa, 0x33, 0xb8,
-	0x1c, 0x67, 0xfc, 0xdf, 0xda, 0xc8, 0x3a, 0x81, 0xe2, 0x13, 0x5e, 0x30, 0x6a, 0xba, 0x14, 0x38,
-	0x2f, 0x46, 0x98, 0x89, 0x33, 0x16, 0xe9, 0x7c, 0xd9, 0xe6, 0xdf, 0x3c, 0x9a, 0x53, 0xea, 0x3e,
-	0xb7, 0x77, 0xc5, 0xab, 0x51, 0xb6, 0x83, 0x31, 0xb9, 0xc6, 0x4a, 0xd5, 0x21, 0xba, 0x07, 0x9f,
-	0x2d, 0xf0, 0x59, 0x8d, 0x82, 0x25, 0xd3, 0xaa, 0x58, 0xa9, 0x35, 0x18, 0x68, 0x2f, 0x47, 0x80,
-	0x67, 0x44, 0xf1, 0xac, 0xd7, 0x70, 0x51, 0xe3, 0xcf, 0x64, 0x86, 0xfb, 0x50, 0x14, 0x55, 0xb1,
-	0x0c, 0x5a, 0xeb, 0x51, 0x29, 0xb1, 0x8c, 0x2d, 0x79, 0xac, 0xdb, 0xb0, 0x26, 0x29, 0x74, 0x3c,
-	0x4d, 0x3a, 0x2b, 0x6e, 0x1f, 0x6b, 0x17, 0xd6, 0xa3, 0x6c, 0x99, 0x5c, 0xa4, 0xa5, 0x16, 0x7d,
-	0x3e, 0x1b, 0x68, 0x31, 0x30, 0x7e, 0x28, 0xba, 0xc1, 0x72, 0x31, 0x83, 0x05, 0x0a, 0x29, 0x88,
-	0x4c, 0x0a, 0xad, 0x29, 0xf3, 0xef, 0x0e, 0xbd, 0xe0, 0xa5, 0x7b, 0x0b, 0x44, 0x27, 0x66, 0x3a,
-	0x94, 0x26, 0x94, 0x84, 0xc1, 0x55, 0x32, 0x95, 0x7c, 0x2a, 0x8a, 0x89, 0x29, 0xd4, 0xa6, 0x2f,
-	0x5d, 0xe7, 0x78, 0x4c, 0x83, 0x98, 0xc3, 0x52, 0x08, 0x9d, 0x98, 0x69, 0xc7, 0x7f, 0xc4, 0xe7,
-	0xb3, 0x35, 0x72, 0xdc, 0xb1, 0x32, 0xfe, 0xe7, 0x50, 0x14, 0xb9, 0x89, 0xcc, 0xdf, 0xef, 0x44,
-	0x61, 0x74, 0x5e, 0x31, 0x68, 0x89, 0x4c, 0x46, 0x4a, 0xb1, 0xc3, 0x92, 0xcd, 0x98, 0x76, 0xac,
-	0x39, 0xd3, 0x26, 0x9f, 0xc0, 0xb2, 0xc3, 0x44, 0xf8, 0x5d, 0xac, 0xc7, 0xb3, 0x42, 0x8e, 0xd6,
-	0x3d, 0x9b, 0x51, 0x5b, 0x70, 0x59, 0x9f, 0x42, 0x45, 0x5b, 0x81, 0x25, 0xbb, 0x8f, 0x3a, 0x5d,
-	0xcc, 0x80, 0xab, 0xb0, 0xd2, 0xda, 0xea, 0x6e, 0x1f, 0x8a, 0x1c, 0xb8, 0x0e, 0xd0, 0xee, 0x04,
-	0xe3, 0x1c, 0x66, 0x41, 0x42, 0x4a, 0xde, 0x70, 0x5d, 0x1f, 0x23, 0x4d, 0x9f, 0xdc, 0x7b, 0xe9,
-	0xf3, 0x06, 0x6a, 0x72, 0xfb, 0x99, 0x7c, 0xe0, 0x21, 0x5a, 0x98, 0xc1, 0x28, 0x17, 0xb8, 0x92,
-	0xb0, 0xac, 0xba, 0x9d, 0x82, 0xd1, 0xc2, 0xec, 0xe1, 0xc0, 0x77, 0xfc, 0xb9, 0xa7, 0x5c, 0xe0,
-	0x0f, 0x06, 0xd4, 0x15, 0x25, 0x6b, 0xf5, 0xae, 0x4a, 0x24, 0x11, 0xf3, 0x82, 0x02, 0xe9, 0x32,
-	0x14, 0x07, 0xbd, 0x83, 0xe1, 0x5b, 0xd5, 0xc5, 0x90, 0x23, 0x46, 0x1f, 0x89, 0x75, 0x44, 0x0b,
-	0x4d, 0x8e, 0x58, 0xee, 0xcd, 0x9a, 0x69, 0xdb, 0x93, 0x01, 0x7d, 0xc3, 0x5f, 0xda, 0x82, 0x1d,
-	0x12, 0x78, 0xba, 0x2c, 0x5b, 0x6d, 0xbc, 0x7e, 0xd2, 0x5b, 0x6f, 0xe8, 0xe4, 0xad, 0xb9, 0x7f,
-	0xd2, 0x99, 0xb0, 0x2e, 0x93, 0xda, 0xe1, 0x3a, 0x10, 0x46, 0x6c, 0x0f, 0x3d, 0x9d, 0xda, 0x81,
-	0x35, 0x46, 0x45, 0xbf, 0xc7, 0x64, 0x3a, 0x8c, 0x18, 0x2a, 0x6c, 0x1b, 0xb1, 0xb0, 0xed, 0x78,
-	0xde, 0xeb, 0xa9, 0x3b, 0x90, 0x5b, 0x0b, 0xc6, 0x56, 0x5b, 0x80, 0x3f, 0xf7, 0x22, 0x81, 0xf9,
-	0xbb, 0xa2, 0xdc, 0x0b, 0x51, 0x1e, 0x51, 0xff, 0x1c, 0x14, 0xeb, 0x63, 0xb8, 0xa4, 0x38, 0x65,
-	0x0d, 0x7d, 0x0e, 0xf3, 0x3e, 0x5c, 0x55, 0xcc, 0x5b, 0x27, 0x2c, 0xd1, 0x7b, 0x2a, 0x17, 0xfc,
-	0x4f, 0xf5, 0xdc, 0x84, 0x46, 0xa0, 0x27, 0xcf, 0x41, 0xa6, 0x23, 0x5d, 0x81, 0xb9, 0x27, 0x7d,
-	0x06, 0xb1, 0xd8, 0x37, 0xa3, 0xb9, 0xc8, 0xa2, 0x1e, 0x41, 0xf6, 0x6d, 0x6d, 0xc1, 0x15, 0x85,
-	0x21, 0xb3, 0x83, 0x28, 0xc8, 0x82, 0x42, 0x49, 0x20, 0xd2, 0x60, 0x4c, 0xf4, 0x7c, 0xb3, 0xeb,
-	0x9c, 0x51, 0xd3, 0x72, 0x4c, 0x43, 0xc3, 0x94, 0xa6, 0x65, 0x9c, 0x0b, 0xa6, 0x5d, 0x60, 0xfe,
-	0x29, 0x5c, 0x0b, 0x60, 0x99, 0x25, 0x9e, 0xa2, 0xfb, 0x0d, 0x3d, 0x4f, 0x2b, 0xeb, 0x92, 0xb6,
-	0x72, 0x07, 0x0a, 0x33, 0x2a, 0xa3, 0x44, 0x65, 0x83, 0x34, 0x45, 0x13, 0xbb, 0xa9, 0x09, 0xf3,
-	0x79, 0x6b, 0x00, 0xd7, 0x15, 0xba, 0xb0, 0x51, 0x22, 0x7c, 0x5c, 0x29, 0x95, 0xf2, 0x0b, 0x43,
-	0x2d, 0xa6, 0xfc, 0x79, 0x71, 0x9a, 0x41, 0xf3, 0xee, 0x4b, 0x61, 0x1a, 0x75, 0x5b, 0x32, 0x45,
-	0xff, 0x1d, 0x71, 0x9d, 0x82, 0x4b, 0x96, 0x09, 0xac, 0x07, 0xeb, 0xd1, 0xbb, 0x99, 0x29, 0x30,
-	0x61, 0x1e, 0xeb, 0xa3, 0x09, 0x55, 0x58, 0x12, 0x03, 0xa5, 0x70, 0x70, 0x71, 0x33, 0x29, 0xec,
-	0x84, 0x60, 0xdc, 0xc9, 0xb2, 0xea, 0xcb, 0x4e, 0x53, 0x65, 0x28, 0x62, 0x60, 0xed, 0xc1, 0xe5,
-	0xf8, 0xc5, 0xcf, 0xa4, 0xf2, 0xa1, 0x70, 0xe0, 0xa4, 0xd8, 0x90, 0x09, 0xf7, 0x59, 0x78, 0xbd,
-	0xb5, 0x10, 0x91, 0x09, 0xd2, 0x06, 0x33, 0x29, 0x62, 0xfc, 0x37, 0xfc, 0x35, 0x08, 0x20, 0x99,
-	0xc0, 0xbc, 0x10, 0x2c, 0xfb, 0xf1, 0x87, 0x31, 0x22, 0x7f, 0x6e, 0x8c, 0x90, 0x0e, 0xa1, 0x87,
-	0xab, 0x4c, 0x9b, 0x78, 0x11, 0xc6, 0x9c, 0x85, 0x88, 0x96, 0x09, 0xf8, 0x2b, 0xb8, 0x91, 0x1e,
-	0xcc, 0xb2, 0x20, 0x7f, 0xcf, 0x82, 0x72, 0x90, 0x5a, 0x69, 0x3f, 0x23, 0x55, 0xa0, 0xb4, 0xb7,
-	0x7f, 0xf0, 0xb4, 0xb5, 0x85, 0x49, 0xdd, 0xc6, 0xdf, 0x73, 0x90, 0xdb, 0x39, 0x24, 0x9b, 0xb0,
-	0x2c, 0xda, 0xe0, 0xe7, 0xfc, 0x4a, 0x60, 0x9e, 0xd7, 0x50, 0xb7, 0x96, 0xc8, 0x67, 0x90, 0x67,
-	0x8d, 0xf0, 0xd4, 0x9f, 0x09, 0xcc, 0xf4, 0x66, 0x3a, 0x4a, 0x77, 0xa1, 0xa2, 0x75, 0xbd, 0xc9,
-	0x3b, 0x7f, 0x26, 0x30, 0xdf, 0xdd, 0x51, 0x17, 0x3a, 0x75, 0xdf, 0x4c, 0xe2, 0x3a, 0x85, 0x5d,
-	0xda, 0xb8, 0x4e, 0x5a, 0x67, 0x14, 0xa5, 0xf7, 0x64, 0xb7, 0xbd, 0xef, 0x93, 0xeb, 0x09, 0xcd,
-	0x5b, 0xbd, 0x4d, 0x69, 0xde, 0x48, 0x67, 0x50, 0x78, 0x1b, 0xfb, 0xb0, 0xcc, 0x5b, 0x38, 0xe4,
-	0x0b, 0xf5, 0x61, 0x26, 0x34, 0xb8, 0x52, 0xcc, 0x1d, 0x69, 0xfe, 0x58, 0x4b, 0xf7, 0x8c, 0xef,
-	0x1b, 0x1b, 0xdf, 0xe6, 0x60, 0x99, 0x97, 0xf4, 0xe4, 0x19, 0x40, 0xd8, 0xfb, 0x88, 0x6b, 0xbb,
-	0xd0, 0x4d, 0x89, 0x6b, 0xbb, 0xd8, 0x36, 0x11, 0x27, 0xa2, 0x35, 0x29, 0x48, 0x92, 0x48, 0xa4,
-	0xcb, 0x11, 0x3f, 0x91, 0x84, 0x0e, 0x07, 0xa2, 0x3a, 0x50, 0x8f, 0x36, 0x21, 0xc8, 0xcd, 0x04,
-	0xb1, 0x78, 0x2f, 0xc3, 0xbc, 0x75, 0x3e, 0x53, 0xc4, 0x2a, 0x7f, 0xce, 0xe1, 0xb9, 0x89, 0x5f,
-	0xb1, 0xf1, 0x08, 0xcb, 0x41, 0x9d, 0x4f, 0xae, 0x25, 0xd5, 0x80, 0x61, 0x82, 0x64, 0x5e, 0x4f,
-	0x9d, 0x0f, 0xd4, 0x7f, 0x01, 0x55, 0xbd, 0x2e, 0x27, 0x1f, 0x25, 0x96, 0x95, 0x7a, 0x69, 0x6f,
-	0x5a, 0xe7, 0xb1, 0x2c, 0x02, 0x8b, 0xfa, 0x3a, 0x19, 0x38, 0x52, 0xbe, 0x27, 0x03, 0x47, 0xcb,
-	0x73, 0x04, 0x46, 0xcf, 0x08, 0xab, 0x6a, 0x92, 0xb8, 0x45, 0xad, 0x08, 0x8f, 0x7b, 0xc6, 0x62,
-	0x41, 0x8e, 0x7e, 0xfc, 0xaf, 0x1c, 0x54, 0x9e, 0x38, 0xc3, 0x89, 0x4f, 0x27, 0xac, 0x0b, 0xc8,
-	0xa2, 0x07, 0x0f, 0x34, 0x71, 0x77, 0xd6, 0x6b, 0xd8, 0xb8, 0x3b, 0x47, 0x0a, 0x3c, 0x54, 0xb3,
-	0x03, 0x45, 0x51, 0x67, 0x91, 0x18, 0x63, 0xa4, 0x1e, 0x33, 0x3f, 0x4c, 0x9e, 0xd4, 0x77, 0x1b,
-	0x96, 0xec, 0xf1, 0xdd, 0x2e, 0x54, 0xf8, 0xe6, 0x8d, 0x74, 0x86, 0x00, 0xf2, 0x27, 0x50, 0x60,
-	0xdd, 0x7e, 0x12, 0x0b, 0x15, 0xda, 0x0f, 0x02, 0xa6, 0x99, 0x34, 0x15, 0x00, 0x3c, 0x81, 0x15,
-	0xd5, 0xc0, 0x27, 0x57, 0x63, 0xfa, 0x47, 0x9b, 0xfd, 0xe6, 0xb5, 0xb4, 0x69, 0x05, 0x86, 0xee,
-	0xfd, 0x5b, 0x80, 0x02, 0x7b, 0x31, 0xd8, 0x5e, 0xc3, 0x04, 0x35, 0xbe, 0xd7, 0x85, 0x42, 0x2f,
-	0xbe, 0xd7, 0xc5, 0xdc, 0x56, 0xdc, 0x79, 0x2d, 0x4f, 0x25, 0x09, 0x22, 0xd1, 0x3a, 0x31, 0x7e,
-	0xe7, 0x13, 0x92, 0x5c, 0xe1, 0xdb, 0x7a, 0xc2, 0x4a, 0x12, 0x84, 0x62, 0x85, 0x66, 0xdc, 0xb7,
-	0x93, 0xf2, 0x5d, 0x04, 0x7e, 0x0a, 0x25, 0x99, 0xa1, 0x26, 0xa9, 0x1a, 0xad, 0x3a, 0x93, 0x54,
-	0x8d, 0xa5, 0xb7, 0x21, 0x22, 0xe6, 0x29, 0x69, 0x88, 0x61, 0x99, 0x94, 0x86, 0xa8, 0x25, 0x39,
-	0x88, 0xf8, 0x35, 0x40, 0x98, 0x95, 0xc6, 0x83, 0x5d, 0x62, 0xb1, 0x1a, 0x0f, 0x76, 0xc9, 0x89,
-	0x2d, 0x42, 0x7f, 0x03, 0x64, 0x31, 0x41, 0x25, 0x1f, 0x27, 0x4b, 0x27, 0x96, 0xb8, 0xe6, 0xfd,
-	0xf7, 0x63, 0x0e, 0x96, 0xec, 0x41, 0x2d, 0x92, 0xbb, 0x92, 0x3b, 0x29, 0x36, 0x88, 0xd5, 0xbf,
-	0xe6, 0xdd, 0x77, 0xf2, 0x05, 0x6b, 0x50, 0xa8, 0x47, 0x93, 0x59, 0x92, 0x22, 0xbc, 0x50, 0x20,
-	0x9b, 0xf7, 0xde, 0xcd, 0xa8, 0x1f, 0xb5, 0xcc, 0x6f, 0x93, 0x8e, 0x3a, 0x5a, 0x3b, 0x27, 0x1d,
-	0x75, 0x2c, 0x39, 0x0e, 0x11, 0x53, 0x9c, 0x27, 0x5a, 0x63, 0xa7, 0x21, 0x2e, 0x38, 0x4f, 0x98,
-	0xc1, 0x26, 0x39, 0xcf, 0x42, 0x39, 0x9e, 0xe4, 0x3c, 0x8b, 0x49, 0x30, 0x42, 0xfb, 0xb0, 0x96,
-	0x90, 0xcc, 0x92, 0xfb, 0x29, 0x6a, 0x25, 0x56, 0xf1, 0xe6, 0x27, 0xef, 0xc9, 0x1d, 0xac, 0xfa,
-	0x1a, 0xd6, 0x93, 0x32, 0x5d, 0x92, 0x02, 0x94, 0x52, 0xde, 0x9b, 0xcd, 0xf7, 0x65, 0x57, 0x0b,
-	0x6f, 0x56, 0x7f, 0xff, 0xd7, 0x6b, 0xc6, 0x9f, 0xf0, 0xcf, 0x5f, 0xf0, 0x4f, 0xaf, 0xc8, 0xff,
-	0x4f, 0xdc, 0x0f, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf4, 0x4d, 0x3d, 0xa0, 0x7c, 0x27, 0x00,
-	0x00,
+	// 2989 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x6f, 0x1c, 0x49,
+	0x15, 0x4f, 0xcf, 0x8c, 0x3f, 0xe6, 0xcd, 0x78, 0xe2, 0x94, 0x9d, 0xac, 0xdd, 0x71, 0x1c, 0xa7,
+	0xf2, 0xb9, 0x5f, 0x1e, 0xd6, 0xbb, 0x70, 0x00, 0xb4, 0xd2, 0xd8, 0x33, 0x64, 0xbd, 0xf6, 0xda,
+	0xd9, 0xf6, 0xc4, 0xbb, 0x48, 0x08, 0xab, 0x3d, 0x53, 0xb1, 0x47, 0x99, 0xaf, 0xed, 0xee, 0x71,
+	0xe2, 0x48, 0x2b, 0xa1, 0x15, 0x7b, 0xe0, 0xbc, 0x08, 0x04, 0x1c, 0xf9, 0x0f, 0x90, 0xf8, 0x1f,
+	0x10, 0x17, 0x90, 0x38, 0x72, 0x41, 0x88, 0x03, 0x07, 0xee, 0x88, 0x13, 0xd4, 0x67, 0x77, 0x75,
+	0x4f, 0xf5, 0xd8, 0x4b, 0xc3, 0x21, 0x71, 0xd7, 0xab, 0x57, 0xef, 0xbd, 0x7a, 0xf5, 0xea, 0xd7,
+	0xef, 0xbd, 0x1e, 0x28, 0x7a, 0xc3, 0xd6, 0xfa, 0xd0, 0x1b, 0x04, 0x03, 0x54, 0x26, 0x41, 0xab,
+	0xed, 0x13, 0xef, 0x8c, 0x78, 0xc3, 0x63, 0x7b, 0xf1, 0x64, 0x70, 0x32, 0xe0, 0x13, 0x55, 0xf6,
+	0x24, 0x78, 0xec, 0x65, 0xc6, 0x53, 0xed, 0x9d, 0xb5, 0x5a, 0xfc, 0xbf, 0xe1, 0x71, 0xf5, 0xf9,
+	0x99, 0x9c, 0xba, 0xc9, 0xa7, 0xdc, 0x51, 0x70, 0xca, 0xff, 0xa3, 0x53, 0xec, 0x8f, 0x9c, 0x5c,
+	0x39, 0x19, 0x0c, 0x4e, 0xba, 0xa4, 0xea, 0x0e, 0x3b, 0x55, 0xb7, 0xdf, 0x1f, 0x04, 0x6e, 0xd0,
+	0x19, 0xf4, 0x7d, 0x31, 0x8b, 0xbf, 0xb4, 0xa0, 0xe2, 0x10, 0x7f, 0x48, 0x29, 0xe4, 0x03, 0xe2,
+	0xb6, 0x89, 0x87, 0x6e, 0x01, 0xb4, 0xba, 0x23, 0x3f, 0x20, 0xde, 0x51, 0xa7, 0xbd, 0x64, 0xad,
+	0x59, 0x8f, 0x0a, 0x4e, 0x51, 0x52, 0xb6, 0xdb, 0xe8, 0x26, 0x14, 0x7b, 0xa4, 0x77, 0x2c, 0x66,
+	0x73, 0x7c, 0x76, 0x56, 0x10, 0xe8, 0xa4, 0x0d, 0xb3, 0x1e, 0x39, 0xeb, 0xf8, 0x54, 0xc3, 0x52,
+	0x9e, 0xce, 0xe5, 0x9d, 0x70, 0xcc, 0x16, 0x7a, 0xee, 0xb3, 0xe0, 0x88, 0x8a, 0xe9, 0x2d, 0x15,
+	0xc4, 0x42, 0x46, 0x68, 0xd2, 0x31, 0xfe, 0x69, 0x1e, 0xca, 0x8e, 0xdb, 0x3f, 0x21, 0x0e, 0xf9,
+	0x6c, 0x44, 0xfc, 0x00, 0xcd, 0x43, 0xfe, 0x39, 0x39, 0xe7, 0xea, 0xcb, 0x0e, 0x7b, 0x14, 0xeb,
+	0x29, 0xc7, 0x11, 0xe9, 0x0b, 0xc5, 0x65, 0xb6, 0x9e, 0x12, 0x1a, 0xfd, 0x36, 0x5a, 0x84, 0xa9,
+	0x6e, 0xa7, 0xd7, 0x09, 0xa4, 0x56, 0x31, 0x88, 0x99, 0x53, 0x48, 0x98, 0xb3, 0x05, 0xe0, 0x0f,
+	0xbc, 0xe0, 0x68, 0xe0, 0xd1, 0x4d, 0x2f, 0x4d, 0xd1, 0xd9, 0xca, 0xc6, 0xbd, 0x75, 0xfd, 0x20,
+	0xd6, 0x75, 0x83, 0xd6, 0x0f, 0x28, 0xf3, 0x3e, 0xe3, 0x75, 0x8a, 0xbe, 0x7a, 0x44, 0xdf, 0x83,
+	0x12, 0x17, 0x12, 0xb8, 0xde, 0x09, 0x09, 0x96, 0xa6, 0xb9, 0x94, 0xfb, 0x17, 0x48, 0x69, 0x72,
+	0x66, 0x87, 0xab, 0x17, 0xcf, 0x08, 0x43, 0x99, 0xf2, 0x77, 0xdc, 0x6e, 0xe7, 0x95, 0x7b, 0xdc,
+	0x25, 0x4b, 0x33, 0x54, 0xd0, 0xac, 0x13, 0xa3, 0xe1, 0x75, 0x28, 0x86, 0x36, 0xa0, 0x59, 0x28,
+	0xec, 0xed, 0xef, 0x35, 0xe6, 0xaf, 0x20, 0x80, 0xe9, 0xda, 0xc1, 0x56, 0x63, 0xaf, 0x3e, 0x6f,
+	0xa1, 0x12, 0xcc, 0xd4, 0x1b, 0x62, 0x90, 0xc3, 0x9b, 0x00, 0x91, 0x36, 0x34, 0x03, 0xf9, 0x9d,
+	0xc6, 0xf7, 0x29, 0x3f, 0xe5, 0x39, 0x6c, 0x38, 0x07, 0xdb, 0xfb, 0x7b, 0x74, 0x01, 0x5d, 0xbc,
+	0xe5, 0x34, 0x6a, 0xcd, 0xc6, 0x7c, 0x8e, 0x71, 0x7c, 0xb4, 0x5f, 0x9f, 0xcf, 0xa3, 0x22, 0x4c,
+	0x1d, 0xd6, 0x76, 0x9f, 0x36, 0xe6, 0x0b, 0xf8, 0x73, 0x98, 0x93, 0xe6, 0x8b, 0x10, 0x41, 0xef,
+	0xc1, 0xf4, 0x29, 0x0f, 0x13, 0x7e, 0x32, 0xa5, 0x8d, 0x95, 0xc4, 0x5e, 0x63, 0xa1, 0xe4, 0x48,
+	0x5e, 0xba, 0xbd, 0xfc, 0xf3, 0x33, 0x9f, 0x1e, 0x5a, 0x9e, 0x2e, 0x99, 0x5f, 0x17, 0xf1, 0xbb,
+	0xbe, 0x43, 0xce, 0x0f, 0xdd, 0xee, 0x88, 0x38, 0x6c, 0x12, 0x21, 0x28, 0xf4, 0x06, 0x1e, 0xe1,
+	0x07, 0x38, 0xeb, 0xf0, 0x67, 0xfc, 0x21, 0xc0, 0x93, 0x51, 0x90, 0x1e, 0x12, 0xf4, 0xd4, 0xcf,
+	0x98, 0x04, 0x19, 0x0e, 0x62, 0xc0, 0x63, 0x81, 0xb8, 0x3e, 0x09, 0x63, 0x81, 0x0d, 0xf0, 0x16,
+	0x94, 0xb8, 0xac, 0x2c, 0x1b, 0xa1, 0x42, 0x50, 0x9d, 0x74, 0x49, 0x40, 0x32, 0xc4, 0x2a, 0x26,
+	0xb0, 0x10, 0x13, 0x92, 0xc9, 0xb5, 0x4b, 0x30, 0xd3, 0xe6, 0xc2, 0x84, 0x9e, 0xbc, 0xa3, 0x86,
+	0xf8, 0x1f, 0x16, 0x14, 0xa5, 0x85, 0xfb, 0x43, 0x54, 0x83, 0x39, 0x4f, 0x0c, 0x8e, 0xb8, 0x21,
+	0x52, 0x89, 0x9d, 0x1e, 0xab, 0x1f, 0x5c, 0x71, 0xca, 0x72, 0x09, 0x27, 0xa3, 0xef, 0x40, 0x49,
+	0x89, 0x18, 0x8e, 0x02, 0xae, 0xae, 0xb4, 0xb1, 0x14, 0x17, 0x10, 0x1d, 0x17, 0x5d, 0x0e, 0x92,
+	0x9d, 0x12, 0x51, 0x13, 0x16, 0xd5, 0x62, 0x61, 0xa0, 0x34, 0x23, 0xcf, 0xa5, 0xac, 0xc5, 0xa5,
+	0x8c, 0xfb, 0x98, 0x4a, 0x43, 0x72, 0xbd, 0x36, 0xb9, 0x59, 0x84, 0x19, 0x49, 0xc5, 0xff, 0xb4,
+	0x00, 0x94, 0x8f, 0xe8, 0x7e, 0xeb, 0x50, 0xf1, 0xe4, 0x28, 0xb6, 0xe1, 0x9b, 0xc6, 0x0d, 0x4b,
+	0xd7, 0x5e, 0x71, 0xe6, 0xd4, 0x22, 0xb1, 0xe5, 0xf7, 0xa1, 0x1c, 0x4a, 0x89, 0xf6, 0xbc, 0x6c,
+	0xd8, 0x73, 0x28, 0xa1, 0xa4, 0x16, 0xb0, 0x5d, 0x7f, 0x02, 0xd7, 0xc3, 0xf5, 0x86, 0x6d, 0xdf,
+	0x99, 0xb0, 0xed, 0x50, 0xe0, 0x82, 0x92, 0xa0, 0x6f, 0x1c, 0x18, 0xb2, 0x09, 0x32, 0xfe, 0x65,
+	0x1e, 0x66, 0xb6, 0x06, 0xbd, 0xa1, 0xeb, 0xb1, 0x33, 0x9a, 0xa6, 0xf4, 0x51, 0x37, 0xe0, 0xdb,
+	0xad, 0x6c, 0xdc, 0x8d, 0x6b, 0x90, 0x6c, 0xea, 0xaf, 0xc3, 0x59, 0x1d, 0xb9, 0x84, 0x2d, 0x96,
+	0x40, 0x96, 0xbb, 0xc4, 0x62, 0x09, 0x63, 0x72, 0x89, 0xba, 0x04, 0xf9, 0xe8, 0x12, 0xd8, 0x30,
+	0x43, 0x17, 0x46, 0xe0, 0x4b, 0xf7, 0xa2, 0x08, 0xe8, 0x75, 0xb8, 0xda, 0xf2, 0x88, 0xcb, 0xfc,
+	0xa1, 0x00, 0x7a, 0x4a, 0xf2, 0x54, 0xc4, 0x84, 0xa3, 0x80, 0xfa, 0x2e, 0x94, 0x7b, 0x83, 0x76,
+	0xc4, 0x37, 0x2d, 0xf9, 0x4a, 0x94, 0x1a, 0x32, 0xdd, 0x50, 0x48, 0xc0, 0x90, 0xb3, 0x4c, 0x67,
+	0xc5, 0x10, 0xbf, 0x03, 0x73, 0xb1, 0xbd, 0x32, 0x70, 0x6b, 0x7c, 0xfc, 0xb4, 0xb6, 0x2b, 0x90,
+	0xf0, 0x31, 0x07, 0x3f, 0x87, 0x22, 0x21, 0x05, 0xd4, 0xdd, 0xc6, 0xc1, 0x01, 0xc5, 0xcd, 0xef,
+	0x86, 0x4b, 0x24, 0x74, 0x6a, 0x88, 0x79, 0x45, 0x43, 0x4c, 0x4b, 0x21, 0x66, 0x2e, 0x42, 0xcc,
+	0xfc, 0x66, 0x05, 0xca, 0xc2, 0x21, 0x47, 0xa3, 0x3e, 0x35, 0x0c, 0xff, 0x9a, 0x86, 0x65, 0xf3,
+	0x65, 0x5f, 0x41, 0x45, 0x15, 0x66, 0x5a, 0x42, 0x38, 0x3d, 0x20, 0x86, 0x86, 0xd7, 0x8d, 0x3e,
+	0x76, 0x14, 0x17, 0x7a, 0x07, 0x66, 0xfc, 0x51, 0xab, 0x45, 0x7c, 0x05, 0x9f, 0xaf, 0x25, 0x61,
+	0x41, 0xde, 0x70, 0x47, 0xf1, 0xb1, 0x25, 0xcf, 0xdc, 0x4e, 0x77, 0xc4, 0xc1, 0x74, 0xf2, 0x12,
+	0xc9, 0x87, 0x7f, 0x61, 0x41, 0x89, 0x5b, 0x99, 0x09, 0x8b, 0x56, 0xa0, 0xc8, 0x6d, 0x20, 0x6d,
+	0x89, 0x46, 0xb3, 0x4e, 0x44, 0x40, 0xdf, 0xa2, 0x98, 0x28, 0xd7, 0xf9, 0xd2, 0xb0, 0x25, 0xb3,
+	0x58, 0x6a, 0x59, 0xc4, 0x8a, 0x77, 0xe0, 0x1a, 0xf7, 0x4a, 0x8b, 0xe5, 0x2d, 0xca, 0x8f, 0xfa,
+	0x9b, 0xdd, 0x4a, 0xbc, 0xd9, 0xe9, 0xdc, 0xf0, 0xf4, 0xdc, 0xef, 0xb4, 0xdc, 0xae, 0xb4, 0x22,
+	0x1c, 0xd3, 0x37, 0x0a, 0xd2, 0x85, 0x65, 0x7a, 0x19, 0xcc, 0x41, 0xe9, 0x03, 0xd7, 0x3f, 0x95,
+	0x26, 0xe1, 0x4f, 0xa1, 0x2c, 0x86, 0x99, 0x7c, 0x48, 0x5f, 0x83, 0xa7, 0x54, 0x0a, 0x37, 0x7c,
+	0xce, 0xe1, 0xcf, 0xf8, 0x1a, 0x5c, 0x3d, 0xe8, 0xbb, 0x43, 0xff, 0x74, 0xa0, 0xc0, 0x95, 0xe5,
+	0x6d, 0xf3, 0x11, 0x2d, 0x93, 0xc6, 0x87, 0x70, 0xd5, 0x23, 0x3d, 0xb7, 0xd3, 0xef, 0xf4, 0x4f,
+	0x8e, 0x8e, 0xcf, 0x03, 0xe2, 0xcb, 0xb4, 0xae, 0x12, 0x92, 0x37, 0x19, 0x95, 0x99, 0x76, 0xdc,
+	0x1d, 0x1c, 0xcb, 0x2b, 0xce, 0x9f, 0xf1, 0x6f, 0x2d, 0x28, 0x7f, 0xe2, 0x06, 0x2d, 0xe5, 0x05,
+	0xb4, 0x0d, 0x95, 0xf0, 0x62, 0x73, 0x8a, 0xb4, 0x25, 0x81, 0xf0, 0x7c, 0xcd, 0x96, 0xbc, 0xe8,
+	0x0a, 0xe1, 0xe7, 0x5a, 0x3a, 0x81, 0x8b, 0x72, 0xfb, 0x2d, 0xd2, 0x0d, 0x45, 0xe5, 0xd2, 0x45,
+	0x71, 0x46, 0x5d, 0x94, 0x4e, 0xd8, 0xbc, 0x1a, 0xbd, 0xfd, 0xc4, 0xb5, 0xfc, 0xca, 0x02, 0x34,
+	0x6e, 0xc3, 0xd7, 0xcd, 0x3a, 0xef, 0x43, 0xc5, 0xa7, 0xb7, 0x3d, 0x38, 0x4a, 0x24, 0xbd, 0x73,
+	0x9c, 0x1a, 0x82, 0x13, 0xf5, 0x30, 0xcd, 0xb6, 0x4f, 0x68, 0x48, 0xfb, 0x47, 0x34, 0x01, 0xef,
+	0x3c, 0x3b, 0xe7, 0x80, 0x38, 0xeb, 0x54, 0x14, 0x79, 0x8f, 0x53, 0x71, 0x55, 0x19, 0xa5, 0x1b,
+	0x8f, 0x96, 0x61, 0xf6, 0x05, 0xa3, 0xaa, 0x74, 0x9c, 0xbe, 0xe3, 0xf9, 0x78, 0xbb, 0x8d, 0xff,
+	0x6e, 0xc1, 0x9c, 0x74, 0x7f, 0xa6, 0x18, 0xd0, 0x55, 0xe4, 0x62, 0x2a, 0x58, 0x82, 0x21, 0x8e,
+	0xa5, 0x2d, 0x53, 0x33, 0x35, 0x64, 0xf7, 0x4c, 0x78, 0x99, 0x4e, 0x89, 0xfd, 0x84, 0x63, 0x8a,
+	0xef, 0xf3, 0x2d, 0x71, 0xcf, 0x12, 0x00, 0xef, 0x5c, 0x95, 0xf4, 0xd0, 0x3b, 0xf7, 0x61, 0x9a,
+	0x9c, 0x91, 0x7e, 0xe0, 0x2f, 0x95, 0x38, 0x28, 0xcc, 0xa9, 0xfc, 0xb0, 0xc1, 0xa8, 0x8e, 0x9c,
+	0xc4, 0xdf, 0x84, 0x6b, 0xbb, 0x2c, 0x91, 0x7b, 0x4c, 0xbd, 0xaf, 0xa7, 0x84, 0xcd, 0xe6, 0xae,
+	0xf4, 0x4a, 0x3e, 0x68, 0xee, 0xa2, 0x0a, 0xe4, 0xb6, 0xeb, 0x72, 0x0f, 0xb9, 0x4e, 0x1d, 0x7f,
+	0x41, 0x0f, 0x5a, 0x5f, 0x97, 0xc9, 0x4d, 0x09, 0xe1, 0x4a, 0x7d, 0x3e, 0x52, 0x4f, 0x73, 0x4f,
+	0xe2, 0x79, 0x03, 0x8f, 0x3b, 0xa4, 0xe8, 0x88, 0x01, 0xbe, 0x27, 0x6d, 0xa0, 0x7b, 0x1e, 0x3c,
+	0x0f, 0x83, 0x4d, 0x48, 0xb3, 0x42, 0x53, 0x77, 0x60, 0x21, 0xc6, 0x95, 0x09, 0x9c, 0x1e, 0xc2,
+	0x75, 0x2e, 0x6c, 0x87, 0x90, 0x61, 0xad, 0xdb, 0x39, 0x4b, 0xd5, 0x3a, 0x84, 0x1b, 0x49, 0xc6,
+	0xff, 0xaf, 0x8f, 0xf0, 0x29, 0x4c, 0x7f, 0xc4, 0x0b, 0x46, 0xcd, 0x96, 0x02, 0xe7, 0xa5, 0x08,
+	0xd3, 0x77, 0x7b, 0x22, 0x9d, 0x2f, 0x3a, 0xfc, 0x99, 0xa3, 0x39, 0x21, 0xde, 0x53, 0x67, 0x57,
+	0xbc, 0x35, 0x8a, 0x4e, 0x38, 0x46, 0xab, 0xac, 0x54, 0xed, 0xd0, 0xf0, 0xe0, 0xb3, 0x05, 0x3e,
+	0xab, 0x51, 0x68, 0xc9, 0x34, 0x2f, 0x34, 0xd5, 0xda, 0x6d, 0xed, 0xcd, 0x11, 0xca, 0xb3, 0xe2,
+	0xf2, 0xf0, 0x0b, 0xb8, 0xa6, 0xf1, 0x67, 0x72, 0xc3, 0x5b, 0x30, 0x2d, 0xaa, 0x62, 0x09, 0x5a,
+	0x8b, 0xf1, 0x55, 0x42, 0x8d, 0x23, 0x79, 0xf0, 0x7d, 0x58, 0x90, 0x14, 0xd2, 0x1b, 0x98, 0xce,
+	0x8a, 0xfb, 0x07, 0xef, 0xc2, 0x62, 0x9c, 0x2d, 0x53, 0x88, 0xd4, 0x94, 0xd2, 0xa7, 0xc3, 0xb6,
+	0x86, 0x81, 0xc9, 0x43, 0xd1, 0x1d, 0x96, 0x4b, 0x38, 0x2c, 0x34, 0x48, 0x89, 0xc8, 0x64, 0xd0,
+	0x82, 0x72, 0xff, 0x6e, 0xc7, 0x0f, 0xdf, 0x74, 0xaf, 0x00, 0xe9, 0xc4, 0x4c, 0x87, 0xb2, 0x0e,
+	0x33, 0xc2, 0xe1, 0x2a, 0x99, 0x32, 0x9f, 0x8a, 0x62, 0x62, 0x06, 0xd5, 0xc9, 0x33, 0xcf, 0x3d,
+	0xe9, 0x91, 0x10, 0x73, 0x58, 0x0a, 0xa1, 0x13, 0x33, 0xed, 0xf8, 0x0f, 0xf4, 0xf5, 0x59, 0xeb,
+	0xba, 0x5e, 0x4f, 0x39, 0xff, 0x7d, 0x98, 0x16, 0xb9, 0x89, 0xcc, 0xdf, 0x1f, 0xc4, 0xc5, 0xe8,
+	0xbc, 0x62, 0x50, 0x13, 0x99, 0x8c, 0x5c, 0xc5, 0x0e, 0x4b, 0x36, 0x63, 0xea, 0x89, 0xe6, 0x4c,
+	0x1d, 0xbd, 0x0d, 0x53, 0x2e, 0x5b, 0xc2, 0xef, 0x62, 0x25, 0x99, 0x15, 0x72, 0x69, 0xcd, 0xf3,
+	0x21, 0x71, 0x04, 0x17, 0x7e, 0x0f, 0x4a, 0x9a, 0x06, 0x96, 0xec, 0x3e, 0x6e, 0x34, 0x69, 0x06,
+	0x5c, 0x86, 0xd9, 0xda, 0x56, 0x73, 0xfb, 0x50, 0xe4, 0xc0, 0x15, 0x80, 0x7a, 0x23, 0x1c, 0xe7,
+	0x68, 0x16, 0x24, 0x56, 0xc9, 0x1b, 0xae, 0xdb, 0x63, 0xa5, 0xd9, 0x93, 0xbb, 0x94, 0x3d, 0x2f,
+	0x61, 0x4e, 0x6e, 0x3f, 0x53, 0x0c, 0xbc, 0x43, 0x3d, 0xcc, 0xc4, 0xa8, 0x10, 0x58, 0x36, 0xa8,
+	0x55, 0xb7, 0x53, 0x30, 0x62, 0x9a, 0x3d, 0x1c, 0x04, 0x6e, 0x30, 0xf2, 0x55, 0x08, 0xfc, 0xde,
+	0x82, 0x8a, 0xa2, 0x64, 0xad, 0xde, 0x55, 0x89, 0x24, 0x30, 0x2f, 0x2c, 0x90, 0x6e, 0xc0, 0x74,
+	0xfb, 0xf8, 0xa0, 0xf3, 0x4a, 0x75, 0x31, 0xe4, 0x88, 0xd1, 0xbb, 0x42, 0x8f, 0x68, 0xa1, 0xc9,
+	0x11, 0xcb, 0xbd, 0x59, 0x33, 0x6d, 0xbb, 0xdf, 0x26, 0x2f, 0xf9, 0x9b, 0xb6, 0xe0, 0x44, 0x04,
+	0x9e, 0x2e, 0xcb, 0x56, 0x1b, 0xaf, 0x9f, 0xf4, 0xd6, 0x1b, 0x0d, 0xf2, 0xda, 0x28, 0x38, 0x6d,
+	0xf4, 0x59, 0x97, 0x49, 0xed, 0x70, 0x11, 0x10, 0x23, 0xd6, 0x3b, 0xbe, 0x4e, 0x6d, 0xc0, 0x02,
+	0xa3, 0xd2, 0xb8, 0xa7, 0xc9, 0x74, 0x84, 0x18, 0x0a, 0xb6, 0xad, 0x04, 0x6c, 0xbb, 0xbe, 0xff,
+	0x62, 0xe0, 0xb5, 0xe5, 0xd6, 0xc2, 0x31, 0xae, 0x0b, 0xe1, 0x4f, 0xfd, 0x18, 0x30, 0x7f, 0x5d,
+	0x29, 0x8f, 0x22, 0x29, 0x8f, 0x49, 0x30, 0x41, 0x0a, 0x7e, 0x13, 0xae, 0x2b, 0x4e, 0x59, 0x43,
+	0x4f, 0x60, 0xde, 0x87, 0x5b, 0x8a, 0x79, 0xeb, 0x94, 0x25, 0x7a, 0x4f, 0xa4, 0xc2, 0xff, 0xd6,
+	0xce, 0x4d, 0x58, 0x0a, 0xed, 0xe4, 0x39, 0xc8, 0xa0, 0xab, 0x1b, 0x30, 0xf2, 0x65, 0xcc, 0x50,
+	0x59, 0xec, 0x99, 0xd1, 0x3c, 0xca, 0xa2, 0x5e, 0x82, 0xec, 0x19, 0x6f, 0xc1, 0xb2, 0x92, 0x21,
+	0xb3, 0x83, 0xb8, 0x90, 0x31, 0x83, 0x4c, 0x42, 0xa4, 0xc3, 0xd8, 0xd2, 0xc9, 0x6e, 0xd7, 0x39,
+	0xe3, 0xae, 0xe5, 0x32, 0x2d, 0x4d, 0xa6, 0x74, 0x2d, 0xe3, 0x1c, 0x73, 0xed, 0x18, 0xf3, 0x0f,
+	0x60, 0x35, 0x14, 0xcb, 0x3c, 0xf1, 0x84, 0x86, 0x5f, 0xc7, 0xf7, 0xb5, 0xb2, 0xce, 0xb4, 0x95,
+	0x07, 0x50, 0x18, 0x12, 0x89, 0x12, 0xa5, 0x0d, 0xb4, 0x2e, 0x5a, 0xdc, 0xeb, 0xda, 0x62, 0x3e,
+	0x8f, 0xdb, 0x70, 0x5b, 0x49, 0x17, 0x3e, 0x32, 0x8a, 0x4f, 0x1a, 0xa5, 0x52, 0x7e, 0xe1, 0xa8,
+	0xf1, 0x94, 0x3f, 0x2f, 0x4e, 0x33, 0x6c, 0xde, 0x7d, 0x28, 0x5c, 0xa3, 0x6e, 0x4b, 0x26, 0xf4,
+	0xdf, 0x11, 0xd7, 0x29, 0xbc, 0x64, 0x99, 0x84, 0x1d, 0xc3, 0x62, 0xfc, 0x6e, 0x66, 0x02, 0x26,
+	0x9a, 0xc7, 0x06, 0xd4, 0x85, 0x0a, 0x96, 0xc4, 0x40, 0x19, 0x1c, 0x5e, 0xdc, 0x4c, 0x06, 0xbb,
+	0x91, 0x30, 0x1e, 0x64, 0x59, 0xed, 0x65, 0xa7, 0xa9, 0x32, 0x14, 0x31, 0xc0, 0x7b, 0x70, 0x23,
+	0x79, 0xf1, 0x33, 0x99, 0x7c, 0x28, 0x02, 0xd8, 0x84, 0x0d, 0x99, 0xe4, 0x7e, 0x1c, 0x5d, 0x6f,
+	0x0d, 0x22, 0x32, 0x89, 0x74, 0xc0, 0x36, 0x21, 0xc6, 0xff, 0x22, 0x5e, 0x43, 0x00, 0xc9, 0x24,
+	0xcc, 0x8f, 0x84, 0x65, 0x3f, 0xfe, 0x08, 0x23, 0xf2, 0x13, 0x31, 0x42, 0x06, 0x84, 0x0e, 0x57,
+	0x99, 0x36, 0xf1, 0x49, 0x84, 0x39, 0x63, 0x88, 0x96, 0x49, 0xf0, 0xa7, 0xb0, 0x96, 0x0e, 0x66,
+	0x59, 0x24, 0xbf, 0x81, 0xa1, 0x18, 0xa6, 0x56, 0xda, 0x67, 0xa4, 0x12, 0xcc, 0xec, 0xed, 0x1f,
+	0x3c, 0xa9, 0x6d, 0xd1, 0xa4, 0x6e, 0xe3, 0xcf, 0x79, 0xc8, 0xed, 0x1c, 0xa2, 0x1f, 0xc2, 0x94,
+	0x68, 0x83, 0x4f, 0xf8, 0x4a, 0x60, 0x4f, 0x6a, 0xa8, 0xe3, 0x95, 0x2f, 0xfe, 0xf4, 0xb7, 0xaf,
+	0x72, 0x37, 0xf0, 0xb5, 0xea, 0xd9, 0xbb, 0x6e, 0x77, 0x78, 0xea, 0x56, 0x9f, 0x9f, 0x55, 0x39,
+	0x96, 0x7e, 0xdb, 0x7a, 0x03, 0x1d, 0x42, 0x9e, 0x35, 0xc9, 0x53, 0x3f, 0x21, 0xd8, 0xe9, 0x8d,
+	0x76, 0x6c, 0x73, 0xc9, 0x8b, 0xf8, 0xaa, 0x2e, 0x79, 0x38, 0x0a, 0x98, 0xdc, 0x26, 0x94, 0xb4,
+	0x5e, 0x39, 0xba, 0xf0, 0xe3, 0x82, 0x7d, 0x71, 0x1f, 0x1e, 0x5f, 0x61, 0xd6, 0x36, 0x5f, 0xf6,
+	0x93, 0xd6, 0x46, 0xbd, 0xdd, 0xa4, 0xb5, 0x5a, 0x3f, 0xd5, 0x6c, 0x6d, 0xf0, 0xb2, 0xcf, 0xac,
+	0x1d, 0xc8, 0xee, 0x7d, 0x2b, 0x40, 0xb7, 0x0d, 0xcd, 0x60, 0xbd, 0xed, 0x69, 0xaf, 0xa5, 0x33,
+	0x48, 0x4d, 0x77, 0xb8, 0xa6, 0x9b, 0xf8, 0x86, 0xae, 0xa9, 0x15, 0xf2, 0x51, 0x85, 0x1b, 0xa7,
+	0x30, 0xc5, 0x7b, 0x46, 0xe8, 0x48, 0x3d, 0xd8, 0x86, 0x8e, 0x5a, 0xca, 0xf9, 0xc6, 0xba, 0x4d,
+	0x78, 0x99, 0x6b, 0x5b, 0xc0, 0x95, 0x50, 0x1b, 0x6f, 0x1b, 0x51, 0x2d, 0x8f, 0xac, 0x6f, 0x58,
+	0x1b, 0xff, 0xca, 0xc1, 0x14, 0x6f, 0x2e, 0xa0, 0x21, 0x40, 0xd4, 0x85, 0x49, 0xee, 0x73, 0xac,
+	0xaf, 0x93, 0xdc, 0xe7, 0x78, 0x03, 0x07, 0xdf, 0xe6, 0x9a, 0x97, 0xf1, 0x62, 0xa8, 0x99, 0x7f,
+	0xe6, 0xab, 0x9e, 0x30, 0x2e, 0xe6, 0xd6, 0x17, 0x50, 0xd2, 0xba, 0x29, 0xc8, 0x24, 0x31, 0xd6,
+	0x8e, 0x49, 0x06, 0x81, 0xa1, 0x15, 0x83, 0xef, 0x72, 0xa5, 0xb7, 0xf0, 0x92, 0xee, 0x5c, 0xa1,
+	0xd7, 0xe3, 0x9c, 0x4c, 0xf1, 0x8f, 0x69, 0x71, 0x10, 0xef, 0xa8, 0xa0, 0xbb, 0x06, 0xd1, 0xc9,
+	0xc6, 0x8c, 0x7d, 0x6f, 0x32, 0x53, 0xaa, 0x09, 0x42, 0xff, 0x73, 0xca, 0xe9, 0x32, 0x4e, 0xe5,
+	0xfb, 0x7f, 0xb3, 0xaf, 0x42, 0xe2, 0xab, 0x3d, 0x0a, 0xa0, 0x18, 0xf6, 0x35, 0xd0, 0xaa, 0xa9,
+	0xe6, 0x8d, 0x12, 0x42, 0xfb, 0x76, 0xea, 0xbc, 0x34, 0xe1, 0x01, 0x37, 0x61, 0x0d, 0xdf, 0x0c,
+	0x4d, 0x90, 0xbf, 0x0e, 0xa8, 0x8a, 0xd2, 0xae, 0xea, 0xb6, 0xdb, 0xcc, 0x11, 0x3f, 0xa2, 0xc5,
+	0xad, 0xde, 0xae, 0x40, 0x77, 0x8c, 0xd5, 0xb6, 0xde, 0xf1, 0xb0, 0xf1, 0x24, 0x16, 0xa9, 0xff,
+	0x75, 0xae, 0xff, 0x2e, 0x5e, 0x4d, 0xd3, 0xef, 0x71, 0xfe, 0xb8, 0x09, 0xa2, 0x41, 0x61, 0x36,
+	0x21, 0xd6, 0xff, 0x30, 0x9b, 0x10, 0xef, 0x6f, 0x5c, 0x6c, 0xc2, 0x88, 0xf3, 0x33, 0x13, 0x5e,
+	0x02, 0x44, 0xfd, 0x0b, 0x64, 0x74, 0xae, 0xd6, 0xee, 0x48, 0x46, 0xfe, 0x78, 0xeb, 0x03, 0x3f,
+	0xe4, 0xba, 0xef, 0xe0, 0x95, 0x34, 0xdd, 0x5d, 0xca, 0xcd, 0xee, 0xf9, 0x6f, 0x0a, 0x50, 0xfa,
+	0xc8, 0xed, 0xf4, 0x03, 0xd2, 0x67, 0x6d, 0x59, 0x44, 0x60, 0x8a, 0x23, 0x7f, 0xf2, 0xba, 0xeb,
+	0x4d, 0x85, 0xe4, 0x75, 0x8f, 0x55, 0xdc, 0x86, 0xe0, 0x63, 0x1f, 0x08, 0x02, 0x26, 0xbd, 0xca,
+	0x6b, 0x65, 0xb6, 0xe1, 0x0e, 0x4c, 0x8b, 0xda, 0x18, 0x25, 0x64, 0xc5, 0x6a, 0x68, 0x7b, 0xc5,
+	0x3c, 0x29, 0x35, 0xdd, 0xe3, 0x9a, 0x56, 0xf1, 0xb2, 0x41, 0x93, 0xcf, 0x59, 0x99, 0xaa, 0x73,
+	0x80, 0xa8, 0x15, 0x93, 0xf4, 0xed, 0x58, 0xe7, 0xc6, 0x5e, 0x4b, 0x67, 0x90, 0x6a, 0x1f, 0x71,
+	0xb5, 0x18, 0xdf, 0x32, 0xa8, 0x6d, 0x87, 0xec, 0x4c, 0xb5, 0x0b, 0x05, 0xf6, 0xb5, 0x07, 0x25,
+	0x40, 0x5f, 0xfb, 0x20, 0x64, 0xdb, 0xa6, 0x29, 0xa9, 0x08, 0x73, 0x45, 0x2b, 0xf8, 0x35, 0x83,
+	0x22, 0xf6, 0xcd, 0x87, 0xa9, 0xf0, 0x61, 0x56, 0x7d, 0xe2, 0x41, 0xb7, 0x12, 0xde, 0x8a, 0x7f,
+	0x0e, 0xb2, 0x57, 0xd3, 0xa6, 0x53, 0xaf, 0xac, 0xe6, 0x4e, 0xc9, 0x4c, 0x55, 0x52, 0xd8, 0xf8,
+	0x59, 0x05, 0x0a, 0x2c, 0xf3, 0x60, 0x88, 0x1d, 0x15, 0x3a, 0x49, 0xdf, 0x8e, 0x35, 0x0c, 0x92,
+	0xbe, 0x1d, 0xaf, 0x91, 0x0c, 0x88, 0xcd, 0x7f, 0xb1, 0x44, 0x38, 0x17, 0xdb, 0x6f, 0x00, 0x25,
+	0xad, 0x1c, 0x42, 0x06, 0x89, 0xf1, 0x76, 0x44, 0x12, 0xb1, 0x0d, 0xb5, 0x14, 0x5e, 0xe3, 0x4a,
+	0x6d, 0x7c, 0x3d, 0xae, 0xb4, 0x2d, 0xd8, 0x98, 0xd6, 0x33, 0x28, 0xeb, 0x75, 0x13, 0x32, 0x08,
+	0x4d, 0xf4, 0x3b, 0x92, 0x08, 0x61, 0x2a, 0xbb, 0x2e, 0xde, 0xed, 0x67, 0x30, 0x23, 0xeb, 0x28,
+	0xd3, 0x4e, 0xe3, 0xbd, 0x11, 0xd3, 0x4e, 0x13, 0x45, 0x98, 0xe1, 0xc5, 0xcf, 0x15, 0xb2, 0x96,
+	0x82, 0x02, 0x64, 0xa9, 0x92, 0xa6, 0xdb, 0x69, 0x2a, 0xa3, 0x6a, 0x3f, 0x4d, 0xa5, 0x96, 0xab,
+	0x4f, 0x54, 0x79, 0x42, 0xf8, 0x35, 0xf9, 0x1c, 0x20, 0xaa, 0xbe, 0x92, 0xef, 0x41, 0x63, 0x53,
+	0x26, 0xf9, 0x1e, 0x34, 0x17, 0x70, 0x06, 0x80, 0x88, 0x74, 0x8b, 0x5f, 0x5a, 0x30, 0xf5, 0x3f,
+	0xb7, 0x00, 0x8d, 0x57, 0x6b, 0xe8, 0x4d, 0xb3, 0x0a, 0x63, 0xbf, 0xc7, 0x7e, 0xeb, 0x72, 0xcc,
+	0xa9, 0x37, 0x2d, 0xb2, 0xab, 0xc5, 0x97, 0x0c, 0x5f, 0x30, 0xcb, 0xbe, 0xb4, 0x60, 0x2e, 0x56,
+	0xef, 0xa1, 0x07, 0x29, 0x0e, 0x4f, 0xf4, 0x8c, 0xec, 0x87, 0x17, 0xf2, 0xa5, 0xa2, 0xb5, 0x76,
+	0x3c, 0x2a, 0x4d, 0xfa, 0x09, 0xcd, 0x56, 0xe2, 0x45, 0x22, 0x4a, 0x51, 0x30, 0xd6, 0x78, 0xb2,
+	0x1f, 0x5d, 0xcc, 0x78, 0x89, 0xd3, 0x8a, 0x32, 0x27, 0x1a, 0x9f, 0xb2, 0xb6, 0x34, 0xc5, 0x67,
+	0xbc, 0x6f, 0x65, 0x8a, 0xcf, 0x44, 0x61, 0x9a, 0x16, 0x9f, 0xac, 0x37, 0xa0, 0x5d, 0x09, 0x59,
+	0x81, 0xa6, 0xa9, 0x9c, 0x7c, 0x25, 0x12, 0xe5, 0xeb, 0x44, 0x95, 0xd1, 0x95, 0x88, 0xea, 0x4f,
+	0xd3, 0x95, 0x18, 0x6b, 0xa6, 0x99, 0xae, 0xc4, 0x78, 0x09, 0x9b, 0xe6, 0x64, 0xae, 0x3b, 0x76,
+	0x25, 0x16, 0x0c, 0xf5, 0x2a, 0x7a, 0x2b, 0x65, 0x73, 0xc6, 0x46, 0x9d, 0xfd, 0xf6, 0x25, 0xb9,
+	0x27, 0x87, 0xa2, 0x70, 0x8b, 0x0a, 0xc5, 0x5f, 0x59, 0xb0, 0x68, 0x2a, 0x78, 0x51, 0x8a, 0xb2,
+	0x94, 0x2e, 0x9f, 0xbd, 0x7e, 0x59, 0xf6, 0x4b, 0xf8, 0x2d, 0x0c, 0xce, 0xcd, 0xf2, 0xef, 0xfe,
+	0xba, 0x6a, 0xfd, 0x91, 0xfe, 0xfb, 0x0b, 0xfd, 0x77, 0x3c, 0xcd, 0x7f, 0x3e, 0xfb, 0xee, 0x7f,
+	0x02, 0x00, 0x00, 0xff, 0xff, 0x25, 0xe0, 0x88, 0x66, 0xc5, 0x2b, 0x00, 0x00,
 }

+ 1719 - 0
etcdserver/etcdserverpb/rpc.pb.gw.go

@@ -0,0 +1,1719 @@
+// Code generated by protoc-gen-grpc-gateway
+// source: etcdserver/etcdserverpb/rpc.proto
+// DO NOT EDIT!
+
+/*
+Package etcdserverpb is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package etcdserverpb
+
+import (
+	"io"
+	"net/http"
+
+	"github.com/gengo/grpc-gateway/runtime"
+	"github.com/gengo/grpc-gateway/utilities"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/grpclog"
+)
+
+var _ codes.Code
+var _ io.Reader
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+
+func request_KV_Range_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq RangeRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq PutRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_Txn_0(ctx context.Context, marshaler runtime.Marshaler, client KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq TxnRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 KVClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq CompactionRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 WatchClient, req *http.Request, pathParams map[string]string) (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 WatchRequest
+		err = dec.Decode(&protoReq)
+		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 err := stream.CloseSend(); err != nil {
+			grpclog.Printf("Failed to terminate client stream: %v", err)
+		}
+		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 LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq LeaseGrantRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 LeaseClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq LeaseRevokeRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 LeaseClient, req *http.Request, pathParams map[string]string) (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 LeaseKeepAliveRequest
+		err = dec.Decode(&protoReq)
+		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 err := stream.CloseSend(); err != nil {
+			grpclog.Printf("Failed to terminate client stream: %v", err)
+		}
+		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_Cluster_MemberAdd_0(ctx context.Context, marshaler runtime.Marshaler, client ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq MemberAddRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq MemberRemoveRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq MemberUpdateRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 ClusterClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq MemberListRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_Maintenance_Alarm_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AlarmRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq StatusRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq DefragmentRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 MaintenanceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq HashRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_Snapshot_0(ctx context.Context, marshaler runtime.Marshaler, client MaintenanceClient, req *http.Request, pathParams map[string]string) (Maintenance_SnapshotClient, runtime.ServerMetadata, error) {
+	var protoReq SnapshotRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_Auth_AuthEnable_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthEnableRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthDisableRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthenticateRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserAddRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserGetRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_UserDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserDeleteRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserChangePasswordRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserGrantRoleRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthUserRevokeRoleRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleAddRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleGetRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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_RoleDelete_0(ctx context.Context, marshaler runtime.Marshaler, client AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleDeleteRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleGrantPermissionRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 AuthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq AuthRoleRevokePermissionRequest
+	var metadata runtime.ServerMetadata
+
+	if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
+		return nil, metadata, grpc.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 {
+	client := NewKVClient(conn)
+
+	mux.Handle("POST", pattern_KV_Range_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_KV_Range_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_KV_Range_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_KV_Put_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_KV_Put_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_KV_Txn_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_KV_Txn_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_KV_Compact_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_KV_Compact_0(ctx, 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{"v3alpha", "kv", "range"}, ""))
+
+	pattern_KV_Put_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "put"}, ""))
+
+	pattern_KV_Txn_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "txn"}, ""))
+
+	pattern_KV_Compact_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "kv", "compaction"}, ""))
+)
+
+var (
+	forward_KV_Range_0 = runtime.ForwardResponseMessage
+
+	forward_KV_Put_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 {
+	client := NewWatchClient(conn)
+
+	mux.Handle("POST", pattern_Watch_Watch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Watch_Watch_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Watch_Watch_0(ctx, 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{"v3alpha", "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 {
+	client := NewLeaseClient(conn)
+
+	mux.Handle("POST", pattern_Lease_LeaseGrant_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Lease_LeaseGrant_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Lease_LeaseGrant_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Lease_LeaseRevoke_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Lease_LeaseRevoke_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Lease_LeaseKeepAlive_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Lease_LeaseKeepAlive_0(ctx, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_Lease_LeaseGrant_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "lease", "grant"}, ""))
+
+	pattern_Lease_LeaseRevoke_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "kv", "lease", "revoke"}, ""))
+
+	pattern_Lease_LeaseKeepAlive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "lease", "keepalive"}, ""))
+)
+
+var (
+	forward_Lease_LeaseGrant_0 = runtime.ForwardResponseMessage
+
+	forward_Lease_LeaseRevoke_0 = runtime.ForwardResponseMessage
+
+	forward_Lease_LeaseKeepAlive_0 = runtime.ForwardResponseStream
+)
+
+// 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 {
+	client := NewClusterClient(conn)
+
+	mux.Handle("POST", pattern_Cluster_MemberAdd_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Cluster_MemberAdd_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Cluster_MemberAdd_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Cluster_MemberRemove_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Cluster_MemberRemove_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Cluster_MemberUpdate_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Cluster_MemberUpdate_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Cluster_MemberList_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Cluster_MemberList_0(ctx, 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{"v3alpha", "cluster", "member", "add"}, ""))
+
+	pattern_Cluster_MemberRemove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "remove"}, ""))
+
+	pattern_Cluster_MemberUpdate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "update"}, ""))
+
+	pattern_Cluster_MemberList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "cluster", "member", "list"}, ""))
+)
+
+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
+)
+
+// 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 {
+	client := NewMaintenanceClient(conn)
+
+	mux.Handle("POST", pattern_Maintenance_Alarm_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Maintenance_Alarm_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Maintenance_Alarm_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Maintenance_Status_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Maintenance_Status_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Maintenance_Defragment_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Maintenance_Defragment_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Maintenance_Hash_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Maintenance_Hash_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Maintenance_Snapshot_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Maintenance_Snapshot_0(ctx, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
+
+	})
+
+	return nil
+}
+
+var (
+	pattern_Maintenance_Alarm_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintance", "alarm"}, ""))
+
+	pattern_Maintenance_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintance", "status"}, ""))
+
+	pattern_Maintenance_Defragment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintance", "defragment"}, ""))
+
+	pattern_Maintenance_Hash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintance", "hash"}, ""))
+
+	pattern_Maintenance_Snapshot_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "maintance", "snapshot"}, ""))
+)
+
+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_Snapshot_0 = runtime.ForwardResponseStream
+)
+
+// 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 {
+	client := NewAuthClient(conn)
+
+	mux.Handle("POST", pattern_Auth_AuthEnable_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_AuthEnable_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_AuthEnable_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_AuthDisable_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_AuthDisable_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_Authenticate_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_Authenticate_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserAdd_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserAdd_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserGet_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserGet_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserDelete_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserDelete_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserChangePassword_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserChangePassword_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserGrantRole_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserGrantRole_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_UserRevokeRole_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_UserRevokeRole_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleAdd_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleAdd_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleGet_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleGet_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleDelete_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleDelete_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleGrantPermission_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleGrantPermission_0(ctx, 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(ctx)
+		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, req)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+		}
+		resp, md, err := request_Auth_RoleRevokePermission_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Auth_RoleRevokePermission_0(ctx, 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{"v3alpha", "auth", "enable"}, ""))
+
+	pattern_Auth_AuthDisable_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "auth", "disable"}, ""))
+
+	pattern_Auth_Authenticate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v3alpha", "auth", "enable"}, ""))
+
+	pattern_Auth_UserAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "add"}, ""))
+
+	pattern_Auth_UserGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "get"}, ""))
+
+	pattern_Auth_UserDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "delete"}, ""))
+
+	pattern_Auth_UserChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "changepw"}, ""))
+
+	pattern_Auth_UserGrantRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "grant"}, ""))
+
+	pattern_Auth_UserRevokeRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "user", "revoke"}, ""))
+
+	pattern_Auth_RoleAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "add"}, ""))
+
+	pattern_Auth_RoleGet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "get"}, ""))
+
+	pattern_Auth_RoleDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "delete"}, ""))
+
+	pattern_Auth_RoleGrantPermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "auth", "role", "grant"}, ""))
+
+	pattern_Auth_RoleRevokePermission_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v3alpha", "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_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_RoleDelete_0 = runtime.ForwardResponseMessage
+
+	forward_Auth_RoleGrantPermission_0 = runtime.ForwardResponseMessage
+
+	forward_Auth_RoleRevokePermission_0 = runtime.ForwardResponseMessage
+)

+ 189 - 31
etcdserver/etcdserverpb/rpc.proto

@@ -5,17 +5,30 @@ 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) {}
+  rpc Range(RangeRequest) returns (RangeResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/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) {}
+  rpc Put(PutRequest) returns (PutResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/kv/put"
+        body: "*"
+    };
+  }
 
   // DeleteRange deletes the given range from the key-value store.
   // A delete request increments the revision of the key-value store
@@ -26,12 +39,22 @@ service KV {
   // 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) {}
+  rpc Txn(TxnRequest) returns (TxnResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/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) {}
+  rpc Compact(CompactionRequest) returns (CompactionResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/kv/compaction"
+        body: "*"
+    };
+  }
 }
 
 service Watch {
@@ -40,21 +63,41 @@ service Watch {
   // 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) {}
+  rpc Watch(stream WatchRequest) returns (stream WatchResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/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) {}
+  rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/lease/grant"
+        body: "*"
+    };
+  }
 
   // LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.
-  rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {}
+  rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/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) {}
+  rpc LeaseKeepAlive(stream LeaseKeepAliveRequest) returns (stream LeaseKeepAliveResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/lease/keepalive"
+        body: "*"
+    };
+  }
 
   // TODO(xiangli) List all existing Leases?
   // TODO(xiangli) Get details information (expirations, leased keys, etc.) of a lease?
@@ -62,79 +105,194 @@ service Lease {
 
 service Cluster {
   // MemberAdd adds a member into the cluster.
-  rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {}
+  rpc MemberAdd(MemberAddRequest) returns (MemberAddResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/cluster/member/add"
+        body: "*"
+    };
+  }
 
   // MemberRemove removes an existing member from the cluster.
-  rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {}
+  rpc MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/cluster/member/remove"
+        body: "*"
+    };
+  }
 
   // MemberUpdate updates the member configuration.
-  rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {}
+  rpc MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/cluster/member/update"
+        body: "*"
+    };
+  }
 
   // MemberList lists all the members in the cluster.
-  rpc MemberList(MemberListRequest) returns (MemberListResponse) {}
+  rpc MemberList(MemberListRequest) returns (MemberListResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/cluster/member/list"
+        body: "*"
+    };
+  }
 }
 
 service Maintenance {
   // Alarm activates, deactivates, and queries alarms regarding cluster health.
-  rpc Alarm(AlarmRequest) returns (AlarmResponse) {}
+  rpc Alarm(AlarmRequest) returns (AlarmResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/maintenance/alarm"
+        body: "*"
+    };
+  }
 
   // Status gets the status of the member.
-  rpc Status(StatusRequest) returns (StatusResponse) {}
+  rpc Status(StatusRequest) returns (StatusResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/maintenance/status"
+        body: "*"
+    };
+  }
 
   // Defragment defragments a member's backend database to recover storage space.
-  rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {}
+  rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/maintenance/defragment"
+        body: "*"
+    };
+  }
 
   // Hash returns the hash of the local KV state for consistency checking purpose.
   // This is designed for testing; do not use this in production when there
   // are ongoing transactions.
-  rpc Hash(HashRequest) returns (HashResponse) {}
+  rpc Hash(HashRequest) returns (HashResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/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) {}
+  rpc Snapshot(SnapshotRequest) returns (stream SnapshotResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/maintenance/snapshot"
+        body: "*"
+    };
+  }
 }
 
 service Auth {
   // AuthEnable enables authentication.
-  rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {}
+  rpc AuthEnable(AuthEnableRequest) returns (AuthEnableResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/enable"
+        body: "*"
+    };
+  }
 
   // AuthDisable disables authentication.
-  rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {}
+  rpc AuthDisable(AuthDisableRequest) returns (AuthDisableResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/disable"
+        body: "*"
+    };
+  }
 
   // Authenticate processes an authenticate request.
-  rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
+  rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/authenticate"
+        body: "*"
+    };
+  }
 
   // UserAdd adds a new user.
-  rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {}
+  rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/add"
+        body: "*"
+    };
+  }
 
   // UserGet gets detailed user information or lists all users.
-  rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {}
+  rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/get"
+        body: "*"
+    };
+  }
 
   // UserDelete deletes a specified user.
-  rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {}
+  rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/delete"
+        body: "*"
+    };
+  }
 
   // UserChangePassword changes the password of a specified user.
-  rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {}
+  rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/changepw"
+        body: "*"
+    };
+  }
 
   // UserGrant grants a role to a specified user.
-  rpc UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse) {}
+  rpc UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/grant"
+        body: "*"
+    };
+  }
 
   // UserRevokeRole revokes a role of specified user.
-  rpc UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse) {}
+  rpc UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/user/revoke"
+        body: "*"
+    };
+  }
 
   // RoleAdd adds a new role.
-  rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {}
+  rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/add"
+        body: "*"
+    };
+  }
 
   // RoleGet gets detailed role information or lists all roles.
-  rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {}
+  rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/get"
+        body: "*"
+    };
+  }
 
   // RoleDelete deletes a specified role.
-  rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {}
+  rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/delete"
+        body: "*"
+    };
+  }
 
   // RoleGrantPermission grants a permission of a specified key or range to a specified role.
-  rpc RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) {}
+  rpc RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/grant"
+        body: "*"
+    };
+  }
 
   // RoleRevokePermission revokes a key or range permission of a specified role.
-  rpc RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse) {}
+  rpc RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse) {
+      option (google.api.http) = {
+        post: "/v3alpha/auth/role/revoke"
+        body: "*"
+    };
+  }
 }
 
 message ResponseHeader {

+ 4 - 4
lease/leasepb/lease.pb.go

@@ -319,13 +319,13 @@ var (
 )
 
 var fileDescriptorLease = []byte{
-	// 122 bytes of a gzipped FileDescriptorProto
+	// 117 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 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, 0x49, 0x93, 0x8b, 0xd5, 0x07, 0xa4,
 	0x40, 0x88, 0x8f, 0x8b, 0xc9, 0xd3, 0x45, 0x82, 0x51, 0x81, 0x51, 0x83, 0x39, 0x88, 0x29, 0xd3,
 	0x45, 0x48, 0x80, 0x8b, 0x39, 0x24, 0xc4, 0x47, 0x82, 0x09, 0x2c, 0xc0, 0x5c, 0x12, 0xe2, 0xe3,
-	0x24, 0x72, 0xe2, 0xa1, 0x1c, 0xc3, 0x85, 0x87, 0x72, 0x0c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78,
-	0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0x63, 0x12, 0x1b, 0xd8, 0x1c, 0x63, 0x40, 0x00, 0x00, 0x00,
-	0xff, 0xff, 0x8c, 0x1d, 0x92, 0xdc, 0x75, 0x00, 0x00, 0x00,
+	0x24, 0x72, 0xe2, 0xa1, 0x1c, 0xc3, 0x05, 0x20, 0x3e, 0xf1, 0x48, 0x8e, 0xf1, 0x02, 0x10, 0x3f,
+	0x00, 0xe2, 0x24, 0x36, 0xb0, 0x39, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x1d, 0x92,
+	0xdc, 0x75, 0x00, 0x00, 0x00,
 }

+ 19 - 19
mvcc/mvccpb/kv.pb.go

@@ -659,23 +659,23 @@ var (
 )
 
 var fileDescriptorKv = []byte{
-	// 279 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x44, 0x90, 0x41, 0x4a, 0xc3, 0x40,
-	0x14, 0x86, 0x3b, 0x49, 0x93, 0xd6, 0xd7, 0x52, 0xc3, 0x10, 0x30, 0xb8, 0x08, 0x31, 0x1b, 0x0b,
-	0x42, 0x84, 0x7a, 0x03, 0x31, 0x2b, 0x5d, 0xc8, 0x10, 0xdd, 0x4a, 0x9a, 0x3e, 0x4a, 0x49, 0xd3,
-	0x09, 0x69, 0x1c, 0xcc, 0xa5, 0x3c, 0x47, 0x97, 0x3d, 0x82, 0xcd, 0x49, 0x24, 0x6f, 0x4c, 0xdd,
-	0x0c, 0xef, 0xff, 0xff, 0x6f, 0x98, 0xff, 0x0d, 0x8c, 0x73, 0x15, 0x95, 0x95, 0xac, 0x25, 0xb7,
-	0x0b, 0x95, 0x65, 0xe5, 0xf2, 0xda, 0x5d, 0xcb, 0xb5, 0x24, 0xeb, 0xbe, 0x9b, 0x74, 0x1a, 0x7e,
-	0x33, 0x18, 0x3f, 0x63, 0xf3, 0x9e, 0x6e, 0x3f, 0x91, 0x3b, 0x60, 0xe6, 0xd8, 0x78, 0x2c, 0x60,
-	0xf3, 0xa9, 0xe8, 0x46, 0x7e, 0x0b, 0x97, 0x59, 0x85, 0x69, 0x8d, 0x1f, 0x15, 0xaa, 0xcd, 0x7e,
-	0x23, 0x77, 0x9e, 0x11, 0xb0, 0xb9, 0x29, 0x66, 0xda, 0x16, 0x7f, 0x2e, 0xbf, 0x81, 0x69, 0x21,
-	0x57, 0xff, 0x94, 0x49, 0xd4, 0xa4, 0x90, 0xab, 0x33, 0xe2, 0xc1, 0x48, 0x61, 0x45, 0xe9, 0x90,
-	0xd2, 0x5e, 0x72, 0x17, 0x2c, 0xd5, 0x15, 0xf0, 0x2c, 0x7a, 0x59, 0x8b, 0xce, 0xdd, 0x62, 0xba,
-	0x47, 0xcf, 0x26, 0x5a, 0x8b, 0xf0, 0x0b, 0xac, 0x58, 0xe1, 0xae, 0xe6, 0x77, 0x30, 0xac, 0x9b,
-	0x12, 0xa9, 0xed, 0x6c, 0x71, 0x15, 0xe9, 0x35, 0x23, 0x0a, 0xf5, 0x99, 0x34, 0x25, 0x0a, 0x82,
-	0x78, 0x00, 0x46, 0xae, 0xa8, 0xfa, 0x64, 0xe1, 0xf4, 0x68, 0xbf, 0xb7, 0x30, 0x72, 0x15, 0x06,
-	0x70, 0x71, 0xbe, 0xc4, 0x47, 0x60, 0xbe, 0xbe, 0x25, 0xce, 0x80, 0x03, 0xd8, 0x4f, 0xf1, 0x4b,
-	0x9c, 0xc4, 0x0e, 0x7b, 0x74, 0x0f, 0x27, 0x7f, 0x70, 0x3c, 0xf9, 0x83, 0x43, 0xeb, 0xb3, 0x63,
-	0xeb, 0xb3, 0x9f, 0xd6, 0x67, 0x4b, 0x9b, 0xfe, 0xf1, 0xe1, 0x37, 0x00, 0x00, 0xff, 0xff, 0x71,
-	0xd2, 0x34, 0xa9, 0x71, 0x01, 0x00, 0x00,
+	// 274 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x44, 0x90, 0xc1, 0x4a, 0xc3, 0x40,
+	0x10, 0x86, 0xbb, 0x4d, 0x93, 0xd6, 0x69, 0xa9, 0x61, 0x09, 0xb8, 0x78, 0x28, 0x31, 0x17, 0x05,
+	0x21, 0x42, 0x7d, 0x03, 0x31, 0x27, 0x3d, 0xc8, 0x12, 0xbd, 0x4a, 0x1a, 0x87, 0x52, 0xd2, 0x76,
+	0x43, 0x1a, 0x17, 0xf3, 0x52, 0x3e, 0x47, 0x8f, 0x7d, 0x04, 0xf5, 0x49, 0xdc, 0xcc, 0x9a, 0x7a,
+	0x98, 0x65, 0xe6, 0xff, 0xfe, 0x65, 0xff, 0x59, 0x18, 0x15, 0x3a, 0x2e, 0x2b, 0x55, 0x2b, 0xee,
+	0x6d, 0x74, 0x9e, 0x97, 0x8b, 0xf3, 0x60, 0xa9, 0x96, 0x8a, 0xa4, 0x9b, 0xb6, 0xb3, 0x34, 0xfa,
+	0x64, 0x30, 0x7a, 0xc0, 0xe6, 0x25, 0x5b, 0xbf, 0x23, 0xf7, 0xc1, 0x29, 0xb0, 0x11, 0x2c, 0x64,
+	0x57, 0x13, 0xd9, 0xb6, 0xfc, 0x12, 0x4e, 0xf3, 0x0a, 0xb3, 0x1a, 0x5f, 0x2b, 0xd4, 0xab, 0xdd,
+	0x4a, 0x6d, 0x45, 0xdf, 0x50, 0x47, 0x4e, 0xad, 0x2c, 0xff, 0x54, 0x7e, 0x01, 0x93, 0x8d, 0x7a,
+	0xfb, 0x77, 0x39, 0xe4, 0x1a, 0x1b, 0xed, 0x68, 0x11, 0x30, 0xd4, 0x58, 0x11, 0x1d, 0x10, 0xed,
+	0x46, 0x1e, 0x80, 0xab, 0xdb, 0x00, 0xc2, 0xa5, 0x97, 0xed, 0xd0, 0xaa, 0x6b, 0xcc, 0x76, 0x28,
+	0x3c, 0x72, 0xdb, 0x21, 0xfa, 0x00, 0x37, 0xd1, 0xb8, 0xad, 0xf9, 0x35, 0x0c, 0xea, 0xa6, 0x44,
+	0x4a, 0x3b, 0x9d, 0x9f, 0xc5, 0x76, 0xcd, 0x98, 0xa0, 0x3d, 0x53, 0x83, 0x25, 0x99, 0x78, 0x08,
+	0xfd, 0x42, 0x53, 0xf4, 0xf1, 0xdc, 0xef, 0xac, 0xdd, 0xde, 0xd2, 0xb0, 0x28, 0x84, 0x93, 0xe3,
+	0x25, 0x3e, 0x04, 0xe7, 0xe9, 0x39, 0xf5, 0x7b, 0x1c, 0xc0, 0xbb, 0x4f, 0x1e, 0x93, 0x34, 0xf1,
+	0xd9, 0x5d, 0xb0, 0xff, 0x9e, 0xf5, 0x0e, 0xa6, 0xf6, 0x3f, 0x33, 0x76, 0x30, 0xf5, 0x65, 0x6a,
+	0xe1, 0xd1, 0x3f, 0xde, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x71, 0xd2, 0x34, 0xa9, 0x71, 0x01,
+	0x00, 0x00,
 }

+ 47 - 48
raft/raftpb/raft.pb.go

@@ -1788,52 +1788,51 @@ var (
 )
 
 var fileDescriptorRaft = []byte{
-	// 746 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x53, 0xc1, 0x6e, 0xdb, 0x38,
-	0x10, 0xb5, 0x64, 0xd9, 0xb2, 0x47, 0x89, 0xc3, 0x30, 0xde, 0x05, 0x11, 0x04, 0x5e, 0xaf, 0xb1,
-	0x07, 0x23, 0x8b, 0x64, 0x77, 0x7d, 0xd8, 0x43, 0x6f, 0x89, 0x5d, 0x20, 0x01, 0xea, 0xa0, 0x75,
-	0x9c, 0x1e, 0x5a, 0x14, 0x05, 0x63, 0xd1, 0xb2, 0xdb, 0x48, 0x14, 0x28, 0x3a, 0x4d, 0x2e, 0x45,
-	0x81, 0x1e, 0x7a, 0xe9, 0x87, 0xe5, 0x98, 0x2f, 0x28, 0x9a, 0x7c, 0x49, 0x41, 0x8a, 0xb2, 0xa5,
-	0xf8, 0x46, 0xbe, 0x37, 0x9c, 0x79, 0xf3, 0x66, 0x08, 0x20, 0xe8, 0x54, 0x1e, 0xc6, 0x82, 0x4b,
-	0x8e, 0xab, 0xea, 0x1c, 0x5f, 0xee, 0x36, 0x03, 0x1e, 0x70, 0x0d, 0xfd, 0xa3, 0x4e, 0x29, 0xdb,
-	0xf9, 0x0c, 0x95, 0xe7, 0x91, 0x14, 0xb7, 0xf8, 0x6f, 0x70, 0xc6, 0xb7, 0x31, 0x23, 0x56, 0xdb,
-	0xea, 0x36, 0x7a, 0xdb, 0x87, 0xe9, 0xab, 0x43, 0x4d, 0x2a, 0xe2, 0xd8, 0xb9, 0xfb, 0xf1, 0x47,
-	0x69, 0xe4, 0xc8, 0xdb, 0x98, 0x61, 0x02, 0xce, 0x98, 0x89, 0x90, 0xd8, 0x6d, 0xab, 0xeb, 0x2c,
-	0x19, 0x26, 0x42, 0xbc, 0x0b, 0x95, 0xd3, 0xc8, 0x67, 0x37, 0xa4, 0x9c, 0xa3, 0x2a, 0x73, 0x05,
-	0x61, 0x0c, 0xce, 0x80, 0x4a, 0x4a, 0x9c, 0xb6, 0xd5, 0xdd, 0x18, 0x39, 0x3e, 0x95, 0xb4, 0xf3,
-	0xc5, 0x02, 0x74, 0x1e, 0xd1, 0x38, 0x99, 0x71, 0x39, 0x64, 0x92, 0x2a, 0x10, 0xff, 0x0f, 0x30,
-	0xe1, 0xd1, 0xf4, 0x7d, 0x22, 0xa9, 0x4c, 0x15, 0x79, 0x2b, 0x45, 0x7d, 0x1e, 0x4d, 0xcf, 0x15,
-	0x61, 0x92, 0xd7, 0x27, 0x19, 0xa0, 0x8a, 0xeb, 0x4a, 0x05, 0x5d, 0xa6, 0x38, 0x01, 0x2d, 0xb0,
-	0xa0, 0x4b, 0x23, 0x9d, 0x37, 0x50, 0xcb, 0x14, 0x28, 0x89, 0x4a, 0x81, 0xae, 0x69, 0x24, 0xe2,
-	0x67, 0x50, 0x0b, 0x8d, 0x32, 0x9d, 0xd8, 0xeb, 0x91, 0x4c, 0xcb, 0x53, 0xe5, 0x26, 0xef, 0x32,
-	0xbe, 0xf3, 0xb5, 0x0c, 0xee, 0x90, 0x25, 0x09, 0x0d, 0x18, 0x3e, 0x00, 0x6d, 0x9e, 0x71, 0x78,
-	0x27, 0xcb, 0x61, 0xe8, 0x35, 0x8f, 0x9b, 0x60, 0x4b, 0x5e, 0xe8, 0xc4, 0x96, 0x5c, 0xb5, 0x31,
-	0x15, 0xfc, 0x49, 0x1b, 0x0a, 0x59, 0x36, 0xe8, 0xac, 0xcd, 0xa4, 0x05, 0xee, 0x15, 0x0f, 0xf4,
-	0xc0, 0x2a, 0x39, 0x32, 0x03, 0x57, 0xb6, 0x55, 0xd7, 0x6d, 0x3b, 0x00, 0x97, 0x45, 0x52, 0xcc,
-	0x59, 0x42, 0xdc, 0x76, 0xb9, 0xeb, 0xf5, 0x36, 0x0b, 0x9b, 0x91, 0xa5, 0x32, 0x31, 0x78, 0x0f,
-	0xaa, 0x13, 0x1e, 0x86, 0x73, 0x49, 0x6a, 0xb9, 0x5c, 0x06, 0xc3, 0x3d, 0xa8, 0x25, 0xc6, 0x31,
-	0x52, 0xd7, 0x4e, 0xa2, 0xa7, 0x4e, 0x66, 0x0e, 0x66, 0x71, 0x2a, 0xa3, 0x60, 0x1f, 0xd8, 0x44,
-	0x12, 0x68, 0x5b, 0xdd, 0x5a, 0x96, 0x31, 0xc5, 0xf0, 0x5f, 0x00, 0xe9, 0xe9, 0x64, 0x1e, 0x49,
-	0xe2, 0xe5, 0x6a, 0xe6, 0xf0, 0xce, 0x3b, 0xa8, 0x9f, 0x50, 0xe1, 0xa7, 0x4b, 0x92, 0xf9, 0x64,
-	0xad, 0xf9, 0x44, 0xc0, 0xb9, 0xe6, 0x92, 0x15, 0xb7, 0x5a, 0x21, 0xb9, 0xb6, 0xca, 0xeb, 0x6d,
-	0x75, 0xfe, 0x84, 0xfa, 0x72, 0x29, 0x71, 0x13, 0x2a, 0x11, 0xf7, 0x59, 0x42, 0xac, 0x76, 0xb9,
-	0xeb, 0x8c, 0xd2, 0x4b, 0xe7, 0xbb, 0x05, 0xa0, 0x62, 0xfa, 0x33, 0x1a, 0x05, 0x7a, 0xb6, 0xa7,
-	0x83, 0x82, 0x02, 0x7b, 0x3e, 0xc0, 0xff, 0x9a, 0x2f, 0x68, 0xeb, 0x05, 0xf9, 0x3d, 0xbf, 0xf0,
-	0xe9, 0xbb, 0xb5, 0x1d, 0xd9, 0x83, 0xea, 0x19, 0xf7, 0xd9, 0xe9, 0xa0, 0xa8, 0x2b, 0xd2, 0x18,
-	0x26, 0xe0, 0xf6, 0x79, 0x24, 0xd9, 0x8d, 0x34, 0x5f, 0xce, 0x9d, 0xa4, 0xd7, 0xfd, 0xff, 0xa0,
-	0xbe, 0xfc, 0xd8, 0x78, 0x0b, 0x3c, 0x7d, 0x39, 0xe3, 0x22, 0xa4, 0x57, 0xa8, 0x84, 0x77, 0x60,
-	0x4b, 0x03, 0xab, 0xc2, 0xc8, 0xda, 0xff, 0x66, 0x83, 0x97, 0x5b, 0x55, 0x0c, 0x50, 0x1d, 0x26,
-	0xc1, 0xc9, 0x22, 0x46, 0x25, 0xec, 0x81, 0x3b, 0x4c, 0x82, 0x63, 0x46, 0x25, 0xb2, 0xcc, 0xe5,
-	0xa5, 0xe0, 0x31, 0xb2, 0x4d, 0xd4, 0x51, 0x1c, 0xa3, 0x32, 0x6e, 0x00, 0xa4, 0xe7, 0x11, 0x4b,
-	0x62, 0xe4, 0x98, 0xc0, 0xd7, 0x5c, 0x32, 0x54, 0x51, 0x22, 0xcc, 0x45, 0xb3, 0x55, 0xc3, 0xaa,
-	0xb5, 0x40, 0x2e, 0x46, 0xb0, 0xa1, 0x8a, 0x31, 0x2a, 0xe4, 0xa5, 0xaa, 0x52, 0xc3, 0x4d, 0x40,
-	0x79, 0x44, 0x3f, 0xaa, 0x63, 0x0c, 0x8d, 0x61, 0x12, 0x5c, 0x44, 0x82, 0xd1, 0xc9, 0x8c, 0x5e,
-	0x5e, 0x31, 0x04, 0x78, 0x1b, 0x36, 0x4d, 0x22, 0x35, 0xa0, 0x45, 0x82, 0x3c, 0x13, 0xd6, 0x9f,
-	0xb1, 0xc9, 0xc7, 0x57, 0x0b, 0x2e, 0x16, 0x21, 0xda, 0xc0, 0xbf, 0xc1, 0xf6, 0x30, 0x09, 0xc6,
-	0x82, 0x46, 0xc9, 0x94, 0x89, 0x17, 0x8c, 0xfa, 0x4c, 0xa0, 0x4d, 0xf3, 0x7a, 0x3c, 0x0f, 0x19,
-	0x5f, 0xc8, 0x33, 0xfe, 0x09, 0x35, 0xf6, 0xdf, 0x42, 0xa3, 0x38, 0x12, 0xf5, 0x76, 0x85, 0x1c,
-	0xf9, 0xbe, 0x9a, 0x09, 0x2a, 0x61, 0x02, 0xcd, 0x15, 0x3c, 0x62, 0x21, 0xbf, 0x66, 0x9a, 0xb1,
-	0x8a, 0xcc, 0x45, 0xec, 0x53, 0x99, 0x32, 0xf6, 0x71, 0xf3, 0xee, 0xa1, 0x55, 0xba, 0x7f, 0x68,
-	0x95, 0xee, 0x1e, 0x5b, 0xd6, 0xfd, 0x63, 0xcb, 0xfa, 0xf9, 0xd8, 0xb2, 0x7e, 0x05, 0x00, 0x00,
-	0xff, 0xff, 0xc8, 0x26, 0x45, 0x2d, 0xd0, 0x05, 0x00, 0x00,
+	// 735 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x54, 0x4d, 0x6f, 0xd3, 0x4a,
+	0x14, 0xad, 0x13, 0xe7, 0xeb, 0xa6, 0x4d, 0xa7, 0xd3, 0xbc, 0x27, 0xab, 0x7a, 0xea, 0xeb, 0xb3,
+	0xde, 0x02, 0x15, 0xb5, 0x40, 0x17, 0x2c, 0xd8, 0xf5, 0x03, 0xa9, 0x95, 0x68, 0x05, 0x69, 0xcb,
+	0x02, 0x84, 0xd0, 0xd4, 0x9e, 0x38, 0x81, 0xda, 0x63, 0x8d, 0x27, 0xa5, 0xdd, 0x20, 0x24, 0x16,
+	0x6c, 0xf8, 0x61, 0x5d, 0xf6, 0x17, 0x20, 0xe0, 0x97, 0x70, 0x67, 0x3c, 0x4e, 0xec, 0x66, 0x11,
+	0x69, 0xe6, 0x9c, 0xfb, 0x71, 0xee, 0x99, 0xeb, 0x00, 0x48, 0x36, 0x54, 0xdb, 0xa9, 0x14, 0x4a,
+	0xd0, 0xa6, 0x3e, 0xa7, 0x17, 0x6b, 0xfd, 0x48, 0x44, 0xc2, 0x40, 0x8f, 0xf4, 0x29, 0x67, 0xfd,
+	0xcf, 0xd0, 0x78, 0x9e, 0x28, 0x79, 0x43, 0x1f, 0x82, 0x7b, 0x76, 0x93, 0x72, 0xcf, 0xd9, 0x70,
+	0x1e, 0xf4, 0x76, 0x56, 0xb6, 0xf3, 0xac, 0x6d, 0x43, 0x6a, 0x62, 0xcf, 0xbd, 0xfd, 0xf1, 0xef,
+	0xc2, 0xc0, 0x55, 0x78, 0xa6, 0x1e, 0x06, 0x73, 0x19, 0x7b, 0x35, 0x0c, 0x76, 0xa7, 0x0c, 0x22,
+	0x74, 0x0d, 0x1a, 0x47, 0x49, 0xc8, 0xaf, 0xbd, 0x7a, 0x89, 0x6a, 0x8c, 0x35, 0x44, 0x29, 0xb8,
+	0x07, 0x4c, 0x31, 0xcf, 0x45, 0x6a, 0x71, 0xe0, 0x86, 0x78, 0xf6, 0xbf, 0x38, 0x40, 0x4e, 0x13,
+	0x96, 0x66, 0x23, 0xa1, 0x8e, 0xb9, 0x62, 0x1a, 0xa4, 0x4f, 0x01, 0x02, 0x91, 0x0c, 0xdf, 0x67,
+	0x8a, 0xa9, 0x5c, 0x51, 0x77, 0xa6, 0x68, 0x1f, 0x99, 0x53, 0x4d, 0xd8, 0xe2, 0x9d, 0xa0, 0x00,
+	0x74, 0x73, 0xd3, 0xa9, 0xa2, 0xcb, 0x36, 0x47, 0xc9, 0x5a, 0x60, 0x45, 0x97, 0x41, 0xfc, 0x37,
+	0xd0, 0x2e, 0x14, 0x68, 0x89, 0x5a, 0x81, 0xe9, 0x69, 0x25, 0xd2, 0x67, 0xd0, 0x8e, 0xad, 0x32,
+	0x53, 0xb8, 0xbb, 0xe3, 0x15, 0x5a, 0xee, 0x2b, 0xb7, 0x75, 0xa7, 0xf1, 0xfe, 0xd7, 0x3a, 0xb4,
+	0x8e, 0x79, 0x96, 0xb1, 0x88, 0xd3, 0x2d, 0x30, 0xe6, 0x59, 0x87, 0x57, 0x8b, 0x1a, 0x96, 0x9e,
+	0xf3, 0xb8, 0x0f, 0x35, 0x25, 0x2a, 0x93, 0xe0, 0x5d, 0x8f, 0x31, 0x94, 0xe2, 0xde, 0x18, 0x1a,
+	0x99, 0x0e, 0xe8, 0xce, 0xbd, 0xc9, 0x3a, 0xb4, 0x2e, 0x45, 0x64, 0x1e, 0xac, 0x51, 0x22, 0x0b,
+	0x70, 0x66, 0x5b, 0x73, 0xde, 0xb6, 0x2d, 0x68, 0x71, 0x5c, 0x81, 0x31, 0xcf, 0xbc, 0xd6, 0x46,
+	0x1d, 0x67, 0x5f, 0xaa, 0x6c, 0x46, 0x51, 0xca, 0xc6, 0xd0, 0x7f, 0xa0, 0x19, 0x88, 0x38, 0x1e,
+	0x2b, 0xaf, 0x5d, 0xaa, 0x65, 0x31, 0xba, 0x03, 0xed, 0xcc, 0x3a, 0xe6, 0x75, 0x8c, 0x93, 0xe4,
+	0xbe, 0x93, 0x85, 0x83, 0x45, 0x9c, 0xae, 0x28, 0xf9, 0x07, 0x1e, 0x28, 0x0f, 0x30, 0xa3, 0x5d,
+	0x54, 0xcc, 0x31, 0xfa, 0x3f, 0xae, 0xba, 0x39, 0x1d, 0x8e, 0x13, 0xe5, 0x75, 0x4b, 0x3d, 0x4b,
+	0xb8, 0xff, 0x0e, 0x3a, 0x87, 0x4c, 0x86, 0xf9, 0x92, 0x14, 0x3e, 0x39, 0x73, 0x3e, 0x21, 0x73,
+	0x25, 0x70, 0xe1, 0x2a, 0x5b, 0xad, 0x91, 0xd2, 0x58, 0xf5, 0xf9, 0xb1, 0xfc, 0xff, 0xa0, 0x33,
+	0x5d, 0x4a, 0x7c, 0xb6, 0x46, 0x22, 0x42, 0xb4, 0xcb, 0x41, 0xbb, 0xdc, 0x41, 0x7e, 0xf1, 0xbf,
+	0x3b, 0x00, 0x3a, 0x66, 0x7f, 0xc4, 0x92, 0xc8, 0xbc, 0xed, 0xd1, 0x41, 0x45, 0x41, 0x6d, 0x7c,
+	0x40, 0x1f, 0xdb, 0x4f, 0xb0, 0x66, 0x16, 0xe4, 0xef, 0xf2, 0xc2, 0xe7, 0x79, 0x73, 0x3b, 0x82,
+	0xba, 0x4e, 0xb0, 0x3e, 0xd6, 0xaa, 0xe8, 0x4a, 0x0c, 0x86, 0xf3, 0xb4, 0x30, 0x57, 0xf1, 0x6b,
+	0x65, 0x3f, 0xb9, 0x56, 0x90, 0x5f, 0x37, 0x9f, 0x40, 0x67, 0xfa, 0x61, 0xd3, 0x65, 0xe8, 0x9a,
+	0xcb, 0x89, 0x90, 0x31, 0xbb, 0x24, 0x0b, 0x74, 0x15, 0x96, 0x0d, 0x30, 0x6b, 0x4c, 0x9c, 0xcd,
+	0x6f, 0x35, 0xe8, 0x96, 0x56, 0x95, 0x02, 0x34, 0x8f, 0xb3, 0xe8, 0x70, 0x92, 0x62, 0x42, 0x17,
+	0x97, 0x3c, 0x8b, 0xf6, 0x38, 0x53, 0xc4, 0xb1, 0x97, 0x97, 0x52, 0xa4, 0xa4, 0x66, 0xa3, 0x76,
+	0xd3, 0x94, 0xd4, 0x69, 0x0f, 0x20, 0x3f, 0x0f, 0x78, 0x96, 0x12, 0xd7, 0x06, 0xbe, 0x46, 0x7f,
+	0x49, 0x43, 0x8b, 0xb0, 0x17, 0xc3, 0x36, 0x2d, 0xab, 0xd7, 0x82, 0xb4, 0x28, 0x81, 0x45, 0xdd,
+	0x8c, 0x33, 0xa9, 0x2e, 0x74, 0x97, 0x36, 0x3a, 0x48, 0xca, 0x88, 0x49, 0xea, 0xe0, 0xe7, 0xdb,
+	0x43, 0xf4, 0x3c, 0x91, 0x9c, 0x05, 0x23, 0x76, 0x71, 0xc9, 0x09, 0xd0, 0x15, 0x58, 0xb2, 0x85,
+	0xf4, 0x03, 0x4d, 0x32, 0xd2, 0xb5, 0x61, 0xfb, 0x23, 0x1e, 0x7c, 0x7c, 0x35, 0x11, 0x72, 0x12,
+	0x93, 0x45, 0xfa, 0x17, 0xac, 0x20, 0x76, 0x26, 0x59, 0x92, 0x0d, 0xb9, 0x7c, 0xc1, 0x59, 0xc8,
+	0x25, 0x59, 0xb2, 0xd9, 0x67, 0xe3, 0x98, 0x8b, 0x89, 0x3a, 0x11, 0x9f, 0x48, 0x6f, 0xf3, 0x2d,
+	0xf4, 0xaa, 0x4f, 0xa2, 0x73, 0x67, 0xc8, 0x6e, 0x18, 0xea, 0x37, 0x41, 0x5b, 0x3c, 0xe8, 0xcf,
+	0xe0, 0x01, 0x8f, 0xc5, 0x15, 0x37, 0x8c, 0x53, 0x65, 0xce, 0x53, 0xfc, 0xab, 0xc8, 0x99, 0xda,
+	0x5e, 0xff, 0xf6, 0xd7, 0xfa, 0xc2, 0x1d, 0xfe, 0x6e, 0x7f, 0xaf, 0x3b, 0x77, 0xf8, 0xfb, 0x89,
+	0xbf, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x26, 0x45, 0x2d, 0xd0, 0x05, 0x00, 0x00,
 }

+ 15 - 1
scripts/genproto.sh

@@ -21,6 +21,7 @@ DIRS="./wal/walpb ./etcdserver/etcdserverpb ./snap/snappb ./raft/raftpb ./mvcc/m
 
 # exact version of protoc-gen-gogo to build
 SHA="c3995ae437bb78d1189f4f147dfe5f87ad3596e4"
+GRPC_GATEWAY_SHA="dcb844349dc5d2cb0300fdc4d2d374839d0d2e13"
 
 # set up self-contained GOPATH for building
 export GOPATH=${PWD}/gopath
@@ -31,6 +32,7 @@ COREOS_ROOT="${GOPATH}/src/github.com/coreos"
 ETCD_ROOT="${COREOS_ROOT}/etcd"
 GOGOPROTO_ROOT="${GOPATH}/src/github.com/gogo/protobuf"
 GOGOPROTO_PATH="${GOGOPROTO_ROOT}:${GOGOPROTO_ROOT}/protobuf"
+GRPC_GATEWAY_ROOT="${GOPATH}/src/github.com/gengo/grpc-gateway"
 
 rm -f "${ETCD_ROOT}"
 mkdir -p "${COREOS_ROOT}"
@@ -45,18 +47,30 @@ pushd "${GOGOPROTO_ROOT}"
 	make install
 popd
 
+# generate gateway code
+go get -u github.com/gengo/grpc-gateway/protoc-gen-grpc-gateway
+pushd "${GRPC_GATEWAY_ROOT}"
+	git reset --hard "${GRPC_GATEWAY_SHA}"
+	go install ./protoc-gen-grpc-gateway
+popd
+
 for dir in ${DIRS}; do
 	pushd ${dir}
-		protoc --gogofast_out=plugins=grpc,import_prefix=github.com/coreos/:. -I=.:"${GOGOPROTO_PATH}":"${COREOS_ROOT}" *.proto
+		protoc --gogofast_out=plugins=grpc,import_prefix=github.com/coreos/:. -I=.:"${GOGOPROTO_PATH}":"${COREOS_ROOT}":"${GRPC_GATEWAY_ROOT}/third_party/googleapis" *.proto
 		sed -i.bak -E "s/github\.com\/coreos\/(gogoproto|github\.com|golang\.org|google\.golang\.org)/\1/g" *.pb.go
 		sed -i.bak -E 's/github\.com\/coreos\/(errors|fmt|io)/\1/g' *.pb.go
 		sed -i.bak -E 's/import _ \"gogoproto\"//g' *.pb.go
 		sed -i.bak -E 's/import fmt \"fmt\"//g' *.pb.go
+		sed -i.bak -E 's/import _ \"github\.com\/coreos\/google\/api\"//g' *.pb.go
 		rm -f *.bak
 		goimports -w *.pb.go
 	popd
 done
 
+protoc -I. \
+    -I${GRPC_GATEWAY_ROOT}/third_party/googleapis \
+    -I${GOGOPROTO_PATH} \
+    -I${COREOS_ROOT} --grpc-gateway_out=logtostderr=true:. ./etcdserver/etcdserverpb/rpc.proto
 
 # install protodoc
 # go get -v -u github.com/coreos/protodoc

+ 4 - 4
snap/snappb/snap.pb.go

@@ -337,13 +337,13 @@ var (
 )
 
 var fileDescriptorSnap = []byte{
-	// 122 bytes of a gzipped FileDescriptorProto
+	// 118 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 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, 0x38, 0xf1, 0x50, 0x8e, 0xe1,
-	0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x04, 0x04, 0x00, 0x00,
-	0xff, 0xff, 0x0d, 0x03, 0x97, 0xa7, 0x74, 0x00, 0x00, 0x00,
+	0x51, 0x82, 0x09, 0x28, 0xc1, 0x13, 0x04, 0x66, 0x3b, 0x09, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe2,
+	0x91, 0x1c, 0xe3, 0x05, 0x20, 0x7e, 0x00, 0xc4, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x03,
+	0x97, 0xa7, 0x74, 0x00, 0x00, 0x00,
 }

+ 7 - 8
wal/walpb/record.pb.go

@@ -501,17 +501,16 @@ var (
 )
 
 var fileDescriptorRecord = []byte{
-	// 182 bytes of a gzipped FileDescriptorProto
+	// 175 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 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, 0x81, 0x13, 0x0f, 0xe5, 0x18, 0x4e, 0x3c, 0x92, 0x63, 0xbc,
-	0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0x46, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe5, 0x20,
-	0xf5, 0xbc, 0xcf, 0x00, 0x00, 0x00,
+	0xc9, 0x12, 0x4c, 0x40, 0x09, 0x5e, 0xa8, 0x04, 0x48, 0x40, 0x48, 0x88, 0x8b, 0x25, 0x25, 0xb1,
+	0x24, 0x51, 0x82, 0x19, 0x28, 0xc1, 0x13, 0x04, 0x66, 0x2b, 0x39, 0x70, 0x71, 0x04, 0xe7, 0x25,
+	0x16, 0x14, 0x67, 0xe4, 0x97, 0x08, 0x49, 0x71, 0xb1, 0x66, 0xe6, 0xa5, 0xa4, 0x56, 0x80, 0x8d,
+	0x64, 0x81, 0xea, 0x84, 0x08, 0x81, 0x6d, 0x4b, 0x2d, 0xca, 0x05, 0x1b, 0xca, 0x02, 0xb7, 0x0d,
+	0x28, 0xe2, 0x24, 0x70, 0xe2, 0xa1, 0x1c, 0xc3, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x80, 0xf8, 0x01,
+	0x10, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe5, 0x20, 0xf5, 0xbc, 0xcf, 0x00, 0x00, 0x00,
 }