Every tool now returns a Go struct (apitypes.go) instead of a map, and typeschema.go derives the OpenAPI response schemas from those types by reflection (json, doc and enum tags), so the document cannot drift from what is sent. Text results are documented as text/plain, settings in answers use the typed settings schema, and edits answer with EditResponse. TestResponsesMatchTheirSchemas checks real responses against the generated schemas. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
109 lines
5.6 KiB
Go
109 lines
5.6 KiB
Go
package main
|
|
|
|
import "time"
|
|
|
|
// What the REST API (and the MCP tools, which are the same code) answer. The
|
|
// OpenAPI document's response schemas are derived from these types.
|
|
|
|
type StatusResponse struct {
|
|
Time time.Time `json:"time" doc:"When the figures were taken."`
|
|
Uplink UplinkInfo `json:"uplink"`
|
|
Pings []PingInfo `json:"pings"`
|
|
System SystemInfo `json:"system"`
|
|
Settings SettingsInfo `json:"settings"`
|
|
}
|
|
|
|
type UplinkInfo struct {
|
|
Device string `json:"device" doc:"The uplink device: pppoe-wan, or the WAN interface."`
|
|
Type string `json:"type" doc:"How the uplink is configured: dhcp or pppoe."`
|
|
Connected bool `json:"connected" doc:"The uplink has an IPv4 address and the default route."`
|
|
Reachable bool `json:"reachable" doc:"At least one public ping target answered."`
|
|
IPv4 []string `json:"ipv4" doc:"The uplink's IPv4 addresses."`
|
|
IPv6 []string `json:"ipv6" doc:"The uplink's IPv6 addresses."`
|
|
Gateway string `json:"gateway" doc:"The default gateway ('' if none)."`
|
|
Since time.Time `json:"since" doc:"When the uplink last changed state."`
|
|
}
|
|
|
|
type PingInfo struct {
|
|
Target string `json:"target" doc:"As configured: 'gateway' or an address."`
|
|
Address string `json:"address" doc:"The address that was pinged."`
|
|
OK bool `json:"ok" doc:"It answered."`
|
|
RttMs int64 `json:"rttMs" doc:"Round-trip time in milliseconds."`
|
|
}
|
|
|
|
type SystemInfo struct {
|
|
UptimeSeconds int `json:"uptimeSeconds"`
|
|
Load string `json:"load" doc:"Load averages (1, 5, 15 minutes)."`
|
|
Kernel string `json:"kernel" doc:"The running kernel."`
|
|
RebootForKernel string `json:"rebootForKernel" doc:"The kernel of the current system when it differs from the running one: a reboot is due ('' if none)."`
|
|
RebootForConfiguration bool `json:"rebootForConfiguration" doc:"A configuration is staged for the next boot (interface names)."`
|
|
CPUPercent *float64 `json:"cpuPercent" doc:"null until the second sample."`
|
|
MemoryUsedBytes uint64 `json:"memoryUsedBytes"`
|
|
MemoryTotalBytes uint64 `json:"memoryTotalBytes"`
|
|
TemperatureC *float64 `json:"temperatureC" doc:"The hottest sensor; null if there is none."`
|
|
DiskUsedBytes uint64 `json:"diskUsedBytes"`
|
|
DiskTotalBytes uint64 `json:"diskTotalBytes"`
|
|
}
|
|
|
|
type SettingsInfo struct {
|
|
Unapplied bool `json:"unapplied" doc:"The saved settings differ from the confirmed (running) ones."`
|
|
Applying bool `json:"applying" doc:"An apply is running."`
|
|
LastApplyResult string `json:"lastApplyResult" doc:"Result of the last apply: success, exit-code, ... ('' if none)."`
|
|
ConfirmationDueInSeconds int `json:"confirmationDueInSeconds" doc:"While a change awaits confirmation: the time left before the router rolls back (0 if none)."`
|
|
}
|
|
|
|
type SettingsResponse struct {
|
|
ETag string `json:"etag" doc:"The settings' version; the same as the ETag header (without quotes)."`
|
|
Unapplied bool `json:"unapplied" doc:"The saved settings differ from the confirmed (running) ones."`
|
|
Settings map[string]any `json:"settings" doc:"The saved settings (settings.json)."`
|
|
}
|
|
|
|
type EditResponse struct {
|
|
Saved bool `json:"saved" doc:"The edit was written to the saved settings."`
|
|
Applied bool `json:"applied" doc:"Always false: a person applies changes in the web UI."`
|
|
ETag string `json:"etag" doc:"The settings' new version, for the next edit."`
|
|
Changes string `json:"changes" doc:"What this edit changed, as diff lines (- removed, + added)."`
|
|
Next string `json:"next" doc:"What to do next."`
|
|
}
|
|
|
|
type InterfaceInfo struct {
|
|
Name string `json:"name" doc:"The name from the settings."`
|
|
Kind string `json:"kind" enum:"physical,VLAN"`
|
|
UsedAs string `json:"usedAs" doc:"WAN, 'LAN <name>', or '' if unused."`
|
|
KernelName string `json:"kernelName,omitempty" doc:"Physical: the name the kernel gives the card now."`
|
|
MAC string `json:"mac,omitempty" doc:"Physical: the card's MAC address, when it is on this machine."`
|
|
DeviceName string `json:"deviceName,omitempty" doc:"VLAN: the name chosen for its device."`
|
|
}
|
|
|
|
type LeaseInfo struct {
|
|
Address string `json:"address"`
|
|
MAC string `json:"mac"`
|
|
Hostname string `json:"hostname"`
|
|
LAN string `json:"lan"`
|
|
Expires time.Time `json:"expires"`
|
|
}
|
|
|
|
type UpdateStatusResponse struct {
|
|
Installed Release `json:"installed"`
|
|
Running bool `json:"running" doc:"An update is being installed."`
|
|
LastResult string `json:"lastResult" doc:"Result of the last update run ('' if none)."`
|
|
Log string `json:"log" doc:"The last update run's log."`
|
|
}
|
|
|
|
type ApplyLogResponse struct {
|
|
Applying bool `json:"applying"`
|
|
Result string `json:"result" doc:"success, exit-code, ... ('' if none or still running)."`
|
|
Log string `json:"log" doc:"The build and activation log."`
|
|
}
|
|
|
|
type CheckResponse struct {
|
|
Status string `json:"status" enum:"done,running" doc:"'running': still evaluating, ask again in a few seconds."`
|
|
OK *bool `json:"ok,omitempty" doc:"The settings evaluate and the router's assertions pass."`
|
|
ForTheSavedSettings *bool `json:"forTheSavedSettings,omitempty" doc:"The result is for the current saved settings (not older ones)."`
|
|
CheckedAt *time.Time `json:"checkedAt,omitempty"`
|
|
Message string `json:"message,omitempty"`
|
|
Error string `json:"error,omitempty" doc:"Why the settings do not evaluate."`
|
|
Note string `json:"note,omitempty"`
|
|
Next string `json:"next,omitempty"`
|
|
}
|