Commit graph

321 commits

Author SHA1 Message Date
59cf53144f
add preseem context and device detail preseem tab 2026-02-12 18:05:26 -06:00
9ab0380c87
add integrations settings page with preseem configuration 2026-02-12 17:02:26 -06:00
a61abd836c
fix: cloud poller automatic rebalancing
- create MonitoringCheck schema for the monitoring_checks table, fixing
  silent data loss where ping results were dropped by the wrong schema
- update agent channel and device monitor worker to use new schema
- fix Stats queries to use MonitoringCheck instead of Check schema
- add list_online_cloud_pollers and list_cloud_polled_devices queries
- add CloudLatencyProbeWorker to dispatch cross-agent latency probes
  every 8 hours via PubSub to all online cloud pollers
- scope AgentLatencyEvaluator to cloud pollers only with cloud_only
  filter, lower min_checks (5), wider time window (48h), and
  device-level assignments to avoid changing site/org defaults
- update cron schedule: probes at 0/8/16h, evaluation at 0:30/8:30/16:30
- refactor monitoring.ex and http_executor.ex to fix credo complexity
2026-02-12 15:32:33 -06:00
07a6128877
feat: add checks tab to device detail page (TDD cycle 1)
- Add 'Checks' tab link to device navigation
- Display empty state when no checks configured
- Add tests for tab visibility and empty state
- Fix unused variable warnings in monitoring context
- Remove unused CheckResult alias and module attributes
- Add stub for legacy get_latency_data for backward compatibility

Tests: 2 new tests added, all passing
Following TDD: RED-GREEN cycle verified for each feature
2026-02-12 14:50:14 -06:00
7371ceb942
feat: add automatic network topology inference
Build a rich network topology from SNMP polling data using evidence-based
confidence scoring. LLDP/CDP neighbors, MAC address tables, and ARP data
are combined to infer device links with weighted confidence merging.

- Add DeviceLink and DeviceLinkEvidence schemas for persistent topology
- Implement evidence collectors: LLDP (0.95), CDP (0.95), MAC (0.7), ARP (0.6)
- Add device role inference from sysObjectID/sysDescr patterns
- Hook topology inference into DevicePollerWorker pipeline
- Add stale link cleanup (24h mark stale, 72h delete) via NeighborCleanupWorker
- Update NetworkMapLive with "Added" vs "All Devices" tabs
- Add connected devices section to device detail page
- Add device role selector to device edit form
- Update Cytoscape.js with role-based node shapes/colors and confidence edges
2026-02-12 13:28:01 -06:00
f106d4c801
fix: prevent back-button trap on device show page
push_patch without replace: true created a history entry loop:
/devices/:id → /devices/:id?tab=overview, so hitting back would
immediately redirect forward again, trapping the user.
2026-02-12 13:09:34 -06:00
cd6f2153ce
fix: reload device stream when switching back to existing devices tab 2026-02-12 12:47:30 -06:00
1318b1b6b7
feat: live device timestamp updates and org-scoped alert PubSub
Always broadcast from update_device_status/2 so the device index
LiveView refreshes even when status hasn't changed. Add a 15-second
tick timer to keep "Last Checked" timestamps fresh between polls.
Scope alert PubSub topics to organization for defense-in-depth.
2026-02-12 11:01:56 -06:00
aa1bac0d46
perf: batch inserts, selective LiveView reloading, and database indexes for scale
Replace individual Repo.insert() with Repo.insert_all() for sensor readings,
interface stats, processor readings, and storage readings in agent channel and
device poller worker. Add partial/composite database indexes for common query
patterns. Dashboard now uses GROUP BY aggregation instead of loading all devices.
DeviceLive.Show only reloads data for the active tab on PubSub events.
DeviceLive.Index debounces status changes and skips quota queries on updates.
Agent polling preloads filtered to monitored sensors/interfaces only.
2026-02-12 10:16:10 -06:00
e68ebdb62d
fix: sync AgentLive.Index modal state to URL for browser navigation
Update AgentLive.Index to properly handle browser back/forward buttons
by syncing the setup token modal to URL parameters.

Changes:
- Update handle_params/3 to read modal param and set modal state
- Update show_setup handler to use push_patch with ?modal=setup
- Update close_token_modal handler to use push_patch (remove modal param)
- Update handle_agent_creation_success to use push_patch after creating agent

Behavior:
- Browser back button now closes the setup modal without navigating away
- URL reflects current modal state (?modal=setup)
- Bookmarkable URLs restore exact modal state (can share agent setup URL)
- After creating agent, modal opens via URL state

Follows idiomatic Phoenix LiveView pattern using push_patch/2 and
handle_params/3 as documented in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 09:28:39 -06:00
d84a685878
fix: sync UserSettingsLive modal state to URL for browser navigation
Update UserSettingsLive to properly handle browser back/forward buttons
by syncing all modal state to URL parameters.

