From ffeca2a53377510b4f645ca34e3c1853323acefb Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Wed, 24 Jul 2024 21:39:14 +0200 Subject: [PATCH] First version with basic communication from agent to server working. --- cmd/agent/agent.go | 2 +- cmd/comms/agentserver.go | 69 ------------------- cmd/converge/server.go | 2 +- pkg/comms/agentserver.go | 144 +++++++++++++++++++++++++++++++++++++++ pkg/converge/admin.go | 2 +- 5 files changed, 147 insertions(+), 72 deletions(-) delete mode 100644 cmd/comms/agentserver.go create mode 100644 pkg/comms/agentserver.go diff --git a/cmd/agent/agent.go b/cmd/agent/agent.go index 7dfd95b..31d7ec0 100755 --- a/cmd/agent/agent.go +++ b/cmd/agent/agent.go @@ -2,8 +2,8 @@ package main import ( "bufio" - "converge/cmd/comms" "converge/pkg/agent" + "converge/pkg/comms" "converge/pkg/iowrappers" "converge/pkg/terminal" "converge/pkg/websocketutil" diff --git a/cmd/comms/agentserver.go b/cmd/comms/agentserver.go deleted file mode 100644 index 726eb79..0000000 --- a/cmd/comms/agentserver.go +++ /dev/null @@ -1,69 +0,0 @@ -package comms - -import ( - "fmt" - "github.com/hashicorp/yamux" - "io" - "log" - "net" -) - -type CommChannel struct { - Peer net.Conn - Session *yamux.Session -} - -type Role int - -const ( - Agent Role = iota - ConvergeServer -) - -func NewCommChannel(role Role, wsConn io.ReadWriteCloser) (CommChannel, error) { - var commChannel CommChannel - switch role { - case Agent: - listener, err := yamux.Server(wsConn, nil) - if err != nil { - return CommChannel{}, err - } - commChannel = CommChannel{ - Peer: nil, - Session: listener, - } - case ConvergeServer: - clientSession, err := yamux.Client(wsConn, nil) - if err != nil { - return CommChannel{}, err - } - commChannel = CommChannel{ - Peer: nil, - Session: clientSession, - } - default: - panic(fmt.Errorf("Undefined role %d", role)) - } - - // communication from Agent to ConvergeServer - - switch role { - case Agent: - conn, err := commChannel.Session.OpenStream() - commChannel.Peer = conn - if err != nil { - return CommChannel{}, err - } - case ConvergeServer: - conn, err := commChannel.Session.Accept() - commChannel.Peer = conn - if err != nil { - return CommChannel{}, err - } - default: - panic(fmt.Errorf("Undefined role %d", role)) - } - - log.Println("Communication channel between agent and converge server established") - return commChannel, nil -} diff --git a/cmd/converge/server.go b/cmd/converge/server.go index 32ae113..1014698 100644 --- a/cmd/converge/server.go +++ b/cmd/converge/server.go @@ -51,7 +51,7 @@ func main() { os.Exit(1) } downloadDir := *downloadOption - log.Println("Doanload directory", downloadDir) + log.Println("Download directory", downloadDir) admin := converge.NewAdmin() registrationService := websocketutil.WebSocketService{ diff --git a/pkg/comms/agentserver.go b/pkg/comms/agentserver.go new file mode 100644 index 0000000..8ec4f45 --- /dev/null +++ b/pkg/comms/agentserver.go @@ -0,0 +1,144 @@ +package comms + +import ( + "encoding/gob" + "fmt" + "github.com/hashicorp/yamux" + "io" + "log" + "net" + "os" + "os/user" + "time" +) + +type CommChannel struct { + Peer net.Conn + Encoder *gob.Encoder + Decoder *gob.Decoder + Session *yamux.Session +} + +type Role int + +const ( + Agent Role = iota + ConvergeServer +) + +func NewCommChannel(role Role, wsConn io.ReadWriteCloser) (CommChannel, error) { + var commChannel CommChannel + switch role { + case Agent: + listener, err := yamux.Server(wsConn, nil) + if err != nil { + return CommChannel{}, err + } + commChannel = CommChannel{ + Peer: nil, + Session: listener, + } + case ConvergeServer: + clientSession, err := yamux.Client(wsConn, nil) + if err != nil { + return CommChannel{}, err + } + commChannel = CommChannel{ + Peer: nil, + Session: clientSession, + } + default: + panic(fmt.Errorf("Undefined role %d", role)) + } + + // communication from Agent to ConvergeServer + + switch role { + case Agent: + conn, err := commChannel.Session.OpenStream() + commChannel.Peer = conn + if err != nil { + return CommChannel{}, err + } + case ConvergeServer: + conn, err := commChannel.Session.Accept() + commChannel.Peer = conn + if err != nil { + return CommChannel{}, err + } + default: + panic(fmt.Errorf("Undefined role %d", role)) + } + log.Println("Communication channel between agent and converge server established") + + gob.Register(RemoteSession{}) + gob.Register(ExpiryTimeUpdate{}) + gob.Register(ConvergeMessage{}) + + commChannel.Encoder = gob.NewEncoder(commChannel.Peer) + commChannel.Decoder = gob.NewDecoder(commChannel.Peer) + + switch role { + case Agent: + err := commChannel.Encoder.Encode(ConvergeMessage{Value: NewRemoteSession()}) + if err != nil { + log.Printf("Encoding error %v", err) + } + err = commChannel.Encoder.Encode(ConvergeMessage{Value: NewExpiryTimeUpdate(time.Now())}) + if err != nil { + log.Printf("Encoding error %v", err) + } + case ConvergeServer: + go serverReader(commChannel) + } + + return commChannel, nil +} + +func serverReader(channel CommChannel) { + for { + var result ConvergeMessage + err := channel.Decoder.Decode(&result) + + if err != nil { + log.Printf("Error decoding object %v", err) + } + switch v := result.Value.(type) { + case RemoteSession: + log.Println("RECEIVED: session info ", v) + case ExpiryTimeUpdate: + log.Println("RECEIVED: expirytime update ", v) + default: + fmt.Printf(" Unknown type: %T\n", v) + } + } +} + +type RemoteSession struct { + Username string + Hostname string + Pwd string +} + +func NewRemoteSession() RemoteSession { + username, _ := user.Current() + host, _ := os.Hostname() + pwd, _ := os.Getwd() + return RemoteSession{ + Username: username.Username, + Hostname: host, + Pwd: pwd, + } +} + +type ExpiryTimeUpdate struct { + ExpiryTime time.Time +} + +type ConvergeMessage struct { + Value interface{} +} + +func NewExpiryTimeUpdate(expiryTime time.Time) ExpiryTimeUpdate { + return ExpiryTimeUpdate{ExpiryTime: expiryTime} +} diff --git a/pkg/converge/admin.go b/pkg/converge/admin.go index 5ed282b..3e76d9c 100644 --- a/pkg/converge/admin.go +++ b/pkg/converge/admin.go @@ -1,7 +1,7 @@ package converge import ( - "converge/cmd/comms" + "converge/pkg/comms" "converge/pkg/iowrappers" "fmt" "github.com/hashicorp/yamux"