Commit graph

471 commits

Author SHA1 Message Date
74e409d6a6
feat: add Pepwave, Ceragon, Tranzeo, and CMM vendor modules 2026-01-22 10:22:19 -06:00
928055cbe3
feat: add FortiAP, D-Link AP, and Moxa AWK vendor modules 2026-01-22 10:12:49 -06:00
508ad99919
feat(snmp): add 6 more vendor modules (xirrus, alvarion, zyxel_wlc, proxim, altalabs, stellar) 2026-01-22 10:02:42 -06:00
e1bc56e065
feat(snmp): add 6 new vendor modules (cnwave60, cnmatrix, ruckus_sz, deliberant, engenius, grandstream) 2026-01-22 09:53:33 -06:00
7c2014842d
feat: add 5 new SNMP vendor modules
Add vendor-specific SNMP handling for:
- Aerohive (HiveOS wireless APs): client counts, CPU/memory, temperature
- Baicells (LTE CPE): RSRP, RSRQ, SINR, RSSI, tx power, temperature
- Cambium PTP (point-to-point radios): RSL, tx power, data rates, temperature
- Cisco WAP (standalone APs): clients, channel utilization, noise floor
- Netonix (WISP switches): temperatures, fan speed, PSU voltages, PoE power

Each module implements the Vendor behaviour with:
- profile_names/0 for profile matching
- detect_hardware/1 for model identification
- discover_wireless_sensors/1 for sensor discovery
- wireless_oid_defs/0 for debug data collection

All modules registered in vendor registry with comprehensive tests.
2026-01-22 09:42:48 -06:00
0a4482f974
feat: add 5 new vendor modules and fix dialyzer issues
Vendor modules added:
- Aviat (WTM microwave radios)
- Aruba (wireless controllers and APs)
- CiscoWLC (Cisco wireless LAN controllers)
- Teltonika (RUTOS LTE routers)
- Sub10 (mmWave backhaul radios)

Dialyzer fixes:
- Fix unknown type Devices.t/0 in alert.ex and device.ex
- Fix unmatched_return warnings across multiple files
- Add :exq to PLT for Exq function detection
- Remove dead code in base.ex, dynamic.ex, vendor.ex
- Fix Device.t() type spec to allow nil name field

Tests: 1437 tests, 0 failures
Dialyzer: 0 errors
Credo: no issues
2026-01-22 09:34:50 -06:00
8f1752e59c
feat: add more vendor modules and fix sensor discovery
New vendor modules for WISP equipment:
- Ruckus: ZoneDirector, SmartZone, Unleashed controllers
- DragonWave: Horizon Compact/Duo/Quantum microwave
- AirFiber: Ubiquiti AF 5/24/60 series (split from Airos)
- Racom: RAy and RAy3 microwave radios
- Exalt: ExtendAir microwave radios
- SIAE: ALFO 80HD microwave radios

Also fixes:
- sensor_value -> last_value consistency in YAML sensor discovery
- Test warnings (assert defs != [] -> assert [_ | _] = defs)

Total: 17 vendor modules, 162 tests passing
2026-01-22 08:59:50 -06:00
a83e63b3ad
feat: add vendor-specific SNMP modules for WISP equipment
Add 8 new vendor modules for wireless sensor discovery:
- PMP: Cambium PMP 450/430/100 and PTP series
- Mimosa: B5/B5c PTP and A5/A5c PTMP radios
- Siklu: EtherHaul mmWave radios
- Radwin: WinLink and JET series
- UniFi: Ubiquiti UniFi Access Points
- LigoOS: LigoWave and Deliberant devices
- cnPilot: Cambium cnPilot E and R series
- SAF: SAF Tehnika Integra/Lumina/CFIP series

Each module implements the Vendor behaviour with:
- profile_names/0: OS profile identifiers
- detect_hardware/1: device model detection
- wireless_oid_defs/0: sensor OID definitions
- discover_wireless_sensors/1: sensor discovery

