Files
headplane/agent/internal/hpagent/handler.go
T
2025-06-16 11:44:59 -04:00

158 lines
3.7 KiB
Go

package hpagent
import (
"bufio"
"bytes"
// "encoding/json"
"os"
// "sync"
"github.com/fxamacker/cbor/v2"
"github.com/tale/headplane/agent/internal/sshutil"
"github.com/tale/headplane/agent/internal/tsnet"
"github.com/tale/headplane/agent/internal/util"
// "tailscale.com/tailcfg"
)
// Represents messages from the Headplane master
type RecvMessage struct {
NodeIDs []string
}
type CborMessage struct {
Op string `cbor:"op"`
Payload cbor.RawMessage `cbor:"payload"`
}
type SSHConnect struct {
SessionId string `cbor:"sessionId"`
Username string `cbor:"username"`
Hostname string `cbor:"hostname"`
Port int `cbor:"port"`
}
type SSHMessage struct {
op string
username string
hostname string
Id string
}
type SendMessage struct {
Type string
Data any
}
// Starts listening for messages from stdin
func FollowMaster(agent *tsnet.TSAgent) {
log := util.GetLogger()
scanner := bufio.NewScanner(os.Stdin)
log.Info("Listening for messages from Headplane master on stdin")
for scanner.Scan() {
line := scanner.Bytes()
log.Info("Got bytes delimited by newline");
var msg CborMessage
decoder := cbor.NewDecoder(bytes.NewReader(line))
err := decoder.Decode(&msg)
if err != nil {
log.Error("Unable to decode message from master: %s", err)
continue;
}
log.Debug("Received message from master: %s", msg)
var sshPayload SSHConnect
err = cbor.Unmarshal(msg.Payload, &sshPayload)
if err != nil {
log.Error("Unable to unmarshal SSH connect payload: %s", err)
continue;
}
log.Info("Opening SSH PTY for session %s to %s@%s:%d", sshPayload.SessionId, sshPayload.Username, sshPayload.Hostname, sshPayload.Port)
sshutil.OpenSshPty(agent, sshutil.SshConnectParams{
Hostname: sshPayload.Hostname,
Port: sshPayload.Port,
Username: sshPayload.Username,
Id: sshPayload.SessionId,
})
}
// var msg RecvMessage
// err := json.Unmarshal(line, &msg)
// if err != nil {
// var cborMsg CborMessage
// dec := cbor.NewDecoder(bytes.NewReader(line))
// err := dec.Decode(&cborMsg)
// if err == nil {
// log.Info("Unmarshalled CBOR message: %s", cborMsg)
// var sshPayload SSHConnect
// err = cbor.Unmarshal(cborMsg.Payload, &sshPayload)
// sshutil.OpenSshPty(agent, sshutil.SshConnectParams{
// Hostname: sshPayload.Hostname,
// Port: sshPayload.Port,
// Username: sshPayload.Username,
// Id: sshPayload.SessionId,
// })
// return;
// }
// log.Error("Unable to unmarshal message: %s", err)
// log.Debug("Full Error: %v", err)
// continue
// }
// log.Debug("Recieved message from master: %v", line)
// if len(msg.NodeIDs) == 0 {
// log.Debug("Message recieved had no node IDs")
// log.Debug("Full message: %s", line)
// continue
// }
// // Accumulate the results since we invoke via gofunc
// results := make(map[string]*tailcfg.HostinfoView)
// mu := sync.Mutex{}
// wg := sync.WaitGroup{}
// for _, nodeID := range msg.NodeIDs {
// wg.Add(1)
// go func(nodeID string) {
// defer wg.Done()
// result, err := agent.GetStatusForPeer(nodeID)
// if err != nil {
// log.Error("Unable to get status for node %s: %s", nodeID, err)
// return
// }
// if result == nil {
// log.Debug("No status for node %s", nodeID)
// return
// }
// mu.Lock()
// results[nodeID] = result
// mu.Unlock()
// }(nodeID)
// }
// wg.Wait()
// // Send the results back to the Headplane master
// log.Debug("Sending status back to master: %v", results)
// log.Msg(&SendMessage{
// Type: "status",
// Data: results,
// })
// }
// if err := scanner.Err(); err != nil {
// log.Fatal("Error reading from stdin: %s", err)
// }
}