feat: add cmd uninstall and rename cmd reset

This commit is contained in:
fengcaiwen
2025-01-18 11:06:07 +08:00
parent b6cfba7db9
commit 2e96247e74
11 changed files with 897 additions and 322 deletions

View File

@@ -1,14 +1,12 @@
package cmds
import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/ptr"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
@@ -20,59 +18,48 @@ func CmdReset(f cmdutil.Factory) *cobra.Command {
var sshConf = &pkgssh.SshConfig{}
cmd := &cobra.Command{
Use: "reset",
Short: "Reset all resource create by kubevpn in k8s cluster",
Short: "Reset workloads to origin status",
Long: templates.LongDesc(i18n.T(`
Reset all resource create by kubevpn in k8s cluster
Reset workloads to origin status
Reset will delete all resources create by kubevpn in k8s cluster, like deployment, service, serviceAccount...
and it will also delete local develop docker containers, docker networks. delete hosts entry added by kubevpn,
cleanup DNS settings.
Reset will remove injected container envoy-proxy and vpn, and restore service mesh rules.
`)),
Example: templates.Examples(i18n.T(`
# Reset default namespace
kubevpn reset
# Reset default namespace workloads depooyment/productpage
kubevpn reset deployment/productpage
# Reset another namespace test
kubevpn reset -n test
# Reset another namespace test workloads depooyment/productpage
kubevpn reset deployment/productpage -n test
# Reset cluster api-server behind of bastion host or ssh jump host
kubevpn reset --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem
# Reset workloads depooyment/productpage which api-server behind of bastion host or ssh jump host
kubevpn reset deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem
# It also supports ProxyJump, like
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐
│ pc ├────►│ ssh1 ├────►│ ssh2 ├────►│ ssh3 ├─────►... ─────► │ api-server │
└──────┘ └──────┘ └──────┘ └──────┘ └────────────┘
kubevpn reset --ssh-alias <alias>
kubevpn reset deployment/productpage --ssh-alias <alias>
# Support ssh auth GSSAPI
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn reset --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn reset deployment/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
`)),
PreRunE: func(cmd *cobra.Command, args []string) error {
util.InitLoggerForClient(false)
return daemon.StartupDaemon(cmd.Context())
},
Args: cobra.MatchAll(cobra.ExactArgs(1)),
RunE: func(cmd *cobra.Command, args []string) error {
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
if err != nil {
return err
}
cli := daemon.GetClient(false)
disconnect, err := cli.Disconnect(cmd.Context(), &rpc.DisconnectRequest{
KubeconfigBytes: ptr.To(string(bytes)),
Namespace: ptr.To(ns),
SshJump: sshConf.ToRPC(),
})
if err != nil {
log.Warnf("Failed to disconnect from cluter: %v", err)
} else {
_ = util.PrintGRPCStream[rpc.DisconnectResponse](disconnect)
}
req := &rpc.ResetRequest{
KubeconfigBytes: string(bytes),
Namespace: ns,
Workloads: args,
SshJump: sshConf.ToRPC(),
}
resp, err := cli.Reset(cmd.Context(), req)

View File

@@ -80,6 +80,7 @@ func NewKubeVPNCommand() *cobra.Command {
CmdLogs(factory),
CmdCp(factory),
CmdReset(factory),
CmdUninstall(factory),
CmdQuit(factory),
},
},

View File

@@ -0,0 +1,95 @@
package cmds
import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"k8s.io/utils/ptr"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
pkgssh "github.com/wencaiwulue/kubevpn/v2/pkg/ssh"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
func CmdUninstall(f cmdutil.Factory) *cobra.Command {
var sshConf = &pkgssh.SshConfig{}
cmd := &cobra.Command{
Use: "uninstall",
Short: "Uninstall all resource create by kubevpn in k8s cluster",
Long: templates.LongDesc(i18n.T(`
Uninstall all resource create by kubevpn in k8s cluster
Uninstall will delete all resources create by kubevpn in k8s cluster, like deployment, service, serviceAccount...
and it will also delete local develop docker containers, docker networks. delete hosts entry added by kubevpn,
cleanup DNS settings.
`)),
Example: templates.Examples(i18n.T(`
# Uninstall default namespace
kubevpn uninstall
# Uninstall another namespace test
kubevpn uninstall -n test
# Uninstall cluster api-server behind of bastion host or ssh jump host
kubevpn uninstall --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem
# It also supports ProxyJump, like
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐
│ pc ├────►│ ssh1 ├────►│ ssh2 ├────►│ ssh3 ├─────►... ─────► │ api-server │
└──────┘ └──────┘ └──────┘ └──────┘ └────────────┘
kubevpn uninstall --ssh-alias <alias>
# Support ssh auth GSSAPI
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-keytab /path/to/keytab
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-cache /path/to/cache
kubevpn uninstall --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
`)),
PreRunE: func(cmd *cobra.Command, args []string) error {
util.InitLoggerForClient(false)
return daemon.StartupDaemon(cmd.Context())
},
RunE: func(cmd *cobra.Command, args []string) error {
bytes, ns, err := util.ConvertToKubeConfigBytes(f)
if err != nil {
return err
}
cli := daemon.GetClient(false)
disconnect, err := cli.Disconnect(cmd.Context(), &rpc.DisconnectRequest{
KubeconfigBytes: ptr.To(string(bytes)),
Namespace: ptr.To(ns),
SshJump: sshConf.ToRPC(),
})
if err != nil {
log.Warnf("Failed to disconnect from cluter: %v", err)
} else {
_ = util.PrintGRPCStream[rpc.DisconnectResponse](disconnect)
}
req := &rpc.UninstallRequest{
KubeconfigBytes: string(bytes),
Namespace: ns,
SshJump: sshConf.ToRPC(),
}
resp, err := cli.Uninstall(cmd.Context(), req)
if err != nil {
return err
}
err = util.PrintGRPCStream[rpc.UninstallResponse](resp)
if err != nil {
if status.Code(err) == codes.Canceled {
return nil
}
return err
}
return nil
},
}
pkgssh.AddSshFlags(cmd.Flags(), sshConf)
return cmd
}

View File

@@ -25,7 +25,7 @@ func (svr *Server) Reset(req *rpc.ResetRequest, resp rpc.Daemon_ResetServer) err
connect := &handler.ConnectOptions{
Namespace: req.Namespace,
Lock: &svr.Lock,
Workloads: req.Workloads,
}
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))

