feat(13-01): add InterfaceInfo collector with MAC lowercasing and tests
- InterfaceInfo struct for link discovery (name, mac, type, running) - CollectInterfaceInfo runs /interface/print (version-agnostic) - MAC addresses lowercased for consistent matching - Entries without mac-address skipped (loopback, bridge) - Preserved existing InterfaceStats traffic counter collector Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
// Package device provides RouterOS metric collectors for the poller.
|
||||
package device
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
routeros "github.com/go-routeros/routeros/v3"
|
||||
)
|
||||
@@ -59,3 +59,65 @@ func CollectInterfaces(client *routeros.Client) ([]InterfaceStats, error) {
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// InterfaceInfo holds basic interface identity data from a RouterOS device.
|
||||
// This is used for link discovery — MAC addresses identify which device owns
|
||||
// each end of a network link.
|
||||
type InterfaceInfo struct {
|
||||
Name string `json:"name"`
|
||||
MacAddress string `json:"mac_address"`
|
||||
Type string `json:"type"`
|
||||
Running bool `json:"running"`
|
||||
}
|
||||
|
||||
// normalizeMACAddress lowercases a MAC address for consistent matching.
|
||||
func normalizeMACAddress(mac string) string {
|
||||
return strings.ToLower(mac)
|
||||
}
|
||||
|
||||
// parseRunning converts a RouterOS "true"/"false" string to a Go bool.
|
||||
func parseRunning(s string) bool {
|
||||
return s == "true"
|
||||
}
|
||||
|
||||
// CollectInterfaceInfo queries the RouterOS device for all interfaces and
|
||||
// returns their name, MAC address, type, and running status.
|
||||
//
|
||||
// The /interface/print command is version-agnostic (works on both v6 and v7).
|
||||
// Entries with an empty mac-address (loopback, bridge without MAC) are skipped.
|
||||
//
|
||||
// Returns nil, nil when the device has no interfaces (matching the
|
||||
// CollectWireless pattern — empty result is not an error).
|
||||
func CollectInterfaceInfo(client *routeros.Client) ([]InterfaceInfo, error) {
|
||||
reply, err := client.Run("/interface/print")
|
||||
if err != nil {
|
||||
slog.Debug("failed to collect interface info", "error", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(reply.Re) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := make([]InterfaceInfo, 0, len(reply.Re))
|
||||
for _, s := range reply.Re {
|
||||
m := s.Map
|
||||
mac := m["mac-address"]
|
||||
if mac == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, InterfaceInfo{
|
||||
Name: m["name"],
|
||||
MacAddress: normalizeMACAddress(mac),
|
||||
Type: m["type"],
|
||||
Running: parseRunning(m["running"]),
|
||||
})
|
||||
}
|
||||
|
||||
if len(result) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user