Commit graph

54 commits

Author SHA1 Message Date
146f5745cf
fix: resolve compilation errors, test failures, and credo issues
- Escape HEEx template braces in GraphQL/API docs with raw(~S[...])
- Fix test assertions for updated marketing copy and UI text
- Extract helper functions in GraphQL resolvers to reduce nesting depth
- Create shared ErrorHelpers module for API controllers
- Fix ETS race condition in brute force whitelist cache for async tests
- Fix property test generators to use ASCII instead of printable unicode
- Add alert_severity helper to site_live/show
- Update accounts fixtures for explicit user confirmation
2026-02-14 12:23:10 -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
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
6b4c098de8
fix warnings 2026-02-08 10:50:27 -06:00
24236dbe30
update oban_web 2026-02-08 10:11:53 -06:00
d431931cfe
update hammer 2026-02-08 10:08:31 -06:00
38eeb1c7b8
fix: improve agent polling and SNMP testing
Changes:
- Fix traffic graph to handle nil interface octets gracefully
- Add comprehensive tests for nil octets scenarios
- Fix agent polling query to support devices assigned directly to org (left join on sites)
- Fix test SNMP connection to inherit credentials from site/org
- Refactor agent_channel process_polling_result to reduce nesting (Credo)
- Add alias for JobCleanupTask in application.ex (Credo)

This fixes crashes when interface stats have nil octets and ensures
devices without a site assignment can be polled by agents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 12:34:28 -06:00
23af86ba73
add mikrotik device handling 2026-02-01 16:42:39 -06:00
02833d0b44 Add rate limiting to auth and API endpoints using Hammer 2026-02-01 14:59:54 -06:00
c856b2142c
Add timezone validation to reject invalid IANA timezone strings
Prevents invalid timezone values from being stored in the database
by validating against Elixir's time zone database during registration.
2026-02-01 11:56:04 -06:00
61a06fc11c
Add firmware version tracking system
- Add firmware context module with upsert, query, and logging functions
- Add FirmwareVersionFetcherWorker to fetch MikroTik RSS daily
- Add Oban cron schedules (2 AM dev, 4 AM prod)
- Add version change detection to Discovery module
- Track firmware history with PubSub broadcasts
- All tests passing

Phase 3-5 of firmware tracking implementation complete.
Next: LiveView UI indicators.
2026-02-01 10:46:27 -06:00
feed25080c
add HIBP password check 2026-02-01 08:57:01 -06:00
2fab08f5f8
forgot password flow 2026-01-31 17:03:22 -06:00
5286d8acba nif ci fix complie in ci 2026-01-30 13:06:39 -06:00
836749ba6b complete overhaul of snmp engine 2026-01-30 10:41:07 -06:00
d29fb8cfd7 totp fixes 2026-01-28 16:16:59 -06:00
0995abbccb Add mandatory TOTP MFA 2026-01-28 15:09:38 -06:00
220f1edce3 cookie improvements 2026-01-28 12:30:28 -06:00
f350a9ade4 test cleanup 2026-01-28 10:31:22 -06:00
124d68d28d
credo fixes 2026-01-27 09:12:22 -06:00
bb86dec559
add oban pro 2026-01-26 17:07:42 -06:00
d0946c3cd0
refactor: simplify job architecture from Oban coordinators to direct workers
Removes unnecessary two-layer architecture (Oban Coordinator → GenServer)
in favor of direct Oban workers that perform the actual work.

Changes:
- Replace DevicePollerCoordinator + PollerWorker with DevicePollerWorker
- Replace DeviceMonitorCoordinator + DeviceMonitor with DeviceMonitorWorker
- Simplify Monitoring.Supervisor (removed Registries, DynamicSupervisors)
- Remove all Exq dependencies (workers, supervisor, mix deps)
- Convert DiscoveryWorker from Exq to Oban pattern
- Update Devices context to auto-start/stop monitoring and polling
- Update all LiveView callers to use new Oban enqueue pattern
- Fix all tests to use Oban.Job struct instead of raw IDs

Benefits:
- Simpler codebase (~850 lines removed)
- Better reliability (Oban handles retries, failures)
- Lower memory (no persistent GenServers)
- Better observability (work visible in Oban dashboard)
- Cluster-wide coordination via PostgreSQL
- Extensive PubSub usage for real-time events

Files deleted:
- lib/towerops/workers/device_monitor_coordinator.ex
- lib/towerops/workers/device_poller_coordinator.ex
- lib/towerops/snmp/poller_worker.ex
- lib/towerops/monitoring/device_monitor.ex
- lib/towerops/workers/monitor_worker.ex
- lib/towerops/workers/poll_worker.ex
- lib/towerops/exq_supervisor.ex
- All related test files

