Files
Jason Staack b840047e19 feat: The Other Dude v9.0.1 — full-featured email system
ci: add GitHub Pages deployment workflow for docs site

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:30:44 -05:00

87 lines
2.6 KiB
Go

package device
import (
"fmt"
"log/slog"
routeros "github.com/go-routeros/routeros/v3"
)
// DeviceInfo holds metadata collected from /system/resource/print and
// /system/routerboard/print.
type DeviceInfo struct {
Version string
MajorVersion int
BoardName string
Architecture string
Uptime string
CPULoad string
FreeMemory string
TotalMemory string
SerialNumber string // from /system/routerboard serial-number
FirmwareVersion string // from /system/routerboard current-firmware
LastConfigChange string // from /system/resource last-config-change (RouterOS 7.x)
}
// DetectVersion queries the RouterOS device for system resource information.
//
// Runs /system/resource/print and parses the response into DeviceInfo.
// The major version is extracted from the first character of the version string
// (e.g. "6.49.10" -> 6, "7.12" -> 7).
func DetectVersion(c *routeros.Client) (DeviceInfo, error) {
reply, err := c.Run("/system/resource/print")
if err != nil {
return DeviceInfo{}, fmt.Errorf("running /system/resource/print: %w", err)
}
if len(reply.Re) == 0 {
return DeviceInfo{}, fmt.Errorf("/system/resource/print returned no sentences")
}
m := reply.Re[0].Map
info := DeviceInfo{
Version: m["version"],
BoardName: m["board-name"],
Architecture: m["architecture-name"],
Uptime: m["uptime"],
CPULoad: m["cpu-load"],
FreeMemory: m["free-memory"],
TotalMemory: m["total-memory"],
LastConfigChange: m["last-config-change"],
}
// Extract major version from first character of version string.
// Valid RouterOS versions start with '6' or '7'.
if len(info.Version) > 0 {
firstChar := info.Version[0]
if firstChar >= '0' && firstChar <= '9' {
info.MajorVersion = int(firstChar - '0')
} else {
slog.Warn("unexpected RouterOS version format", "version", info.Version)
info.MajorVersion = 0
}
}
// Query routerboard info for serial number and firmware version.
// Non-fatal: CHR and x86 devices don't have a routerboard.
rbReply, rbErr := c.Run("/system/routerboard/print")
if rbErr == nil && len(rbReply.Re) > 0 {
rb := rbReply.Re[0].Map
info.SerialNumber = rb["serial-number"]
info.FirmwareVersion = rb["current-firmware"]
} else if rbErr != nil {
slog.Debug("routerboard query failed (normal for CHR/x86)", "error", rbErr)
}
slog.Debug("detected RouterOS version",
"version", info.Version,
"major_version", info.MajorVersion,
"board_name", info.BoardName,
"serial", info.SerialNumber,
"firmware", info.FirmwareVersion,
)
return info, nil
}