Files
lpra/internal/proto/proto.go
T
2026-10-13 00:25:29 +03:00

147 lines
4.6 KiB
Go

// Package proto describes the wire messages shared by the server and the agent.
//
// All agent<->server traffic is plain JSON over HTTP(S) long-polling so it
// survives NAT and restrictive egress firewalls: the agent only ever makes
// outbound requests.
package proto
import "encoding/json"
// Control poll message types (server -> agent, returned from /api/agent/poll).
const (
// CtrlIdle is returned when the long-poll times out with nothing to do.
CtrlIdle = "idle"
// CtrlOpenTerminal tells the agent to spawn a PTY for the session id.
CtrlOpenTerminal = "open_terminal"
// CtrlOpenForward tells the agent to dial 127.0.0.1:Port and bridge it to
// the session id (reverse TCP port-forward).
CtrlOpenForward = "open_forward"
// CtrlTask tells the agent to fetch and run the one-shot task TaskID.
CtrlTask = "task"
)
// EnrollRequest is sent once by a freshly installed agent.
type EnrollRequest struct {
Name string `json:"name"`
Hostname string `json:"hostname"`
OS string `json:"os"`
Arch string `json:"arch"`
Version string `json:"version"`
}
// EnrollResponse carries the identity the agent persists and uses from then on.
type EnrollResponse struct {
AgentID string `json:"agent_id"`
Token string `json:"token"`
}
// ControlMessage is the body returned by the control long-poll.
type ControlMessage struct {
Type string `json:"type"`
SessionID string `json:"session_id,omitempty"`
Port int `json:"port,omitempty"` // CtrlOpenForward: client-side port to dial
TaskID string `json:"task_id,omitempty"` // CtrlTask
}
// Terminal / stream frame types on the session "in" channel (server -> agent).
// Reused for both PTY terminals and raw TCP port-forward streams.
const (
FrameStdin = "stdin" // base64 bytes for the PTY / socket
FrameResize = "resize" // PTY window size (terminal only)
FrameClose = "close" // tear the stream down
)
// InFrame is one element of the stream downstream batch (server -> agent).
type InFrame struct {
Type string `json:"type"`
Data string `json:"data,omitempty"` // base64 bytes
Cols uint16 `json:"cols,omitempty"`
Rows uint16 `json:"rows,omitempty"`
}
// InBatch is the JSON body returned by GET /api/agent/term/{sid}/in.
type InBatch struct {
Frames []InFrame `json:"frames"`
}
// OutMessage is POSTed by the agent to /api/agent/term/{sid}/out.
type OutMessage struct {
Data string `json:"data,omitempty"` // base64 bytes
Exit bool `json:"exit,omitempty"`
}
// --- one-shot tasks (file manager, native in the agent) ---
const (
TaskFSList = "fs.list" // list a directory
TaskFSRead = "fs.read" // read file content (for view/edit)
TaskFSWrite = "fs.write" // write/overwrite file (edit save, create, upload)
TaskFSMkdir = "fs.mkdir" // create directory
TaskFSDelete = "fs.delete" // delete a single file or empty dir
TaskFSDelTree = "fs.deltree" // recursively delete a directory
TaskFSUnzip = "fs.unzip" // unzip an archive (needs `unzip` on the client)
TaskFSZip = "fs.zip" // zip selected paths (native archive/zip)
TaskFSMove = "fs.move" // move/rename
TaskFSDownload = "fs.download" // read a whole file (larger cap) for browser download
TaskSysUpdate = "sys.update" // download the latest agent binary and restart
)
// TaskEnvelope is what the agent fetches for a task id.
type TaskEnvelope struct {
Type string `json:"type"`
Args json.RawMessage `json:"args"`
}
// TaskResult is POSTed back by the agent.
type TaskResult struct {
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
}
// fs task argument shapes.
type FSPathArgs struct {
Path string `json:"path"`
}
type FSWriteArgs struct {
Path string `json:"path"`
Data string `json:"data"` // base64 content
}
type FSUnzipArgs struct {
Path string `json:"path"`
Dest string `json:"dest"`
}
type FSZipArgs struct {
Paths []string `json:"paths"`
Dest string `json:"dest"`
}
type FSMoveArgs struct {
Src string `json:"src"`
Dst string `json:"dst"`
}
// FSEntry is one directory entry.
type FSEntry struct {
Name string `json:"name"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
Mode string `json:"mode"`
MTime int64 `json:"mtime"`
}
// FSListResult is returned for TaskFSList.
type FSListResult struct {
Path string `json:"path"`
Entries []FSEntry `json:"entries"`
}
// FSReadResult is returned for TaskFSRead.
type FSReadResult struct {
Path string `json:"path"`
Size int64 `json:"size"`
Content string `json:"content"` // base64
Truncated bool `json:"truncated"`
Binary bool `json:"binary"`
}