Changes:
- Update handle_params/3 to read modal param and set modal states
- Add build_settings_path/2 helper to construct URLs with preserved params
- Update all modal show/close handlers to use push_patch instead of assign:
  - add_token modal
  - token_created modal (shown after creating token)
  - revoke_all modal
  - add_device modal (TOTP)
  - device_qr modal (shown after creating device)
  - recovery_codes modal

Behavior:
- Browser back button now closes modals without navigating away
- URL reflects current modal state (?modal=add_token, etc.)
- Tab and page params preserved when opening/closing modals
- Bookmarkable URLs restore exact modal state

Follows idiomatic Phoenix LiveView pattern using push_patch/2 and
handle_params/3 as documented in CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 09:26:45 -06:00
26bb3d5ca1
color network map nodes by device status
green for online, yellow for unknown, red for offline. previously
nodes were colored by device type which didn't convey health state.
also remove agent last_seen_at display from device detail page since
the offline badge already communicates agent health.
2026-02-11 15:41:50 -06:00
475dea639a
remove agent last_seen_at display from device detail page
the offline badge already communicates agent health status,
so the relative timestamp is redundant.
2026-02-11 15:35:59 -06:00
45357e334a
fix live polling to use effective agent from site/org cascade
live poll mode used get_device_assignment which only checks direct
device-level assignments. devices with agent assigned at site or
org level fell through to direct Phoenix SNMP. replaced with
get_effective_agent_token which walks the full cascade.
2026-02-11 14:12:42 -06:00
10d1157ec3
fix agent discovery system OIDs returning no_such_name
gosnmp returns OIDs with leading dots (e.g., ".1.3.6.1.2.1.1.1.0")
but the Replay adapter did exact-match lookups without the dot.
Walks already normalized both sides, so interfaces worked. GETs
did not, breaking all system OID resolution (sysDescr, sysName, etc).
2026-02-11 12:46:44 -06:00
d36fcbe628
fix raw discovery data timestamp to use user's timezone 2026-02-11 12:41:31 -06:00
c9f154f8cd
fix 5 failing tests
- increase timing threshold in session activity test (flaky at 50ms)
- show org name instead of agent ID in admin agents list
- fix agent live tests wiping auth session with init_test_session
- add resilient error handling in FourOhFourTracker for missing redis
2026-02-11 12:21:06 -06:00
92eb583a8b
fix siteless devices not inheriting org default agent
devices assigned directly to an org (no site) were excluded from
apply_agent_to_all_equipment due to inner join through site table.
also fix fallback agent resolution to check device.organization
when device.site is nil.
2026-02-11 12:20:53 -06:00
e4623f0c3d
show agent ID instead of org name in admin agents list
Makes it easier to identify and reference specific agents in the admin view
2026-02-11 11:56:09 -06:00
f53332672b
add IP allowlist link to superadmin nav, rename whitelist/blacklist to allowlist/denylist 2026-02-11 11:40:44 -06:00
c5d8d73a0c
add row_link to table component for proper anchor tags
Replace phx-click JS.navigate with real <.link navigate> elements
on table rows so users can Ctrl+Click to open in new tabs, use
right-click context menus, and navigate via keyboard. Adds row_link
attr to <.table> core component and applies it to all agent tables.
Converts device list custom table from phx-click to inner links.
2026-02-11 08:46:03 -06:00
77cf289058
Add real-time device list with PubSub and LiveView streams
Broadcast org-scoped PubSub events from Devices context mutations
(create, update, delete, status change). Convert DeviceLive.Index
from assigns to streams with flat row items. Subscribe on mount so
the device list updates automatically across browser tabs.
2026-02-10 17:38:58 -06:00
4d73e77f3a
Add 404-based brute force protection system
Implements automated detection and blocking of IPs exhibiting scanning behavior (5+ unique 404s within 1 minute).

Key features:
- Progressive ban escalation (5 min → 1 hour → permanent)
- CIDR range and exact IP whitelisting
- Redis-backed 404 path tracking with 60s TTL
- Cloudflare WAF integration for permanent bans
- Admin UI for whitelist and blocked IP management
- Oban cron jobs for cleanup (expired bans, stale violations)
- ETS caching for whitelist performance

Components:
- Plug: ToweropsWeb.Plugs.BruteForceProtection
- Context: Towerops.Security.BruteForce
- Schemas: IpBlock, IpWhitelist
- Workers: CloudflareBanWorker, ExpiredBanCleanupWorker, StaleViolationCleanupWorker
- Admin UI: /admin/security (superuser only)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 16:31:48 -06:00
fbce65070a
Add agent restart and self-update commands
Add server-initiated restart and self-update capabilities for remote
agents. Restart broadcasts on the lifecycle PubSub topic causing the
agent to exit cleanly for Docker to restart. Self-update fetches the
latest release from GitHub, finds the matching binary for the agent's
architecture, and sends the download URL with SHA256 checksum.