Files created:
- lib/towerops/workers/device_poller_worker.ex
- lib/towerops/workers/device_monitor_worker.ex

All 3,686 tests passing.
2026-01-24 16:36:57 -06:00
29593ac734
refactor: migrate from etcd to Oban for distributed job coordination
Replaces etcd-based distributed locking with Oban's PostgreSQL-backed job queue.
This simplifies the architecture by eliminating the need for a separate etcd cluster
while providing better reliability and observability.

Changes:
- Add Oban dependency and migration (oban_jobs table)
- Create DevicePollerCoordinator and DeviceMonitorCoordinator Oban workers
- Remove EtcdCoordinator and EtcdLock modules
- Update application supervisor to start Oban
- Configure Oban with pollers (50 workers) and monitors (50 workers) queues
- Remove etcd StatefulSet from Kubernetes manifests
- Update monitoring supervisor documentation

Benefits:
- Simpler architecture (no etcd cluster to manage)
- PostgreSQL-based (uses existing database)
- Built-in uniqueness prevents duplicate jobs cluster-wide
- Better observability with Oban Web UI
- Automatic job rescue on node crashes
- Easier local development (no etcd required)

What was removed:
- etcd StatefulSet (3 pods)
- EtcdCoordinator module (320 lines)
- EtcdLock module (158 lines)
- eetcd dependency

All 3,686 tests passing.
2026-01-24 16:12:27 -06:00
f084e09ea1
add multiple cloud agents 2026-01-23 18:04:01 -06:00
2b78b1a2d3
snmpkit overhaul and etcd 2026-01-23 16:23:57 -06:00
518b49318c
routeros fix 2026-01-23 13:16:02 -06:00
a0ba9285dd
bring in snmpkit 2026-01-23 12:52:17 -06:00
7c660169b7
better mib handling and tests 2026-01-21 10:07:07 -06:00
1f123bbeb9
add honeybadger and snmp overhaul 2026-01-18 16:16:08 -06:00
e4b3778da4
exq improvements 2026-01-18 11:50:19 -06:00
1b4b7f1773
fix user deletion bug and implement timezone support
User deletion bug:
- Store client IP in socket assigns during mount
- Access stored IP during delete event instead of connect_info
- Fixes RuntimeError when attempting to delete users

Timezone support:
- Add timezone offset maps for common timezones (no external deps)
- Implement shift_timezone/2 helper using DateTime.add/3
- Add timezone-aware format_datetime/2, format_date/2, format_iso8601/2
- Keep backwards-compatible 1-arity versions defaulting to UTC
- Add comprehensive test coverage for timezone conversions
- All tests passing (23 tests, 0 failures)

Note: Timezone offsets are standard time only (no DST handling)
Common timezones supported: America/New_York, America/Los_Angeles,
Europe/London, Europe/Paris, Asia/Tokyo, Asia/Shanghai, Australia/Sydney
2026-01-18 10:51:11 -06:00
3cc69c9250
feat: add Horde for cluster-aware distributed supervision
Prevents duplicate polling in multi-node production environment:
- Replace DynamicSupervisor with Horde.DynamicSupervisor (distributed)
- Replace Registry with Horde.Registry (cluster-aware)
- Each device monitor runs on exactly ONE node across the cluster
- Each SNMP poller runs on exactly ONE node across the cluster
- Automatic failover when nodes go down
- Automatic rebalancing when nodes join/leave

Architecture:
- Horde.Registry for process naming (distributed lookup)
- Horde.DynamicSupervisor for DeviceMonitor processes
- Horde.DynamicSupervisor for PollerWorker processes
- Task.Supervisor remains local per-node for parallel operations
- members: :auto enables automatic cluster discovery via libcluster

Production impact:
- 2 replicas = devices split ~50/50 across both pods
- No duplicate SNMP polls to same device
- If pod dies, surviving pod takes over all devices
- When new pod starts, devices rebalance automatically