Includes comprehensive tests for all modules (104 tests).
2026-01-22 08:48:38 -06:00
56bb855996
refactor: extract vendor-specific SNMP discovery to modules
Mirrors LibreNMS architecture where vendor-specific discovery logic
lives in OS PHP classes. Creates modular vendor system with:

- Vendor behaviour defining callbacks for profile_names, detect_hardware,
  discover_wireless_sensors, wireless_oid_defs
- Epmp vendor module for Cambium ePMP devices
- Airos vendor module for Ubiquiti AirOS devices
- Routeros vendor module for MikroTik devices with table-based discovery
- Registry module for dispatching to appropriate vendor by profile name

Removes 250+ lines of inline vendor code from dynamic.ex.
2026-01-22 08:34:35 -06:00
28a9517a1f
fix: use last_value field so sensor values are saved to database
- Change sensor_value to last_value to match Sensor schema
- Make wireless sensor_index unique using OID suffix
- Values now persist and can be graphed
2026-01-21 17:29:23 -06:00
985e3533df
feat: add additional ePMP sensors matching LibreNMS
Add all sensors that LibreNMS Epmp.php collects:
- GPS tracked/visible satellites
- Transmit power
- Channel width
- Network entry attempts/success/auth failures
2026-01-21 17:25:48 -06:00
605f8c09ec
feat: add discovered sensors table to debug tab
Display discovered sensors in a parsed table format showing type,
description, OID, value with unit, and state description for state
sensors.
2026-01-21 17:18:44 -06:00
74c9544688
feat: add wireless sensor discovery and fix YAML sensor parsing
- Add wireless sensor discovery for ePMP and AirOS devices
- Implement vendor-specific OIDs matching LibreNMS PHP discovery
- Fix table/state sensor discovery to handle map format from Client.walk
- Add discovered_sensors to debug data with values and state descriptions
- ePMP: frequency, clients, rssi, snr (rssi/snr for SM only)
- AirOS: frequency, capacity, ccq, clients, distance, noise-floor, power, quality, rate, rssi, utilization
2026-01-21 17:15:00 -06:00
12875d7f48
fix device table 2026-01-21 14:44:16 -06:00
c26e379dd7
fix device update handler 2026-01-21 14:42:55 -06:00
7656ac7212
import yamls 2026-01-21 14:30:04 -06:00
d68991c484
fix discovery issue 2026-01-21 13:07:30 -06:00
1b7c4f6a6a
update 2026-01-21 12:31:01 -06:00
f8c417a338
feat: add Cisco VTP VLAN discovery
- Add discover_vlans/1 to Cisco profile for VTP MIB discovery
- VTP OIDs: vtpVlanName, vtpVlanState, vtpVlanType
- Falls back to Q-BRIDGE-MIB when VTP not available
- Maps VTP states (operational, suspended, mtuTooBig)
- Maps VTP types (ethernet, fddi, tokenRing, etc.)
- Validates VLAN ID range (1-4094)
2026-01-21 11:32:18 -06:00
7e1fc35f2c
feat: add state sensor polling alongside numeric sensors
- Added state_sensors association to Snmp.Device schema
- Updated get_device_with_associations to preload state_sensors
- Added update_state_sensor and list_state_sensors functions to Snmp context
- Added state sensor polling task in PollerWorker parallel polling
- Poll state sensors via ENTITY-STATE-MIB OIDs every polling interval
- Detect and broadcast state changes (ok/warning/critical/unknown)
- State changes emit device events for real-time UI updates
2026-01-21 11:23:26 -06:00
ba5464332b
fix: use system ping command instead of raw ICMP sockets
- Rewrote Ping module to use system ping binary instead of raw ICMP
  sockets which required CAP_NET_RAW privileges
