port the share infrastructure over to the subordinate framework (#789)

This commit is contained in:
Michael Quigley 2024-11-15 12:09:20 -05:00
parent 5c4cf9b26a
commit 3205b92d06
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
7 changed files with 126 additions and 113 deletions

View File

@ -1,14 +1,11 @@
package agent package agent
import ( import (
"bytes"
"encoding/json"
"errors" "errors"
"github.com/michaelquigley/pfxlog" "github.com/michaelquigley/pfxlog"
"github.com/openziti/zrok/agent/proctree" "github.com/openziti/zrok/agent/proctree"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/sdk/golang/sdk"
"github.com/sirupsen/logrus"
"strings"
"time" "time"
) )
@ -28,11 +25,8 @@ type share struct {
closed bool closed bool
accessGrants []string accessGrants []string
process *proctree.Child process *proctree.Child
readBuffer bytes.Buffer sub *subordinate.MessageHandler
booted bool
bootComplete chan struct{}
bootErr error
agent *Agent agent *Agent
} }
@ -44,79 +38,46 @@ func (s *share) monitor() {
s.agent.rmShare <- s s.agent.rmShare <- s
} }
func (s *share) tail(data []byte) { func (s *share) bootHandler(msgType string, msg subordinate.Message) error {
defer func() { switch msgType {
if r := recover(); r != nil { case subordinate.BootMessage:
logrus.Errorf("recovering: %v", r) if v, found := msg["token"]; found {
if str, ok := v.(string); ok {
s.token = str
}
} }
}() if v, found := msg["backend_mode"]; found {
s.readBuffer.Write(data) if str, ok := v.(string); ok {
if line, err := s.readBuffer.ReadString('\n'); err == nil { s.backendMode = sdk.BackendMode(str)
line = strings.Trim(line, "\n") }
if !s.booted { }
if strings.HasPrefix(line, "{") { if v, found := msg["share_mode"]; found {
in := make(map[string]interface{}) if str, ok := v.(string); ok {
if err := json.Unmarshal([]byte(line), &in); err == nil { s.shareMode = sdk.ShareMode(str)
if v, found := in["message"]; found { }
if str, ok := v.(string); ok { }
if str == "boot" { if v, found := msg["frontend_endpoints"]; found {
if v, found := in["token"]; found { if vArr, ok := v.([]interface{}); ok {
if str, ok := v.(string); ok { for _, v := range vArr {
s.token = str if str, ok := v.(string); ok {
} s.frontendEndpoints = append(s.frontendEndpoints, str)
}
if v, found := in["backend_mode"]; found {
if str, ok := v.(string); ok {
s.backendMode = sdk.BackendMode(str)
}
}
if v, found := in["share_mode"]; found {
if str, ok := v.(string); ok {
s.shareMode = sdk.ShareMode(str)
}
}
if v, found := in["frontend_endpoints"]; found {
if vArr, ok := v.([]interface{}); ok {
for _, v := range vArr {
if str, ok := v.(string); ok {
s.frontendEndpoints = append(s.frontendEndpoints, str)
}
}
}
}
if v, found := in["target"]; found {
if str, ok := v.(string); ok {
s.target = str
}
}
s.booted = true
} else {
s.bootErr = errors.New(line)
}
} else {
s.bootErr = errors.New(line)
}
} else {
s.bootErr = errors.New(line)
} }
} else {
s.bootErr = errors.New(line)
} }
close(s.bootComplete)
} else {
logrus.Warn(line)
}
} else {
if strings.HasPrefix(line, "{") {
in := make(map[string]interface{})
if err := json.Unmarshal([]byte(line), &in); err == nil {
pfxlog.ChannelLogger(s.token).Info(in)
}
} else {
pfxlog.ChannelLogger(s.token).Info(strings.Trim(line, "\n"))
} }
} }
} else { if v, found := msg["target"]; found {
s.readBuffer.WriteString(line) if str, ok := v.(string); ok {
s.target = str
}
}
case subordinate.ErrorMessage:
if v, found := msg[subordinate.ErrorMessage]; found {
if str, ok := v.(string); ok {
return errors.New(str)
}
}
} }
return nil
} }

View File