Dependencies added:
- horde ~> 0.9.0 (distributed supervisor/registry)
- delta_crdt (Horde dependency for CRDT-based state)
- libring (Horde dependency for consistent hashing)
2026-01-18 10:14:50 -06:00
3c46c805a0
Add real-time updates with Redis-backed PubSub
- Configure Phoenix.PubSub to use Redis adapter for pod-resilient messaging
- Add PubSub broadcasts for sensor readings updates in PollerWorker
- Add PubSub broadcasts for interface stats updates in PollerWorker
- Add PubSub broadcasts for neighbor discovery updates in PollerWorker
- Add PubSub broadcasts for monitoring check updates in MonitorWorker
- Broadcast interface and sensor events to device-specific topics
- Add event handlers in DeviceLive.Show for all update types
- Device show page now updates in real-time without polling
- Updates survive pod restarts and work across multiple pods
2026-01-17 17:55:49 -06:00
13f447f1b0
feat: add Exq background job processor
- Add exq ~> 0.23 dependency with redix and elixir_uuid
- Configure Exq in application supervisor with 4 queues (default, discovery, polling, maintenance)
- Set Exq as included_application to prevent auto-start
- Only start Exq in dev/prod environments, skip in test
- Use :env config to determine runtime environment
- Configure 10 concurrent workers with exq namespace
- Connect to Redis/Valkey sidecar via existing :redis config
2026-01-17 16:36:49 -06:00
8442d9e1fc
update liveview 2026-01-14 13:54:48 -06:00
cb93c02d74
update deps 2026-01-12 17:07:33 -06:00
53b99fd3ca
Add gen_smtp dependency for Swoosh AmazonSES adapter
The AmazonSES adapter requires gen_smtp to encode emails with mimemail.
2026-01-11 15:41:21 -06:00
f16b0ebabd
awsses 2026-01-11 14:55:07 -06:00
3ef04f261f
protobufs 2026-01-09 17:33:01 -06:00
0f238ac33d
set up ses 2026-01-09 16:52:11 -06:00
4f924ba9a7
add passkey 2026-01-09 12:26:32 -06:00
96bd8b3829
add MIB-based validation and generic profile tests
- Add MIB files from LibreNMS in priv/mibs/ for reference
- Create MibParser module to validate OIDs against official MIB definitions
- Add MIB validation tests to ensure hardcoded OIDs match MIB specs
- Refactor SNMP tests to be generic/behavior-focused instead of vendor-specific
- Remove vendor-specific test files (cisco_test, net_snmp_test)
- All 104 tests passing with automated OID validation
2026-01-08 08:57:21 -06:00
c3303cc194
moar tests 2026-01-06 15:43:54 -06:00
152c308b68
Add input validation for port numbers and SNMP testing
Security improvements to prevent potential issues:

1. Port Validation (normalize_port):
   - Validate port range is 1-65535
   - Use Integer.parse instead of String.to_integer to prevent crashes
   - Return default port 161 for any invalid input

2. SNMP Test Validation (validate_test_snmp_input):
   - Validate IP address format before allowing SNMP tests
   - Require non-empty community string
   - Prevent network scanning with invalid/missing IPs
   - Return clear error messages for validation failures

These changes ensure user input is properly validated and prevent:
- Integer overflow/underflow with ports
- Process crashes from invalid input
- Unauthorized network scanning via SNMP test feature
- SNMP requests with missing credentials
2026-01-06 13:28:30 -06:00
853d548f82
Add superuser system with user impersonation for admin support
Implement comprehensive admin interface allowing designated superusers to view all users and organizations, impersonate users for debugging, and perform administrative operations. All superuser actions are tracked in audit logs for compliance.

Features:
- Superuser authentication with dedicated admin routes at /admin
- User impersonation with session state preservation
- Admin dashboard with system statistics
- User and organization management interfaces
- Comprehensive audit logging with IP tracking
- Visual impersonation banner with exit capability
- Security controls preventing self-impersonation and superuser-to-superuser impersonation

Database:
- Add is_superuser boolean field to users table
- Create audit_logs table for tracking sensitive operations
- Set graham@mcintire.me as initial superuser
2026-01-06 12:50:10 -06:00
d09d64f7bd
add more things to dashboard 2026-01-04 12:13:20 -06:00
5dda738816
add deps 2026-01-03 16:09:48 -06:00
8cbca259fc
snmp bits 2026-01-03 14:41:28 -06:00
287fd8064a
Add Dialyzer for static type analysis
- Added dialyxir dependency for static analysis
- Configured PLT file location and analysis flags
- Added priv/plts/ to .gitignore
- Enabled unmatched_returns, error_handling, and unknown type checks
2026-01-03 12:39:02 -06:00
6986a14e13
Add mix_test_watch for automatic test running
- Added mix_test_watch dependency for dev/test environments
- Enables 'mix test.watch' command to run tests on file changes
2026-01-03 12:34:19 -06:00