- Added iputils-ping package to Docker images for production
- Added proper IP address validation before executing ping command
- Updated tests to account for 1 second minimum timeout of system ping
- System ping binary is setuid root and works without elevated privileges
2026-01-21 11:15:59 -06:00
8509a4a64c
feat: display neighbor IP address in device neighbors tab 2026-01-21 11:01:48 -06:00
cba1f87f8f
fix: disable loading animations on chart graphs 2026-01-21 10:59:12 -06:00
1fc066d95b
feat: add memory pool and storage discovery (Phase 1.5)
- Add snmp_memory_pools table and MemoryPool schema
- Add snmp_storage table and Storage schema
- Add discover_memory_pools/1 for HOST-RESOURCES-MIB RAM/swap
- Add discover_storage/1 for HOST-RESOURCES-MIB disk storage
- Add comprehensive tests for schema validation and discovery
- Completes Phase 1 of discovery improvements
2026-01-21 10:57:08 -06:00
45ddcdac80
feat: add physical inventory discovery (Phase 1.4)
- Create snmp_physical_entities table with migration
- Add PhysicalEntity schema with entity_class validation
- Support parent/child hierarchy via parent_entity_id
- Implement discover_physical_entities/1 in Base profile
- Discover chassis, modules, PSUs, fans from ENTITY-MIB
- Map entity class integers to string names
- Add 10 schema tests and 4 discovery tests
- Fix flaky AlertNotifier test with unique names and mailbox clearing
2026-01-21 10:46:27 -06:00
1cf6f327ea
feat: add IP address discovery (Phase 1.3)
- Create snmp_ip_addresses table with migration
- Add IpAddress schema with ip_type validation (ipv4/ipv6)
- Add prefix_length validation based on ip_type
- Implement discover_ip_addresses/1 in Base profile
- Extract IP addresses from IP-MIB ipAdEntTable
- Support multiple IPs per interface with subnet masks
- Add 12 schema tests and 4 discovery tests
2026-01-21 10:36:19 -06:00
579a7bac21
add VLAN schema, migration, and discovery 2026-01-21 10:31:21 -06:00
c3e26a44d6
add state sensor schema, migration, and discovery 2026-01-21 10:25:01 -06:00
7c660169b7
better mib handling and tests 2026-01-21 10:07:07 -06:00
3abd70e133
use password for user regi 2026-01-21 09:13:08 -06:00
1d45699240
discovery no longer deletes historical data 2026-01-20 17:29:58 -06:00
c54b5d81bb
more dark mode 2026-01-20 17:23:11 -06:00
fbad8c64b2
dark mode 2026-01-20 16:56:49 -06:00
856c2e926b
credo fix 2026-01-20 16:41:44 -06:00
23c92b2c44
more tests 2026-01-20 16:38:53 -06:00
7f338d8388
test: enhance Monitoring.Supervisor test coverage
Added tests for:
- Edge cases with disabled monitoring/SNMP
- Process lifecycle and crash recovery
- Concurrent operation handling

Coverage improvement: 63.89% → target 90%+
2026-01-20 15:44:20 -06:00
f11ccd2cb1
test: add MibTranslator and NeighborDiscovery tests
MibTranslator coverage: 75% → 90% ✓
- Tests for translate/1 with numeric OIDs and MIB names
- Tests for translate_batch/1
- Tests for error handling and edge cases
- Tests for directory expansion

NeighborDiscovery coverage: 72.63% → 14.74% (basic tests added)
- Tests for error handling
- TODO: Add comprehensive LLDP/CDP parsing tests
2026-01-20 15:42:39 -06:00
a0c6889a22
refactor: improve code quality in ApiTokens.update_last_used
Reduced nesting and extracted helper functions to address credo
warnings. The logic remains the same:
- Test environment: synchronous update
- Production: async Task with sandbox support