@ -3,8 +3,10 @@ package agent
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/agent/proctree" "github.com/openziti/zrok/agent/proctree"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/environment" "github.com/openziti/zrok/environment"
"github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/sdk/golang/sdk"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -23,10 +25,20 @@ func (i *agentGrpcImpl) SharePrivate(_ context.Context, req *agentGrpc.SharePriv
shrCmd := []string{os.Args[0], "share", "private", "--subordinate", "-b", req.BackendMode} shrCmd := []string{os.Args[0], "share", "private", "--subordinate", "-b", req.BackendMode}
shr := &share{ shr := &share{
shareMode: sdk.PrivateShareMode, shareMode: sdk.PrivateShareMode,
backendMode: sdk.BackendMode(req.BackendMode), backendMode: sdk.BackendMode(req.BackendMode),
bootComplete: make(chan struct{}), sub: subordinate.NewMessageHandler(),
agent: i.agent, agent: i.agent,
}
shr.sub.MessageHandler = func(msg subordinate.Message) {
logrus.Info(msg)
}
var bootErr error
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
bootErr = shr.bootHandler(msgType, msg)
}
shr.sub.MalformedHandler = func(msg subordinate.Message) {
logrus.Error(msg)
} }
if req.Insecure { if req.Insecure {
@ -49,18 +61,22 @@ func (i *agentGrpcImpl) SharePrivate(_ context.Context, req *agentGrpc.SharePriv
logrus.Infof("executing '%v'", shrCmd) logrus.Infof("executing '%v'", shrCmd)
shr.process, err = proctree.StartChild(shr.tail, shrCmd...) shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
go shr.monitor() <-shr.sub.BootComplete
<-shr.bootComplete
if shr.bootErr == nil { if bootErr == nil {
go shr.monitor()
i.agent.addShare <- shr i.agent.addShare <- shr
return &agentGrpc.SharePrivateResponse{Token: shr.token}, nil return &agentGrpc.SharePrivateResponse{Token: shr.token}, nil
} else {
if err := proctree.WaitChild(shr.process); err != nil {
logrus.Errorf("error joining: %v", err)
}
return nil, fmt.Errorf("unable to start share: %v", bootErr)
} }
return nil, shr.bootErr
} }

View File

@ -3,8 +3,10 @@ package agent
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/agent/proctree" "github.com/openziti/zrok/agent/proctree"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/environment" "github.com/openziti/zrok/environment"
"github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/sdk/golang/sdk"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -23,10 +25,20 @@ func (i *agentGrpcImpl) SharePublic(_ context.Context, req *agentGrpc.SharePubli
shrCmd := []string{os.Args[0], "share", "public", "--subordinate", "-b", req.BackendMode} shrCmd := []string{os.Args[0], "share", "public", "--subordinate", "-b", req.BackendMode}
shr := &share{ shr := &share{
shareMode: sdk.PublicShareMode, shareMode: sdk.PublicShareMode,
backendMode: sdk.BackendMode(req.BackendMode), backendMode: sdk.BackendMode(req.BackendMode),
bootComplete: make(chan struct{}), sub: subordinate.NewMessageHandler(),
agent: i.agent, agent: i.agent,
}
shr.sub.MessageHandler = func(msg subordinate.Message) {
logrus.Info(msg)
}
var bootErr error
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
bootErr = shr.bootHandler(msgType, msg)
}
shr.sub.MalformedHandler = func(msg subordinate.Message) {
logrus.Error(msg)
} }
for _, basicAuth := range req.BasicAuth { for _, basicAuth := range req.BasicAuth {
@ -73,21 +85,25 @@ func (i *agentGrpcImpl) SharePublic(_ context.Context, req *agentGrpc.SharePubli
logrus.Infof("executing '%v'", shrCmd) logrus.Infof("executing '%v'", shrCmd)
shr.process, err = proctree.StartChild(shr.tail, shrCmd...) shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
go shr.monitor() <-shr.sub.BootComplete
<-shr.bootComplete
if shr.bootErr == nil { if bootErr == nil {
go shr.monitor()
i.agent.addShare <- shr i.agent.addShare <- shr
return &agentGrpc.SharePublicResponse{ return &agentGrpc.SharePublicResponse{
Token: shr.token, Token: shr.token,
FrontendEndpoints: shr.frontendEndpoints, FrontendEndpoints: shr.frontendEndpoints,
}, nil }, nil
}
return nil, shr.bootErr } else {
if err := proctree.WaitChild(shr.process); err != nil {
logrus.Errorf("error joining: %v", err)
}
return nil, fmt.Errorf("unable to start share: %v", bootErr)
}
} }

View File

@ -3,9 +3,12 @@ package agent
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/agent/proctree" "github.com/openziti/zrok/agent/proctree"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/environment" "github.com/openziti/zrok/environment"
"github.com/sirupsen/logrus"
"os" "os"
) )
@ -21,9 +24,19 @@ func (i *agentGrpcImpl) ShareReserved(_ context.Context, req *agentGrpc.ShareRes
shrCmd := []string{os.Args[0], "share", "reserved", "--subordinate"} shrCmd := []string{os.Args[0], "share", "reserved", "--subordinate"}
shr := &share{ shr := &share{
reserved: true, reserved: true,
bootComplete: make(chan struct{}), sub: subordinate.NewMessageHandler(),
agent: i.agent, agent: i.agent,
}
shr.sub.MessageHandler = func(msg subordinate.Message) {
logrus.Info(msg)
}
var bootErr error
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
bootErr = shr.bootHandler(msgType, msg)
}
shr.sub.MalformedHandler = func(msg subordinate.Message) {
logrus.Error(msg)
} }
if req.OverrideEndpoint != "" { if req.OverrideEndpoint != "" {
@ -38,15 +51,15 @@ func (i *agentGrpcImpl) ShareReserved(_ context.Context, req *agentGrpc.ShareRes
shrCmd = append(shrCmd, req.Token) shrCmd = append(shrCmd, req.Token)
shr.token = req.Token shr.token = req.Token
shr.process, err = proctree.StartChild(shr.tail, shrCmd...) shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
go shr.monitor() <-shr.sub.BootComplete
<-shr.bootComplete
if shr.bootErr == nil { if bootErr == nil {
go shr.monitor()
i.agent.addShare <- shr i.agent.addShare <- shr
return &agentGrpc.ShareReservedResponse{ return &agentGrpc.ShareReservedResponse{
Token: shr.token, Token: shr.token,
@ -55,7 +68,11 @@ func (i *agentGrpcImpl) ShareReserved(_ context.Context, req *agentGrpc.ShareRes
FrontendEndpoints: shr.frontendEndpoints, FrontendEndpoints: shr.frontendEndpoints,
Target: shr.target, Target: shr.target,
}, nil }, nil
}
return nil, shr.bootErr } else {
if err := proctree.WaitChild(shr.process); err != nil {
logrus.Errorf("error joining: %v", err)
}
return nil, fmt.Errorf("unable to start share: %v", bootErr)
}
} }

View File

@ -7,6 +7,7 @@ import (
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/openziti/zrok/agent/agentClient" "github.com/openziti/zrok/agent/agentClient"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints"
"github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/drive"
"github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/endpoints/proxy"
@ -371,7 +372,7 @@ func (cmd *sharePrivateCommand) shareLocal(args []string, root env_core.Root) {
if cmd.subordinate { if cmd.subordinate {
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "boot" data[subordinate.MessageKey] = subordinate.BootMessage
data["token"] = shr.Token data["token"] = shr.Token
data["frontend_endpoints"] = shr.FrontendEndpoints data["frontend_endpoints"] = shr.FrontendEndpoints
jsonData, err := json.Marshal(data) jsonData, err := json.Marshal(data)
@ -395,7 +396,7 @@ func (cmd *sharePrivateCommand) shareLocal(args []string, root env_core.Root) {
select { select {
case req := <-requests: case req := <-requests:
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "access" data[subordinate.MessageKey] = "access"
data["remote_address"] = req.RemoteAddr data["remote_address"] = req.RemoteAddr
data["method"] = req.Method data["method"] = req.Method
data["path"] = req.Path data["path"] = req.Path

View File

@ -8,6 +8,7 @@ import (
"github.com/gobwas/glob" "github.com/gobwas/glob"
"github.com/openziti/zrok/agent/agentClient" "github.com/openziti/zrok/agent/agentClient"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints"
"github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/drive"
"github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/endpoints/proxy"
@ -273,7 +274,7 @@ func (cmd *sharePublicCommand) shareLocal(args []string, root env_core.Root) {
if cmd.subordinate { if cmd.subordinate {
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "boot" data[subordinate.MessageKey] = subordinate.BootMessage
data["token"] = shr.Token data["token"] = shr.Token
data["frontend_endpoints"] = shr.FrontendEndpoints data["frontend_endpoints"] = shr.FrontendEndpoints
jsonData, err := json.Marshal(data) jsonData, err := json.Marshal(data)
@ -297,7 +298,7 @@ func (cmd *sharePublicCommand) shareLocal(args []string, root env_core.Root) {
select { select {
case req := <-requests: case req := <-requests:
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "access" data[subordinate.MessageKey] = "access"
data["remote_address"] = req.RemoteAddr data["remote_address"] = req.RemoteAddr
data["method"] = req.Method data["method"] = req.Method
data["path"] = req.Path data["path"] = req.Path

View File

@ -8,6 +8,7 @@ import (
httptransport "github.com/go-openapi/runtime/client" httptransport "github.com/go-openapi/runtime/client"
"github.com/openziti/zrok/agent/agentClient" "github.com/openziti/zrok/agent/agentClient"
"github.com/openziti/zrok/agent/agentGrpc" "github.com/openziti/zrok/agent/agentGrpc"
"github.com/openziti/zrok/cmd/zrok/subordinate"
"github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints"
"github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/drive"
"github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/endpoints/proxy"
@ -321,7 +322,7 @@ func (cmd *shareReservedCommand) shareLocal(args []string, root env_core.Root) {
if cmd.subordinate { if cmd.subordinate {
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "boot" data[subordinate.MessageKey] = subordinate.BootMessage
data["token"] = resp.Payload.Token data["token"] = resp.Payload.Token
data["backend_mode"] = resp.Payload.BackendMode data["backend_mode"] = resp.Payload.BackendMode
data["share_mode"] = resp.Payload.ShareMode data["share_mode"] = resp.Payload.ShareMode
@ -358,7 +359,7 @@ func (cmd *shareReservedCommand) shareLocal(args []string, root env_core.Root) {
select { select {
case req := <-requests: case req := <-requests:
data := make(map[string]interface{}) data := make(map[string]interface{})
data["message"] = "access" data[subordinate.MessageKey] = "access"
data["remote-address"] = req.RemoteAddr data["remote-address"] = req.RemoteAddr
data["method"] = req.Method data["method"] = req.Method
data["path"] = req.Path data["path"] = req.Path