- Add restart_agent/1 and update_agent/3 to Agents context
- Handle :restart_requested and :update_requested in AgentChannel
- Add superuser-only Restart and Update buttons on agent show page
- Add ReleaseChecker module for GitHub Releases API with 5-min cache
- Add arch field to AgentHeartbeat protobuf for architecture detection
- Store arch in agent metadata from heartbeat
2026-02-10 13:06:10 -06:00
c066399e18
Allow superadmins to view and edit any agent regardless of org
The admin agents page links to /agents/:id but the show and edit
pages were scoped to the current user's organization, causing 404s
for agents belonging to other orgs.
2026-02-10 12:19:20 -06:00
c1fca6276a
Add real-time updates to admin agents page via PubSub
Broadcast agent lifecycle events (created/deleted) on a separate
"admin:agents" topic so the admin page updates dynamically when
agents are added or removed from any organization.
2026-02-10 11:20:51 -06:00
c6caa81850
Group cloud pollers and org agents separately on admin agents page
Cloud pollers render in their own table at the top, org agents
below with the organization name shown under each agent name.
2026-02-10 11:07:41 -06:00
6a66203e48
Add link to admin agents page from admin dashboard 2026-02-10 11:04:55 -06:00
183f2a89ac
Add admin agents page at /admin/agents
Superuser-only page showing all agents across all organizations
and cloud pollers in a single table with live-ticking timestamps
and real-time status updates via PubSub.
2026-02-10 10:56:10 -06:00
5c59777baa
Live-ticking relative timestamps on agents page 2026-02-10 10:24:21 -06:00
481fc6d4a2
Add absolute format to timestamp component to fix render flash 2026-02-10 10:19:54 -06:00
d1cd567cd5
Show full timestamp below relative time in Last Seen column 2026-02-10 10:07:44 -06:00
e9afac3e9d
Show full timestamp below relative time on Last Seen card 2026-02-10 09:55:34 -06:00
07a9366892
clean up agent view 2026-02-10 09:48:09 -06:00
ba56dee1ca
remove date helper 2026-02-10 09:15:41 -06:00
fce1a8b229
Show full version timestamp with friendly date on agents page 2026-02-10 09:04:56 -06:00
94405f0716
fix agents updates 2026-02-10 08:08:34 -06:00
144e04b998
change metadata version to version 2026-02-09 17:39:33 -06:00
41594e5a96
fix bugs on agents screen 2026-02-09 14:03:40 -06:00
ae9b393137
Fix agent page jumping by using streams for real-time updates
- Convert agent_tokens from assign to stream to prevent full page re-renders
- Update handle_info callbacks to only update the specific agent that changed
- Only update stats when agent status changes, not device counts
- Prevents IP address from temporarily disappearing during updates
2026-02-09 13:39:59 -06:00
94bcf8ac4e
fix bug on device add/edit page with mikrotik api fields showing 2026-02-09 13:01:47 -06:00
f7b5e63429
live update agent status 2026-02-09 12:58:54 -06:00
623fe07081
wip 2026-02-09 12:44:37 -06:00
b12a03b82f
update 2026-02-09 08:47:53 -06:00
7a57f7c9d2
fix: resolve critical sensor discovery pipeline data loss
Critical fixes to sensor discovery and display pipeline:

- Fix float value rejection: Change is_integer guards to is_number in
  vendor.ex, dynamic.ex to accept decimal sensor values (temperature,
  counters, etc.)
- Fix scale factor calculation: Rewrite base.ex divisor calculation
  using pure integer arithmetic to prevent rounding errors
- Add missing sensor type support: Current, power, fan, load, and
  signal quality sensor categories now filtered and assigned in UI
- Refactor resolve_snmp_community to reduce cyclomatic complexity

Impact:
- Sensors with float values (DHCP leases, connection counts, precise
  temperatures) no longer silently dropped before database
- ENTITY-SENSOR-MIB divisors calculated correctly without float errors
- UI coverage increased from ~35% to ~60% of discovered sensor types

Files modified:
- lib/towerops/snmp/profiles/vendors/vendor.ex
- lib/towerops/snmp/profiles/dynamic.ex
- lib/towerops/snmp/profiles/base.ex
- lib/towerops_web/live/device_live/show.ex
- lib/towerops/devices.ex

Documentation: SENSOR_PIPELINE_FIXES.md
2026-02-09 08:32:24 -06:00
b823b5e848
feat: display cloud poller name on device page
Show the specific cloud poller name (e.g., dfw, lon) alongside "Cloud"
when a device is assigned to a cloud poller. Displays as "Cloud (dfw)"
instead of just "Cloud" for better visibility of which poller is being used.

When no agent is assigned, continues to show just "Cloud".
2026-02-08 11:40:58 -06:00
10b1168044
refactor: round latency graph values to 1 decimal place
Display latency values with single decimal precision (e.g., 114.1ms)
for improved readability in graphs. This ensures consistency between
the raw chart data and tooltip formatting.
2026-02-08 11:13:39 -06:00
d431931cfe
update hammer 2026-02-08 10:08:31 -06:00
8d4333b237
fix superadmin page 2026-02-07 11:58:56 -06:00
3931a9c14a
more tests and fixes 2026-02-07 11:50:18 -06:00