Fixes credo warnings:
- Reduced function body nesting (was 3, now 2)
- Extracted spawn_async_update and helper functions
2026-01-20 15:38:07 -06:00
a32a50a5fd
fix: make ApiTokens.update_last_used synchronous in test env
The async Task.start pattern was causing DBConnection.Ownership errors
when tests finished before the spawned Task could complete its database
update. By making the update synchronous in test environment, we ensure
the database connection is properly managed within the test process.

In production, we still use the async Task.start to avoid blocking
requests when updating last_used_at timestamps.

Fixes all "owner #PID<...> exited" errors in test suite.
2026-01-20 15:30:14 -06:00
5ccda65dd1
Add comprehensive tests for Towerops.Snmp context
Added 18 new tests covering:
- get_latest_sensor_readings_batch/1 (batch operations)
- get_latest_interface_stats_batch/1 (batch operations)
- list_neighbors/1 (neighbor queries with ordering)
- get_neighbor/1 (single neighbor retrieval)
- upsert_neighbor/1 (create and update operations)
- delete_stale_neighbors/2 (time-based cleanup)

Tests verify:
- Batch operations match individual queries
- Empty input handling
- Latest record selection
- Ordering by protocol and name
- Stale data cleanup across devices
- Update semantics for existing records

Coverage improvement:
- Towerops.Snmp: 63.33% → 73.33% (+10%)
- Total tests: 1089 → 1106 (+17 tests)
- Overall coverage: 49.69% → 49.82%
2026-01-20 14:02:45 -06:00
f5ff6c5c61
Add comprehensive tests for Towerops.Monitoring.DeviceMonitor
- Test start_link/1 and Horde Registry registration
- Test initial check on monitoring enabled/disabled
- Test trigger_check/1 for running and stopped monitors
- Test successful and failed ping handling
- Test status change detection (up->down, down->up)
- Test alert creation and resolution
- Test PubSub broadcasts for status changes and alerts
- Test alert message formatting for ICMP vs SNMP
- Test check scheduling based on check_interval_seconds
- Coverage improved from 43.93% to 96.67%

Total tests: 1066 -> 1089 (23 new tests)
Total coverage: 48.72% -> 49.65%
2026-01-20 13:53:46 -06:00
f9553b1444
Fix flaky tests in MonitoringSupervisor and AlertNotifier
- Add Mox stub setup in supervisor_test.exs to handle DeviceMonitor ping calls
- Change alert_notifier_test.exs to async: true to prevent mailbox contamination
- All 1066 tests now passing with 0 failures
2026-01-20 13:48:13 -06:00
1dbcbb92f1
Add comprehensive tests for Towerops.Snmp.MibParser
Created test/towerops/snmp/mib_parser_test.exs with 25 tests covering:
- parse_mib_content/1: OID extraction and resolution logic
- parse_mib_file/1: File reading and error handling
- validate_oid/3: OID validation against MIB definitions
- list_mib_files/0: MIB file discovery
- Edge cases: whitespace, comments, nested assignments

Coverage improvement:
- Before: 60.00%
- After: 97.50%
- Improvement: +37.5%

All 1066 tests passing.
2026-01-20 13:39:48 -06:00
ace3f1f661
Fix database connection ownership issues in async Tasks
Changes:
- ApiTokens.update_last_used/1: Allow Task to access sandbox in tests
- DeviceMonitor.enqueue_check/1: Allow Task to access sandbox in tests
- PollerWorker.enqueue_poll/1: Allow Task to access sandbox in tests

Problem:
When tests spawn async Tasks that access the database, those Tasks
don't have ownership of the database connection in Sandbox mode,
causing DBConnection.ConnectionError warnings.

Solution:
Before accessing the database in a Task, check if we're in test mode
and call Ecto.Adapters.SQL.Sandbox.allow/3 to transfer connection
ownership from the parent process to the Task.

Pattern used:
```elixir
parent = self()
Task.start(fn ->
  if Application.get_env(:towerops, :sql_sandbox) do
    Ecto.Adapters.SQL.Sandbox.allow(Repo, parent, self())
  end
  # ... database operations ...
end)
```