View File

@@ -0,0 +1,71 @@
package action
import (
"io"
log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
"github.com/wencaiwulue/kubevpn/v2/pkg/ssh"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
func (svr *Server) Uninstall(req *rpc.UninstallRequest, resp rpc.Daemon_UninstallServer) error {
defer func() {
util.InitLoggerForServer(true)
log.SetOutput(svr.LogFile)
config.Debug = false
}()
out := io.MultiWriter(newUninstallWarp(resp), svr.LogFile)
util.InitLoggerForClient(config.Debug)
log.SetOutput(out)
connect := &handler.ConnectOptions{
Namespace: req.Namespace,
Lock: &svr.Lock,
}
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
if err != nil {
return err
}
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.AddFlag(&pflag.Flag{
Name: "kubeconfig",
DefValue: file,
})
var sshConf = ssh.ParseSshFromRPC(req.SshJump)
var ctx = resp.Context()
var path string
path, err = ssh.SshJump(ctx, sshConf, flags, false)
if err != nil {
return err
}
err = connect.InitClient(util.InitFactoryByPath(path, req.Namespace))
if err != nil {
return err
}
err = connect.Uninstall(ctx)
if err != nil {
return err
}
return nil
}
type uninstallWarp struct {
server rpc.Daemon_UninstallServer
}
func (r *uninstallWarp) Write(p []byte) (n int, err error) {
_ = r.server.Send(&rpc.UninstallResponse{
Message: string(p),
})
return len(p), nil
}
func newUninstallWarp(server rpc.Daemon_UninstallServer) io.Writer {
return &uninstallWarp{server: server}
}

View File

@@ -2392,6 +2392,117 @@ func (x *UpgradeResponse) GetNeedUpgrade() bool {
return false
}
type UninstallRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KubeconfigBytes string `protobuf:"bytes,1,opt,name=KubeconfigBytes,proto3" json:"KubeconfigBytes,omitempty"`
Namespace string `protobuf:"bytes,2,opt,name=Namespace,proto3" json:"Namespace,omitempty"`
// ssh jump
SshJump *SshJump `protobuf:"bytes,3,opt,name=SshJump,proto3" json:"SshJump,omitempty"`
}
func (x *UninstallRequest) Reset() {
*x = UninstallRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UninstallRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UninstallRequest) ProtoMessage() {}
func (x *UninstallRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[39]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UninstallRequest.ProtoReflect.Descriptor instead.
func (*UninstallRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{39}
}
func (x *UninstallRequest) GetKubeconfigBytes() string {
if x != nil {
return x.KubeconfigBytes
}
return ""
}
func (x *UninstallRequest) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *UninstallRequest) GetSshJump() *SshJump {
if x != nil {
return x.SshJump
}
return nil
}
type UninstallResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *UninstallResponse) Reset() {
*x = UninstallResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UninstallResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UninstallResponse) ProtoMessage() {}
func (x *UninstallResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UninstallResponse.ProtoReflect.Descriptor instead.
func (*UninstallResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{40}
}
func (x *UninstallResponse) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type ResetRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -2399,16 +2510,15 @@ type ResetRequest struct {
KubeconfigBytes string `protobuf:"bytes,1,opt,name=KubeconfigBytes,proto3" json:"KubeconfigBytes,omitempty"`
Namespace string `protobuf:"bytes,2,opt,name=Namespace,proto3" json:"Namespace,omitempty"`
// repeated string Workloads = 3;
//
Workloads []string `protobuf:"bytes,3,rep,name=Workloads,proto3" json:"Workloads,omitempty"`
// ssh jump
SshJump *SshJump `protobuf:"bytes,3,opt,name=SshJump,proto3" json:"SshJump,omitempty"`
SshJump *SshJump `protobuf:"bytes,4,opt,name=SshJump,proto3" json:"SshJump,omitempty"`
}
func (x *ResetRequest) Reset() {
*x = ResetRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[39]
mi := &file_daemon_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2421,7 +2531,7 @@ func (x *ResetRequest) String() string {
func (*ResetRequest) ProtoMessage() {}
func (x *ResetRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[39]
mi := &file_daemon_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2434,7 +2544,7 @@ func (x *ResetRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResetRequest.ProtoReflect.Descriptor instead.
func (*ResetRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{39}
return file_daemon_proto_rawDescGZIP(), []int{41}
}
func (x *ResetRequest) GetKubeconfigBytes() string {
@@ -2451,6 +2561,13 @@ func (x *ResetRequest) GetNamespace() string {
return ""
}
func (x *ResetRequest) GetWorkloads() []string {
if x != nil {
return x.Workloads
}
return nil
}
func (x *ResetRequest) GetSshJump() *SshJump {
if x != nil {
return x.SshJump
@@ -2469,7 +2586,7 @@ type ResetResponse struct {
func (x *ResetResponse) Reset() {
*x = ResetResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[40]
mi := &file_daemon_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2482,7 +2599,7 @@ func (x *ResetResponse) String() string {
func (*ResetResponse) ProtoMessage() {}
func (x *ResetResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[40]
mi := &file_daemon_proto_msgTypes[42]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2495,7 +2612,7 @@ func (x *ResetResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResetResponse.ProtoReflect.Descriptor instead.
func (*ResetResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{40}
return file_daemon_proto_rawDescGZIP(), []int{42}
}
func (x *ResetResponse) GetMessage() string {
@@ -2525,7 +2642,7 @@ type SshJump struct {
func (x *SshJump) Reset() {
*x = SshJump{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[41]
mi := &file_daemon_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2538,7 +2655,7 @@ func (x *SshJump) String() string {
func (*SshJump) ProtoMessage() {}
func (x *SshJump) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[41]
mi := &file_daemon_proto_msgTypes[43]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2551,7 +2668,7 @@ func (x *SshJump) ProtoReflect() protoreflect.Message {
// Deprecated: Use SshJump.ProtoReflect.Descriptor instead.
func (*SshJump) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{41}
return file_daemon_proto_rawDescGZIP(), []int{43}
}
func (x *SshJump) GetAddr() string {
@@ -2637,7 +2754,7 @@ type ExtraRoute struct {
func (x *ExtraRoute) Reset() {
*x = ExtraRoute{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[42]
mi := &file_daemon_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2650,7 +2767,7 @@ func (x *ExtraRoute) String() string {
func (*ExtraRoute) ProtoMessage() {}
func (x *ExtraRoute) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[42]
mi := &file_daemon_proto_msgTypes[44]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2663,7 +2780,7 @@ func (x *ExtraRoute) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExtraRoute.ProtoReflect.Descriptor instead.
func (*ExtraRoute) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{42}
return file_daemon_proto_rawDescGZIP(), []int{44}
}
func (x *ExtraRoute) GetExtraCIDR() []string {
@@ -2696,7 +2813,7 @@ type IdentifyRequest struct {
func (x *IdentifyRequest) Reset() {
*x = IdentifyRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[43]
mi := &file_daemon_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2709,7 +2826,7 @@ func (x *IdentifyRequest) String() string {
func (*IdentifyRequest) ProtoMessage() {}
func (x *IdentifyRequest) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[43]
mi := &file_daemon_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2722,7 +2839,7 @@ func (x *IdentifyRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use IdentifyRequest.ProtoReflect.Descriptor instead.
func (*IdentifyRequest) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{43}
return file_daemon_proto_rawDescGZIP(), []int{45}
}
type IdentifyResponse struct {
@@ -2736,7 +2853,7 @@ type IdentifyResponse struct {
func (x *IdentifyResponse) Reset() {
*x = IdentifyResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_daemon_proto_msgTypes[44]
mi := &file_daemon_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2749,7 +2866,7 @@ func (x *IdentifyResponse) String() string {
func (*IdentifyResponse) ProtoMessage() {}
func (x *IdentifyResponse) ProtoReflect() protoreflect.Message {
mi := &file_daemon_proto_msgTypes[44]
mi := &file_daemon_proto_msgTypes[46]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2762,7 +2879,7 @@ func (x *IdentifyResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use IdentifyResponse.ProtoReflect.Descriptor instead.
func (*IdentifyResponse) Descriptor() ([]byte, []int) {
return file_daemon_proto_rawDescGZIP(), []int{44}
return file_daemon_proto_rawDescGZIP(), []int{46}
}
func (x *IdentifyResponse) GetID() string {
@@ -3059,124 +3176,142 @@ var file_daemon_proto_rawDesc = []byte{
0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a, 0x0f, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70,
0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x65,
0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74,
0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52,
0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x22, 0xc7, 0x02, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x12,
0x12, 0x0a, 0x04, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41,
0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x75, 0x6d,
0x70, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73,
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c,
0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62,
0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52,
0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x2a, 0x0a, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43,
0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50,
0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26, 0x0a, 0x0e, 0x47,
0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63,
0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x47, 0x53,
0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x6e, 0x0a,
0x0a, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x45,
0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74,
0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b,
0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x45,
0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x22, 0x11, 0x0a,
0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x22, 0x22, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x49, 0x44, 0x32, 0xa6, 0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12,
0x38, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72,
0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12,
0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x06, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x3c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x12, 0x15,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x45, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12,
0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61,
0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x36, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x13, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x73, 0x68,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73,
0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2d,
0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f,
0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2d, 0x0a,
0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x03,
0x47, 0x65, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55, 0x70, 0x67, 0x72,
0x61, 0x64, 0x65, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55,
0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x33, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a,
0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73,
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x2f, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x30, 0x01, 0x12, 0x39, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x14,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a,
0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x10, 0x55, 0x6e, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a,
0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68,
0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x2d, 0x0a,
0x11, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9c, 0x01, 0x0a,
0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a,
0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61,
0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f,
0x61, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75,
0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52,
0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc7, 0x02, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75,
0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x41, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x4a, 0x75, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c,
0x69, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65,
0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
0x52, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x2a, 0x0a, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74,
0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53,
0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26,
0x0a, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49,
0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65,
0x22, 0x6e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c,
0x0a, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28,
0x09, 0x52, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b,
0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20,
0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20,
0x01, 0x28, 0x08, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50,
0x22, 0x11, 0x0a, 0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x32, 0xe6, 0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d,
0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69,
0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44,
0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a,
0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f,
0x6e, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e,
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a,
0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64,
0x64, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64,
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x45, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68,
0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53,
0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12,
0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74,
0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a,
0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30,
0x01, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x2a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55,
0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67,
0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x32, 0x0a, 0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x09, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c,
0x6c, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c,
0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55,
0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
0x79, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64,
0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
@@ -3191,7 +3326,7 @@ func file_daemon_proto_rawDescGZIP() []byte {
return file_daemon_proto_rawDescData
}
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 50)
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 52)
var file_daemon_proto_goTypes = []interface{}{
(*ConnectRequest)(nil), // 0: rpc.ConnectRequest
(*ConnectResponse)(nil), // 1: rpc.ConnectResponse
@@ -3232,84 +3367,89 @@ var file_daemon_proto_goTypes = []interface{}{
(*GetResponse)(nil), // 36: rpc.GetResponse
(*UpgradeRequest)(nil), // 37: rpc.UpgradeRequest
(*UpgradeResponse)(nil), // 38: rpc.UpgradeResponse
(*ResetRequest)(nil), // 39: rpc.ResetRequest
(*ResetResponse)(nil), // 40: rpc.ResetResponse
(*SshJump)(nil), // 41: rpc.SshJump
(*ExtraRoute)(nil), // 42: rpc.ExtraRoute
(*IdentifyRequest)(nil), // 43: rpc.IdentifyRequest
(*IdentifyResponse)(nil), // 44: rpc.IdentifyResponse
nil, // 45: rpc.ConnectRequest.HeadersEntry
nil, // 46: rpc.CloneRequest.HeadersEntry
nil, // 47: rpc.ProxyRule.HeadersEntry
nil, // 48: rpc.ProxyRule.PortMapEntry
nil, // 49: rpc.CloneRule.HeadersEntry
(*UninstallRequest)(nil), // 39: rpc.UninstallRequest
(*UninstallResponse)(nil), // 40: rpc.UninstallResponse
(*ResetRequest)(nil), // 41: rpc.ResetRequest
(*ResetResponse)(nil), // 42: rpc.ResetResponse
(*SshJump)(nil), // 43: rpc.SshJump
(*ExtraRoute)(nil), // 44: rpc.ExtraRoute
(*IdentifyRequest)(nil), // 45: rpc.IdentifyRequest
(*IdentifyResponse)(nil), // 46: rpc.IdentifyResponse
nil, // 47: rpc.ConnectRequest.HeadersEntry
nil, // 48: rpc.CloneRequest.HeadersEntry
nil, // 49: rpc.ProxyRule.HeadersEntry
nil, // 50: rpc.ProxyRule.PortMapEntry
nil, // 51: rpc.CloneRule.HeadersEntry
}
var file_daemon_proto_depIdxs = []int32{
45, // 0: rpc.ConnectRequest.Headers:type_name -> rpc.ConnectRequest.HeadersEntry
42, // 1: rpc.ConnectRequest.ExtraRoute:type_name -> rpc.ExtraRoute
41, // 2: rpc.ConnectRequest.SshJump:type_name -> rpc.SshJump
41, // 3: rpc.DisconnectRequest.SshJump:type_name -> rpc.SshJump
46, // 4: rpc.CloneRequest.Headers:type_name -> rpc.CloneRequest.HeadersEntry
42, // 5: rpc.CloneRequest.ExtraRoute:type_name -> rpc.ExtraRoute
41, // 6: rpc.CloneRequest.SshJump:type_name -> rpc.SshJump
47, // 0: rpc.ConnectRequest.Headers:type_name -> rpc.ConnectRequest.HeadersEntry
44, // 1: rpc.ConnectRequest.ExtraRoute:type_name -> rpc.ExtraRoute
43, // 2: rpc.ConnectRequest.SshJump:type_name -> rpc.SshJump
43, // 3: rpc.DisconnectRequest.SshJump:type_name -> rpc.SshJump
48, // 4: rpc.CloneRequest.Headers:type_name -> rpc.CloneRequest.HeadersEntry
44, // 5: rpc.CloneRequest.ExtraRoute:type_name -> rpc.ExtraRoute
43, // 6: rpc.CloneRequest.SshJump:type_name -> rpc.SshJump
14, // 7: rpc.StatusResponse.List:type_name -> rpc.Status
15, // 8: rpc.Status.ProxyList:type_name -> rpc.Proxy
17, // 9: rpc.Status.CloneList:type_name -> rpc.Clone
16, // 10: rpc.Proxy.RuleList:type_name -> rpc.ProxyRule
47, // 11: rpc.ProxyRule.Headers:type_name -> rpc.ProxyRule.HeadersEntry
48, // 12: rpc.ProxyRule.PortMap:type_name -> rpc.ProxyRule.PortMapEntry
49, // 11: rpc.ProxyRule.Headers:type_name -> rpc.ProxyRule.HeadersEntry
50, // 12: rpc.ProxyRule.PortMap:type_name -> rpc.ProxyRule.PortMapEntry
18, // 13: rpc.Clone.RuleList:type_name -> rpc.CloneRule
49, // 14: rpc.CloneRule.Headers:type_name -> rpc.CloneRule.HeadersEntry
41, // 15: rpc.ConfigAddRequest.SshJump:type_name -> rpc.SshJump
41, // 16: rpc.SshConnectRequest.SshJump:type_name -> rpc.SshJump
41, // 17: rpc.ResetRequest.SshJump:type_name -> rpc.SshJump
0, // 18: rpc.Daemon.Connect:input_type -> rpc.ConnectRequest
0, // 19: rpc.Daemon.ConnectFork:input_type -> rpc.ConnectRequest
2, // 20: rpc.Daemon.Disconnect:input_type -> rpc.DisconnectRequest
0, // 21: rpc.Daemon.Proxy:input_type -> rpc.ConnectRequest
4, // 22: rpc.Daemon.Leave:input_type -> rpc.LeaveRequest
6, // 23: rpc.Daemon.Clone:input_type -> rpc.CloneRequest
8, // 24: rpc.Daemon.Remove:input_type -> rpc.RemoveRequest
21, // 25: rpc.Daemon.ConfigAdd:input_type -> rpc.ConfigAddRequest
29, // 26: rpc.Daemon.ConfigRemove:input_type -> rpc.ConfigRemoveRequest
22, // 27: rpc.Daemon.SshStart:input_type -> rpc.SshStartRequest
24, // 28: rpc.Daemon.SshStop:input_type -> rpc.SshStopRequest
26, // 29: rpc.Daemon.SshConnect:input_type -> rpc.SshConnectRequest
31, // 30: rpc.Daemon.Logs:input_type -> rpc.LogRequest
33, // 31: rpc.Daemon.List:input_type -> rpc.ListRequest
35, // 32: rpc.Daemon.Get:input_type -> rpc.GetRequest
37, // 33: rpc.Daemon.Upgrade:input_type -> rpc.UpgradeRequest
12, // 34: rpc.Daemon.Status:input_type -> rpc.StatusRequest
19, // 35: rpc.Daemon.Version:input_type -> rpc.VersionRequest
39, // 36: rpc.Daemon.Reset:input_type -> rpc.ResetRequest
10, // 37: rpc.Daemon.Quit:input_type -> rpc.QuitRequest
43, // 38: rpc.Daemon.Identify:input_type -> rpc.IdentifyRequest
1, // 39: rpc.Daemon.Connect:output_type -> rpc.ConnectResponse
1, // 40: rpc.Daemon.ConnectFork:output_type -> rpc.ConnectResponse
3, // 41: rpc.Daemon.Disconnect:output_type -> rpc.DisconnectResponse
1, // 42: rpc.Daemon.Proxy:output_type -> rpc.ConnectResponse
5, // 43: rpc.Daemon.Leave:output_type -> rpc.LeaveResponse
7, // 44: rpc.Daemon.Clone:output_type -> rpc.CloneResponse
9, // 45: rpc.Daemon.Remove:output_type -> rpc.RemoveResponse
28, // 46: rpc.Daemon.ConfigAdd:output_type -> rpc.ConfigAddResponse
30, // 47: rpc.Daemon.ConfigRemove:output_type -> rpc.ConfigRemoveResponse
23, // 48: rpc.Daemon.SshStart:output_type -> rpc.SshStartResponse
25, // 49: rpc.Daemon.SshStop:output_type -> rpc.SshStopResponse
27, // 50: rpc.Daemon.SshConnect:output_type -> rpc.SshConnectResponse
32, // 51: rpc.Daemon.Logs:output_type -> rpc.LogResponse
34, // 52: rpc.Daemon.List:output_type -> rpc.ListResponse
36, // 53: rpc.Daemon.Get:output_type -> rpc.GetResponse
38, // 54: rpc.Daemon.Upgrade:output_type -> rpc.UpgradeResponse
13, // 55: rpc.Daemon.Status:output_type -> rpc.StatusResponse
20, // 56: rpc.Daemon.Version:output_type -> rpc.VersionResponse
40, // 57: rpc.Daemon.Reset:output_type -> rpc.ResetResponse
11, // 58: rpc.Daemon.Quit:output_type -> rpc.QuitResponse
44, // 59: rpc.Daemon.Identify:output_type -> rpc.IdentifyResponse
39, // [39:60] is the sub-list for method output_type
18, // [18:39] is the sub-list for method input_type
18, // [18:18] is the sub-list for extension type_name
18, // [18:18] is the sub-list for extension extendee
0, // [0:18] is the sub-list for field type_name
51, // 14: rpc.CloneRule.Headers:type_name -> rpc.CloneRule.HeadersEntry
43, // 15: rpc.ConfigAddRequest.SshJump:type_name -> rpc.SshJump
43, // 16: rpc.SshConnectRequest.SshJump:type_name -> rpc.SshJump
43, // 17: rpc.UninstallRequest.SshJump:type_name -> rpc.SshJump
43, // 18: rpc.ResetRequest.SshJump:type_name -> rpc.SshJump
0, // 19: rpc.Daemon.Connect:input_type -> rpc.ConnectRequest
0, // 20: rpc.Daemon.ConnectFork:input_type -> rpc.ConnectRequest
2, // 21: rpc.Daemon.Disconnect:input_type -> rpc.DisconnectRequest
0, // 22: rpc.Daemon.Proxy:input_type -> rpc.ConnectRequest
4, // 23: rpc.Daemon.Leave:input_type -> rpc.LeaveRequest
6, // 24: rpc.Daemon.Clone:input_type -> rpc.CloneRequest
8, // 25: rpc.Daemon.Remove:input_type -> rpc.RemoveRequest
21, // 26: rpc.Daemon.ConfigAdd:input_type -> rpc.ConfigAddRequest
29, // 27: rpc.Daemon.ConfigRemove:input_type -> rpc.ConfigRemoveRequest
22, // 28: rpc.Daemon.SshStart:input_type -> rpc.SshStartRequest
24, // 29: rpc.Daemon.SshStop:input_type -> rpc.SshStopRequest
26, // 30: rpc.Daemon.SshConnect:input_type -> rpc.SshConnectRequest
31, // 31: rpc.Daemon.Logs:input_type -> rpc.LogRequest
33, // 32: rpc.Daemon.List:input_type -> rpc.ListRequest
35, // 33: rpc.Daemon.Get:input_type -> rpc.GetRequest
37, // 34: rpc.Daemon.Upgrade:input_type -> rpc.UpgradeRequest
12, // 35: rpc.Daemon.Status:input_type -> rpc.StatusRequest
19, // 36: rpc.Daemon.Version:input_type -> rpc.VersionRequest
41, // 37: rpc.Daemon.Uninstall:input_type -> rpc.ResetRequest
39, // 38: rpc.Daemon.Uninstall:input_type -> rpc.UninstallRequest
10, // 39: rpc.Daemon.Quit:input_type -> rpc.QuitRequest
45, // 40: rpc.Daemon.Identify:input_type -> rpc.IdentifyRequest
1, // 41: rpc.Daemon.Connect:output_type -> rpc.ConnectResponse
1, // 42: rpc.Daemon.ConnectFork:output_type -> rpc.ConnectResponse
3, // 43: rpc.Daemon.Disconnect:output_type -> rpc.DisconnectResponse
1, // 44: rpc.Daemon.Proxy:output_type -> rpc.ConnectResponse
5, // 45: rpc.Daemon.Leave:output_type -> rpc.LeaveResponse
7, // 46: rpc.Daemon.Clone:output_type -> rpc.CloneResponse
9, // 47: rpc.Daemon.Remove:output_type -> rpc.RemoveResponse
28, // 48: rpc.Daemon.ConfigAdd:output_type -> rpc.ConfigAddResponse
30, // 49: rpc.Daemon.ConfigRemove:output_type -> rpc.ConfigRemoveResponse
23, // 50: rpc.Daemon.SshStart:output_type -> rpc.SshStartResponse
25, // 51: rpc.Daemon.SshStop:output_type -> rpc.SshStopResponse
27, // 52: rpc.Daemon.SshConnect:output_type -> rpc.SshConnectResponse
32, // 53: rpc.Daemon.Logs:output_type -> rpc.LogResponse
34, // 54: rpc.Daemon.List:output_type -> rpc.ListResponse
36, // 55: rpc.Daemon.Get:output_type -> rpc.GetResponse
38, // 56: rpc.Daemon.Upgrade:output_type -> rpc.UpgradeResponse
13, // 57: rpc.Daemon.Status:output_type -> rpc.StatusResponse
20, // 58: rpc.Daemon.Version:output_type -> rpc.VersionResponse
42, // 59: rpc.Daemon.Uninstall:output_type -> rpc.ResetResponse
40, // 60: rpc.Daemon.Uninstall:output_type -> rpc.UninstallResponse
11, // 61: rpc.Daemon.Quit:output_type -> rpc.QuitResponse
46, // 62: rpc.Daemon.Identify:output_type -> rpc.IdentifyResponse
41, // [41:63] is the sub-list for method output_type
19, // [19:41] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
}
func init() { file_daemon_proto_init() }
@@ -3787,7 +3927,7 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResetRequest); i {
switch v := v.(*UninstallRequest); i {
case 0:
return &v.state
case 1:
@@ -3799,7 +3939,7 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ResetResponse); i {
switch v := v.(*UninstallResponse); i {
case 0:
return &v.state
case 1:
@@ -3811,7 +3951,7 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SshJump); i {
switch v := v.(*ResetRequest); i {
case 0:
return &v.state
case 1:
@@ -3823,7 +3963,7 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExtraRoute); i {
switch v := v.(*ResetResponse); i {
case 0:
return &v.state
case 1:
@@ -3835,7 +3975,7 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IdentifyRequest); i {
switch v := v.(*SshJump); i {
case 0:
return &v.state
case 1:
@@ -3847,6 +3987,30 @@ func file_daemon_proto_init() {
}
}
file_daemon_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExtraRoute); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_daemon_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IdentifyRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_daemon_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IdentifyResponse); i {
case 0:
return &v.state
@@ -3866,7 +4030,7 @@ func file_daemon_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_daemon_proto_rawDesc,
NumEnums: 0,
NumMessages: 50,
NumMessages: 52,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -26,6 +26,7 @@ service Daemon {
rpc Status (StatusRequest) returns (StatusResponse) {}
rpc Version (VersionRequest) returns (VersionResponse) {}
rpc Reset (ResetRequest) returns (stream ResetResponse) {}
rpc Uninstall (UninstallRequest) returns (stream UninstallResponse) {}
rpc Quit (QuitRequest) returns (stream QuitResponse) {}
rpc Identify (IdentifyRequest) returns (IdentifyResponse) {}
@@ -281,12 +282,23 @@ message UpgradeResponse {
bool NeedUpgrade = 1;
}
message UninstallRequest {
string KubeconfigBytes = 1;
string Namespace = 2;
// ssh jump
SshJump SshJump = 3;
}
message UninstallResponse {
string message = 1;
}
message ResetRequest {
string KubeconfigBytes = 1;
string Namespace = 2;
// repeated string Workloads = 3;
repeated string Workloads = 3;
// ssh jump
SshJump SshJump = 3;
SshJump SshJump = 4;
}
message ResetResponse {

View File

@@ -38,6 +38,7 @@ const (
Daemon_Status_FullMethodName = "/rpc.Daemon/Status"
Daemon_Version_FullMethodName = "/rpc.Daemon/Version"
Daemon_Reset_FullMethodName = "/rpc.Daemon/Reset"
Daemon_Uninstall_FullMethodName = "/rpc.Daemon/Uninstall"
Daemon_Quit_FullMethodName = "/rpc.Daemon/Quit"
Daemon_Identify_FullMethodName = "/rpc.Daemon/Identify"
)
@@ -65,6 +66,7 @@ type DaemonClient interface {
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error)
Reset(ctx context.Context, in *ResetRequest, opts ...grpc.CallOption) (Daemon_ResetClient, error)
Uninstall(ctx context.Context, in *UninstallRequest, opts ...grpc.CallOption) (Daemon_UninstallClient, error)
Quit(ctx context.Context, in *QuitRequest, opts ...grpc.CallOption) (Daemon_QuitClient, error)
Identify(ctx context.Context, in *IdentifyRequest, opts ...grpc.CallOption) (*IdentifyResponse, error)
}
@@ -477,8 +479,40 @@ func (x *daemonResetClient) Recv() (*ResetResponse, error) {
return m, nil
}
func (c *daemonClient) Uninstall(ctx context.Context, in *UninstallRequest, opts ...grpc.CallOption) (Daemon_UninstallClient, error) {
stream, err := c.cc.NewStream(ctx, &Daemon_ServiceDesc.Streams[10], Daemon_Uninstall_FullMethodName, opts...)
if err != nil {
return nil, err
}
x := &daemonUninstallClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type Daemon_UninstallClient interface {
Recv() (*UninstallResponse, error)
grpc.ClientStream
}
type daemonUninstallClient struct {
grpc.ClientStream
}
func (x *daemonUninstallClient) Recv() (*UninstallResponse, error) {
m := new(UninstallResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *daemonClient) Quit(ctx context.Context, in *QuitRequest, opts ...grpc.CallOption) (Daemon_QuitClient, error) {
stream, err := c.cc.NewStream(ctx, &Daemon_ServiceDesc.Streams[10], Daemon_Quit_FullMethodName, opts...)
stream, err := c.cc.NewStream(ctx, &Daemon_ServiceDesc.Streams[11], Daemon_Quit_FullMethodName, opts...)
if err != nil {
return nil, err
}
@@ -541,6 +575,7 @@ type DaemonServer interface {
Status(context.Context, *StatusRequest) (*StatusResponse, error)
Version(context.Context, *VersionRequest) (*VersionResponse, error)
Reset(*ResetRequest, Daemon_ResetServer) error
Uninstall(*UninstallRequest, Daemon_UninstallServer) error
Quit(*QuitRequest, Daemon_QuitServer) error
Identify(context.Context, *IdentifyRequest) (*IdentifyResponse, error)
mustEmbedUnimplementedDaemonServer()
@@ -607,6 +642,9 @@ func (UnimplementedDaemonServer) Version(context.Context, *VersionRequest) (*Ver
func (UnimplementedDaemonServer) Reset(*ResetRequest, Daemon_ResetServer) error {
return status.Errorf(codes.Unimplemented, "method Reset not implemented")
}
func (UnimplementedDaemonServer) Uninstall(*UninstallRequest, Daemon_UninstallServer) error {
return status.Errorf(codes.Unimplemented, "method Uninstall not implemented")
}
func (UnimplementedDaemonServer) Quit(*QuitRequest, Daemon_QuitServer) error {
return status.Errorf(codes.Unimplemented, "method Quit not implemented")
}
@@ -1003,6 +1041,27 @@ func (x *daemonResetServer) Send(m *ResetResponse) error {
return x.ServerStream.SendMsg(m)
}
func _Daemon_Uninstall_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(UninstallRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(DaemonServer).Uninstall(m, &daemonUninstallServer{stream})
}
type Daemon_UninstallServer interface {
Send(*UninstallResponse) error
grpc.ServerStream
}
type daemonUninstallServer struct {
grpc.ServerStream
}
func (x *daemonUninstallServer) Send(m *UninstallResponse) error {
return x.ServerStream.SendMsg(m)
}
func _Daemon_Quit_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(QuitRequest)
if err := stream.RecvMsg(m); err != nil {
@@ -1142,6 +1201,11 @@ var Daemon_ServiceDesc = grpc.ServiceDesc{
Handler: _Daemon_Reset_Handler,
ServerStreams: true,
},
{
StreamName: "Uninstall",
Handler: _Daemon_Uninstall_Handler,
ServerStreams: true,
},
{
StreamName: "Quit",
Handler: _Daemon_Quit_Handler,

View File

@@ -2,81 +2,64 @@ package handler
import (
"context"
"encoding/json"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
pkgresource "k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"sigs.k8s.io/yaml"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/controlplane"
"github.com/wencaiwulue/kubevpn/v2/pkg/inject"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
// Reset
// 1) quit daemon
// 2) get all proxy-resources from configmap
// 3) cleanup all containers
// 4) cleanup hosts
// 1) reset configmap
// 2) remove inject containers envoy and vpn
// 3) restore service targetPort to containerPort
func (c *ConnectOptions) Reset(ctx context.Context) error {
err := c.LeaveProxyResources(ctx)
if c == nil || c.clientset == nil {
return nil
}
err := c.PreCheckResource()
if err != nil {
log.Errorf("Leave proxy resources error: %v", err)
} else {
log.Debugf("Leave proxy resources successfully")
return err
}
log.Infof("Cleaning up resources")
ns := c.Namespace
name := config.ConfigMapPodTrafficManager
options := metav1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)}
_ = c.clientset.CoreV1().ConfigMaps(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().Pods(ns).Delete(ctx, config.CniNetName, options)
_ = c.clientset.CoreV1().Secrets(ns).Delete(ctx, name, options)
_ = c.clientset.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(ctx, name+"."+ns, options)
_ = c.clientset.RbacV1().RoleBindings(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().ServiceAccounts(ns).Delete(ctx, name, options)
_ = c.clientset.RbacV1().Roles(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().Services(ns).Delete(ctx, name, options)
_ = c.clientset.AppsV1().Deployments(ns).Delete(ctx, name, options)
err = resetConfigMap(ctx, c.clientset.CoreV1().ConfigMaps(c.Namespace), c.Workloads)
if err != nil {
log.Error(err)
}
for _, workload := range c.Workloads {
err = removeInjectContainer(ctx, c.factory, c.clientset, c.Namespace, workload)
if err != nil {
log.Error(err)
}
}
_ = c.CleanupLocalContainer(ctx)
log.Info("Done")
return nil
}
func (c *ConnectOptions) CleanupLocalContainer(ctx context.Context) error {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
func resetConfigMap(ctx context.Context, mapInterface v1.ConfigMapInterface, workloads []string) error {
cm, err := mapInterface.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
if err != nil {
return err
}
var networkResource types.NetworkResource
networkResource, err = cli.NetworkInspect(ctx, config.ConfigMapPodTrafficManager, types.NetworkInspectOptions{})
if err != nil {
return err
}
if len(networkResource.Containers) == 0 {
err = cli.NetworkRemove(ctx, config.ConfigMapPodTrafficManager)
if apierrors.IsNotFound(err) {
return nil
}
return err
}
func (c *ConnectOptions) LeaveProxyResources(ctx context.Context) (err error) {
if c == nil || c.clientset == nil {
return
}
mapInterface := c.clientset.CoreV1().ConfigMaps(c.Namespace)
var cm *corev1.ConfigMap
cm, err = mapInterface.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) {
return
}
if cm == nil || cm.Data == nil || len(cm.Data[config.KeyEnvoy]) == 0 {
log.Infof("No proxy resources found")
return nil
@@ -85,29 +68,90 @@ func (c *ConnectOptions) LeaveProxyResources(ctx context.Context) (err error) {
str := cm.Data[config.KeyEnvoy]
if err = yaml.Unmarshal([]byte(str), &v); err != nil {
log.Errorf("Unmarshal envoy config error: %v", err)
return
return nil
}
v4, _ := c.GetLocalTunIP()
for _, virtual := range v {
var found bool
for _, rule := range virtual.Rules {
if rule.LocalTunIPv4 == v4 {
found = true
break
}
}
if !found {
continue
ws := sets.New[string]()
for _, workload := range workloads {
ws.Insert(ConvertWorkloadToUid(workload))
}
// deployments.apps.ry-server --> deployments.apps/ry-server
lastIndex := strings.LastIndex(virtual.Uid, ".")
uid := virtual.Uid[:lastIndex] + "/" + virtual.Uid[lastIndex+1:]
err = inject.UnPatchContainer(c.factory, c.clientset.CoreV1().ConfigMaps(c.Namespace), c.Namespace, uid, v4)
for i := 0; i < len(v); i++ {
if ws.Has(v[i].Uid) {
v = append(v[:i], v[i+1:]...)
i--
}
}
marshal, err := yaml.Marshal(v)
if err != nil {
log.Errorf("Failed to leave workload %s: %v", uid, err)
continue
}
}
return err
}
cm.Data[config.KeyEnvoy] = string(marshal)
_, err = mapInterface.Update(ctx, cm, metav1.UpdateOptions{})
return err
}
// ConvertUidToWorkload
// deployments.apps.ry-server --> deployments.apps/ry-server
func ConvertUidToWorkload(uid string) string {
lastIndex := strings.LastIndex(uid, ".")
workload := uid[:lastIndex] + "/" + uid[lastIndex+1:]
return workload
}
// ConvertWorkloadToUid
// deployments.apps/ry-server --> deployments.apps.ry-server
func ConvertWorkloadToUid(workload string) string {
lastIndex := strings.LastIndex(workload, "/")
uid := workload[:lastIndex] + "." + workload[lastIndex+1:]
return uid
}
func removeInjectContainer(ctx context.Context, factory cmdutil.Factory, clientset *kubernetes.Clientset, namespace, workload string) error {
object, err := util.GetUnstructuredObject(factory, namespace, workload)
if err != nil {
log.Errorf("Failed to get unstructured object: %v", err)
return err
}
u := object.Object.(*unstructured.Unstructured)
templateSpec, depth, err := util.GetPodTemplateSpecPath(u)
if err != nil {
log.Errorf("Failed to get template spec path: %v", err)
return err
}
log.Infof("Leaving workload %s", workload)
inject.RemoveContainers(templateSpec)
helper := pkgresource.NewHelper(object.Client, object.Mapping)
log.Debugf("The %s is under controller management", workload)
// resource with controller, like deployment,statefulset
var bytes []byte
bytes, err = json.Marshal([]inject.P{
{
Op: "replace",
Path: "/" + strings.Join(append(depth, "spec"), "/"),
Value: templateSpec.Spec,
},
})
if err != nil {
log.Errorf("Failed to generate json patch: %v", err)
return err
}
_, err = helper.Patch(object.Namespace, object.Name, types.JSONPatchType, bytes, &metav1.PatchOptions{})
if err != nil {
log.Errorf("Failed to patch resource: %s %s: %v", object.Mapping.GroupVersionKind.GroupKind().String(), object.Name, err)
return err
}
var portmap = make(map[int32]int32)
for _, container := range templateSpec.Spec.Containers {
for _, port := range container.Ports {
portmap[port.ContainerPort] = port.ContainerPort
}
}
err = inject.ModifyServiceTargetPort(ctx, clientset, namespace, labels.SelectorFromSet(templateSpec.Labels).String(), portmap)
return err
}

113
pkg/handler/uninstall.go Normal file
View File

@@ -0,0 +1,113 @@
package handler
import (
"context"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
"sigs.k8s.io/yaml"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/controlplane"
"github.com/wencaiwulue/kubevpn/v2/pkg/inject"
)
// Uninstall
// 1) quit daemon
// 2) get all proxy-resources from configmap
// 3) cleanup all containers
// 4) cleanup hosts
func (c *ConnectOptions) Uninstall(ctx context.Context) error {
err := c.LeaveProxyResources(ctx)
if err != nil {
log.Errorf("Leave proxy resources error: %v", err)
} else {
log.Debugf("Leave proxy resources successfully")
}
log.Infof("Cleaning up resources")
ns := c.Namespace
name := config.ConfigMapPodTrafficManager
options := metav1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)}
_ = c.clientset.CoreV1().ConfigMaps(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().Pods(ns).Delete(ctx, config.CniNetName, options)
_ = c.clientset.CoreV1().Secrets(ns).Delete(ctx, name, options)
_ = c.clientset.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(ctx, name+"."+ns, options)
_ = c.clientset.RbacV1().RoleBindings(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().ServiceAccounts(ns).Delete(ctx, name, options)
_ = c.clientset.RbacV1().Roles(ns).Delete(ctx, name, options)
_ = c.clientset.CoreV1().Services(ns).Delete(ctx, name, options)
_ = c.clientset.AppsV1().Deployments(ns).Delete(ctx, name, options)
_ = c.CleanupLocalContainer(ctx)
log.Info("Done")
return nil
}
func (c *ConnectOptions) CleanupLocalContainer(ctx context.Context) error {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return err
}
var networkResource types.NetworkResource
networkResource, err = cli.NetworkInspect(ctx, config.ConfigMapPodTrafficManager, types.NetworkInspectOptions{})
if err != nil {
return err
}
if len(networkResource.Containers) == 0 {
err = cli.NetworkRemove(ctx, config.ConfigMapPodTrafficManager)
}
return err
}
func (c *ConnectOptions) LeaveProxyResources(ctx context.Context) (err error) {
if c == nil || c.clientset == nil {
return
}
mapInterface := c.clientset.CoreV1().ConfigMaps(c.Namespace)
var cm *corev1.ConfigMap
cm, err = mapInterface.Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) {
return
}
if cm == nil || cm.Data == nil || len(cm.Data[config.KeyEnvoy]) == 0 {
log.Infof("No proxy resources found")
return nil
}
var v = make([]*controlplane.Virtual, 0)
str := cm.Data[config.KeyEnvoy]
if err = yaml.Unmarshal([]byte(str), &v); err != nil {
log.Errorf("Unmarshal envoy config error: %v", err)
return
}
v4, _ := c.GetLocalTunIP()
for _, virtual := range v {
var found bool
for _, rule := range virtual.Rules {
if rule.LocalTunIPv4 == v4 {
found = true
break
}
}
if !found {
continue
}
// deployments.apps.ry-server --> deployments.apps/ry-server
lastIndex := strings.LastIndex(virtual.Uid, ".")
uid := virtual.Uid[:lastIndex] + "/" + virtual.Uid[lastIndex+1:]
err = inject.UnPatchContainer(c.factory, c.clientset.CoreV1().ConfigMaps(c.Namespace), c.Namespace, uid, v4)
if err != nil {
log.Errorf("Failed to leave workload %s: %v", uid, err)
continue
}
}
return err
}

View File

@@ -3,8 +3,10 @@ package inject
import (
"context"
"fmt"
"net"
"net/netip"
"strings"
"sync"
"time"
log "github.com/sirupsen/logrus"
@@ -19,6 +21,7 @@ import (
pkgresource "k8s.io/cli-runtime/pkg/resource"
runtimeresource "k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
@@ -99,7 +102,7 @@ func InjectEnvoySidecar(ctx context.Context, f cmdutil.Factory, clientset *kuber
}
// 2) modify service containerPort to envoy listener port
err = modifyServiceTargetPort(ctx, clientset, namespace, labels.SelectorFromSet(templateSpec.Labels).String(), containerPort2EnvoyListenerPort)
err = ModifyServiceTargetPort(ctx, clientset, namespace, labels.SelectorFromSet(templateSpec.Labels).String(), containerPort2EnvoyListenerPort)
if err != nil {
return err
}
@@ -108,7 +111,7 @@ func InjectEnvoySidecar(ctx context.Context, f cmdutil.Factory, clientset *kuber
return err
}
func modifyServiceTargetPort(ctx context.Context, clientset *kubernetes.Clientset, namespace string, labels string, m map[int32]int32) error {
func ModifyServiceTargetPort(ctx context.Context, clientset *kubernetes.Clientset, namespace string, labels string, m map[int32]int32) error {
list, err := clientset.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{LabelSelector: labels})
if err != nil {
return err
@@ -201,3 +204,24 @@ func exposeLocalPortToRemote(ctx context.Context, clientset *kubernetes.Clientse
}
return nil
}
type Injector struct {
Namespace string
Headers map[string]string
PortMap []string
Workloads []string
Engine config.Engine
Lock *sync.Mutex
ctx context.Context
cancel context.CancelFunc
clientset *kubernetes.Clientset
restclient *rest.RESTClient
config *rest.Config
factory cmdutil.Factory
// needs to give it back to dhcp
localTunIPv4 *net.IPNet
localTunIPv6 *net.IPNet
tunName string
}