feat(snmp,ui): устройства за портом (MAC/IP) в таблице 2

Добавил сбор FDB/ARP по SNMP (BRIDGE-MIB + ipNetToMedia), хранение и API /port-devices.
В UI Таблица 2 теперь показывает MAC/IP за выбранным портом после клика по строке Таблицы 1.

Made-with: Cursor
This commit is contained in:
Луценко Андрей Анатольевич
2026-04-10 17:44:42 +10:00
parent 526c67b5b1
commit 5b82901565
7 changed files with 350 additions and 39 deletions
+46
View File
@@ -538,3 +538,49 @@ func (s *PostgresStore) PurgeAllScanData() error {
_, err := s.db.ExecContext(context.Background(), `truncate table scan_jobs restart identity cascade`)
return err
}
func (s *PostgresStore) SavePortDeviceResult(scanID string, result PortDeviceResult) error {
query := `
insert into scan_port_devices (scan_id, ip, if_index, mac, learned_ip, checked_at)
values ($1, $2, $3, $4, $5, $6)`
_, err := s.db.ExecContext(
context.Background(),
query,
scanID,
result.IP,
result.IfIndex,
result.MAC,
result.LearnedIP,
result.CheckedAt,
)
return err
}
func (s *PostgresStore) ListPortDeviceResults(scanID string, filterIP string, filterIfIndex int, limit int) []PortDeviceResult {
if limit <= 0 {
limit = 20000
}
query := `
select ip::text, if_index, coalesce(mac, ''), coalesce(learned_ip::text, ''), checked_at
from scan_port_devices
where scan_id = $1
and ($2 = '' or ip = $2::inet)
and ($3 = 0 or if_index = $3)
order by if_index asc, mac asc, learned_ip asc
limit $4`
rows, err := s.db.QueryContext(context.Background(), query, scanID, filterIP, filterIfIndex, limit)
if err != nil {
return nil
}
defer rows.Close()
out := make([]PortDeviceResult, 0, 256)
for rows.Next() {
var r PortDeviceResult
if err = rows.Scan(&r.IP, &r.IfIndex, &r.MAC, &r.LearnedIP, &r.CheckedAt); err != nil {
return nil
}
out = append(out, r)
}
return out
}