All 1041 tests passing. Some harmless disconnection warnings remain
when Tasks complete after tests finish, but these don't affect results.
2026-01-20 12:39:25 -06:00
fcc1fbbe73
Refactor MonitorWorker to use ping adapter and eliminate real network traffic from tests
Changes:
- Updated MonitorWorker to use configured ping_module adapter instead of System.cmd
- Removed direct ping command execution and regex parsing
- Simplified ping_device/1 to use adapter.ping/2 (mockable in tests)
- Added PingMock expectations to all MonitorWorker tests
- Removed @tag :integration from unreachable host test (now mocked)
- All ping calls now use mocked responses in tests

Benefits:
- MonitorWorker tests now run in 0.2s instead of 5+ seconds
- No real ICMP network traffic during test runs
- Tests are deterministic and don't depend on network conditions
- Follows same adapter pattern as SNMP (testable, configurable)

All 1041 tests passing with no real network operations.
2026-01-20 12:29:12 -06:00
dc7db8ce39
Fix all remaining worker test failures
- Add 'error' to valid sensor reading status values
  - SensorReading changeset was rejecting 'error' status
  - PollWorker creates error readings when SNMP fails
  - Fixed validation to include: ok, warning, critical, error

- Replace log capture tests with functional assertions
  - ExUnit.CaptureLog not reliably capturing worker logs
  - Changed to verify actual behavior instead of log messages
  - Tests now check created records and state changes

- Add debug assertions to sensor error test
  - Verify SNMP device exists and has sensors
  - Better error messages for test failures

All 1045 tests now passing (0 failures, 2 skipped)
2026-01-20 12:20:04 -06:00
b116ed4f71
Fix worker test mock expectations and API calls
- Fix Monitoring context API calls (list_devices_checks vs list_checks_for_device)
- Fix Snmp context API calls (get_interface_stats, get_sensor_readings)
- Fix Devices context API calls (update_device vs update_device!)
- Fix Discovery worker to expect 7 GET calls (test_connection + system_info)
- Fix Poll worker to use stub instead of expect for variable call counts
- Fix sensor setup to use correct types (sensor_index: string, sensor_divisor: integer)
- Fix neighbor schema to include required fields (protocol, last_discovered_at)
- Simplify walk mocks to use stub for complex neighbor discovery

18 of 23 tests now passing. Remaining issues:
- 1 sensor error reading test (may need investigation)
- 4 log capture tests (ExUnit.CaptureLog not capturing logs from workers)
2026-01-20 12:13:14 -06:00
638551eb95
Add comprehensive tests for Monitoring.Check schema
Tests cover:
- Valid and invalid changesets
- All required field validations
- Foreign key constraints
- Status enum values
- Schema field types and associations
- Binary ID usage for primary/foreign keys

All 16 tests passing with good coverage of schema validation logic.
2026-01-20 11:59:54 -06:00
a2466722b7
Add comprehensive tests for background workers
- DiscoveryWorker: Tests for SNMP device discovery
- MonitorWorker: Tests for ICMP ping monitoring checks
- PollWorker: Tests for SNMP polling of sensors, interfaces, and neighbors

These tests use fixtures and Mox for SNMP mocking to achieve good coverage
of the worker modules without requiring real SNMP devices.

Note: Some function names need correction based on actual Monitoring/Snmp context APIs.
2026-01-20 11:58:47 -06:00
795ab8a041
Add Redix connection resilience options to Exq config
Configures Redix (Exq's Redis client) with better connection handling:
- sync_connect: true - fail fast if Redis unavailable at startup
- exit_on_disconnection: false - don't crash process on disconnect
- backoff_initial: 500ms, backoff_max: 30s - retry with exponential backoff

This helps Exq survive temporary Redis disconnections without crashing,
reducing the frequency of Protocol.UndefinedError crashes in Exq.Node.Server.
2026-01-20 11:42:02 -06:00