server

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package server's handlers.go exposes the agent's three operations (Scan / Probe / RunLua) as plain Go functions that take request structs and return response structs. This lets the HTTP server in server.go and the NATS dispatcher in cmd/hugin-agent/nats.go share a single implementation.

Design contract:

  • Functions are package-public (capitalised) and stable.
  • Inputs are JSON-tagged structs so the same shape goes over HTTP and NATS without an extra translation layer.
  • RunLuaContext takes an EventSink callback so long-running operations can stream emissions/log lines as they happen instead of buffering until the end. HTTP currently buffers (kept intentionally — preserves existing behaviour). NATS dispatcher publishes each event as it arrives.

The HTTP handlers in server.go are now thin wrappers.

Package server is the thin HTTP surface of hugin-agent: five endpoints that map directly onto the protocol the Hugin web app (https://hugin.sourceful-labs.net) speaks.

The real work lives in handlers.go (Scan, Probe, RunLuaContext) as plain Go functions so the NATS dispatcher in cmd/hugin-agent/nats.go can share the same implementation. This file is just the JSON + auth shell.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(cfg Config) http.Handler

New builds an http.Handler with all five protocol endpoints wired.

Types

type Config

type Config struct {
	Version string
	Token   string // pairing token; empty disables auth (dev only)
}

Config drives the HTTP server.

type Emission added in v0.2.0

type Emission struct {
	TS      string             `json:"ts"`
	Channel string             `json:"channel"`
	Data    map[string]float64 `json:"data"`
}

type EventSink added in v0.2.0

type EventSink func(kind string, payload map[string]any)

EventSink is called as side-effects happen during RunLuaContext. kind is one of "emission", "log", "metric". Used by the NATS dispatcher to publish on agent.<id>.event.run-lua-progress as emissions arrive, instead of buffering.

Pass nil to disable streaming — that's what HTTP does.

type HealthResponse added in v0.2.0

type HealthResponse struct {
	Status string `json:"status"`
	TS     string `json:"ts"`
}

HealthResponse body of GET /v1/health and agent.<id>.req.health.

func Health added in v0.2.0

func Health() HealthResponse

Health is the liveness blob. Always "ok" — if the process can respond, it's healthy. Used as a synchronous check on top of the 15s presence heartbeat for finer-grained connection diagnostics.

type InfoResponse added in v0.2.0

type InfoResponse struct {
	Name            string   `json:"name"`
	Version         string   `json:"version"`
	ProtocolVersion int      `json:"protocol_version"`
	Capabilities    []string `json:"capabilities"`
}

InfoResponse body of GET /v1/info and agent.<id>.req.info. Stable contract — workbench reads `capabilities` to decide which UI affordances to show.

func Info added in v0.2.0

func Info(version string) InfoResponse

Info returns a stable identity + capability blob. Pure function shared by the HTTP handler in server.go and the NATS req.info subscriber in cmd/hugin-agent/nats.go.

type ProbeRequest added in v0.2.0

type ProbeRequest struct {
	IP       string `json:"ip"`
	Protocol string `json:"protocol"`
	Modbus   struct {
		Port      int            `json:"port"`
		SlaveID   byte           `json:"slave_id"`
		Registers []RegisterSpec `json:"registers"`
	} `json:"modbus"`
}

ProbeRequest body of POST /v1/probe and agent.<id>.req.probe.

type ProbeResponse added in v0.2.0

type ProbeResponse struct {
	Results []ProbeResultEntry `json:"results"`
	Errors  []string           `json:"errors"`
}

func Probe added in v0.2.0

func Probe(ctx context.Context, req ProbeRequest) (ProbeResponse, error)

Probe reads a list of Modbus holding-register specs and decodes each value. Returns per-register errors inline (other registers still attempted).

type ProbeResultEntry added in v0.2.0

type ProbeResultEntry struct {
	Addr   uint16  `json:"addr"`
	Value  float64 `json:"value"`
	RawHex string  `json:"raw_hex"`
}

type RegisterSpec added in v0.2.0

type RegisterSpec struct {
	Addr  uint16 `json:"addr"`
	Count uint16 `json:"count"`
	Kind  string `json:"kind"`
}

type RunLuaRequest added in v0.2.0

type RunLuaRequest struct {
	LuaSource  string                 `json:"lua_source"`
	Config     map[string]interface{} `json:"config"`
	Actions    []string               `json:"actions"`
	DurationMS int                    `json:"duration_ms"`
}

RunLuaRequest body of POST /v1/run-lua and agent.<id>.req.run-lua.

type RunLuaResponse added in v0.2.0

type RunLuaResponse struct {
	OK        bool               `json:"ok"`
	Emissions []Emission         `json:"emissions"`
	Metrics   map[string]float64 `json:"metrics"`
	Logs      []string           `json:"logs"`
	Errors    []string           `json:"errors"`
}

func RunLuaContext added in v0.2.0

func RunLuaContext(ctx context.Context, req RunLuaRequest, sink EventSink) RunLuaResponse

RunLuaContext executes a Lua driver source in a sandboxed runtime. If sink is non-nil, every emission/log/metric is also delivered to the sink as it happens (same data is also accumulated into the returned response, so HTTP keeps its buffered behaviour).

The NATS dispatcher passes a sink that publishes on agent.<id>.event.run-lua-progress, giving live progress to remote clients.

type ScanDevice added in v0.2.0

type ScanDevice struct {
	IP         string         `json:"ip"`
	MAC        string         `json:"mac,omitempty"`
	VendorOUI  string         `json:"vendor_oui,omitempty"`
	OpenPorts  []int          `json:"open_ports"`
	Modbus     map[string]any `json:"modbus,omitempty"`
	HTTPBanner string         `json:"http_banner,omitempty"`
}

type ScanRequest added in v0.2.0

type ScanRequest struct {
	CIDR      string `json:"cidr"`
	Ports     []int  `json:"ports"`
	DeepProbe bool   `json:"deep_probe"`
}

ScanRequest is the body of POST /v1/scan and the agent.<id>.req.scan NATS subject.

type ScanResponse added in v0.2.0

type ScanResponse struct {
	Devices []ScanDevice `json:"devices"`
	Errors  []string     `json:"errors"`
}

func Scan added in v0.2.0

func Scan(ctx context.Context, req ScanRequest) ScanResponse

Scan executes a CIDR sweep + optional deep-probe of Modbus devices. Pure function — same body as the previous HTTP handler, but no http.ResponseWriter dependency.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL