diff --git a/common/datapipe/config.go b/common/datapipe/config.go new file mode 100644 index 000000000..c15e4857c --- /dev/null +++ b/common/datapipe/config.go @@ -0,0 +1,177 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package datapipe + +import ( + "fmt" + "github.com/gliderlabs/ssh" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/identity" + gossh "golang.org/x/crypto/ssh" + "os" + "path" + "strconv" + "strings" +) + +type LocalAccessType string + +const ( + LocalAccessTypeNone LocalAccessType = "" + LocalAccessTypePort LocalAccessType = "local-port" + LocalAccessTypeEmbeddedSshServer LocalAccessType = "embedded-ssh-server" +) + +type Config struct { + Enabled bool + LocalAccessType LocalAccessType // values: 'none', 'localhost:port', 'embedded' + DestinationPort uint16 + AuthorizedKeysFile string + HostKey gossh.Signer + ShellPath string +} + +func (self *Config) IsLocalAccessAllowed() bool { + return self.Enabled && self.LocalAccessType != LocalAccessTypeNone +} + +func (self *Config) IsLocalPort() bool { + return self.LocalAccessType == LocalAccessTypePort +} + +func (self *Config) IsEmbedded() bool { + return self.LocalAccessType == LocalAccessTypeEmbeddedSshServer +} + +func (self *Config) LoadConfig(m map[interface{}]interface{}) error { + log := pfxlog.Logger() + if v, ok := m["enabled"]; ok { + if enabled, ok := v.(bool); ok { + self.Enabled = enabled + } else { + self.Enabled = strings.EqualFold("true", fmt.Sprintf("%v", v)) + } + } + if v, ok := m["enableExperimentalFeature"]; ok { + if enabled, ok := v.(bool); ok { + if !enabled { + self.Enabled = false + } + } else if !strings.EqualFold("true", fmt.Sprintf("%v", v)) { + self.Enabled = false + } + } else { + self.Enabled = false + } + + if self.Enabled { + log.Infof("mgmt.pipe enabled") + if v, ok := m["destination"]; ok { + if destination, ok := v.(string); ok { + if strings.HasPrefix(destination, "127.0.0.1:") { + self.LocalAccessType = LocalAccessTypePort + portStr := strings.TrimPrefix(destination, "127.0.0.1:") + port, err := strconv.ParseUint(portStr, 10, 16) + if err != nil { + log.WithError(err).Warn("mgmt.pipe is enabled, but destination not valid. Must be '127.0.0.1:' or 'embedded'") + self.Enabled = false + return nil + } + self.DestinationPort = uint16(port) + } else if destination == "embedded-ssh-server" { + self.LocalAccessType = LocalAccessTypeEmbeddedSshServer + + if v, ok = m["authorizedKeysFile"]; ok { + if keysFile, ok := v.(string); ok { + self.AuthorizedKeysFile = keysFile + } else { + log.Warnf("mgmt.pipe is enabled, but 'embedded' destination configured and authorizedKeysFile configuration is not type string, but %T", v) + self.Enabled = false + return nil + } + } + + if v, ok = m["shell"]; ok { + if s, ok := v.(string); ok { + self.ShellPath = s + } else { + log.Warnf("mgmt.pipe is enabled, but 'embedded' destination configured and shell configuration is not type string, but %T", v) + } + } + } else { + log.Warn("mgmt.pipe is enabled, but destination not valid. Must be 'localhost:port' or 'embedded'") + self.Enabled = false + return nil + } + } + } else { + self.Enabled = false + log.Warn("mgmt.pipe is enabled, but destination not specified. mgmt.pipe disabled.") + return nil + } + } else { + log.Infof("mgmt.pipe disabled") + } + return nil +} + +func (self *Config) NewSshRequestHandler(identity *identity.TokenId) (*SshRequestHandler, error) { + if self.HostKey == nil { + signer, err := gossh.NewSignerFromKey(identity.Cert().PrivateKey) + if err != nil { + return nil, err + } + self.HostKey = signer + } + + keysFile := self.AuthorizedKeysFile + if keysFile == "" { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("could not set up ssh request handler, failing get home dir, trying to load default authorized keys (%w)", err) + } + keysFile = path.Join(homeDir, ".ssh", "authorized_keys") + } + + keysFileContents, err := os.ReadFile(keysFile) + if err != nil { + return nil, fmt.Errorf("could not set up ssh request handler, failed to load authorized keys from '%s' (%w)", keysFile, err) + } + + authorizedKeys := map[string]struct{}{} + entryIdx := 0 + for len(keysFileContents) > 0 { + pubKey, _, _, rest, err := gossh.ParseAuthorizedKey(keysFileContents) + if err != nil { + return nil, fmt.Errorf("could not set up ssh request handler, failed to load authorized key at index %d from '%s' (%w)", entryIdx, keysFile, err) + } + + authorizedKeys[string(pubKey.Marshal())] = struct{}{} + keysFileContents = rest + entryIdx++ + } + + publicKeyOption := ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool { + _, found := authorizedKeys[string(key.Marshal())] + return found + }) + + return &SshRequestHandler{ + config: self, + options: []ssh.Option{publicKeyOption}, + }, nil +} diff --git a/common/datapipe/embedded_ssh_server_conn.go b/common/datapipe/embedded_ssh_server_conn.go new file mode 100644 index 000000000..0d9b69c69 --- /dev/null +++ b/common/datapipe/embedded_ssh_server_conn.go @@ -0,0 +1,133 @@ +package datapipe + +import ( + "errors" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/foundation/v2/concurrenz" + "io" + "net" + "sync/atomic" + "time" +) + +type MessageTypes struct { + DataMessageType int32 + PipeIdHeaderType int32 + CloseMessageType int32 +} + +func NewEmbeddedSshConn(ch channel.Channel, id uint32, msgTypes *MessageTypes) *EmbeddedSshConn { + return &EmbeddedSshConn{ + id: id, + ch: ch, + ReadAdapter: channel.NewReadAdapter(fmt.Sprintf("pipe-%d", id), 4), + msgTypes: msgTypes, + } +} + +type EmbeddedSshConn struct { + msgTypes *MessageTypes + id uint32 + ch channel.Channel + closed atomic.Bool + *channel.ReadAdapter + sshConn concurrenz.AtomicValue[io.Closer] + deadline atomic.Pointer[time.Time] +} + +func (self *EmbeddedSshConn) Id() uint32 { + return self.id +} + +func (self *EmbeddedSshConn) SetSshConn(conn io.Closer) { + self.sshConn.Store(conn) +} + +func (self *EmbeddedSshConn) WriteToServer(data []byte) error { + return self.ReadAdapter.PushData(data) +} + +func (self *EmbeddedSshConn) Write(data []byte) (n int, err error) { + msg := channel.NewMessage(self.msgTypes.DataMessageType, data) + msg.PutUint32Header(self.msgTypes.PipeIdHeaderType, self.id) + deadline := time.Second + if val := self.deadline.Load(); val != nil && !val.IsZero() { + deadline = time.Until(*val) + } + return len(data), msg.WithTimeout(deadline).SendAndWaitForWire(self.ch) +} + +func (self *EmbeddedSshConn) Close() error { + self.CloseWithErr(errors.New("close called")) + return nil +} + +func (self *EmbeddedSshConn) CloseWithErr(err error) { + if self.closed.CompareAndSwap(false, true) { + self.ReadAdapter.Close() + log := pfxlog.ContextLogger(self.ch.Label()).WithField("connId", self.id) + + log.WithError(err).Info("closing mgmt pipe connection") + + if sshConn := self.sshConn.Load(); sshConn != nil { + if closeErr := sshConn.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing mgmt pipe embedded ssh connection") + } + } + + if !self.ch.IsClosed() && err != io.EOF && err != nil { + msg := channel.NewMessage(self.msgTypes.CloseMessageType, []byte(err.Error())) + msg.PutUint32Header(self.msgTypes.PipeIdHeaderType, self.id) + if sendErr := self.ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending mgmt pipe close message") + } + } + + if closeErr := self.ch.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing mgmt pipe client channel") + } + } +} + +func (self *EmbeddedSshConn) LocalAddr() net.Addr { + return embeddedSshPipeAddr{ + id: self.id, + } +} + +func (self *EmbeddedSshConn) RemoteAddr() net.Addr { + return embeddedSshPipeAddr{ + id: self.id, + } +} + +func (self *EmbeddedSshConn) SetDeadline(t time.Time) error { + if err := self.ReadAdapter.SetReadDeadline(t); err != nil { + return err + } + return self.SetWriteDeadline(t) +} + +func (self *EmbeddedSshConn) SetWriteDeadline(t time.Time) error { + self.deadline.Store(&t) + return nil +} + +func (self *EmbeddedSshConn) WriteToClient(data []byte) error { + _, err := self.Write(data) + return err +} + +type embeddedSshPipeAddr struct { + id uint32 +} + +func (self embeddedSshPipeAddr) Network() string { + return "ziti" +} + +func (self embeddedSshPipeAddr) String() string { + return fmt.Sprintf("ssh-pipe-%d", self.id) +} diff --git a/common/datapipe/registry.go b/common/datapipe/registry.go new file mode 100644 index 000000000..6268c2932 --- /dev/null +++ b/common/datapipe/registry.go @@ -0,0 +1,87 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package datapipe + +import ( + "errors" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/foundation/v2/concurrenz" + "sync" + "sync/atomic" +) + +type Pipe interface { + Id() uint32 + WriteToServer(data []byte) error + WriteToClient(data []byte) error + CloseWithErr(err error) +} + +func NewRegistry(config *Config) *Registry { + return &Registry{ + config: config, + } +} + +type Registry struct { + lock sync.Mutex + nextId atomic.Uint32 + connections concurrenz.CopyOnWriteMap[uint32, Pipe] + config *Config +} + +func (self *Registry) GetConfig() *Config { + return self.config +} + +func (self *Registry) GetNextId() (uint32, error) { + self.lock.Lock() + defer self.lock.Unlock() + + limit := 0 + for { + nextId := self.nextId.Add(1) + if val := self.connections.Get(nextId); val == nil { + return nextId, nil + } + if limit++; limit >= 1000 { + return 0, errors.New("pipe pool in bad state, bailing out after 1000 attempts to get next id") + } + } +} + +func (self *Registry) Register(pipe Pipe) error { + self.lock.Lock() + defer self.lock.Unlock() + + if self.connections.Get(pipe.Id()) != nil { + pfxlog.Logger().Errorf("pipe already registered (id=%d)", pipe.Id()) + return fmt.Errorf("pipe already registered") + } + + self.connections.Put(pipe.Id(), pipe) + return nil +} + +func (self *Registry) Unregister(id uint32) { + self.connections.Delete(id) +} + +func (self *Registry) Get(id uint32) Pipe { + return self.connections.Get(id) +} diff --git a/common/datapipe/ssh.go b/common/datapipe/ssh.go new file mode 100644 index 000000000..4893c4a95 --- /dev/null +++ b/common/datapipe/ssh.go @@ -0,0 +1,424 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package datapipe + +import ( + "context" + "errors" + "fmt" + "github.com/creack/pty" + "github.com/gliderlabs/ssh" + "github.com/michaelquigley/pfxlog" + "github.com/pkg/sftp" + "io" + "net" + "os" + "os/exec" + "sync/atomic" + "time" +) + +type SshRequestHandler struct { + config *Config + options []ssh.Option +} + +func (self *SshRequestHandler) HandleSshRequest(conn *EmbeddedSshConn) error { + log := pfxlog.Logger() + + sftpHandler := func(s ssh.Session) { + sftpServer, err := sftp.NewServer(s) + if err != nil { + log.WithError(err).Error("error initializing sftp server") + return + } + + if err = sftpServer.Serve(); err == io.EOF { + if closeErr := sftpServer.Close(); closeErr != nil { + log.WithError(closeErr).Error("error closing sftp server") + } + log.Info("sftp client exited session") + } else if err != nil { + log.WithError(err).Error("sftp server completed with error") + } + } + + server := &ssh.Server{ + Handler: func(s ssh.Session) { + conn.SetSshConn(s) + log.Infof("requested subsystem: %s, cmd: %s", s.Subsystem(), s.RawCommand()) + if _, _, hasPty := s.Pty(); hasPty { + log.Infof("pty requested") + self.startPty(s) + } else { + self.startNonPty(s) + } + }, + SubsystemHandlers: map[string]ssh.SubsystemHandler{ + "sftp": sftpHandler, + }, + } + + server.AddHostKey(self.config.HostKey) + for _, option := range self.options { + if err := server.SetOption(option); err != nil { + return err + } + } + + l := &singleServingListener{ + conn: conn, + } + + go func() { + err := server.Serve(l) + if err != nil && !l.IsComplete() { + pfxlog.Logger().WithError(err).Error("ssh server finished") + } + }() + + return nil +} + +func (self *SshRequestHandler) startPty(s ssh.Session) { + log := pfxlog.Logger() + + cmd, cancelF := self.getCommand(s) + defer cancelF() + + ptyx, winC, _ := s.Pty() + cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyx.Term)) + f, err := pty.StartWithSize(cmd, &pty.Winsize{ + X: uint16(ptyx.Window.Width), + Y: uint16(ptyx.Window.Height), + }) + + if err != nil { + log.WithError(err).Error("error getting pty for ssh shell") + return + } + + log.Info("pty allocated for ssh shell") + + done := make(chan struct{}) + + defer func() { + close(done) + if err := f.Close(); err != nil { + log.WithError(err).Error("error closing pty for ssh shell") + } + log.Info("exiting pty shell") + }() + + go self.handleWindowSizes(winC, f, done) + + errC := make(chan error, 2) + go func() { + _, err := io.Copy(s, f) + errC <- err + }() + + go func() { + _, err := io.Copy(f, s) + errC <- err + }() + + err = <-errC + if err == nil { + select { + case err = <-errC: + default: + } + } + + if err != nil { + log.WithError(err).Error("error reported from ssh shell io copy") + return + } + + if err = cmd.Wait(); err != nil { + log.WithError(err).Error("error reported from ssh shell wait-for-exit") + return + } +} + +func (self *SshRequestHandler) handleWindowSizes(winC <-chan ssh.Window, f *os.File, done <-chan struct{}) { + log := pfxlog.Logger() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + var size *ssh.Window + + for { + select { + case nextSize := <-winC: + size = &nextSize + case <-ticker.C: + if size != nil { + newSize := &pty.Winsize{ + Rows: uint16(size.Height), + Cols: uint16(size.Width), + } + if err := pty.Setsize(f, newSize); err != nil { + log.WithError(err).Error("error setting pty size for ssh shell") + } + } + size = nil + case <-done: + return + } + } +} + +func (self *SshRequestHandler) startNonPty(s ssh.Session) { + log := pfxlog.Logger() + + cmd, cancelF := self.getCommand(s) + defer cancelF() + + stdout, err := cmd.StdoutPipe() + if err != nil { + log.WithError(err).Error("error getting stdout pipe for ssh shell") + return + } + + stderr, err := cmd.StderrPipe() + if err != nil { + log.WithError(err).Error("error getting stderr pipe for ssh shell") + return + } + + stdin, err := cmd.StdinPipe() + if err != nil { + log.WithError(err).Error("error getting stdin pipe for ssh shell") + return + } + + if err = cmd.Start(); err != nil { + return + } + + errC := make(chan error, 3) + go func() { + _, err := io.Copy(s, stdout) + errC <- err + }() + + go func() { + _, err := io.Copy(stdin, s) + errC <- err + }() + + go func() { + _, err := io.Copy(s.Stderr(), stderr) + errC <- err + }() + + for i := 0; i < 3; i++ { + err = <-errC + if err != nil { + break + } + } + + if err != nil { + log.WithError(err).Error("error reported from ssh shell io copy") + return + } + + if err = cmd.Wait(); err != nil { + log.WithError(err).Error("error reported from ssh shell wait-for-exit") + return + } +} + +func (self *SshRequestHandler) getCommand(s ssh.Session) (*exec.Cmd, func()) { + var executable string + var args []string + + if cmdLine := s.Command(); len(cmdLine) > 0 { + executable = cmdLine[0] + if len(cmdLine) > 1 { + args = cmdLine[1:] + } + } else { + executable = self.config.ShellPath + if executable == "" { + executable = "/bin/sh" + } + } + + ctx, cancelF := context.WithCancel(context.Background()) + cmd := exec.CommandContext(ctx, executable, args...) + return cmd, cancelF +} + +type singleServingListener struct { + served atomic.Bool + conn net.Conn + complete atomic.Bool +} + +func (self *singleServingListener) Network() string { + return "ziti-ssa" +} + +func (self *singleServingListener) String() string { + return self.conn.LocalAddr().String() +} + +func (self *singleServingListener) Accept() (net.Conn, error) { + if self.served.CompareAndSwap(false, true) { + self.complete.Store(true) + return self.conn, nil + } + return nil, errors.New("closed") +} + +func (self *singleServingListener) IsComplete() bool { + return self.complete.Load() +} + +func (self *singleServingListener) Close() error { + self.served.Store(true) + return nil +} + +func (self *singleServingListener) Addr() net.Addr { + return self +} + +//func (self *SshRequestHandler) connLoop(chans <-chan ssh.NewChannel, reqs <-chan *ssh.Request) { +// log := pfxlog.Logger() +// +// var channelRequests <-chan *ssh.Request +// var channel ssh.Channel +// +// for { +// select { +// case req := <-reqs: +// if req.WantReply { +// if err := req.Reply(false, nil); err != nil { +// log.WithError(err).Error("error replying to ssh request") +// } +// } +// case req, ok := <-channelRequests: +// if !ok { +// channelRequests = nil +// if err := channel.Close(); err != nil { +// log.WithError(err).Error("error closing embedded ssh channel") +// } +// } else { +// log.WithField("reqType", req.Type).Debug("handling ssh request") +// handled := false +// if req.Type == "shell" { +// go self.exec(channel) +// handled = true +// } else if req.Type == "exec" { +// log.WithField("payload", req.Payload).Debug("handling exec") +// command := string(req.Payload[4 : req.Payload[3]+4]) +// go self.exec(channel, "-c", command) +// handled = true +// } else if req.Type == "pty-req" { +// handled = true +// } +// +// if req.WantReply { +// if err := req.Reply(handled, nil); err != nil { +// log.WithError(err).Error("error replying to channel ssh request") +// } +// } +// } +// case newChannel, ok := <-chans: +// if !ok { +// return +// } +// +// if newChannel.ChannelType() != "session" { +// if err := newChannel.Reject(ssh.UnknownChannelType, "unknown channel type"); err != nil { +// log.WithError(err).WithField("channelType", newChannel.ChannelType()). +// Error("error sending ssh channel reject for channel type") +// } +// } else if channelRequests != nil { +// if err := newChannel.Reject(ssh.ResourceShortage, "only one connection allowed at a time"); err != nil { +// log.WithError(err).Error("error sending ssh channel reject for additional channel") +// } +// } else { +// var err error +// channel, channelRequests, err = newChannel.Accept() +// if err != nil { +// log.WithError(err).WithField("type", newChannel.ChannelType()).Error("error accepting ssh channel") +// continue +// } +// } +// } +// } +//} +// +//func (self *SshRequestHandler) exec(ch ssh.Channel, args ...string) { +// log := pfxlog.Logger() +// defer func() { +// if _, err := ch.SendRequest("exit-status", false, []byte{0, 0, 0, 0}); err != nil { +// log.WithError(err).Error("error sending ssh exit-status request") +// } +// }() +// +// shellPath := self.config.ShellPath +// if shellPath == "" { +// shellPath = "/bin/sh" +// } +// cmd := exec.Command(shellPath, args...) +// f, err := pty.Start(cmd) +// if err != nil { +// log.WithError(err).Error("error getting stdout pipe for ssh shell") +// return +// } +// +// defer func() { +// f.Close() +// }() +// +// //stdout, err := cmd.StdoutPipe() +// //if err != nil { +// // log.WithError(err).Error("error getting stdout pipe for ssh shell") +// // return +// //} +// //stderr, err := cmd.StderrPipe() +// //if err != nil { +// // log.WithError(err).Error("error getting stderr pipe for ssh shell") +// // return +// //} +// //input, err := cmd.StdinPipe() +// //if err != nil { +// // log.WithError(err).Error("error getting stdin pipe for ssh shell") +// // return +// //} +// // +// //if err = cmd.Start(); err != nil { +// // return +// //} +// +// go io.Copy(f, ch) +// //go io.Copy(ch.Stderr(), stderr) +// io.Copy(ch, f) +// +// if err = cmd.Wait(); err != nil { +// log.WithError(err).Error("error reported from ssh shell wait-for-exit") +// return +// } +//} diff --git a/common/pb/ctrl_pb/ctrl.pb.go b/common/pb/ctrl_pb/ctrl.pb.go index df1085a8a..b6ff7f6f0 100644 --- a/common/pb/ctrl_pb/ctrl.pb.go +++ b/common/pb/ctrl_pb/ctrl.pb.go @@ -57,6 +57,11 @@ const ( ContentType_ValidateTerminatorsV2ResponseType ContentType = 1042 ContentType_DecommissionRouterRequestType ContentType = 1043 ContentType_PeerStateChangeRequestType ContentType = 1050 + // Control Channel Pipes + ContentType_CtrlPipeRequestType ContentType = 1060 + ContentType_CtrlPipeResponseType ContentType = 1061 + ContentType_CtrlPipeDataType ContentType = 1062 + ContentType_CtrlPipeCloseType ContentType = 1063 ) // Enum value maps for ContentType. @@ -90,6 +95,10 @@ var ( 1042: "ValidateTerminatorsV2ResponseType", 1043: "DecommissionRouterRequestType", 1050: "PeerStateChangeRequestType", + 1060: "CtrlPipeRequestType", + 1061: "CtrlPipeResponseType", + 1062: "CtrlPipeDataType", + 1063: "CtrlPipeCloseType", } ContentType_value = map[string]int32{ "Zero": 0, @@ -120,6 +129,10 @@ var ( "ValidateTerminatorsV2ResponseType": 1042, "DecommissionRouterRequestType": 1043, "PeerStateChangeRequestType": 1050, + "CtrlPipeRequestType": 1060, + "CtrlPipeResponseType": 1061, + "CtrlPipeDataType": 1062, + "CtrlPipeCloseType": 1063, } ) @@ -157,6 +170,7 @@ const ( ControlHeaders_ListenersHeader ControlHeaders = 10 ControlHeaders_RouterMetadataHeader ControlHeaders = 11 ControlHeaders_CapabilitiesHeader ControlHeaders = 12 + ControlHeaders_CtrlPipeIdHeader ControlHeaders = 20 ) // Enum value maps for ControlHeaders. @@ -166,12 +180,14 @@ var ( 10: "ListenersHeader", 11: "RouterMetadataHeader", 12: "CapabilitiesHeader", + 20: "CtrlPipeIdHeader", } ControlHeaders_value = map[string]int32{ "NoneHeader": 0, "ListenersHeader": 10, "RouterMetadataHeader": 11, "CapabilitiesHeader": 12, + "CtrlPipeIdHeader": 20, } ) @@ -2316,6 +2332,124 @@ func (x *RouterMetadata) GetCapabilities() []RouterCapability { return nil } +type CtrlPipeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` + TimeoutMillis uint64 `protobuf:"varint,2,opt,name=timeoutMillis,proto3" json:"timeoutMillis,omitempty"` + ConnId uint32 `protobuf:"varint,3,opt,name=connId,proto3" json:"connId,omitempty"` +} + +func (x *CtrlPipeRequest) Reset() { + *x = CtrlPipeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ctrl_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CtrlPipeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CtrlPipeRequest) ProtoMessage() {} + +func (x *CtrlPipeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ctrl_proto_msgTypes[29] + 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 CtrlPipeRequest.ProtoReflect.Descriptor instead. +func (*CtrlPipeRequest) Descriptor() ([]byte, []int) { + return file_ctrl_proto_rawDescGZIP(), []int{29} +} + +func (x *CtrlPipeRequest) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *CtrlPipeRequest) GetTimeoutMillis() uint64 { + if x != nil { + return x.TimeoutMillis + } + return 0 +} + +func (x *CtrlPipeRequest) GetConnId() uint32 { + if x != nil { + return x.ConnId + } + return 0 +} + +type CtrlPipeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (x *CtrlPipeResponse) Reset() { + *x = CtrlPipeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ctrl_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CtrlPipeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CtrlPipeResponse) ProtoMessage() {} + +func (x *CtrlPipeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ctrl_proto_msgTypes[30] + 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 CtrlPipeResponse.ProtoReflect.Descriptor instead. +func (*CtrlPipeResponse) Descriptor() ([]byte, []int) { + return file_ctrl_proto_rawDescGZIP(), []int{30} +} + +func (x *CtrlPipeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *CtrlPipeResponse) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + type RouterLinks_RouterLink struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2332,7 +2466,7 @@ type RouterLinks_RouterLink struct { func (x *RouterLinks_RouterLink) Reset() { *x = RouterLinks_RouterLink{} if protoimpl.UnsafeEnabled { - mi := &file_ctrl_proto_msgTypes[34] + mi := &file_ctrl_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2345,7 +2479,7 @@ func (x *RouterLinks_RouterLink) String() string { func (*RouterLinks_RouterLink) ProtoMessage() {} func (x *RouterLinks_RouterLink) ProtoReflect() protoreflect.Message { - mi := &file_ctrl_proto_msgTypes[34] + mi := &file_ctrl_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2417,7 +2551,7 @@ type Route_Egress struct { func (x *Route_Egress) Reset() { *x = Route_Egress{} if protoimpl.UnsafeEnabled { - mi := &file_ctrl_proto_msgTypes[36] + mi := &file_ctrl_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2430,7 +2564,7 @@ func (x *Route_Egress) String() string { func (*Route_Egress) ProtoMessage() {} func (x *Route_Egress) ProtoReflect() protoreflect.Message { - mi := &file_ctrl_proto_msgTypes[36] + mi := &file_ctrl_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2487,7 +2621,7 @@ type Route_Forward struct { func (x *Route_Forward) Reset() { *x = Route_Forward{} if protoimpl.UnsafeEnabled { - mi := &file_ctrl_proto_msgTypes[37] + mi := &file_ctrl_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2500,7 +2634,7 @@ func (x *Route_Forward) String() string { func (*Route_Forward) ProtoMessage() {} func (x *Route_Forward) ProtoReflect() protoreflect.Message { - mi := &file_ctrl_proto_msgTypes[37] + mi := &file_ctrl_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2549,7 +2683,7 @@ type InspectResponse_InspectValue struct { func (x *InspectResponse_InspectValue) Reset() { *x = InspectResponse_InspectValue{} if protoimpl.UnsafeEnabled { - mi := &file_ctrl_proto_msgTypes[40] + mi := &file_ctrl_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2562,7 +2696,7 @@ func (x *InspectResponse_InspectValue) String() string { func (*InspectResponse_InspectValue) ProtoMessage() {} func (x *InspectResponse_InspectValue) ProtoReflect() protoreflect.Message { - mi := &file_ctrl_proto_msgTypes[40] + mi := &file_ctrl_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2885,96 +3019,115 @@ var file_ctrl_proto_rawDesc = []byte{ 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, - 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2a, 0x83, 0x06, - 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, - 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x69, 0x72, 0x63, 0x75, - 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe8, 0x07, - 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x10, 0xea, 0x07, 0x12, - 0x16, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xeb, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x61, 0x75, 0x6c, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xec, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xed, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x6e, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xee, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x54, - 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf0, 0x07, 0x12, 0x13, 0x0a, - 0x0e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xf2, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, - 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xf3, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xf4, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x07, 0x12, - 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x07, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x07, 0x12, 0x20, - 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x07, - 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xfc, 0x07, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8a, - 0x08, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, - 0x54, 0x79, 0x70, 0x65, 0x10, 0x8b, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8c, 0x08, 0x12, 0x1c, - 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8d, 0x08, 0x12, 0x21, 0x0a, 0x1c, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8e, 0x08, 0x12, - 0x1d, 0x0a, 0x18, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8f, 0x08, 0x12, 0x1f, - 0x0a, 0x1a, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x90, 0x08, 0x12, - 0x25, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, - 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0x91, 0x08, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x92, 0x08, 0x12, 0x22, - 0x0a, 0x1d, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x6f, + 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0x71, 0x0a, + 0x0f, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x69, 0x6c, + 0x6c, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x6e, + 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x6e, 0x49, 0x64, + 0x22, 0x3e, 0x0a, 0x10, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, + 0x2a, 0xe7, 0x06, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x69, + 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xe8, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xea, 0x07, 0x12, 0x16, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xeb, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x61, + 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xec, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xed, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x6e, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xee, 0x07, 0x12, 0x10, 0x0a, 0x0b, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x07, 0x12, 0x20, + 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf0, 0x07, + 0x12, 0x13, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xf2, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xf3, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, + 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xf5, 0x07, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x07, 0x12, 0x23, 0x0a, 0x1e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, + 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xfa, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xfc, 0x07, 0x12, 0x1c, 0x0a, 0x17, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x10, 0x8a, 0x08, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, + 0x6e, 0x6b, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8b, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8c, + 0x08, 0x12, 0x1c, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8d, 0x08, 0x12, + 0x21, 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0x8e, 0x08, 0x12, 0x1d, 0x0a, 0x18, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x8f, + 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0x93, 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0x9a, 0x08, 0x2a, 0x67, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x69, 0x65, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0c, 0x2a, 0x3a, 0x0a, 0x10, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5a, 0x65, - 0x72, 0x6f, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x6e, 0x75, 0x73, - 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4e, - 0x65, 0x77, 0x43, 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x2a, - 0x3d, 0x0a, 0x14, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, - 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, - 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x52, - 0x0a, 0x17, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x15, 0x0a, - 0x11, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x10, 0x02, 0x2a, 0x83, 0x01, 0x0a, 0x0c, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, 0x61, - 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, - 0x61, 0x75, 0x6c, 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x46, 0x61, - 0x75, 0x6c, 0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, - 0x46, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, - 0x77, 0x6e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x46, 0x61, - 0x75, 0x6c, 0x74, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x75, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x28, 0x0a, 0x08, 0x44, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x10, 0x00, 0x12, - 0x07, 0x0a, 0x03, 0x45, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, - 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x0b, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, - 0x55, 0x6e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x10, 0x02, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, - 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x70, - 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x90, 0x08, 0x12, 0x25, 0x0a, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x91, 0x08, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x92, + 0x08, 0x12, 0x22, 0x0a, 0x1d, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x10, 0x93, 0x08, 0x12, 0x1f, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0x9a, 0x08, 0x12, 0x18, 0x0a, 0x13, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, + 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa4, 0x08, + 0x12, 0x19, 0x0a, 0x14, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa5, 0x08, 0x12, 0x15, 0x0a, 0x10, 0x43, + 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xa6, 0x08, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa7, 0x08, 0x2a, 0x7d, 0x0a, 0x0e, 0x43, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0e, 0x0a, 0x0a, + 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, + 0x0a, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x43, + 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x74, 0x72, 0x6c, 0x50, 0x69, 0x70, 0x65, 0x49, + 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x14, 0x2a, 0x3a, 0x0a, 0x10, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, + 0x0e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5a, 0x65, 0x72, 0x6f, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x65, 0x77, 0x43, + 0x74, 0x72, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x01, 0x2a, 0x3d, 0x0a, 0x14, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x10, 0x01, 0x12, + 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x52, 0x0a, 0x17, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x6e, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x02, 0x2a, + 0x83, 0x01, 0x0a, 0x0c, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, 0x61, 0x75, 0x6c, 0x74, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x67, 0x72, 0x65, 0x73, 0x73, 0x46, 0x61, 0x75, 0x6c, + 0x74, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x75, 0x6c, 0x74, + 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x46, 0x61, 0x75, + 0x6c, 0x74, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x4f, + 0x77, 0x6e, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x46, 0x61, 0x75, 0x6c, 0x74, + 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x75, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x10, 0x05, 0x2a, 0x28, 0x0a, 0x08, 0x44, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, + 0x45, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x02, 0x2a, + 0x34, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x6e, 0x68, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x10, 0x02, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x66, 0x61, 0x62, + 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2990,7 +3143,7 @@ func file_ctrl_proto_rawDescGZIP() []byte { } var file_ctrl_proto_enumTypes = make([]protoimpl.EnumInfo, 9) -var file_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_ctrl_proto_goTypes = []interface{}{ (ContentType)(0), // 0: ziti.ctrl.pb.ContentType (ControlHeaders)(0), // 1: ziti.ctrl.pb.ControlHeaders @@ -3030,46 +3183,48 @@ var file_ctrl_proto_goTypes = []interface{}{ (*PeerStateChange)(nil), // 35: ziti.ctrl.pb.PeerStateChange (*PeerStateChanges)(nil), // 36: ziti.ctrl.pb.PeerStateChanges (*RouterMetadata)(nil), // 37: ziti.ctrl.pb.RouterMetadata - nil, // 38: ziti.ctrl.pb.Settings.DataEntry - nil, // 39: ziti.ctrl.pb.CircuitRequest.PeerDataEntry - nil, // 40: ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry - nil, // 41: ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry - nil, // 42: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry - (*RouterLinks_RouterLink)(nil), // 43: ziti.ctrl.pb.RouterLinks.RouterLink - nil, // 44: ziti.ctrl.pb.Context.FieldsEntry - (*Route_Egress)(nil), // 45: ziti.ctrl.pb.Route.Egress - (*Route_Forward)(nil), // 46: ziti.ctrl.pb.Route.Forward - nil, // 47: ziti.ctrl.pb.Route.TagsEntry - nil, // 48: ziti.ctrl.pb.Route.Egress.PeerDataEntry - (*InspectResponse_InspectValue)(nil), // 49: ziti.ctrl.pb.InspectResponse.InspectValue + (*CtrlPipeRequest)(nil), // 38: ziti.ctrl.pb.CtrlPipeRequest + (*CtrlPipeResponse)(nil), // 39: ziti.ctrl.pb.CtrlPipeResponse + nil, // 40: ziti.ctrl.pb.Settings.DataEntry + nil, // 41: ziti.ctrl.pb.CircuitRequest.PeerDataEntry + nil, // 42: ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry + nil, // 43: ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry + nil, // 44: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry + (*RouterLinks_RouterLink)(nil), // 45: ziti.ctrl.pb.RouterLinks.RouterLink + nil, // 46: ziti.ctrl.pb.Context.FieldsEntry + (*Route_Egress)(nil), // 47: ziti.ctrl.pb.Route.Egress + (*Route_Forward)(nil), // 48: ziti.ctrl.pb.Route.Forward + nil, // 49: ziti.ctrl.pb.Route.TagsEntry + nil, // 50: ziti.ctrl.pb.Route.Egress.PeerDataEntry + (*InspectResponse_InspectValue)(nil), // 51: ziti.ctrl.pb.InspectResponse.InspectValue } var file_ctrl_proto_depIdxs = []int32{ - 38, // 0: ziti.ctrl.pb.Settings.data:type_name -> ziti.ctrl.pb.Settings.DataEntry - 39, // 1: ziti.ctrl.pb.CircuitRequest.peerData:type_name -> ziti.ctrl.pb.CircuitRequest.PeerDataEntry - 40, // 2: ziti.ctrl.pb.CircuitConfirmation.idleTimes:type_name -> ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry - 41, // 3: ziti.ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry + 40, // 0: ziti.ctrl.pb.Settings.data:type_name -> ziti.ctrl.pb.Settings.DataEntry + 41, // 1: ziti.ctrl.pb.CircuitRequest.peerData:type_name -> ziti.ctrl.pb.CircuitRequest.PeerDataEntry + 42, // 2: ziti.ctrl.pb.CircuitConfirmation.idleTimes:type_name -> ziti.ctrl.pb.CircuitConfirmation.IdleTimesEntry + 43, // 3: ziti.ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.ctrl.pb.CreateTerminatorRequest.PeerDataEntry 4, // 4: ziti.ctrl.pb.CreateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence 15, // 5: ziti.ctrl.pb.ValidateTerminatorsRequest.terminators:type_name -> ziti.ctrl.pb.Terminator 15, // 6: ziti.ctrl.pb.ValidateTerminatorsV2Request.terminators:type_name -> ziti.ctrl.pb.Terminator 5, // 7: ziti.ctrl.pb.RouterTerminatorState.reason:type_name -> ziti.ctrl.pb.TerminatorInvalidReason - 42, // 8: ziti.ctrl.pb.ValidateTerminatorsV2Response.states:type_name -> ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry + 44, // 8: ziti.ctrl.pb.ValidateTerminatorsV2Response.states:type_name -> ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry 4, // 9: ziti.ctrl.pb.UpdateTerminatorRequest.precedence:type_name -> ziti.ctrl.pb.TerminatorPrecedence 22, // 10: ziti.ctrl.pb.LinkConnected.conns:type_name -> ziti.ctrl.pb.LinkConn - 43, // 11: ziti.ctrl.pb.RouterLinks.links:type_name -> ziti.ctrl.pb.RouterLinks.RouterLink + 45, // 11: ziti.ctrl.pb.RouterLinks.links:type_name -> ziti.ctrl.pb.RouterLinks.RouterLink 6, // 12: ziti.ctrl.pb.Fault.subject:type_name -> ziti.ctrl.pb.FaultSubject - 44, // 13: ziti.ctrl.pb.Context.fields:type_name -> ziti.ctrl.pb.Context.FieldsEntry - 45, // 14: ziti.ctrl.pb.Route.egress:type_name -> ziti.ctrl.pb.Route.Egress - 46, // 15: ziti.ctrl.pb.Route.forwards:type_name -> ziti.ctrl.pb.Route.Forward + 46, // 13: ziti.ctrl.pb.Context.fields:type_name -> ziti.ctrl.pb.Context.FieldsEntry + 47, // 14: ziti.ctrl.pb.Route.egress:type_name -> ziti.ctrl.pb.Route.Egress + 48, // 15: ziti.ctrl.pb.Route.forwards:type_name -> ziti.ctrl.pb.Route.Forward 26, // 16: ziti.ctrl.pb.Route.context:type_name -> ziti.ctrl.pb.Context - 47, // 17: ziti.ctrl.pb.Route.tags:type_name -> ziti.ctrl.pb.Route.TagsEntry - 49, // 18: ziti.ctrl.pb.InspectResponse.values:type_name -> ziti.ctrl.pb.InspectResponse.InspectValue + 49, // 17: ziti.ctrl.pb.Route.tags:type_name -> ziti.ctrl.pb.Route.TagsEntry + 51, // 18: ziti.ctrl.pb.InspectResponse.values:type_name -> ziti.ctrl.pb.InspectResponse.InspectValue 32, // 19: ziti.ctrl.pb.Listeners.listeners:type_name -> ziti.ctrl.pb.Listener 8, // 20: ziti.ctrl.pb.PeerStateChange.state:type_name -> ziti.ctrl.pb.PeerState 32, // 21: ziti.ctrl.pb.PeerStateChange.listeners:type_name -> ziti.ctrl.pb.Listener 35, // 22: ziti.ctrl.pb.PeerStateChanges.changes:type_name -> ziti.ctrl.pb.PeerStateChange 2, // 23: ziti.ctrl.pb.RouterMetadata.capabilities:type_name -> ziti.ctrl.pb.RouterCapability 18, // 24: ziti.ctrl.pb.ValidateTerminatorsV2Response.StatesEntry.value:type_name -> ziti.ctrl.pb.RouterTerminatorState - 48, // 25: ziti.ctrl.pb.Route.Egress.peerData:type_name -> ziti.ctrl.pb.Route.Egress.PeerDataEntry + 50, // 25: ziti.ctrl.pb.Route.Egress.peerData:type_name -> ziti.ctrl.pb.Route.Egress.PeerDataEntry 7, // 26: ziti.ctrl.pb.Route.Forward.dstType:type_name -> ziti.ctrl.pb.DestType 27, // [27:27] is the sub-list for method output_type 27, // [27:27] is the sub-list for method input_type @@ -3432,8 +3587,20 @@ func file_ctrl_proto_init() { return nil } } - file_ctrl_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterLinks_RouterLink); i { + file_ctrl_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CtrlPipeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ctrl_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CtrlPipeResponse); i { case 0: return &v.state case 1: @@ -3445,6 +3612,18 @@ func file_ctrl_proto_init() { } } file_ctrl_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RouterLinks_RouterLink); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ctrl_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Route_Egress); i { case 0: return &v.state @@ -3456,7 +3635,7 @@ func file_ctrl_proto_init() { return nil } } - file_ctrl_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_ctrl_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Route_Forward); i { case 0: return &v.state @@ -3468,7 +3647,7 @@ func file_ctrl_proto_init() { return nil } } - file_ctrl_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_ctrl_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InspectResponse_InspectValue); i { case 0: return &v.state @@ -3487,7 +3666,7 @@ func file_ctrl_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ctrl_proto_rawDesc, NumEnums: 9, - NumMessages: 41, + NumMessages: 43, NumExtensions: 0, NumServices: 0, }, diff --git a/common/pb/ctrl_pb/ctrl.proto b/common/pb/ctrl_pb/ctrl.proto index eb64a1be2..4d8369892 100644 --- a/common/pb/ctrl_pb/ctrl.proto +++ b/common/pb/ctrl_pb/ctrl.proto @@ -41,13 +41,22 @@ enum ContentType { DecommissionRouterRequestType = 1043; PeerStateChangeRequestType = 1050; + + // Control Channel Pipes + CtrlPipeRequestType = 1060; + CtrlPipeResponseType = 1061; + CtrlPipeDataType = 1062; + CtrlPipeCloseType = 1063; } enum ControlHeaders { NoneHeader = 0; + ListenersHeader = 10; RouterMetadataHeader = 11; CapabilitiesHeader = 12; + + CtrlPipeIdHeader = 20; } enum RouterCapability { @@ -287,4 +296,15 @@ message PeerStateChanges { message RouterMetadata { repeated RouterCapability capabilities = 1; -} \ No newline at end of file +} + +message CtrlPipeRequest { + string destination = 1; + uint64 timeoutMillis = 2; + uint32 connId = 3; +} + +message CtrlPipeResponse { + bool success = 1; + string msg = 2; +} diff --git a/common/pb/ctrl_pb/impl.go b/common/pb/ctrl_pb/impl.go index 0b08aee27..55df10c1f 100644 --- a/common/pb/ctrl_pb/impl.go +++ b/common/pb/ctrl_pb/impl.go @@ -107,3 +107,11 @@ func (request *UpdateCtrlAddresses) GetContentType() int32 { func (request *PeerStateChanges) GetContentType() int32 { return int32(ContentType_PeerStateChangeRequestType) } + +func (request *CtrlPipeRequest) GetContentType() int32 { + return int32(ContentType_CtrlPipeRequestType) +} + +func (request *CtrlPipeResponse) GetContentType() int32 { + return int32(ContentType_CtrlPipeResponseType) +} diff --git a/common/pb/mgmt_pb/impl.go b/common/pb/mgmt_pb/impl.go index b8506d876..dc201d1c7 100644 --- a/common/pb/mgmt_pb/impl.go +++ b/common/pb/mgmt_pb/impl.go @@ -8,6 +8,14 @@ func (request *InspectResponse) GetContentType() int32 { return int32(ContentType_InspectResponseType) } +func (request *MgmtPipeRequest) GetContentType() int32 { + return int32(ContentType_MgmtPipeRequestType) +} + +func (request *MgmtPipeResponse) GetContentType() int32 { + return int32(ContentType_MgmtPipeResponseType) +} + func (request *RaftMemberListResponse) GetContentType() int32 { return int32(ContentType_RaftListMembersResponseType) } @@ -71,3 +79,11 @@ func (request *ValidateIdentityConnectionStatusesResponse) GetContentType() int3 func (request *RouterIdentityConnectionStatusesDetails) GetContentType() int32 { return int32(ContentType_ValidateIdentityConnectionStatusesResultType) } + +func (x DestinationType) CheckControllers() bool { + return x == DestinationType_Any || x == DestinationType_Controller +} + +func (x DestinationType) CheckRouters() bool { + return x == DestinationType_Any || x == DestinationType_Router +} diff --git a/common/pb/mgmt_pb/mgmt.pb.go b/common/pb/mgmt_pb/mgmt.pb.go index 3d13ba444..16187c292 100644 --- a/common/pb/mgmt_pb/mgmt.pb.go +++ b/common/pb/mgmt_pb/mgmt.pb.go @@ -36,6 +36,11 @@ const ( // Inspect ContentType_InspectRequestType ContentType = 10048 ContentType_InspectResponseType ContentType = 10049 + // Management Pipes + ContentType_MgmtPipeRequestType ContentType = 10060 + ContentType_MgmtPipeResponseType ContentType = 10061 + ContentType_MgmtPipeDataType ContentType = 10062 + ContentType_MgmtPipeCloseType ContentType = 10063 // Snapshot db ContentType_SnapshotDbRequestType ContentType = 10070 // Router Mgmt @@ -85,6 +90,10 @@ var ( 10047: "StreamTracesEventType", 10048: "InspectRequestType", 10049: "InspectResponseType", + 10060: "MgmtPipeRequestType", + 10061: "MgmtPipeResponseType", + 10062: "MgmtPipeDataType", + 10063: "MgmtPipeCloseType", 10070: "SnapshotDbRequestType", 10071: "RouterDebugForgetLinkRequestType", 10072: "RouterDebugToggleCtrlChannelRequestType", @@ -127,6 +136,10 @@ var ( "StreamTracesEventType": 10047, "InspectRequestType": 10048, "InspectResponseType": 10049, + "MgmtPipeRequestType": 10060, + "MgmtPipeResponseType": 10061, + "MgmtPipeDataType": 10062, + "MgmtPipeCloseType": 10063, "SnapshotDbRequestType": 10070, "RouterDebugForgetLinkRequestType": 10071, "RouterDebugToggleCtrlChannelRequestType": 10072, @@ -191,10 +204,11 @@ func (ContentType) EnumDescriptor() ([]byte, []int) { type Header int32 const ( - Header_NoneHeader Header = 0 - Header_EventTypeHeader Header = 10 - Header_CtrlChanToggle Header = 11 - Header_ControllerId Header = 12 + Header_NoneHeader Header = 0 + Header_EventTypeHeader Header = 10 + Header_CtrlChanToggle Header = 11 + Header_ControllerId Header = 12 + Header_MgmtPipeIdHeader Header = 20 ) // Enum value maps for Header. @@ -204,12 +218,14 @@ var ( 10: "EventTypeHeader", 11: "CtrlChanToggle", 12: "ControllerId", + 20: "MgmtPipeIdHeader", } Header_value = map[string]int32{ - "NoneHeader": 0, - "EventTypeHeader": 10, - "CtrlChanToggle": 11, - "ControllerId": 12, + "NoneHeader": 0, + "EventTypeHeader": 10, + "CtrlChanToggle": 11, + "ControllerId": 12, + "MgmtPipeIdHeader": 20, } ) @@ -341,6 +357,55 @@ func (TraceFilterType) EnumDescriptor() ([]byte, []int) { return file_mgmt_proto_rawDescGZIP(), []int{3} } +type DestinationType int32 + +const ( + DestinationType_Any DestinationType = 0 + DestinationType_Controller DestinationType = 1 + DestinationType_Router DestinationType = 2 +) + +// Enum value maps for DestinationType. +var ( + DestinationType_name = map[int32]string{ + 0: "Any", + 1: "Controller", + 2: "Router", + } + DestinationType_value = map[string]int32{ + "Any": 0, + "Controller": 1, + "Router": 2, + } +) + +func (x DestinationType) Enum() *DestinationType { + p := new(DestinationType) + *p = x + return p +} + +func (x DestinationType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DestinationType) Descriptor() protoreflect.EnumDescriptor { + return file_mgmt_proto_enumTypes[4].Descriptor() +} + +func (DestinationType) Type() protoreflect.EnumType { + return &file_mgmt_proto_enumTypes[4] +} + +func (x DestinationType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DestinationType.Descriptor instead. +func (DestinationType) EnumDescriptor() ([]byte, []int) { + return file_mgmt_proto_rawDescGZIP(), []int{4} +} + type TerminatorState int32 const ( @@ -380,11 +445,11 @@ func (x TerminatorState) String() string { } func (TerminatorState) Descriptor() protoreflect.EnumDescriptor { - return file_mgmt_proto_enumTypes[4].Descriptor() + return file_mgmt_proto_enumTypes[5].Descriptor() } func (TerminatorState) Type() protoreflect.EnumType { - return &file_mgmt_proto_enumTypes[4] + return &file_mgmt_proto_enumTypes[5] } func (x TerminatorState) Number() protoreflect.EnumNumber { @@ -393,7 +458,7 @@ func (x TerminatorState) Number() protoreflect.EnumNumber { // Deprecated: Use TerminatorState.Descriptor instead. func (TerminatorState) EnumDescriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{4} + return file_mgmt_proto_rawDescGZIP(), []int{5} } type LinkState int32 @@ -432,11 +497,11 @@ func (x LinkState) String() string { } func (LinkState) Descriptor() protoreflect.EnumDescriptor { - return file_mgmt_proto_enumTypes[5].Descriptor() + return file_mgmt_proto_enumTypes[6].Descriptor() } func (LinkState) Type() protoreflect.EnumType { - return &file_mgmt_proto_enumTypes[5] + return &file_mgmt_proto_enumTypes[6] } func (x LinkState) Number() protoreflect.EnumNumber { @@ -445,7 +510,7 @@ func (x LinkState) Number() protoreflect.EnumNumber { // Deprecated: Use LinkState.Descriptor instead. func (LinkState) EnumDescriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{5} + return file_mgmt_proto_rawDescGZIP(), []int{6} } type StreamMetricsRequest struct { @@ -992,6 +1057,132 @@ func (x *InspectResponse) GetValues() []*InspectResponse_InspectValue { return nil } +type MgmtPipeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DestinationType DestinationType `protobuf:"varint,1,opt,name=destinationType,proto3,enum=ziti.mgmt_pb.DestinationType" json:"destinationType,omitempty"` + Destination string `protobuf:"bytes,2,opt,name=destination,proto3" json:"destination,omitempty"` + TimeoutMillis uint64 `protobuf:"varint,3,opt,name=timeoutMillis,proto3" json:"timeoutMillis,omitempty"` +} + +func (x *MgmtPipeRequest) Reset() { + *x = MgmtPipeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_mgmt_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MgmtPipeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MgmtPipeRequest) ProtoMessage() {} + +func (x *MgmtPipeRequest) ProtoReflect() protoreflect.Message { + mi := &file_mgmt_proto_msgTypes[8] + 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 MgmtPipeRequest.ProtoReflect.Descriptor instead. +func (*MgmtPipeRequest) Descriptor() ([]byte, []int) { + return file_mgmt_proto_rawDescGZIP(), []int{8} +} + +func (x *MgmtPipeRequest) GetDestinationType() DestinationType { + if x != nil { + return x.DestinationType + } + return DestinationType_Any +} + +func (x *MgmtPipeRequest) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *MgmtPipeRequest) GetTimeoutMillis() uint64 { + if x != nil { + return x.TimeoutMillis + } + return 0 +} + +type MgmtPipeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + ConnId uint32 `protobuf:"varint,2,opt,name=connId,proto3" json:"connId,omitempty"` + Msg string `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (x *MgmtPipeResponse) Reset() { + *x = MgmtPipeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_mgmt_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MgmtPipeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MgmtPipeResponse) ProtoMessage() {} + +func (x *MgmtPipeResponse) ProtoReflect() protoreflect.Message { + mi := &file_mgmt_proto_msgTypes[9] + 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 MgmtPipeResponse.ProtoReflect.Descriptor instead. +func (*MgmtPipeResponse) Descriptor() ([]byte, []int) { + return file_mgmt_proto_rawDescGZIP(), []int{9} +} + +func (x *MgmtPipeResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *MgmtPipeResponse) GetConnId() uint32 { + if x != nil { + return x.ConnId + } + return 0 +} + +func (x *MgmtPipeResponse) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + // Raft type RaftMember struct { state protoimpl.MessageState @@ -1009,7 +1200,7 @@ type RaftMember struct { func (x *RaftMember) Reset() { *x = RaftMember{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[8] + mi := &file_mgmt_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1022,7 +1213,7 @@ func (x *RaftMember) String() string { func (*RaftMember) ProtoMessage() {} func (x *RaftMember) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[8] + mi := &file_mgmt_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1035,7 +1226,7 @@ func (x *RaftMember) ProtoReflect() protoreflect.Message { // Deprecated: Use RaftMember.ProtoReflect.Descriptor instead. func (*RaftMember) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{8} + return file_mgmt_proto_rawDescGZIP(), []int{10} } func (x *RaftMember) GetId() string { @@ -1091,7 +1282,7 @@ type RaftMemberListResponse struct { func (x *RaftMemberListResponse) Reset() { *x = RaftMemberListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[9] + mi := &file_mgmt_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1104,7 +1295,7 @@ func (x *RaftMemberListResponse) String() string { func (*RaftMemberListResponse) ProtoMessage() {} func (x *RaftMemberListResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[9] + mi := &file_mgmt_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1117,7 +1308,7 @@ func (x *RaftMemberListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RaftMemberListResponse.ProtoReflect.Descriptor instead. func (*RaftMemberListResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{9} + return file_mgmt_proto_rawDescGZIP(), []int{11} } func (x *RaftMemberListResponse) GetMembers() []*RaftMember { @@ -1139,7 +1330,7 @@ type ValidateTerminatorsRequest struct { func (x *ValidateTerminatorsRequest) Reset() { *x = ValidateTerminatorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[10] + mi := &file_mgmt_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1152,7 +1343,7 @@ func (x *ValidateTerminatorsRequest) String() string { func (*ValidateTerminatorsRequest) ProtoMessage() {} func (x *ValidateTerminatorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[10] + mi := &file_mgmt_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1165,7 +1356,7 @@ func (x *ValidateTerminatorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateTerminatorsRequest.ProtoReflect.Descriptor instead. func (*ValidateTerminatorsRequest) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{10} + return file_mgmt_proto_rawDescGZIP(), []int{12} } func (x *ValidateTerminatorsRequest) GetFilter() string { @@ -1195,7 +1386,7 @@ type ValidateTerminatorsResponse struct { func (x *ValidateTerminatorsResponse) Reset() { *x = ValidateTerminatorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[11] + mi := &file_mgmt_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1208,7 +1399,7 @@ func (x *ValidateTerminatorsResponse) String() string { func (*ValidateTerminatorsResponse) ProtoMessage() {} func (x *ValidateTerminatorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[11] + mi := &file_mgmt_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1221,7 +1412,7 @@ func (x *ValidateTerminatorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateTerminatorsResponse.ProtoReflect.Descriptor instead. func (*ValidateTerminatorsResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{11} + return file_mgmt_proto_rawDescGZIP(), []int{13} } func (x *ValidateTerminatorsResponse) GetSuccess() bool { @@ -1267,7 +1458,7 @@ type TerminatorDetail struct { func (x *TerminatorDetail) Reset() { *x = TerminatorDetail{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[12] + mi := &file_mgmt_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1280,7 +1471,7 @@ func (x *TerminatorDetail) String() string { func (*TerminatorDetail) ProtoMessage() {} func (x *TerminatorDetail) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[12] + mi := &file_mgmt_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1293,7 +1484,7 @@ func (x *TerminatorDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use TerminatorDetail.ProtoReflect.Descriptor instead. func (*TerminatorDetail) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{12} + return file_mgmt_proto_rawDescGZIP(), []int{14} } func (x *TerminatorDetail) GetTerminatorId() string { @@ -1391,7 +1582,7 @@ type ValidateRouterLinksRequest struct { func (x *ValidateRouterLinksRequest) Reset() { *x = ValidateRouterLinksRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[13] + mi := &file_mgmt_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1404,7 +1595,7 @@ func (x *ValidateRouterLinksRequest) String() string { func (*ValidateRouterLinksRequest) ProtoMessage() {} func (x *ValidateRouterLinksRequest) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[13] + mi := &file_mgmt_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1417,7 +1608,7 @@ func (x *ValidateRouterLinksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRouterLinksRequest.ProtoReflect.Descriptor instead. func (*ValidateRouterLinksRequest) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{13} + return file_mgmt_proto_rawDescGZIP(), []int{15} } func (x *ValidateRouterLinksRequest) GetFilter() string { @@ -1440,7 +1631,7 @@ type ValidateRouterLinksResponse struct { func (x *ValidateRouterLinksResponse) Reset() { *x = ValidateRouterLinksResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[14] + mi := &file_mgmt_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1453,7 +1644,7 @@ func (x *ValidateRouterLinksResponse) String() string { func (*ValidateRouterLinksResponse) ProtoMessage() {} func (x *ValidateRouterLinksResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[14] + mi := &file_mgmt_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1466,7 +1657,7 @@ func (x *ValidateRouterLinksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRouterLinksResponse.ProtoReflect.Descriptor instead. func (*ValidateRouterLinksResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{14} + return file_mgmt_proto_rawDescGZIP(), []int{16} } func (x *ValidateRouterLinksResponse) GetSuccess() bool { @@ -1505,7 +1696,7 @@ type RouterLinkDetails struct { func (x *RouterLinkDetails) Reset() { *x = RouterLinkDetails{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[15] + mi := &file_mgmt_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1518,7 +1709,7 @@ func (x *RouterLinkDetails) String() string { func (*RouterLinkDetails) ProtoMessage() {} func (x *RouterLinkDetails) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[15] + mi := &file_mgmt_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1531,7 +1722,7 @@ func (x *RouterLinkDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use RouterLinkDetails.ProtoReflect.Descriptor instead. func (*RouterLinkDetails) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{15} + return file_mgmt_proto_rawDescGZIP(), []int{17} } func (x *RouterLinkDetails) GetRouterId() string { @@ -1586,7 +1777,7 @@ type RouterLinkDetail struct { func (x *RouterLinkDetail) Reset() { *x = RouterLinkDetail{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[16] + mi := &file_mgmt_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1599,7 +1790,7 @@ func (x *RouterLinkDetail) String() string { func (*RouterLinkDetail) ProtoMessage() {} func (x *RouterLinkDetail) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[16] + mi := &file_mgmt_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1612,7 +1803,7 @@ func (x *RouterLinkDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use RouterLinkDetail.ProtoReflect.Descriptor instead. func (*RouterLinkDetail) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{16} + return file_mgmt_proto_rawDescGZIP(), []int{18} } func (x *RouterLinkDetail) GetLinkId() string { @@ -1675,7 +1866,7 @@ type ValidateRouterSdkTerminatorsRequest struct { func (x *ValidateRouterSdkTerminatorsRequest) Reset() { *x = ValidateRouterSdkTerminatorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[17] + mi := &file_mgmt_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1688,7 +1879,7 @@ func (x *ValidateRouterSdkTerminatorsRequest) String() string { func (*ValidateRouterSdkTerminatorsRequest) ProtoMessage() {} func (x *ValidateRouterSdkTerminatorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[17] + mi := &file_mgmt_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1701,7 +1892,7 @@ func (x *ValidateRouterSdkTerminatorsRequest) ProtoReflect() protoreflect.Messag // Deprecated: Use ValidateRouterSdkTerminatorsRequest.ProtoReflect.Descriptor instead. func (*ValidateRouterSdkTerminatorsRequest) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{17} + return file_mgmt_proto_rawDescGZIP(), []int{19} } func (x *ValidateRouterSdkTerminatorsRequest) GetFilter() string { @@ -1724,7 +1915,7 @@ type ValidateRouterSdkTerminatorsResponse struct { func (x *ValidateRouterSdkTerminatorsResponse) Reset() { *x = ValidateRouterSdkTerminatorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[18] + mi := &file_mgmt_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1737,7 +1928,7 @@ func (x *ValidateRouterSdkTerminatorsResponse) String() string { func (*ValidateRouterSdkTerminatorsResponse) ProtoMessage() {} func (x *ValidateRouterSdkTerminatorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[18] + mi := &file_mgmt_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1750,7 +1941,7 @@ func (x *ValidateRouterSdkTerminatorsResponse) ProtoReflect() protoreflect.Messa // Deprecated: Use ValidateRouterSdkTerminatorsResponse.ProtoReflect.Descriptor instead. func (*ValidateRouterSdkTerminatorsResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{18} + return file_mgmt_proto_rawDescGZIP(), []int{20} } func (x *ValidateRouterSdkTerminatorsResponse) GetSuccess() bool { @@ -1789,7 +1980,7 @@ type RouterSdkTerminatorsDetails struct { func (x *RouterSdkTerminatorsDetails) Reset() { *x = RouterSdkTerminatorsDetails{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[19] + mi := &file_mgmt_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1802,7 +1993,7 @@ func (x *RouterSdkTerminatorsDetails) String() string { func (*RouterSdkTerminatorsDetails) ProtoMessage() {} func (x *RouterSdkTerminatorsDetails) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[19] + mi := &file_mgmt_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1815,7 +2006,7 @@ func (x *RouterSdkTerminatorsDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use RouterSdkTerminatorsDetails.ProtoReflect.Descriptor instead. func (*RouterSdkTerminatorsDetails) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{19} + return file_mgmt_proto_rawDescGZIP(), []int{21} } func (x *RouterSdkTerminatorsDetails) GetRouterId() string { @@ -1870,7 +2061,7 @@ type RouterSdkTerminatorDetail struct { func (x *RouterSdkTerminatorDetail) Reset() { *x = RouterSdkTerminatorDetail{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[20] + mi := &file_mgmt_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1883,7 +2074,7 @@ func (x *RouterSdkTerminatorDetail) String() string { func (*RouterSdkTerminatorDetail) ProtoMessage() {} func (x *RouterSdkTerminatorDetail) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[20] + mi := &file_mgmt_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1896,7 +2087,7 @@ func (x *RouterSdkTerminatorDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use RouterSdkTerminatorDetail.ProtoReflect.Descriptor instead. func (*RouterSdkTerminatorDetail) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{20} + return file_mgmt_proto_rawDescGZIP(), []int{22} } func (x *RouterSdkTerminatorDetail) GetTerminatorId() string { @@ -1960,7 +2151,7 @@ type ValidateRouterDataModelRequest struct { func (x *ValidateRouterDataModelRequest) Reset() { *x = ValidateRouterDataModelRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[21] + mi := &file_mgmt_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1973,7 +2164,7 @@ func (x *ValidateRouterDataModelRequest) String() string { func (*ValidateRouterDataModelRequest) ProtoMessage() {} func (x *ValidateRouterDataModelRequest) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[21] + mi := &file_mgmt_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1986,7 +2177,7 @@ func (x *ValidateRouterDataModelRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRouterDataModelRequest.ProtoReflect.Descriptor instead. func (*ValidateRouterDataModelRequest) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{21} + return file_mgmt_proto_rawDescGZIP(), []int{23} } func (x *ValidateRouterDataModelRequest) GetRouterFilter() string { @@ -2016,7 +2207,7 @@ type ValidateRouterDataModelResponse struct { func (x *ValidateRouterDataModelResponse) Reset() { *x = ValidateRouterDataModelResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[22] + mi := &file_mgmt_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2029,7 +2220,7 @@ func (x *ValidateRouterDataModelResponse) String() string { func (*ValidateRouterDataModelResponse) ProtoMessage() {} func (x *ValidateRouterDataModelResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[22] + mi := &file_mgmt_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2042,7 +2233,7 @@ func (x *ValidateRouterDataModelResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidateRouterDataModelResponse.ProtoReflect.Descriptor instead. func (*ValidateRouterDataModelResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{22} + return file_mgmt_proto_rawDescGZIP(), []int{24} } func (x *ValidateRouterDataModelResponse) GetSuccess() bool { @@ -2081,7 +2272,7 @@ type RouterDataModelDetails struct { func (x *RouterDataModelDetails) Reset() { *x = RouterDataModelDetails{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[23] + mi := &file_mgmt_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2094,7 +2285,7 @@ func (x *RouterDataModelDetails) String() string { func (*RouterDataModelDetails) ProtoMessage() {} func (x *RouterDataModelDetails) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[23] + mi := &file_mgmt_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2107,7 +2298,7 @@ func (x *RouterDataModelDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use RouterDataModelDetails.ProtoReflect.Descriptor instead. func (*RouterDataModelDetails) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{23} + return file_mgmt_proto_rawDescGZIP(), []int{25} } func (x *RouterDataModelDetails) GetComponentType() string { @@ -2156,7 +2347,7 @@ type ValidateIdentityConnectionStatusesRequest struct { func (x *ValidateIdentityConnectionStatusesRequest) Reset() { *x = ValidateIdentityConnectionStatusesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[24] + mi := &file_mgmt_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2169,7 +2360,7 @@ func (x *ValidateIdentityConnectionStatusesRequest) String() string { func (*ValidateIdentityConnectionStatusesRequest) ProtoMessage() {} func (x *ValidateIdentityConnectionStatusesRequest) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[24] + mi := &file_mgmt_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2182,7 +2373,7 @@ func (x *ValidateIdentityConnectionStatusesRequest) ProtoReflect() protoreflect. // Deprecated: Use ValidateIdentityConnectionStatusesRequest.ProtoReflect.Descriptor instead. func (*ValidateIdentityConnectionStatusesRequest) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{24} + return file_mgmt_proto_rawDescGZIP(), []int{26} } func (x *ValidateIdentityConnectionStatusesRequest) GetRouterFilter() string { @@ -2205,7 +2396,7 @@ type ValidateIdentityConnectionStatusesResponse struct { func (x *ValidateIdentityConnectionStatusesResponse) Reset() { *x = ValidateIdentityConnectionStatusesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[25] + mi := &file_mgmt_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2218,7 +2409,7 @@ func (x *ValidateIdentityConnectionStatusesResponse) String() string { func (*ValidateIdentityConnectionStatusesResponse) ProtoMessage() {} func (x *ValidateIdentityConnectionStatusesResponse) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[25] + mi := &file_mgmt_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2231,7 +2422,7 @@ func (x *ValidateIdentityConnectionStatusesResponse) ProtoReflect() protoreflect // Deprecated: Use ValidateIdentityConnectionStatusesResponse.ProtoReflect.Descriptor instead. func (*ValidateIdentityConnectionStatusesResponse) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{25} + return file_mgmt_proto_rawDescGZIP(), []int{27} } func (x *ValidateIdentityConnectionStatusesResponse) GetSuccess() bool { @@ -2270,7 +2461,7 @@ type RouterIdentityConnectionStatusesDetails struct { func (x *RouterIdentityConnectionStatusesDetails) Reset() { *x = RouterIdentityConnectionStatusesDetails{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[26] + mi := &file_mgmt_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2283,7 +2474,7 @@ func (x *RouterIdentityConnectionStatusesDetails) String() string { func (*RouterIdentityConnectionStatusesDetails) ProtoMessage() {} func (x *RouterIdentityConnectionStatusesDetails) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[26] + mi := &file_mgmt_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2296,7 +2487,7 @@ func (x *RouterIdentityConnectionStatusesDetails) ProtoReflect() protoreflect.Me // Deprecated: Use RouterIdentityConnectionStatusesDetails.ProtoReflect.Descriptor instead. func (*RouterIdentityConnectionStatusesDetails) Descriptor() ([]byte, []int) { - return file_mgmt_proto_rawDescGZIP(), []int{26} + return file_mgmt_proto_rawDescGZIP(), []int{28} } func (x *RouterIdentityConnectionStatusesDetails) GetComponentType() string { @@ -2346,7 +2537,7 @@ type StreamMetricsRequest_MetricMatcher struct { func (x *StreamMetricsRequest_MetricMatcher) Reset() { *x = StreamMetricsRequest_MetricMatcher{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[27] + mi := &file_mgmt_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2359,7 +2550,7 @@ func (x *StreamMetricsRequest_MetricMatcher) String() string { func (*StreamMetricsRequest_MetricMatcher) ProtoMessage() {} func (x *StreamMetricsRequest_MetricMatcher) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[27] + mi := &file_mgmt_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2403,7 +2594,7 @@ type StreamMetricsEvent_IntervalMetric struct { func (x *StreamMetricsEvent_IntervalMetric) Reset() { *x = StreamMetricsEvent_IntervalMetric{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[31] + mi := &file_mgmt_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2416,7 +2607,7 @@ func (x *StreamMetricsEvent_IntervalMetric) String() string { func (*StreamMetricsEvent_IntervalMetric) ProtoMessage() {} func (x *StreamMetricsEvent_IntervalMetric) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[31] + mi := &file_mgmt_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2473,7 +2664,7 @@ type InspectResponse_InspectValue struct { func (x *InspectResponse_InspectValue) Reset() { *x = InspectResponse_InspectValue{} if protoimpl.UnsafeEnabled { - mi := &file_mgmt_proto_msgTypes[34] + mi := &file_mgmt_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2486,7 +2677,7 @@ func (x *InspectResponse_InspectValue) String() string { func (*InspectResponse_InspectValue) ProtoMessage() {} func (x *InspectResponse_InspectValue) ProtoReflect() protoreflect.Message { - mi := &file_mgmt_proto_msgTypes[34] + mi := &file_mgmt_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2673,324 +2864,351 @@ var file_mgmt_proto_rawDesc = []byte{ 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x0a, - 0x52, 0x61, 0x66, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x64, - 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x64, 0x64, 0x72, 0x12, 0x18, - 0x0a, 0x07, 0x49, 0x73, 0x56, 0x6f, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x49, 0x73, 0x56, 0x6f, 0x74, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x4c, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x4c, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, - 0x0a, 0x0b, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x22, 0x4c, 0x0a, 0x16, 0x52, 0x61, 0x66, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x7a, 0x69, - 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x66, 0x74, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x54, - 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x49, 0x6e, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x22, 0x7b, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x65, 0x72, 0x6d, 0x69, - 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0x81, 0x03, 0x0a, 0x10, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x6f, - 0x73, 0x74, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, - 0x74, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, - 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x34, 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x73, 0x0a, 0x1b, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, - 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0xd5, 0x01, 0x0a, 0x11, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x7a, 0x69, - 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0b, 0x6c, 0x69, 0x6e, - 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x10, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, - 0x06, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, - 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0b, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x17, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, - 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x64, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, - 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, - 0x69, 0x61, 0x6c, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x69, 0x61, - 0x6c, 0x65, 0x64, 0x22, 0x3d, 0x0a, 0x23, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x22, 0x7c, 0x0a, 0x24, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0xe0, 0x01, 0x0a, 0x1b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, - 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x22, 0xa4, 0x02, 0x0a, 0x19, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, - 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, - 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x28, - 0x0a, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, - 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, - 0x61, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x22, 0x68, 0x0a, 0x1e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, - 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x74, 0x72, 0x6c, 0x22, 0x7d, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x0f, + 0x4d, 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x47, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, + 0x22, 0x56, 0x0a, 0x10, 0x4d, 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x6e, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x63, 0x6f, 0x6e, 0x6e, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0xa2, 0x01, 0x0a, 0x0a, 0x52, 0x61, 0x66, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x64, 0x64, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x64, 0x64, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x49, + 0x73, 0x56, 0x6f, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, 0x73, + 0x56, 0x6f, 0x74, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x49, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x49, + 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0b, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x4c, 0x0a, + 0x16, 0x52, 0x61, 0x66, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x66, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x54, 0x0a, 0x1a, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x22, 0x7b, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x81, + 0x03, 0x0a, 0x10, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, + 0x33, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, + 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x69, 0x78, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x22, 0x34, 0x0a, 0x1a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x73, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, - 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, - 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x4f, - 0x0a, 0x29, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, - 0x88, 0x01, 0x0a, 0x2a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x27, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, - 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2a, 0xb6, 0x0b, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, - 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, 0x1a, - 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x6f, - 0x67, 0x67, 0x6c, 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, 0x1e, - 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, - 0x4e, 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, 0x12, - 0x1a, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, 0x49, - 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xc0, 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, 0x1a, - 0x0a, 0x15, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x4c, - 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd7, - 0x4e, 0x12, 0x2c, 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, - 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, 0x12, - 0x26, 0x0a, 0x21, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, - 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, 0x0a, - 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdc, - 0x4e, 0x12, 0x1d, 0x0a, 0x18, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, 0x73, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, 0x4e, - 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, - 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xde, - 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xdf, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xe0, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, - 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, 0x74, - 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xe2, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xe3, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, 0x0a, - 0x0e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, 0x10, - 0xe5, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, 0x1c, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, 0x12, - 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xf7, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, - 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x12, 0x2c, - 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x4e, 0x12, 0x2d, 0x0a, 0x28, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, - 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfb, 0x4e, 0x12, 0x2b, 0x0a, 0x26, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, - 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfc, 0x4e, 0x12, 0x27, 0x0a, 0x22, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, - 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfd, - 0x4e, 0x12, 0x28, 0x0a, 0x23, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd5, 0x01, + 0x0a, 0x11, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, + 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, + 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x69, + 0x6e, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x6e, 0x6b, + 0x49, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x09, + 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x4c, 0x69, + 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x64, 0x65, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x61, 0x6c, + 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, + 0x22, 0x3d, 0x0a, 0x23, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, + 0x7c, 0x0a, 0x24, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe0, 0x01, + 0x0a, 0x1b, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x41, 0x0a, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0xa4, 0x02, 0x0a, 0x19, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x22, + 0x0a, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, + 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x6d, 0x67, 0x6d, + 0x74, 0x5f, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x09, 0x63, 0x74, 0x72, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x41, 0x74, 0x74, + 0x65, 0x6d, 0x70, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, + 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x22, 0x68, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, + 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, + 0x6c, 0x22, 0x7d, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfe, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, - 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xff, 0x4e, 0x12, 0x32, 0x0a, 0x2d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0x80, 0x4f, 0x12, 0x33, 0x0a, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x81, 0x4f, 0x12, 0x31, 0x0a, 0x2c, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x82, 0x4f, 0x2a, - 0x53, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, - 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x12, - 0x0a, 0x0e, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, - 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x10, 0x0c, 0x2a, 0x78, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, - 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, - 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, - 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, - 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, - 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, - 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x77, 0x0a, 0x0f, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, - 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, - 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, - 0x13, 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x10, 0x04, 0x2a, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, - 0x44, 0x69, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, - 0x2f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x4f, 0x0a, 0x29, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, + 0x2a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x73, 0x2a, 0x9a, 0x0c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x1c, 0x0a, + 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x54, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, 0x4e, 0x12, 0x1c, + 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, 0x12, 0x1a, 0x0a, 0x15, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc0, + 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x4d, + 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xcc, 0x4e, 0x12, 0x19, 0x0a, 0x14, 0x4d, 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcd, 0x4e, + 0x12, 0x15, 0x0a, 0x10, 0x4d, 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xce, 0x4e, 0x12, 0x16, 0x0a, 0x11, 0x4d, 0x67, 0x6d, 0x74, 0x50, + 0x69, 0x70, 0x65, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcf, 0x4e, 0x12, + 0x1a, 0x0a, 0x15, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, + 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xd7, 0x4e, 0x12, 0x2c, 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, + 0x12, 0x26, 0x0a, 0x21, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, + 0x72, 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, + 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xdc, 0x4e, 0x12, 0x1d, 0x0a, 0x18, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, + 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, + 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, + 0x65, 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xde, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xdf, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xe0, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, + 0x74, 0x41, 0x64, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xe2, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xe3, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, + 0x0a, 0x0e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, + 0x10, 0xe5, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, + 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, + 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xf7, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, + 0x6b, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x12, + 0x2c, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x4e, 0x12, 0x2d, 0x0a, + 0x28, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, + 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfb, 0x4e, 0x12, 0x2b, 0x0a, 0x26, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, + 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfc, 0x4e, 0x12, 0x27, 0x0a, 0x22, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xfd, 0x4e, 0x12, 0x28, 0x0a, 0x23, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfe, 0x4e, 0x12, 0x26, 0x0a, 0x21, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xff, 0x4e, 0x12, 0x32, 0x0a, 0x2d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x80, 0x4f, 0x12, 0x33, 0x0a, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x81, 0x4f, 0x12, 0x31, 0x0a, + 0x2c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x82, 0x4f, + 0x2a, 0x69, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, + 0x6e, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, + 0x12, 0x0a, 0x0e, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x64, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x67, 0x6d, 0x74, 0x50, 0x69, 0x70, + 0x65, 0x49, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x14, 0x2a, 0x78, 0x0a, 0x16, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, + 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x10, 0x01, 0x12, 0x12, 0x0a, + 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, + 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x63, 0x65, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x43, 0x4c, + 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x45, + 0x10, 0x01, 0x2a, 0x36, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x10, 0x00, 0x12, 0x0e, + 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x10, 0x01, 0x12, 0x0a, + 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x10, 0x02, 0x2a, 0x77, 0x0a, 0x0f, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, + 0x05, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, + 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x13, + 0x0a, 0x0f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x10, 0x04, 0x2a, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, + 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x44, + 0x69, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, + 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3005,79 +3223,83 @@ func file_mgmt_proto_rawDescGZIP() []byte { return file_mgmt_proto_rawDescData } -var file_mgmt_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_mgmt_proto_msgTypes = make([]protoimpl.MessageInfo, 35) +var file_mgmt_proto_enumTypes = make([]protoimpl.EnumInfo, 7) +var file_mgmt_proto_msgTypes = make([]protoimpl.MessageInfo, 37) var file_mgmt_proto_goTypes = []interface{}{ (ContentType)(0), // 0: ziti.mgmt_pb.ContentType (Header)(0), // 1: ziti.mgmt_pb.Header (StreamCircuitEventType)(0), // 2: ziti.mgmt_pb.StreamCircuitEventType (TraceFilterType)(0), // 3: ziti.mgmt_pb.TraceFilterType - (TerminatorState)(0), // 4: ziti.mgmt_pb.TerminatorState - (LinkState)(0), // 5: ziti.mgmt_pb.LinkState - (*StreamMetricsRequest)(nil), // 6: ziti.mgmt_pb.StreamMetricsRequest - (*StreamMetricsEvent)(nil), // 7: ziti.mgmt_pb.StreamMetricsEvent - (*Path)(nil), // 8: ziti.mgmt_pb.Path - (*StreamCircuitsEvent)(nil), // 9: ziti.mgmt_pb.StreamCircuitsEvent - (*ToggleCircuitTracesRequest)(nil), // 10: ziti.mgmt_pb.ToggleCircuitTracesRequest - (*StreamTracesRequest)(nil), // 11: ziti.mgmt_pb.StreamTracesRequest - (*InspectRequest)(nil), // 12: ziti.mgmt_pb.InspectRequest - (*InspectResponse)(nil), // 13: ziti.mgmt_pb.InspectResponse - (*RaftMember)(nil), // 14: ziti.mgmt_pb.RaftMember - (*RaftMemberListResponse)(nil), // 15: ziti.mgmt_pb.RaftMemberListResponse - (*ValidateTerminatorsRequest)(nil), // 16: ziti.mgmt_pb.ValidateTerminatorsRequest - (*ValidateTerminatorsResponse)(nil), // 17: ziti.mgmt_pb.ValidateTerminatorsResponse - (*TerminatorDetail)(nil), // 18: ziti.mgmt_pb.TerminatorDetail - (*ValidateRouterLinksRequest)(nil), // 19: ziti.mgmt_pb.ValidateRouterLinksRequest - (*ValidateRouterLinksResponse)(nil), // 20: ziti.mgmt_pb.ValidateRouterLinksResponse - (*RouterLinkDetails)(nil), // 21: ziti.mgmt_pb.RouterLinkDetails - (*RouterLinkDetail)(nil), // 22: ziti.mgmt_pb.RouterLinkDetail - (*ValidateRouterSdkTerminatorsRequest)(nil), // 23: ziti.mgmt_pb.ValidateRouterSdkTerminatorsRequest - (*ValidateRouterSdkTerminatorsResponse)(nil), // 24: ziti.mgmt_pb.ValidateRouterSdkTerminatorsResponse - (*RouterSdkTerminatorsDetails)(nil), // 25: ziti.mgmt_pb.RouterSdkTerminatorsDetails - (*RouterSdkTerminatorDetail)(nil), // 26: ziti.mgmt_pb.RouterSdkTerminatorDetail - (*ValidateRouterDataModelRequest)(nil), // 27: ziti.mgmt_pb.ValidateRouterDataModelRequest - (*ValidateRouterDataModelResponse)(nil), // 28: ziti.mgmt_pb.ValidateRouterDataModelResponse - (*RouterDataModelDetails)(nil), // 29: ziti.mgmt_pb.RouterDataModelDetails - (*ValidateIdentityConnectionStatusesRequest)(nil), // 30: ziti.mgmt_pb.ValidateIdentityConnectionStatusesRequest - (*ValidateIdentityConnectionStatusesResponse)(nil), // 31: ziti.mgmt_pb.ValidateIdentityConnectionStatusesResponse - (*RouterIdentityConnectionStatusesDetails)(nil), // 32: ziti.mgmt_pb.RouterIdentityConnectionStatusesDetails - (*StreamMetricsRequest_MetricMatcher)(nil), // 33: ziti.mgmt_pb.StreamMetricsRequest.MetricMatcher - nil, // 34: ziti.mgmt_pb.StreamMetricsEvent.TagsEntry - nil, // 35: ziti.mgmt_pb.StreamMetricsEvent.IntMetricsEntry - nil, // 36: ziti.mgmt_pb.StreamMetricsEvent.FloatMetricsEntry - (*StreamMetricsEvent_IntervalMetric)(nil), // 37: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric - nil, // 38: ziti.mgmt_pb.StreamMetricsEvent.MetricGroupEntry - nil, // 39: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.ValuesEntry - (*InspectResponse_InspectValue)(nil), // 40: ziti.mgmt_pb.InspectResponse.InspectValue - (*timestamppb.Timestamp)(nil), // 41: google.protobuf.Timestamp + (DestinationType)(0), // 4: ziti.mgmt_pb.DestinationType + (TerminatorState)(0), // 5: ziti.mgmt_pb.TerminatorState + (LinkState)(0), // 6: ziti.mgmt_pb.LinkState + (*StreamMetricsRequest)(nil), // 7: ziti.mgmt_pb.StreamMetricsRequest + (*StreamMetricsEvent)(nil), // 8: ziti.mgmt_pb.StreamMetricsEvent + (*Path)(nil), // 9: ziti.mgmt_pb.Path + (*StreamCircuitsEvent)(nil), // 10: ziti.mgmt_pb.StreamCircuitsEvent + (*ToggleCircuitTracesRequest)(nil), // 11: ziti.mgmt_pb.ToggleCircuitTracesRequest + (*StreamTracesRequest)(nil), // 12: ziti.mgmt_pb.StreamTracesRequest + (*InspectRequest)(nil), // 13: ziti.mgmt_pb.InspectRequest + (*InspectResponse)(nil), // 14: ziti.mgmt_pb.InspectResponse + (*MgmtPipeRequest)(nil), // 15: ziti.mgmt_pb.MgmtPipeRequest + (*MgmtPipeResponse)(nil), // 16: ziti.mgmt_pb.MgmtPipeResponse + (*RaftMember)(nil), // 17: ziti.mgmt_pb.RaftMember + (*RaftMemberListResponse)(nil), // 18: ziti.mgmt_pb.RaftMemberListResponse + (*ValidateTerminatorsRequest)(nil), // 19: ziti.mgmt_pb.ValidateTerminatorsRequest + (*ValidateTerminatorsResponse)(nil), // 20: ziti.mgmt_pb.ValidateTerminatorsResponse + (*TerminatorDetail)(nil), // 21: ziti.mgmt_pb.TerminatorDetail + (*ValidateRouterLinksRequest)(nil), // 22: ziti.mgmt_pb.ValidateRouterLinksRequest + (*ValidateRouterLinksResponse)(nil), // 23: ziti.mgmt_pb.ValidateRouterLinksResponse + (*RouterLinkDetails)(nil), // 24: ziti.mgmt_pb.RouterLinkDetails + (*RouterLinkDetail)(nil), // 25: ziti.mgmt_pb.RouterLinkDetail + (*ValidateRouterSdkTerminatorsRequest)(nil), // 26: ziti.mgmt_pb.ValidateRouterSdkTerminatorsRequest + (*ValidateRouterSdkTerminatorsResponse)(nil), // 27: ziti.mgmt_pb.ValidateRouterSdkTerminatorsResponse + (*RouterSdkTerminatorsDetails)(nil), // 28: ziti.mgmt_pb.RouterSdkTerminatorsDetails + (*RouterSdkTerminatorDetail)(nil), // 29: ziti.mgmt_pb.RouterSdkTerminatorDetail + (*ValidateRouterDataModelRequest)(nil), // 30: ziti.mgmt_pb.ValidateRouterDataModelRequest + (*ValidateRouterDataModelResponse)(nil), // 31: ziti.mgmt_pb.ValidateRouterDataModelResponse + (*RouterDataModelDetails)(nil), // 32: ziti.mgmt_pb.RouterDataModelDetails + (*ValidateIdentityConnectionStatusesRequest)(nil), // 33: ziti.mgmt_pb.ValidateIdentityConnectionStatusesRequest + (*ValidateIdentityConnectionStatusesResponse)(nil), // 34: ziti.mgmt_pb.ValidateIdentityConnectionStatusesResponse + (*RouterIdentityConnectionStatusesDetails)(nil), // 35: ziti.mgmt_pb.RouterIdentityConnectionStatusesDetails + (*StreamMetricsRequest_MetricMatcher)(nil), // 36: ziti.mgmt_pb.StreamMetricsRequest.MetricMatcher + nil, // 37: ziti.mgmt_pb.StreamMetricsEvent.TagsEntry + nil, // 38: ziti.mgmt_pb.StreamMetricsEvent.IntMetricsEntry + nil, // 39: ziti.mgmt_pb.StreamMetricsEvent.FloatMetricsEntry + (*StreamMetricsEvent_IntervalMetric)(nil), // 40: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric + nil, // 41: ziti.mgmt_pb.StreamMetricsEvent.MetricGroupEntry + nil, // 42: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.ValuesEntry + (*InspectResponse_InspectValue)(nil), // 43: ziti.mgmt_pb.InspectResponse.InspectValue + (*timestamppb.Timestamp)(nil), // 44: google.protobuf.Timestamp } var file_mgmt_proto_depIdxs = []int32{ - 33, // 0: ziti.mgmt_pb.StreamMetricsRequest.matchers:type_name -> ziti.mgmt_pb.StreamMetricsRequest.MetricMatcher - 41, // 1: ziti.mgmt_pb.StreamMetricsEvent.timestamp:type_name -> google.protobuf.Timestamp - 34, // 2: ziti.mgmt_pb.StreamMetricsEvent.tags:type_name -> ziti.mgmt_pb.StreamMetricsEvent.TagsEntry - 35, // 3: ziti.mgmt_pb.StreamMetricsEvent.intMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntMetricsEntry - 36, // 4: ziti.mgmt_pb.StreamMetricsEvent.floatMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.FloatMetricsEntry - 37, // 5: ziti.mgmt_pb.StreamMetricsEvent.intervalMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric - 38, // 6: ziti.mgmt_pb.StreamMetricsEvent.metricGroup:type_name -> ziti.mgmt_pb.StreamMetricsEvent.MetricGroupEntry + 36, // 0: ziti.mgmt_pb.StreamMetricsRequest.matchers:type_name -> ziti.mgmt_pb.StreamMetricsRequest.MetricMatcher + 44, // 1: ziti.mgmt_pb.StreamMetricsEvent.timestamp:type_name -> google.protobuf.Timestamp + 37, // 2: ziti.mgmt_pb.StreamMetricsEvent.tags:type_name -> ziti.mgmt_pb.StreamMetricsEvent.TagsEntry + 38, // 3: ziti.mgmt_pb.StreamMetricsEvent.intMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntMetricsEntry + 39, // 4: ziti.mgmt_pb.StreamMetricsEvent.floatMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.FloatMetricsEntry + 40, // 5: ziti.mgmt_pb.StreamMetricsEvent.intervalMetrics:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric + 41, // 6: ziti.mgmt_pb.StreamMetricsEvent.metricGroup:type_name -> ziti.mgmt_pb.StreamMetricsEvent.MetricGroupEntry 2, // 7: ziti.mgmt_pb.StreamCircuitsEvent.eventType:type_name -> ziti.mgmt_pb.StreamCircuitEventType - 8, // 8: ziti.mgmt_pb.StreamCircuitsEvent.path:type_name -> ziti.mgmt_pb.Path + 9, // 8: ziti.mgmt_pb.StreamCircuitsEvent.path:type_name -> ziti.mgmt_pb.Path 3, // 9: ziti.mgmt_pb.StreamTracesRequest.filterType:type_name -> ziti.mgmt_pb.TraceFilterType - 40, // 10: ziti.mgmt_pb.InspectResponse.values:type_name -> ziti.mgmt_pb.InspectResponse.InspectValue - 14, // 11: ziti.mgmt_pb.RaftMemberListResponse.members:type_name -> ziti.mgmt_pb.RaftMember - 4, // 12: ziti.mgmt_pb.TerminatorDetail.state:type_name -> ziti.mgmt_pb.TerminatorState - 22, // 13: ziti.mgmt_pb.RouterLinkDetails.linkDetails:type_name -> ziti.mgmt_pb.RouterLinkDetail - 5, // 14: ziti.mgmt_pb.RouterLinkDetail.ctrlState:type_name -> ziti.mgmt_pb.LinkState - 5, // 15: ziti.mgmt_pb.RouterLinkDetail.routerState:type_name -> ziti.mgmt_pb.LinkState - 26, // 16: ziti.mgmt_pb.RouterSdkTerminatorsDetails.details:type_name -> ziti.mgmt_pb.RouterSdkTerminatorDetail - 4, // 17: ziti.mgmt_pb.RouterSdkTerminatorDetail.ctrlState:type_name -> ziti.mgmt_pb.TerminatorState - 41, // 18: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.intervalStartUTC:type_name -> google.protobuf.Timestamp - 41, // 19: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.intervalEndUTC:type_name -> google.protobuf.Timestamp - 39, // 20: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.values:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.ValuesEntry - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 43, // 10: ziti.mgmt_pb.InspectResponse.values:type_name -> ziti.mgmt_pb.InspectResponse.InspectValue + 4, // 11: ziti.mgmt_pb.MgmtPipeRequest.destinationType:type_name -> ziti.mgmt_pb.DestinationType + 17, // 12: ziti.mgmt_pb.RaftMemberListResponse.members:type_name -> ziti.mgmt_pb.RaftMember + 5, // 13: ziti.mgmt_pb.TerminatorDetail.state:type_name -> ziti.mgmt_pb.TerminatorState + 25, // 14: ziti.mgmt_pb.RouterLinkDetails.linkDetails:type_name -> ziti.mgmt_pb.RouterLinkDetail + 6, // 15: ziti.mgmt_pb.RouterLinkDetail.ctrlState:type_name -> ziti.mgmt_pb.LinkState + 6, // 16: ziti.mgmt_pb.RouterLinkDetail.routerState:type_name -> ziti.mgmt_pb.LinkState + 29, // 17: ziti.mgmt_pb.RouterSdkTerminatorsDetails.details:type_name -> ziti.mgmt_pb.RouterSdkTerminatorDetail + 5, // 18: ziti.mgmt_pb.RouterSdkTerminatorDetail.ctrlState:type_name -> ziti.mgmt_pb.TerminatorState + 44, // 19: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.intervalStartUTC:type_name -> google.protobuf.Timestamp + 44, // 20: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.intervalEndUTC:type_name -> google.protobuf.Timestamp + 42, // 21: ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.values:type_name -> ziti.mgmt_pb.StreamMetricsEvent.IntervalMetric.ValuesEntry + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_mgmt_proto_init() } @@ -3183,7 +3405,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RaftMember); i { + switch v := v.(*MgmtPipeRequest); i { case 0: return &v.state case 1: @@ -3195,7 +3417,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RaftMemberListResponse); i { + switch v := v.(*MgmtPipeResponse); i { case 0: return &v.state case 1: @@ -3207,7 +3429,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateTerminatorsRequest); i { + switch v := v.(*RaftMember); i { case 0: return &v.state case 1: @@ -3219,7 +3441,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateTerminatorsResponse); i { + switch v := v.(*RaftMemberListResponse); i { case 0: return &v.state case 1: @@ -3231,7 +3453,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TerminatorDetail); i { + switch v := v.(*ValidateTerminatorsRequest); i { case 0: return &v.state case 1: @@ -3243,7 +3465,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterLinksRequest); i { + switch v := v.(*ValidateTerminatorsResponse); i { case 0: return &v.state case 1: @@ -3255,7 +3477,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterLinksResponse); i { + switch v := v.(*TerminatorDetail); i { case 0: return &v.state case 1: @@ -3267,7 +3489,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterLinkDetails); i { + switch v := v.(*ValidateRouterLinksRequest); i { case 0: return &v.state case 1: @@ -3279,7 +3501,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterLinkDetail); i { + switch v := v.(*ValidateRouterLinksResponse); i { case 0: return &v.state case 1: @@ -3291,7 +3513,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterSdkTerminatorsRequest); i { + switch v := v.(*RouterLinkDetails); i { case 0: return &v.state case 1: @@ -3303,7 +3525,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterSdkTerminatorsResponse); i { + switch v := v.(*RouterLinkDetail); i { case 0: return &v.state case 1: @@ -3315,7 +3537,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterSdkTerminatorsDetails); i { + switch v := v.(*ValidateRouterSdkTerminatorsRequest); i { case 0: return &v.state case 1: @@ -3327,7 +3549,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterSdkTerminatorDetail); i { + switch v := v.(*ValidateRouterSdkTerminatorsResponse); i { case 0: return &v.state case 1: @@ -3339,7 +3561,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterDataModelRequest); i { + switch v := v.(*RouterSdkTerminatorsDetails); i { case 0: return &v.state case 1: @@ -3351,7 +3573,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateRouterDataModelResponse); i { + switch v := v.(*RouterSdkTerminatorDetail); i { case 0: return &v.state case 1: @@ -3363,7 +3585,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterDataModelDetails); i { + switch v := v.(*ValidateRouterDataModelRequest); i { case 0: return &v.state case 1: @@ -3375,7 +3597,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateIdentityConnectionStatusesRequest); i { + switch v := v.(*ValidateRouterDataModelResponse); i { case 0: return &v.state case 1: @@ -3387,7 +3609,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidateIdentityConnectionStatusesResponse); i { + switch v := v.(*RouterDataModelDetails); i { case 0: return &v.state case 1: @@ -3399,7 +3621,7 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouterIdentityConnectionStatusesDetails); i { + switch v := v.(*ValidateIdentityConnectionStatusesRequest); i { case 0: return &v.state case 1: @@ -3411,6 +3633,30 @@ func file_mgmt_proto_init() { } } file_mgmt_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateIdentityConnectionStatusesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mgmt_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RouterIdentityConnectionStatusesDetails); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_mgmt_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StreamMetricsRequest_MetricMatcher); i { case 0: return &v.state @@ -3422,7 +3668,7 @@ func file_mgmt_proto_init() { return nil } } - file_mgmt_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_mgmt_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StreamMetricsEvent_IntervalMetric); i { case 0: return &v.state @@ -3434,7 +3680,7 @@ func file_mgmt_proto_init() { return nil } } - file_mgmt_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_mgmt_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InspectResponse_InspectValue); i { case 0: return &v.state @@ -3453,8 +3699,8 @@ func file_mgmt_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mgmt_proto_rawDesc, - NumEnums: 6, - NumMessages: 35, + NumEnums: 7, + NumMessages: 37, NumExtensions: 0, NumServices: 0, }, diff --git a/common/pb/mgmt_pb/mgmt.proto b/common/pb/mgmt_pb/mgmt.proto index d8d70c3bf..af542f03e 100644 --- a/common/pb/mgmt_pb/mgmt.proto +++ b/common/pb/mgmt_pb/mgmt.proto @@ -23,6 +23,12 @@ enum ContentType { InspectRequestType = 10048; InspectResponseType = 10049; + // Management Pipes + MgmtPipeRequestType = 10060; + MgmtPipeResponseType = 10061; + MgmtPipeDataType = 10062; + MgmtPipeCloseType = 10063; + // Snapshot db SnapshotDbRequestType = 10070; @@ -74,6 +80,7 @@ enum Header { EventTypeHeader = 10; CtrlChanToggle = 11; ControllerId = 12; + MgmtPipeIdHeader = 20; } // @@ -167,6 +174,24 @@ message InspectResponse { } } +enum DestinationType { + Any = 0; + Controller = 1; + Router = 2; +} + +message MgmtPipeRequest { + DestinationType destinationType = 1; + string destination = 2; + uint64 timeoutMillis = 3; +} + +message MgmtPipeResponse { + bool success = 1; + uint32 connId = 2; + string msg = 3; +} + // Raft message RaftMember { string Id = 1; diff --git a/controller/config/config.go b/controller/config/config.go index bb36b8869..4805e88b6 100644 --- a/controller/config/config.go +++ b/controller/config/config.go @@ -31,6 +31,7 @@ import ( "github.com/openziti/transport/v2" transporttls "github.com/openziti/transport/v2/tls" "github.com/openziti/ziti/common/config" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/common/pb/mgmt_pb" "github.com/openziti/ziti/controller/command" @@ -111,7 +112,10 @@ type Config struct { } CommandRateLimiter command.RateLimiterConfig TlsHandshakeRateLimiter command.AdaptiveRateLimiterConfig - Src map[interface{}]interface{} + Mgmt struct { + Pipe datapipe.Config + } + Src map[interface{}]interface{} } func (self *Config) ToJson() (string, error) { @@ -663,6 +667,18 @@ func LoadConfig(path string) (*Config, error) { } controllerConfig.Edge = edgeConfig + if value, found := cfgmap["mgmt"]; found { + if subMap, ok := value.(map[interface{}]interface{}); ok { + if value, found = subMap["pipe"]; found { + if subMap, ok = value.(map[interface{}]interface{}); ok { + if err = controllerConfig.Mgmt.Pipe.LoadConfig(subMap); err != nil { + return nil, err + } + } + } + } + } + return controllerConfig, nil } diff --git a/controller/controller.go b/controller/controller.go index c0c835659..f9016bed9 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -35,6 +35,7 @@ import ( "github.com/openziti/xweb/v2" "github.com/openziti/ziti/common/capabilities" "github.com/openziti/ziti/common/concurrency" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/common/health" fabricMetrics "github.com/openziti/ziti/common/metrics" "github.com/openziti/ziti/common/pb/ctrl_pb" @@ -94,7 +95,8 @@ type Controller struct { apiDataBytes []byte apiDataOnce sync.Once - xwebInitialized concurrency.InitState + xwebInitialized concurrency.InitState + securePipeRegistry *datapipe.Registry } func (c *Controller) GetPeerSigners() []*x509.Certificate { @@ -223,6 +225,7 @@ func NewController(cfg *config.Config, versionProvider versions.VersionProvider) versionProvider: versionProvider, eventDispatcher: events.NewDispatcher(shutdownC), xwebInitialized: concurrency.NewInitState(), + securePipeRegistry: datapipe.NewRegistry(&cfg.Mgmt.Pipe), } c.xweb = xweb.NewDefaultInstance(c.xwebFactoryRegistry, c.config.Id) @@ -294,7 +297,7 @@ func (c *Controller) initWeb() { logrus.WithError(err).Fatalf("failed to create health checks api factory") } - fabricManagementFactory := webapis.NewFabricManagementApiFactory(c.config.Id, c.network, &c.xmgmts) + fabricManagementFactory := webapis.NewFabricManagementApiFactory(c.config.Id, c.network, &c.xmgmts, c.securePipeRegistry) if err = c.xweb.GetRegistry().Add(fabricManagementFactory); err != nil { logrus.WithError(err).Fatalf("failed to create management api factory") } @@ -377,7 +380,12 @@ func (c *Controller) Run() error { panic(err) } - ctrlAccepter := handler_ctrl.NewCtrlAccepter(c.network, c.xctrls, c.config.Ctrl.Options.Options, c.config.Ctrl.Options.RouterHeartbeatOptions, c.config.Trace.Handler) + ctrlAccepter := handler_ctrl.NewCtrlAccepter(c.network, + c.xctrls, + c.config.Ctrl.Options.Options, + c.config.Ctrl.Options.RouterHeartbeatOptions, + c.config.Trace.Handler, + c.securePipeRegistry) ctrlAcceptors := map[string]channel.UnderlayAcceptor{} if c.raftController != nil { diff --git a/controller/handler_ctrl/accept.go b/controller/handler_ctrl/accept.go index c5b4bae1b..e34a2a78f 100644 --- a/controller/handler_ctrl/accept.go +++ b/controller/handler_ctrl/accept.go @@ -19,6 +19,7 @@ package handler_ctrl import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v3" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/controller/network" "github.com/openziti/ziti/controller/xctrl" @@ -28,24 +29,27 @@ import ( ) type CtrlAccepter struct { - network *network.Network - xctrls []xctrl.Xctrl - options *channel.Options - heartbeatOptions *channel.HeartbeatOptions - traceHandler *channel.TraceHandler + network *network.Network + xctrls []xctrl.Xctrl + options *channel.Options + heartbeatOptions *channel.HeartbeatOptions + traceHandler *channel.TraceHandler + securePipeRegistry *datapipe.Registry } func NewCtrlAccepter(network *network.Network, xctrls []xctrl.Xctrl, options *channel.Options, heartbeatOptions *channel.HeartbeatOptions, - traceHandler *channel.TraceHandler) *CtrlAccepter { + traceHandler *channel.TraceHandler, + securePipeRegistry *datapipe.Registry) *CtrlAccepter { return &CtrlAccepter{ - network: network, - xctrls: xctrls, - options: options, - heartbeatOptions: heartbeatOptions, - traceHandler: traceHandler, + network: network, + xctrls: xctrls, + options: options, + heartbeatOptions: heartbeatOptions, + traceHandler: traceHandler, + securePipeRegistry: securePipeRegistry, } } @@ -117,7 +121,7 @@ func (self *CtrlAccepter) Bind(binding channel.Binding) error { r.Control = ch r.ConnectTime = time.Now() - if err := binding.Bind(newBindHandler(self.heartbeatOptions, r, self.network, self.xctrls)); err != nil { + if err := binding.Bind(newBindHandler(self.heartbeatOptions, r, self.network, self.xctrls, self.securePipeRegistry)); err != nil { return errors.Wrap(err, "error binding router") } diff --git a/controller/handler_ctrl/bind.go b/controller/handler_ctrl/bind.go index 65c237511..bc012216b 100644 --- a/controller/handler_ctrl/bind.go +++ b/controller/handler_ctrl/bind.go @@ -17,6 +17,7 @@ package handler_ctrl import ( + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/common/pb/ctrl_pb" "github.com/openziti/ziti/controller/model" "github.com/sirupsen/logrus" @@ -34,18 +35,24 @@ import ( ) type bindHandler struct { - heartbeatOptions *channel.HeartbeatOptions - router *model.Router - network *network.Network - xctrls []xctrl.Xctrl + heartbeatOptions *channel.HeartbeatOptions + router *model.Router + network *network.Network + xctrls []xctrl.Xctrl + securityPipeRegistry *datapipe.Registry } -func newBindHandler(heartbeatOptions *channel.HeartbeatOptions, router *model.Router, network *network.Network, xctrls []xctrl.Xctrl) channel.BindHandler { +func newBindHandler(heartbeatOptions *channel.HeartbeatOptions, + router *model.Router, + network *network.Network, + xctrls []xctrl.Xctrl, + securePipeRegistry *datapipe.Registry) channel.BindHandler { return &bindHandler{ - heartbeatOptions: heartbeatOptions, - router: router, - network: network, - xctrls: xctrls, + heartbeatOptions: heartbeatOptions, + router: router, + network: network, + xctrls: xctrls, + securityPipeRegistry: securePipeRegistry, } } @@ -78,6 +85,7 @@ func (self *bindHandler) BindChannel(binding channel.Binding) error { Type: int32(ctrl_pb.ContentType_ValidateTerminatorsV2ResponseType), Handler: self.network.RouterMessaging.NewValidationResponseHandler(self.network, self.router), }) + binding.AddTypedReceiveHandler(newCtrlPipeDataHandler(self.securityPipeRegistry)) binding.AddPeekHandler(trace.NewChannelPeekHandler(self.network.GetAppId(), binding.GetChannel(), self.network.GetTraceController())) binding.AddPeekHandler(metrics2.NewCtrlChannelPeekHandler(self.router.Id, self.network.GetMetricsRegistry())) diff --git a/controller/handler_ctrl/pipe.go b/controller/handler_ctrl/pipe.go new file mode 100644 index 000000000..97217f551 --- /dev/null +++ b/controller/handler_ctrl/pipe.go @@ -0,0 +1,69 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package handler_ctrl + +import ( + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/ziti/common/datapipe" + "github.com/openziti/ziti/common/pb/ctrl_pb" +) + +func newCtrlPipeDataHandler(registry *datapipe.Registry) *ctrlPipeDataHandler { + return &ctrlPipeDataHandler{ + registry: registry, + } +} + +type ctrlPipeDataHandler struct { + registry *datapipe.Registry +} + +func (*ctrlPipeDataHandler) ContentType() int32 { + return int32(ctrl_pb.ContentType_CtrlPipeDataType) +} + +func (handler *ctrlPipeDataHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + connId, _ := msg.GetUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader)) + pipe := handler.registry.Get(connId) + + if pipe == nil { + pfxlog.ContextLogger(ch.Label()). + WithField("connId", connId). + Error("no ctrl pipe found for given connection id") + + go func() { + errorMsg := fmt.Sprintf("invalid conn id '%v", connId) + replyMsg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeCloseType), []byte(errorMsg)) + replyMsg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), connId) + if sendErr := ch.Send(msg); sendErr != nil { + pfxlog.ContextLogger(ch.Label()). + WithField("connId", connId). + WithError(sendErr). + Error("failed sending ctrl pipe close message after data with invalid conn") + } + + _ = ch.Close() + }() + return + } + + if err := pipe.WriteToClient(msg.Body); err != nil { + pipe.CloseWithErr(err) + } +} diff --git a/controller/handler_mgmt/bind.go b/controller/handler_mgmt/bind.go index 589097328..3df483926 100644 --- a/controller/handler_mgmt/bind.go +++ b/controller/handler_mgmt/bind.go @@ -19,18 +19,24 @@ package handler_mgmt import ( "github.com/openziti/channel/v3" "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/common/trace" "github.com/openziti/ziti/controller/network" "github.com/openziti/ziti/controller/xmgmt" ) type BindHandler struct { - network *network.Network - xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt] + network *network.Network + xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt] + securePipeRegistry *datapipe.Registry } -func NewBindHandler(network *network.Network, xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt]) channel.BindHandler { - return &BindHandler{network: network, xmgmts: xmgmts} +func NewBindHandler(network *network.Network, xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt], securePipeRegistry *datapipe.Registry) channel.BindHandler { + return &BindHandler{ + network: network, + xmgmts: xmgmts, + securePipeRegistry: securePipeRegistry, + } } func (bindHandler *BindHandler) BindChannel(binding channel.Binding) error { @@ -70,6 +76,16 @@ func (bindHandler *BindHandler) BindChannel(binding channel.Binding) error { binding.AddPeekHandler(trace.NewChannelPeekHandler(bindHandler.network.GetAppId(), binding.GetChannel(), bindHandler.network.GetTraceController())) + if bindHandler.securePipeRegistry.GetConfig().Enabled { + mgmtPipeRequestHandler := newMgmtPipeHandler(bindHandler.network, bindHandler.securePipeRegistry, binding.GetChannel()) + binding.AddTypedReceiveHandler(&channel.AsyncFunctionReceiveAdapter{ + Type: mgmtPipeRequestHandler.ContentType(), + Handler: mgmtPipeRequestHandler.HandleReceive, + }) + binding.AddCloseHandler(mgmtPipeRequestHandler) + binding.AddTypedReceiveHandler(newMgmtPipeDataHandler(bindHandler.securePipeRegistry)) + } + xmgmtDone := make(chan struct{}) for _, x := range bindHandler.xmgmts.Value() { if err := binding.Bind(x); err != nil { diff --git a/controller/handler_mgmt/pipe.go b/controller/handler_mgmt/pipe.go new file mode 100644 index 000000000..524dc0657 --- /dev/null +++ b/controller/handler_mgmt/pipe.go @@ -0,0 +1,467 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package handler_mgmt + +import ( + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/channel/v3/protobufs" + "github.com/openziti/ziti/common/datapipe" + "github.com/openziti/ziti/common/pb/ctrl_pb" + "github.com/openziti/ziti/common/pb/mgmt_pb" + "github.com/openziti/ziti/controller/model" + "github.com/openziti/ziti/controller/network" + "google.golang.org/protobuf/proto" + "io" + "net" + "sync/atomic" + "time" +) + +var mgmtMsgTypes = datapipe.MessageTypes{ + DataMessageType: int32(mgmt_pb.ContentType_MgmtPipeDataType), + PipeIdHeaderType: int32(mgmt_pb.Header_MgmtPipeIdHeader), + CloseMessageType: int32(mgmt_pb.ContentType_MgmtPipeCloseType), +} + +type mgmtPipeHandler struct { + network *network.Network + registry *datapipe.Registry + pipe datapipe.Pipe + ch channel.Channel +} + +func newMgmtPipeHandler(network *network.Network, registry *datapipe.Registry, ch channel.Channel) *mgmtPipeHandler { + return &mgmtPipeHandler{ + network: network, + registry: registry, + ch: ch, + } +} + +func (*mgmtPipeHandler) ContentType() int32 { + return int32(mgmt_pb.ContentType_MgmtPipeRequestType) +} + +func (handler *mgmtPipeHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + log := pfxlog.ContextLogger(ch.Label()).Entry + + request := &mgmt_pb.MgmtPipeRequest{} + if err := proto.Unmarshal(msg.Body, request); err != nil { + log.WithError(err).Error("unable to unmarshall mgmt pipe request") + return + } + + if !handler.registry.GetConfig().Enabled { + handler.respondError(msg, "access denied") + return + } + + if request.DestinationType.CheckControllers() { + log.Infof("checking requested destination '%s' against local id '%s'", request.Destination, handler.network.GetAppId()) + if request.Destination == handler.network.GetAppId() { + handler.pipeToLocalhost(msg) + return + } + + if request.DestinationType == mgmt_pb.DestinationType_Controller { + handler.respondError(msg, fmt.Sprintf("no controllers found with id '%s'", request.Destination)) + return + } + } + + if request.DestinationType.CheckRouters() { + r := handler.network.GetConnectedRouter(request.Destination) + if r != nil { + handler.pipeToRouter(msg, request, r) + return + } + if request.DestinationType == mgmt_pb.DestinationType_Router { + r, _ = handler.network.GetRouter(request.Destination) + if r == nil { + handler.respondError(msg, fmt.Sprintf("no router found with id '%s'", request.Destination)) + } else { + handler.respondError(msg, fmt.Sprintf("router '%s' not connected to controller", request.Destination)) + } + return + } + } + + handler.respondError(msg, fmt.Sprintf("no destination found with with id '%s'", request.Destination)) +} + +func (handler *mgmtPipeHandler) pipeToRouter(msg *channel.Message, mgmtReq *mgmt_pb.MgmtPipeRequest, r *model.Router) { + pipe := &routerPipe{ + ch: handler.ch, + r: r, + } + + log := pfxlog.ContextLogger(handler.ch.Label()). + WithField("destination", "router") + + pipeId, err := handler.registry.GetNextId() + if err != nil { + log.WithError(err).Error("failed to acquire pipe identifier") + handler.respondError(msg, err.Error()) + return + } + + log = log.WithField("pipeId", pipeId) + + handler.pipe = pipe + if err = handler.registry.Register(pipe); err != nil { + log.WithError(err).Error("failed to register mgmt pipe") + handler.respondError(msg, err.Error()) + pipe.CloseWithErr(err) + return + } + + req := &ctrl_pb.CtrlPipeRequest{ + Destination: r.Id, + TimeoutMillis: mgmtReq.TimeoutMillis, + ConnId: pipe.id, + } + + envelope := protobufs.MarshalTyped(req).WithTimeout(time.Duration(mgmtReq.TimeoutMillis) * time.Millisecond) + + routerResp := &ctrl_pb.CtrlPipeResponse{} + if err = protobufs.TypedResponse(routerResp).Unmarshall(envelope.SendForReply(r.Control)); err != nil { + handler.respondError(msg, fmt.Sprintf("router error: %s", err.Error())) + return + } + + response := &mgmt_pb.MgmtPipeResponse{ + Success: true, + ConnId: pipe.id, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(msg).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log.WithError(sendErr).Error("unable to send mgmt pipe response for successful pipe") + pipe.CloseWithErr(sendErr) + return + } + + log.Info("started mgmt pipe to router") +} + +func (handler *mgmtPipeHandler) pipeToLocalhost(msg *channel.Message) { + log := pfxlog.ContextLogger(handler.ch.Label()).Entry + cfg := handler.registry.GetConfig() + + if !cfg.IsLocalAccessAllowed() { + log.Error("mgmt.pipe does not allow local access") + handler.respondError(msg, "access denied") + return + } + + pipeId, err := handler.registry.GetNextId() + if err != nil { + log.WithError(err).Error("failed to acquire pipe identifier") + handler.respondError(msg, err.Error()) + return + } + + if cfg.IsLocalPort() { + handler.pipeToLocalPort(msg, pipeId) + return + } + + if cfg.IsEmbedded() { + handler.pipeToEmbeddedSshServer(msg, pipeId) + return + } + + log.Error("mgmt.pipe misconfigured, enabled, but neither localPort nor embedded enabled") + handler.respondError(msg, "server is misconfigured, unable to connect pipe") +} + +func (handler *mgmtPipeHandler) pipeToLocalPort(msg *channel.Message, pipeId uint32) { + cfg := handler.registry.GetConfig() + log := pfxlog.ContextLogger(handler.ch.Label()). + WithField("destination", fmt.Sprintf("localhost:%d", cfg.DestinationPort)). + WithField("pipeId", pipeId) + + conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", cfg.DestinationPort)) + if err != nil { + log.WithError(err).Error("failed to connect mgmt pipe") + handler.respondError(msg, err.Error()) + return + } + + pipe := &localPipe{ + id: pipeId, + conn: conn, + ch: handler.ch, + } + + handler.pipe = pipe + if err = handler.registry.Register(pipe); err != nil { + log.WithError(err).Error("failed to register mgmt pipe") + handler.respondError(msg, err.Error()) + pipe.CloseWithErr(err) + return + } + + log.Info("registered mgmt pipe connection") + + response := &mgmt_pb.MgmtPipeResponse{ + Success: true, + ConnId: pipe.id, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(msg).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log.WithError(sendErr).Error("unable to send mgmt pipe response for successful pipe") + pipe.CloseWithErr(sendErr) + return + } + + go pipe.readLoop() + + log.Info("started mgmt pipe to local controller") +} + +func (handler *mgmtPipeHandler) pipeToEmbeddedSshServer(msg *channel.Message, pipeId uint32) { + log := pfxlog.ContextLogger(handler.ch.Label()). + WithField("destination", "embedded-ssh-server"). + WithField("pipeId", pipeId) + + cfg := handler.registry.GetConfig() + + requestHandler, err := cfg.NewSshRequestHandler(handler.network.GetIdentity()) + if err != nil { + log.WithError(err).Error("failed to connect pipe") + handler.respondError(msg, "failed to connect pipe") + return + } + + pipe := datapipe.NewEmbeddedSshConn(handler.ch, pipeId, &mgmtMsgTypes) + + handler.pipe = pipe + + if err = handler.registry.Register(pipe); err != nil { + log.WithError(err).Error("failed to register mgmt pipe") + handler.respondError(msg, err.Error()) + pipe.CloseWithErr(err) + return + } + + log.Info("registered mgmt pipe connection") + + response := &mgmt_pb.MgmtPipeResponse{ + Success: true, + ConnId: pipe.Id(), + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(msg).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log.WithError(sendErr).Error("unable to send mgmt pipe response for successful pipe") + pipe.CloseWithErr(sendErr) + return + } + + if err = requestHandler.HandleSshRequest(pipe); err != nil { + log.WithError(err).Error("failed to connect pipe") + handler.respondError(msg, err.Error()) + if closeErr := handler.ch.Close(); closeErr != nil { + log.WithError(err).Error("error while closing mgmt channel") + } + return + } + + log.Info("started mgmt pipe to local controller using embedded ssh server") +} + +func (handler *mgmtPipeHandler) respondError(request *channel.Message, msg string) { + response := &mgmt_pb.MgmtPipeResponse{ + Success: false, + Msg: msg, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(request).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log := pfxlog.ContextLogger(handler.ch.Label()).Entry + log.WithError(sendErr).Error("unable to send mgmt pipe response for failed pipe") + } +} + +func (handler *mgmtPipeHandler) HandleClose(channel.Channel) { + if handler.pipe != nil { + handler.pipe.CloseWithErr(nil) + handler.registry.Unregister(handler.pipe.Id()) + } +} + +type localPipe struct { + id uint32 + conn net.Conn + ch channel.Channel + closed atomic.Bool +} + +func (self *localPipe) Id() uint32 { + return self.id +} + +func (self *localPipe) WriteToServer(data []byte) error { + _, err := self.conn.Write(data) + return err +} + +func (self *localPipe) WriteToClient(data []byte) error { + msg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeDataType), data) + msg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), self.id) + return msg.WithTimeout(time.Second).SendAndWaitForWire(self.ch) +} + +func (self *localPipe) readLoop() { + for { + buf := make([]byte, 10240) + n, err := self.conn.Read(buf) + if err != nil { + self.CloseWithErr(err) + return + } + buf = buf[:n] + if err := self.WriteToClient(buf); err != nil { + self.CloseWithErr(err) + return + } + } +} + +func (self *localPipe) CloseWithErr(err error) { + if self.closed.CompareAndSwap(false, true) { + log := pfxlog.ContextLogger(self.ch.Label()).WithField("connId", self.id) + + log.WithError(err).Info("closing mgmt pipe connection") + + if closeErr := self.conn.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing mgmt pipe connection") + } + + if !self.ch.IsClosed() && err != io.EOF && err != nil { + msg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeCloseType), []byte(err.Error())) + msg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), self.id) + if sendErr := self.ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending mgmt pipe close message") + } + } + + if closeErr := self.ch.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing mgmt pipe client channel") + } + } +} + +type routerPipe struct { + id uint32 + ch channel.Channel + r *model.Router + closed atomic.Bool +} + +func (self *routerPipe) Id() uint32 { + return self.id +} + +func (self *routerPipe) WriteToServer(data []byte) error { + msg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeDataType), data) + msg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), self.id) + return msg.WithTimeout(time.Second).SendAndWaitForWire(self.r.Control) +} + +func (self *routerPipe) WriteToClient(data []byte) error { + msg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeDataType), data) + msg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), self.id) + return msg.WithTimeout(time.Second).SendAndWaitForWire(self.ch) +} + +func (self *routerPipe) CloseWithErr(err error) { + if self.closed.CompareAndSwap(false, true) { + log := pfxlog.ContextLogger(self.ch.Label()).WithField("connId", self.id) + + log.WithError(err).Info("closing router ctrl pipe connection") + + if !self.r.Control.IsClosed() { + msg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeCloseType), func() []byte { + if err != nil { + return []byte(err.Error()) + } + return []byte("closing") + }()) + msg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), self.id) + if sendErr := self.ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending ctrl pipe close message") + } + } + + if !self.ch.IsClosed() && err != io.EOF && err != nil { + msg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeCloseType), []byte(err.Error())) + msg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), self.id) + if sendErr := self.ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending mgmt pipe close message") + } + } + + if closeErr := self.ch.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing mgmt pipe client channel") + } + } +} + +func newMgmtPipeDataHandler(registry *datapipe.Registry) *mgmtPipeDataHandler { + return &mgmtPipeDataHandler{ + registry: registry, + } +} + +type mgmtPipeDataHandler struct { + registry *datapipe.Registry +} + +func (*mgmtPipeDataHandler) ContentType() int32 { + return int32(mgmt_pb.ContentType_MgmtPipeDataType) +} + +func (handler *mgmtPipeDataHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + connId, _ := msg.GetUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader)) + pipe := handler.registry.Get(connId) + + if pipe == nil { + pfxlog.ContextLogger(ch.Label()). + WithField("connId", connId). + Error("no mgmt pipe found for given connection id") + + go func() { + errorMsg := fmt.Sprintf("invalid conn id '%v", connId) + replyMsg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeCloseType), []byte(errorMsg)) + replyMsg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), connId) + if sendErr := ch.Send(msg); sendErr != nil { + pfxlog.ContextLogger(ch.Label()). + WithField("connId", connId). + WithError(sendErr). + Error("failed sending mgmt pipe close message after data with invalid connection id") + } + + _ = ch.Close() + }() + return + } + + if err := pipe.WriteToServer(msg.Body); err != nil { + pipe.CloseWithErr(err) + } +} diff --git a/controller/network/network.go b/controller/network/network.go index c61193f15..c7f513b87 100644 --- a/controller/network/network.go +++ b/controller/network/network.go @@ -181,6 +181,10 @@ func NewNetwork(config Config, env model.Env) (*Network, error) { return network, nil } +func (self *Network) GetIdentity() *identity.TokenId { + return self.config.GetId() +} + func (self *Network) HandleRouterDelete(id string) { self.routerDeleted(id) self.RouterMessaging.RouterDeleted(id) diff --git a/controller/webapis/fabric-management-api.go b/controller/webapis/fabric-management-api.go index 3847e448a..f04742935 100644 --- a/controller/webapis/fabric-management-api.go +++ b/controller/webapis/fabric-management-api.go @@ -27,6 +27,7 @@ import ( "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/identity" "github.com/openziti/xweb/v2" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/controller/api_impl" "github.com/openziti/ziti/controller/handler_mgmt" "github.com/openziti/ziti/controller/network" @@ -45,24 +46,26 @@ const ( var _ xweb.ApiHandlerFactory = &FabricManagementApiFactory{} type FabricManagementApiFactory struct { - InitFunc func(managementApi *FabricManagementApiHandler) error - network *network.Network - nodeId identity.Identity - xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt] - MakeDefault bool + InitFunc func(managementApi *FabricManagementApiHandler) error + network *network.Network + nodeId identity.Identity + xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt] + MakeDefault bool + securePipeRegistry *datapipe.Registry } func (factory *FabricManagementApiFactory) Validate(_ *xweb.InstanceConfig) error { return nil } -func NewFabricManagementApiFactory(nodeId identity.Identity, network *network.Network, xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt]) *FabricManagementApiFactory { +func NewFabricManagementApiFactory(nodeId identity.Identity, network *network.Network, xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt], securityPipeRegistry *datapipe.Registry) *FabricManagementApiFactory { pfxlog.Logger().Infof("initializing management api factory with %d xmgmt instances", len(xmgmts.Value())) return &FabricManagementApiFactory{ - network: network, - nodeId: nodeId, - xmgmts: xmgmts, - MakeDefault: false, + network: network, + nodeId: nodeId, + xmgmts: xmgmts, + MakeDefault: false, + securePipeRegistry: securityPipeRegistry, } } @@ -96,7 +99,7 @@ func (factory *FabricManagementApiFactory) New(_ *xweb.ServerConfig, options map return nil, err } - managementApiHandler.bindHandler = handler_mgmt.NewBindHandler(factory.network, factory.xmgmts) + managementApiHandler.bindHandler = handler_mgmt.NewBindHandler(factory.network, factory.xmgmts, factory.securePipeRegistry) if factory.InitFunc != nil { if err := factory.InitFunc(managementApiHandler); err != nil { diff --git a/etc/ctrl.with.edge.yml b/etc/ctrl.with.edge.yml index dc21f6cf1..5c75c12f5 100644 --- a/etc/ctrl.with.edge.yml +++ b/etc/ctrl.with.edge.yml @@ -57,6 +57,14 @@ identity: key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem +mgmt: + pipe: + enabled: true + enableExperimentalFeature: true + destination: embedded-ssh-server + authorizedKeysFile: /home/plorenz/tmp/authorized_keys + shell: /usr/bin/bash + # the endpoint that routers will connect to the controller over. ctrl: listener: tls:127.0.0.1:6262 diff --git a/go.mod b/go.mod index 2eb517c6c..be9021051 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/blang/semver v3.5.1+incompatible github.com/cenkalti/backoff/v4 v4.3.0 github.com/coreos/go-iptables v0.8.0 + github.com/creack/pty v1.1.11 github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 github.com/dineshappavoo/basex v0.0.0-20170425072625-481a6f6dc663 github.com/ef-ds/deque v1.0.4 @@ -19,6 +20,7 @@ require ( github.com/fatih/color v1.18.0 github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa github.com/gaissmai/extnetip v1.1.0 + github.com/gliderlabs/ssh v0.1.1 github.com/go-acme/lego/v4 v4.19.2 github.com/go-openapi/errors v0.22.0 github.com/go-openapi/loads v0.22.0 @@ -67,6 +69,7 @@ require ( github.com/openziti/ziti-db-explorer v1.1.3 github.com/orcaman/concurrent-map/v2 v2.0.1 github.com/pkg/errors v0.9.1 + github.com/pkg/sftp v1.13.6 github.com/rabbitmq/amqp091-go v1.8.1 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 github.com/russross/blackfriday v1.6.0 @@ -87,6 +90,7 @@ require ( golang.org/x/oauth2 v0.23.0 golang.org/x/sync v0.8.0 golang.org/x/sys v0.26.0 + golang.org/x/term v0.25.0 golang.org/x/text v0.19.0 google.golang.org/protobuf v1.35.1 gopkg.in/AlecAivazis/survey.v1 v1.8.8 @@ -102,6 +106,7 @@ require ( github.com/MichaelMure/go-term-text v0.3.1 // indirect github.com/alecthomas/chroma v0.10.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect + github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect @@ -109,7 +114,6 @@ require ( github.com/boltdb/bolt v1.3.1 // indirect github.com/c-bata/go-prompt v0.2.6 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect - github.com/creack/pty v1.1.11 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/disintegration/imaging v1.6.2 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect @@ -138,6 +142,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/kr/fs v0.1.0 // indirect github.com/kr/pty v1.1.8 // indirect github.com/kyokomi/emoji/v2 v2.2.12 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -195,7 +200,6 @@ require ( golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/image v0.18.0 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/term v0.25.0 // indirect golang.org/x/tools v0.26.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index 05accd08e..180ccdfcc 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= @@ -182,6 +183,7 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -198,6 +200,7 @@ github.com/gaissmai/extnetip v1.1.0 h1:ZWEPVPUtw1o//CWh69/Eo79gWEKVYB1STrJjpTR4Q github.com/gaissmai/extnetip v1.1.0/go.mod h1:Ad+qyjy0r98Uc655JzzWoBTzDW29QR4YZDxzHgqhuqM= github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-acme/lego/v4 v4.19.2 h1:Y8hrmMvWETdqzzkRly7m98xtPJJivWFsgWi8fcvZo+Y= github.com/go-acme/lego/v4 v4.19.2/go.mod h1:wtDe3dDkmV4/oI2nydpNXSJpvV10J9RCyZ6MbYxNtlQ= @@ -435,6 +438,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -625,6 +629,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= +github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/router/config.go b/router/config.go index 1adeeb755..73007fc97 100644 --- a/router/config.go +++ b/router/config.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "github.com/openziti/transport/v2/tls" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/controller/command" "github.com/openziti/ziti/router/env" "io" @@ -183,10 +184,13 @@ type Config struct { Enabled bool } ConnectEvents env.ConnectEventsConfig - Proxy *transport.ProxyConfiguration - Plugins []string - src map[interface{}]interface{} - path string + Mgmt struct { + Pipe datapipe.Config + } + Proxy *transport.ProxyConfiguration + Plugins []string + src map[interface{}]interface{} + path string } func (config *Config) CurrentCtrlAddress() string { @@ -908,6 +912,18 @@ func LoadConfig(path string) (*Config, error) { cfg.ConnectEvents.MaxQueuedEvents = MaxConnectEventsMaxQueuedEvents } + if value, found := cfgmap["mgmt"]; found { + if subMap, ok := value.(map[interface{}]interface{}); ok { + if value, found = subMap["pipe"]; found { + if subMap, ok = value.(map[interface{}]interface{}); ok { + if err = cfg.Mgmt.Pipe.LoadConfig(subMap); err != nil { + return nil, err + } + } + } + } + } + return cfg, nil } diff --git a/router/env/env.go b/router/env/env.go index b55fc90d7..fd69e50ee 100644 --- a/router/env/env.go +++ b/router/env/env.go @@ -24,6 +24,7 @@ import ( "github.com/openziti/identity" "github.com/openziti/metrics" "github.com/openziti/ziti/common" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/router/xgress" "github.com/openziti/ziti/router/xlink" "time" @@ -46,6 +47,7 @@ type RouterEnv interface { GetVersionInfo() versions.VersionProvider GetRouterDataModel() *common.RouterDataModel GetConnectEventsConfig() *ConnectEventsConfig + GetMgmtPipeConfig() *datapipe.Config } type ConnectEventsConfig struct { diff --git a/router/handler_ctrl/bind.go b/router/handler_ctrl/bind.go index 46e758096..24491dee9 100644 --- a/router/handler_ctrl/bind.go +++ b/router/handler_ctrl/bind.go @@ -17,6 +17,7 @@ package handler_ctrl import ( + "github.com/openziti/ziti/common/datapipe" "runtime/debug" "time" @@ -37,6 +38,7 @@ type bindHandler struct { xgDialerPool goroutines.Pool terminatorValidationPool goroutines.Pool ctrlAddressUpdater CtrlAddressUpdater + dataPipeRegistry *datapipe.Registry } func NewBindHandler(routerEnv env.RouterEnv, forwarder *forwarder.Forwarder, ctrlAddressUpdater CtrlAddressUpdater) (channel.BindHandler, error) { @@ -82,6 +84,7 @@ func NewBindHandler(routerEnv env.RouterEnv, forwarder *forwarder.Forwarder, ctr xgDialerPool: xgDialerPool, terminatorValidationPool: terminatorValidationPool, ctrlAddressUpdater: ctrlAddressUpdater, + dataPipeRegistry: datapipe.NewRegistry(routerEnv.GetMgmtPipeConfig()), }, nil } @@ -111,6 +114,17 @@ func (self *bindHandler) BindChannel(binding channel.Binding) error { binding.AddPeekHandler(self.env.GetTraceHandler()) } + if self.env.GetMgmtPipeConfig().IsLocalAccessAllowed() { + sshTunnelRegistry := &pipeRegistry{} + sshTunnelRequestHandler := newCtrlPipeHandler(self.env, sshTunnelRegistry, binding.GetChannel()) + binding.AddTypedReceiveHandler(&channel.AsyncFunctionReceiveAdapter{ + Type: sshTunnelRequestHandler.ContentType(), + Handler: sshTunnelRequestHandler.HandleReceive, + }) + binding.AddTypedReceiveHandler(newCtrlPipeDataHandler(sshTunnelRegistry)) + binding.AddTypedReceiveHandler(newCtrlPipeCloseHandler(sshTunnelRegistry)) + } + for _, x := range self.env.GetXrctrls() { if err := binding.Bind(x); err != nil { return err diff --git a/router/handler_ctrl/pipe.go b/router/handler_ctrl/pipe.go new file mode 100644 index 000000000..99b477f3c --- /dev/null +++ b/router/handler_ctrl/pipe.go @@ -0,0 +1,288 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package handler_ctrl + +import ( + "errors" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/channel/v3/protobufs" + "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/ziti/common/datapipe" + "github.com/openziti/ziti/common/pb/ctrl_pb" + "github.com/openziti/ziti/router/env" + "google.golang.org/protobuf/proto" + "io" + "net" + "time" +) + +var mgmtMsgTypes = datapipe.MessageTypes{ + DataMessageType: int32(ctrl_pb.ContentType_CtrlPipeDataType), + PipeIdHeaderType: int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), + CloseMessageType: int32(ctrl_pb.ContentType_CtrlPipeCloseType), +} + +type mgmtPipe interface { + WriteToServer(b []byte) error + CloseWithErr(err error) +} + +type pipeRegistry struct { + pipes concurrenz.CopyOnWriteMap[uint32, mgmtPipe] +} + +type ctrlPipeHandler struct { + env env.RouterEnv + registry *pipeRegistry + ch channel.Channel +} + +func newCtrlPipeHandler(routerEnv env.RouterEnv, registry *pipeRegistry, ch channel.Channel) *ctrlPipeHandler { + return &ctrlPipeHandler{ + env: routerEnv, + registry: registry, + ch: ch, + } +} + +func (*ctrlPipeHandler) ContentType() int32 { + return int32(ctrl_pb.ContentType_CtrlPipeRequestType) +} + +func (handler *ctrlPipeHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + log := pfxlog.ContextLogger(ch.Label()).Entry + + req := &ctrl_pb.CtrlPipeRequest{} + if err := proto.Unmarshal(msg.Body, req); err != nil { + log.WithError(err).Error("unable to unmarshal ssh tunnel request") + return + } + + if handler.env.GetMgmtPipeConfig().IsLocalPort() { + handler.pipeToLocalPort(msg, req) + return + } + + if handler.env.GetMgmtPipeConfig().IsEmbedded() { + handler.pipeToEmbeddedSshServer(msg, req) + return + } + + log.Error("no configured pipe handler") + handler.respondError(msg, "no configured pipe handler") +} + +func (handler *ctrlPipeHandler) pipeToLocalPort(msg *channel.Message, req *ctrl_pb.CtrlPipeRequest) { + log := pfxlog.ContextLogger(handler.ch.Label()). + WithField("destination", fmt.Sprintf("localhost:%d", handler.env.GetMgmtPipeConfig().DestinationPort)). + WithField("pipeId", req.ConnId) + + conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", handler.env.GetMgmtPipeConfig().DestinationPort)) + if err != nil { + log.WithError(err).Error("failed to dial pipe destination") + handler.respondError(msg, err.Error()) + return + } + + pipe := &ctrlChanPipe{ + conn: conn, + ch: handler.ch, + id: req.ConnId, + } + + handler.registry.pipes.Put(pipe.id, pipe) + + log = log.WithField("connId", pipe.id) + log.Info("registered ctrl channel pipe connection") + + response := &ctrl_pb.CtrlPipeResponse{ + Success: true, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(msg).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log.WithError(sendErr).Error("unable to send ctrl channel pipe response for successful pipe") + pipe.CloseWithErr(sendErr) + return + } + + log.Info("started mgmt pipe") + + go pipe.readLoop() +} + +func (handler *ctrlPipeHandler) pipeToEmbeddedSshServer(msg *channel.Message, req *ctrl_pb.CtrlPipeRequest) { + log := pfxlog.ContextLogger(handler.ch.Label()). + WithField("destination", "embedded-ssh-server"). + WithField("pipeId", req.ConnId) + + cfg := handler.env.GetMgmtPipeConfig() + + requestHandler, err := cfg.NewSshRequestHandler(handler.env.GetRouterId()) + if err != nil { + log.WithError(err).Error("failed to connect pipe") + handler.respondError(msg, "failed to connect pipe") + return + } + + pipe := datapipe.NewEmbeddedSshConn(handler.ch, req.ConnId, &mgmtMsgTypes) + + handler.registry.pipes.Put(pipe.Id(), pipe) + log.Info("registered mgmt pipe connection") + + response := &ctrl_pb.CtrlPipeResponse{ + Success: true, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(msg).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log.WithError(sendErr).Error("unable to send mgmt pipe response for successful pipe") + pipe.CloseWithErr(sendErr) + return + } + + if err = requestHandler.HandleSshRequest(pipe); err != nil { + log.WithError(err).Error("failed to connect pipe") + handler.respondError(msg, err.Error()) + pipe.CloseWithErr(err) + return + } + + log.Info("started mgmt pipe to local controller using embedded ssh server") +} + +func (handler *ctrlPipeHandler) respondError(request *channel.Message, msg string) { + response := &ctrl_pb.CtrlPipeResponse{ + Success: false, + Msg: msg, + } + + if sendErr := protobufs.MarshalTyped(response).ReplyTo(request).WithTimeout(5 * time.Second).SendAndWaitForWire(handler.ch); sendErr != nil { + log := pfxlog.ContextLogger(handler.ch.Label()).Entry + log.WithError(sendErr).Error("unable to send ctrl channel pipe response for failed pipe") + } +} + +type ctrlChanPipe struct { + id uint32 + conn net.Conn + ch channel.Channel +} + +func (self *ctrlChanPipe) WriteToServer(b []byte) error { + _, err := self.conn.Write(b) + return err +} + +func (self *ctrlChanPipe) readLoop() { + for { + buf := make([]byte, 10240) + n, err := self.conn.Read(buf) + if err != nil { + self.CloseWithErr(err) + return + } + buf = buf[:n] + msg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeDataType), buf) + msg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), self.id) + if err = self.ch.Send(msg); err != nil { + self.CloseWithErr(err) + return + } + } +} + +func (self *ctrlChanPipe) CloseWithErr(err error) { + log := pfxlog.ContextLogger(self.ch.Label()).WithField("connId", self.id) + + log.WithError(err).Info("closing ctrl channel pipe connection") + + if closeErr := self.conn.Close(); closeErr != nil { + log.WithError(closeErr).Error("failed closing ctrl channel pipe connection") + } + + if err != io.EOF && err != nil { + msg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeCloseType), []byte(err.Error())) + msg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), self.id) + if sendErr := self.ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending ctrl channel pipe close message") + } + } +} + +func newCtrlPipeDataHandler(registry *pipeRegistry) *ctrlPipeDataHandler { + return &ctrlPipeDataHandler{ + registry: registry, + } +} + +type ctrlPipeDataHandler struct { + registry *pipeRegistry +} + +func (*ctrlPipeDataHandler) ContentType() int32 { + return int32(ctrl_pb.ContentType_CtrlPipeDataType) +} + +func (handler *ctrlPipeDataHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + pipeId, _ := msg.GetUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader)) + pipe := handler.registry.pipes.Get(pipeId) + + if pipe == nil { + log := pfxlog.ContextLogger(ch.Label()).WithField("pipeId", pipeId) + log.Error("no ctrl channel pipe found for given id") + + go func() { + errorMsg := fmt.Sprintf("invalid pipe id '%v", pipeId) + replyMsg := channel.NewMessage(int32(ctrl_pb.ContentType_CtrlPipeCloseType), []byte(errorMsg)) + replyMsg.PutUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader), pipeId) + if sendErr := ch.Send(msg); sendErr != nil { + log.WithError(sendErr).Error("failed sending ctrl channel pipe close message after data with invalid conn") + } + }() + return + } + + if err := pipe.WriteToServer(msg.Body); err != nil { + pipe.CloseWithErr(err) + } +} + +func newCtrlPipeCloseHandler(registry *pipeRegistry) *ctrlPipeCloseHandler { + return &ctrlPipeCloseHandler{ + registry: registry, + } +} + +type ctrlPipeCloseHandler struct { + registry *pipeRegistry +} + +func (*ctrlPipeCloseHandler) ContentType() int32 { + return int32(ctrl_pb.ContentType_CtrlPipeCloseType) +} + +func (handler *ctrlPipeCloseHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + pipeId, _ := msg.GetUint32Header(int32(ctrl_pb.ControlHeaders_CtrlPipeIdHeader)) + log := pfxlog.ContextLogger(ch.Label()).WithField("pipeId", pipeId) + + if pipe := handler.registry.pipes.Get(pipeId); pipe == nil { + log.Error("no mgmt pipe found for given id") + } else { + pipe.CloseWithErr(errors.New("close message received")) + } +} diff --git a/router/router.go b/router/router.go index ca8b2cbe8..9af2627e9 100644 --- a/router/router.go +++ b/router/router.go @@ -23,6 +23,7 @@ import ( "fmt" "github.com/openziti/foundation/v2/rate" "github.com/openziti/ziti/common" + "github.com/openziti/ziti/common/datapipe" "github.com/openziti/ziti/controller/command" "github.com/openziti/ziti/router/state" "io/fs" @@ -175,6 +176,10 @@ func (self *Router) GetConnectEventsConfig() *env.ConnectEventsConfig { return &self.config.ConnectEvents } +func (self *Router) GetMgmtPipeConfig() *datapipe.Config { + return &self.config.Mgmt.Pipe +} + func Create(config *Config, versionProvider versions.VersionProvider) *Router { closeNotify := make(chan struct{}) diff --git a/ziti/cmd/api/list.go b/ziti/cmd/api/list.go index 071c80b21..c9b8fba63 100644 --- a/ziti/cmd/api/list.go +++ b/ziti/cmd/api/list.go @@ -122,7 +122,7 @@ func MapNameToID(api util.API, entityType string, o *Options, idOrName string) ( func MapNamesToIDs(api util.API, entityType string, o *Options, list ...string) ([]string, error) { var result []string for _, val := range list { - if strings.HasPrefix(val, "id") { + if strings.HasPrefix(val, "id:") { id := strings.TrimPrefix(val, "id:") result = append(result, id) } else { diff --git a/ziti/cmd/fabric/root.go b/ziti/cmd/fabric/root.go index fd44e4523..ba5954238 100644 --- a/ziti/cmd/fabric/root.go +++ b/ziti/cmd/fabric/root.go @@ -37,6 +37,7 @@ func NewFabricCmd(p common.OptionsProvider) *cobra.Command { fabricCmd.AddCommand(newStreamCommand(p)) fabricCmd.AddCommand(newRaftCmd(p)) fabricCmd.AddCommand(newValidateCommand(p)) + fabricCmd.AddCommand(NewSshCmd(p)) return fabricCmd } diff --git a/ziti/cmd/fabric/ssh.go b/ziti/cmd/fabric/ssh.go new file mode 100644 index 000000000..cc7633970 --- /dev/null +++ b/ziti/cmd/fabric/ssh.go @@ -0,0 +1,362 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fabric + +import ( + "errors" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/channel/v3/protobufs" + "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/ziti/common/pb/mgmt_pb" + "github.com/openziti/ziti/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/common" + "github.com/openziti/ziti/ziti/util" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/agent" + "golang.org/x/term" + "io" + "net" + "os" + "os/user" + "strings" + "time" +) + +type sshAction struct { + api.Options + + incomingData chan []byte + user string + keyPath string + proxyMode bool + done chan struct{} + + connections concurrenz.CopyOnWriteSlice[*sshConn] +} + +func NewSshCmd(p common.OptionsProvider) *cobra.Command { + action := sshAction{ + Options: api.Options{ + CommonOptions: p(), + }, + incomingData: make(chan []byte, 4), + done: make(chan struct{}), + } + + sshCmd := &cobra.Command{ + Use: "ssh ", + Short: "ssh to ziti components", + Example: "ziti fabric ssh ctrl", + Args: cobra.ExactArgs(1), + RunE: action.ssh, + } + + action.AddCommonFlags(sshCmd) + sshCmd.Flags().StringVarP(&action.user, "user", "u", "", "SSH username") + sshCmd.Flags().StringVarP(&action.keyPath, "key", "k", "", "SSH key path") + sshCmd.Flags().BoolVar(&action.proxyMode, "proxy-mode", false, "run in proxy mode, to be called from ssh") + return sshCmd +} + +func (self *sshAction) closeConnections() { + for _, conn := range self.connections.Value() { + pfxlog.Logger().Infof("closing ssh connection %d", conn.id) + _ = conn.Close() + } + close(self.done) +} + +func (self *sshAction) ssh(cmd *cobra.Command, args []string) error { + bindHandler := func(binding channel.Binding) error { + binding.AddReceiveHandlerF(int32(mgmt_pb.ContentType_MgmtPipeDataType), self.receiveData) + binding.AddCloseHandler(channel.CloseHandlerF(func(ch channel.Channel) { + self.closeConnections() + })) + binding.AddReceiveHandlerF(int32(mgmt_pb.ContentType_MgmtPipeCloseType), func(m *channel.Message, ch channel.Channel) { + self.closeConnections() + }) + return nil + } + + ch, err := api.NewWsMgmtChannel(channel.BindHandlerF(bindHandler)) + if err != nil { + return err + } + + destination := args[0] + + if idx := strings.IndexByte(destination, '@'); idx > 0 { + self.user = destination[0:idx] + destination = destination[idx+1:] + } + + sshRequest := &mgmt_pb.MgmtPipeRequest{ + DestinationType: mgmt_pb.DestinationType_Any, + Destination: destination, + TimeoutMillis: uint64(self.Timeout * 1000), + } + + if strings.HasPrefix(destination, "ctrl:") { + sshRequest.DestinationType = mgmt_pb.DestinationType_Controller + sshRequest.Destination = strings.TrimPrefix(destination, "ctrl:") + } else if strings.HasPrefix(destination, "c:") { + sshRequest.DestinationType = mgmt_pb.DestinationType_Controller + sshRequest.Destination = strings.TrimPrefix(destination, "c:") + } else if strings.HasPrefix(destination, "router:") { + sshRequest.DestinationType = mgmt_pb.DestinationType_Router + sshRequest.Destination = strings.TrimPrefix(destination, "router:") + } else if strings.HasPrefix(destination, "r:") { + sshRequest.DestinationType = mgmt_pb.DestinationType_Router + sshRequest.Destination = strings.TrimPrefix(destination, "r:") + } + + // router name -> router id mapping + if sshRequest.DestinationType == mgmt_pb.DestinationType_Any || sshRequest.DestinationType == mgmt_pb.DestinationType_Router { + id, err := api.MapNameToID(util.FabricAPI, "routers", &self.Options, sshRequest.Destination) + if err == nil { + sshRequest.DestinationType = mgmt_pb.DestinationType_Router + sshRequest.Destination = id + } + } + + resp, err := protobufs.MarshalTyped(sshRequest).WithTimeout(time.Duration(self.Timeout) * time.Second).SendForReply(ch) + sshResp := &mgmt_pb.MgmtPipeResponse{} + err = protobufs.TypedResponse(sshResp).Unmarshall(resp, err) + if err != nil { + return err + } + + if !sshResp.Success { + return errors.New(sshResp.Msg) + } + + conn := &sshConn{ + id: sshResp.ConnId, + ch: ch, + ReadAdapter: channel.NewReadAdapter(fmt.Sprintf("mgmt-pipe-%d", sshResp.ConnId), 4), + } + + go func() { + done := false + for !done { + select { + case data := <-self.incomingData: + if err := conn.PushData(data); err != nil { + return + } + case <-self.done: + done = true + } + } + + for { + select { + case data := <-self.incomingData: + if err := conn.PushData(data); err != nil { + return + } + default: + break + } + } + }() + + self.connections.Append(conn) + + if self.proxyMode { + return self.runProxy(conn) + } + + return self.remoteShell(conn) +} + +func (self *sshAction) runProxy(conn net.Conn) error { + errC := make(chan error, 2) + go func() { + _, err := io.Copy(conn, os.Stdin) + errC <- err + }() + + go func() { + _, err := io.Copy(os.Stdout, conn) + errC <- err + }() + + err := <-errC + if err == nil { + select { + case err = <-errC: + default: + } + } + + return err +} + +func sshAuthMethodFromFile(keyPath string) (ssh.AuthMethod, error) { + content, err := os.ReadFile(keyPath) + if err != nil { + return nil, fmt.Errorf("could not read ssh file [%s]: %w", keyPath, err) + } + + if signer, err := ssh.ParsePrivateKey(content); err == nil { + return ssh.PublicKeys(signer), nil + } else { + if err.Error() == "ssh: no key found" { + return nil, fmt.Errorf("no private key found in [%s]: %w", keyPath, err) + } else if err.(*ssh.PassphraseMissingError) != nil { + return nil, fmt.Errorf("file is password protected [%s] %w", keyPath, err) + } else { + return nil, fmt.Errorf("error parsing private key from [%s]L %w", keyPath, err) + } + } +} + +func sshAuthMethodAgent() ssh.AuthMethod { + if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { + return ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers) + } + return nil +} + +func (self *sshAction) newSshConfig() *ssh.ClientConfig { + var methods []ssh.AuthMethod + + if fileMethod, err := sshAuthMethodFromFile(self.keyPath); err == nil { + methods = append(methods, fileMethod) + } else { + logrus.Error(err) + } + + if agentMethod := sshAuthMethodAgent(); agentMethod != nil { + methods = append(methods, sshAuthMethodAgent()) + } + + return &ssh.ClientConfig{ + User: self.user, + Auth: methods, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + } +} + +func (self *sshAction) remoteShell(conn net.Conn) error { + if self.user == "" { + current, err := user.Current() + if err != nil { + return fmt.Errorf("unable to get current user: %w", err) + } + self.user = current.Name + } + + clientConfig := self.newSshConfig() + c, chans, reqs, err := ssh.NewClientConn(conn, "localhost:22", clientConfig) + if err != nil { + return err + } + client := ssh.NewClient(c, chans, reqs) + + session, err := client.NewSession() + if err != nil { + return err + } + + fd := int(os.Stdout.Fd()) + + oldState, err := term.MakeRaw(fd) + if err != nil { + panic(err) + } + defer func() { + _ = session.Close() + _ = term.Restore(fd, oldState) + }() + + session.Stdout = os.Stdout + session.Stderr = os.Stderr + session.Stdin = os.Stdin + + termWidth, termHeight, err := term.GetSize(fd) + if err != nil { + panic(err) + } + + if err := session.RequestPty("xterm", termHeight, termWidth, ssh.TerminalModes{ssh.ECHO: 1}); err != nil { + return err + } + + return session.Run("/bin/bash") +} + +func (self *sshAction) receiveData(msg *channel.Message, _ channel.Channel) { + self.incomingData <- msg.Body +} + +type sshConn struct { + id uint32 + ch channel.Channel + *channel.ReadAdapter +} + +func (self *sshConn) Write(b []byte) (n int, err error) { + msg := channel.NewMessage(int32(mgmt_pb.ContentType_MgmtPipeDataType), b) + msg.PutUint32Header(int32(mgmt_pb.Header_MgmtPipeIdHeader), self.id) + if err = msg.WithTimeout(5 * time.Second).SendAndWaitForWire(self.ch); err != nil { + return 0, err + } + return len(b), err +} + +func (self *sshConn) Close() error { + self.ReadAdapter.Close() + return self.ch.Close() +} + +func (self *sshConn) LocalAddr() net.Addr { + return self.ch.Underlay().GetLocalAddr() +} + +func (self *sshConn) RemoteAddr() net.Addr { + return sshAddr{ + destination: fmt.Sprintf("%v", self.id), + } +} + +func (self *sshConn) SetDeadline(t time.Time) error { + //TODO implement me + panic("implement me") +} + +func (self *sshConn) SetWriteDeadline(t time.Time) error { + //TODO implement me + panic("implement me") +} + +type sshAddr struct { + destination string +} + +func (self sshAddr) Network() string { + return "ziti" +} + +func (self sshAddr) String() string { + return "ziti:" + self.destination +} diff --git a/zititest/go.mod b/zititest/go.mod index 6b96e7165..de56fa7bc 100644 --- a/zititest/go.mod +++ b/zititest/go.mod @@ -13,7 +13,7 @@ require ( github.com/openziti/agent v1.0.18 github.com/openziti/channel/v3 v3.0.7 github.com/openziti/edge-api v0.26.35 - github.com/openziti/fablab v0.5.72 + github.com/openziti/fablab v0.5.60 github.com/openziti/foundation/v2 v2.0.49 github.com/openziti/identity v1.0.87 github.com/openziti/sdk-golang v0.23.44 @@ -39,6 +39,7 @@ require ( github.com/MichaelMure/go-term-text v0.3.1 // indirect github.com/alecthomas/chroma v0.10.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect + github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -51,6 +52,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/coreos/go-iptables v0.8.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/creack/pty v1.1.11 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 // indirect github.com/dineshappavoo/basex v0.0.0-20170425072625-481a6f6dc663 // indirect @@ -60,13 +62,14 @@ require ( github.com/ef-ds/deque v1.0.4 // indirect github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/fatih/color v1.17.0 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa // indirect github.com/gaissmai/extnetip v1.1.0 // indirect - github.com/go-acme/lego/v4 v4.18.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/gliderlabs/ssh v0.1.1 // indirect + github.com/go-acme/lego/v4 v4.19.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -103,7 +106,7 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.14.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect - github.com/jedib0t/go-pretty/v6 v6.5.9 // indirect + github.com/jedib0t/go-pretty/v6 v6.6.1 // indirect github.com/jessevdk/go-flags v1.6.1 // indirect github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/zititest/go.sum b/zititest/go.sum index c018fab53..9c7985a93 100644 --- a/zititest/go.sum +++ b/zititest/go.sum @@ -80,6 +80,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= @@ -183,10 +184,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -203,16 +205,17 @@ github.com/gaissmai/extnetip v1.1.0 h1:ZWEPVPUtw1o//CWh69/Eo79gWEKVYB1STrJjpTR4Q github.com/gaissmai/extnetip v1.1.0/go.mod h1:Ad+qyjy0r98Uc655JzzWoBTzDW29QR4YZDxzHgqhuqM= github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-acme/lego/v4 v4.18.0 h1:2hH8KcdRBSb+p5o9VZIm61GAOXYALgILUCSs1Q+OYsk= -github.com/go-acme/lego/v4 v4.18.0/go.mod h1:Blkg3izvXpl3zxk7WKngIuwR2I/hvYVP3vRnvgBp7m8= +github.com/go-acme/lego/v4 v4.19.2 h1:Y8hrmMvWETdqzzkRly7m98xtPJJivWFsgWi8fcvZo+Y= +github.com/go-acme/lego/v4 v4.19.2/go.mod h1:wtDe3dDkmV4/oI2nydpNXSJpvV10J9RCyZ6MbYxNtlQ= github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -414,8 +417,8 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU= -github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= +github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc= +github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc= github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI= @@ -600,8 +603,8 @@ github.com/openziti/dilithium v0.3.5 h1:+envGNzxc3OyVPiuvtxivQmCsOjdZjtOMLpQBeMz github.com/openziti/dilithium v0.3.5/go.mod h1:XONq1iK6te/WwNzkgZHfIDHordMPqb0hMwJ8bs9EfSk= github.com/openziti/edge-api v0.26.35 h1:32ILwMAPCQrf5ZVIR8IQO5AQwblIM60yD1+ABw48vXU= github.com/openziti/edge-api v0.26.35/go.mod h1:sYHVpm26Jr1u7VooNJzTb2b2nGSlmCHMnbGC8XfWSng= -github.com/openziti/fablab v0.5.72 h1:omcV1vS8C7FS1gnEFItczq7irf/8pMnvZNg/L7M/N2Q= -github.com/openziti/fablab v0.5.72/go.mod h1:qETYWQwY7QClVPQMpB5mS7izh2Bnk3LzbhbCrprbAR0= +github.com/openziti/fablab v0.5.60 h1:RsqrEb3LV6asK5N97uZKyNSDhcNOeDcAuT4OAD/hY9Y= +github.com/openziti/fablab v0.5.60/go.mod h1:B/ib+GOtozEIytv2aXSFl9+dL7AiGfbpGS/VjnNduU8= github.com/openziti/foundation/v2 v2.0.49 h1:aQ5I/lMhkHQ6urhRpLwrWP+7YtoeUitCfY/wub+nOqo= github.com/openziti/foundation/v2 v2.0.49/go.mod h1:tFk7wg5WE/nDDur5jSVQTROugKDXQkFvmqRSV4pvWp0= github.com/openziti/identity v1.0.87 h1:v0NnaDee/5GkPGSoG+2XTl0+0b3BDsm1R6EkkBmK+Zw= diff --git a/zititest/models/smoke/configs/ctrl.yml.tmpl b/zititest/models/smoke/configs/ctrl.yml.tmpl index 5ccfb98d0..8ca71c5ce 100644 --- a/zititest/models/smoke/configs/ctrl.yml.tmpl +++ b/zititest/models/smoke/configs/ctrl.yml.tmpl @@ -15,6 +15,14 @@ identity: trustDomain: smoke-test +mgmt: + pipe: + enabled: true + enableExperimentalFeature: true + destination: embedded-ssh-server + authorizedKeysFile: /home/ubuntu/.ssh/authorized_keys + shell: /usr/bin/bash + # the endpoint that routers will connect to the controller over. ctrl: listener: tls:0.0.0.0:6262 diff --git a/zititest/models/smoke/configs/router.yml.tmpl b/zititest/models/smoke/configs/router.yml.tmpl index 3fdcfc53e..ed6233935 100644 --- a/zititest/models/smoke/configs/router.yml.tmpl +++ b/zititest/models/smoke/configs/router.yml.tmpl @@ -17,6 +17,14 @@ identity: key: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}.key ca: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-server.chain.pem +mgmt: + pipe: + enabled: true + enableExperimentalFeature: true + destination: embedded-ssh-server + authorizedKeysFile: /home/ubuntu/.ssh/authorized_keys + shell: /usr/bin/bash + ctrl: endpoints: {{ range $host := .Model.MustSelectHosts "component.ctrl" 1 }} - tls:{{ $host.PublicIp }}:6262{{end}}