Commit graph

814 commits

Author SHA1 Message Date
14ec708e93
Add comprehensive tests for PDU.Encoder (87 tests)
Improve coverage from 43.82% to 75.84% with tests for:
- Message encoding (SNMPv1, v2c, v3 delegation)
- PDU encoding (all PDU types: get, getnext, response, set, getbulk)
- Varbind encoding (explicit types, auto types, all SNMP value types)
- Integer encoding edge cases (zero, small, large, negative)
- Counter32/Gauge32/Timeticks (min/max values)
- Counter64 (0 to 18446744073709551615)
- String encoding (empty, short, long, special chars, binary)
- OID encoding (simple, large subids, very large subids, long OIDs)
- Bulk request encoding (non_repeaters, max_repetitions)
- Exception values (no_such_object, no_such_instance, end_of_mib_view)
- Length encoding edge cases (short, medium, long form)
- Error handling (invalid formats, missing fields)
- Complete integration tests (GET/GETNEXT/SET/GETBULK)

Coverage: 1,304 → 1,391 tests, all passing

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 08:53:52 -06:00
07977bc16f
test: add comprehensive tests for MIB.SnmpTokenizer
Added complete test coverage for MIB.SnmpTokenizer module (32.93% -> target higher):

**Tokenization Tests:**
- Empty input handling
- Simple MIB header (DEFINITIONS, BEGIN, END)
- Reserved word recognition (30+ SMI keywords tested)
- Identifier tokenization (lowercase atoms, uppercase variables)
- Number tokenization (integers, negative numbers, leading zeros, large numbers)
- String tokenization with quotes
- Special characters (::=, {}, (), commas, semicolons, dots)
- OID notation
- Complete OBJECT-TYPE definitions
- Access modifiers (read-only, read-write, not-accessible, read-create)
- SMI types (INTEGER, OCTET STRING, Counter32, Gauge32, TimeTicks, IpAddress)
- Hyphenated keywords (OBJECT-TYPE, MAX-ACCESS, MODULE-IDENTITY, etc.)

**Format and Syntax:**
- Whitespace handling (spaces, tabs, newlines)
- Comment handling (-- comments)
- Multiline input
- Line number tracking
- Token order preservation
- Complex MIB structures (IMPORTS, MODULE-IDENTITY, etc.)
- SIZE constraints
- SEQUENCE OF notation

**Error Handling:**
- format_error/1 for illegal characters
- Unterminated string errors
- Unterminated quote errors
- Unknown error formatting

**Edge Cases:**
- Very long identifiers (up to 200 chars)
- Many tokens (100+ identifiers)
- Deeply nested braces
- Mixed case keywords (case-sensitive)
- Empty strings
- Consecutive operators
- Tabs and mixed whitespace
- Numbers with leading zeros
- Very large numbers

**Reserved Word Coverage:**
- All common SMI/SMIv2 reserved words tested
- Distinction between reserved words and similar identifiers
- Case-sensitive recognition

40 new tests added
Test count: 1,264 -> 1,304 (all passing)
2026-02-06 08:45:23 -06:00
42895fea8f
test: add comprehensive tests for MIB.Error
Added complete test coverage for MIB.Error module (16.13% -> target 100%):

**Error Creation:**
- All supported error types (syntax, semantic, import, type, constraint, etc.)
- Error creation with line and column information
- Error creation with context maps
- Suggestion generation for common mistakes

**Error Types Tested:**
- unexpected_token with various combinations (expected/actual/value)
- unexpected_eof with expected values
- unterminated_string
- invalid_number and invalid_identifier
- file_not_found with path
- import_error with symbol and module
- duplicate_definition with name
- Generic error types

**Suggestion Generation:**
- MAX-ACCESS vs ACCESS typo
- deprecated 'mandatory' vs 'current'
- OBJECT-TYPE vs OBJECT-IDENTITY confusion
- Unterminated string hints
- File not found with RFC/MIB name detection
- Import error dependency hints

**Error Formatting:**
- Format with/without line and column
- Format with/without suggestions
- Multiple suggestion formatting
- Edge cases (nil values, empty strings, non-standard types)

**Edge Cases:**
- All nil fields
- Large line numbers
- Zero/negative line/column values
- Various context data types
- Mixed token value types
- Empty options handling

53 new tests added
Test count: 1,211 -> 1,264 (all passing)
2026-02-06 08:38:33 -06:00
82b4dbdf28
test: add comprehensive tests for PDU.Constants and MIB.Logger
Added complete test coverage for two low-coverage modules:

**PDU.Constants (11.65% -> target 100%)**:
- Error status code accessors and conversions
- SNMPv3 constants (USM security model, max message size)
- PDU type constants and tag conversion (get, getnext, response, set, getbulk)
- Data type constants and tag conversion (all SNMP types)
- SNMP version normalization (:v1, :v2c, :v3)
- OID normalization (list and string formats)
- SNMPv3 message flags encoding/decoding
- Default message flags for security levels
- Error status code/atom conversion
- Roundtrip encoding/decoding verification
- 43 new tests

**MIB.Logger (11.11% -> target 100%)**:
- Compilation lifecycle logging (start, success, error, warning, complete)
- Batch compilation logging (start, progress, success, error)
- Parse progress and import resolution logging
- Code generation and tokenization statistics
- Dependency order and performance metrics
- Vendor quirk handling
- Warning logging with context
- Error type extraction and aggregation
- 40 new tests

Total: 83 new tests added
Test count: 1,128 -> 1,211 (all passing)
2026-02-06 08:36:20 -06:00
35ee87952f
test: expand Types module test coverage
Added comprehensive test coverage for previously untested functionality:

- IP address parsing (valid IPs, invalid inputs, IPv6 rejection)
- Zero-filling behavior for incomplete IPs (Erlang :inet standard)
- Type inference for all SNMP types (integers, strings, lists, booleans, nulls)
- Value decoding for all SNMP types (strings, integers, IPs, OIDs, exceptions)
- Value encoding with type inference and validation controls
- Unsigned32 validation (valid ranges, overflow, underflow)
- Coercion edge cases (IP addresses, unsigned32, octet_string, OIDs, booleans)

Fixes:
- Corrected type inference expectation for large integers (returns :unsigned32)
- Fixed boolean assertion to use equality check instead of pattern match
- Documented :inet.parse_address zero-fill behavior for incomplete IPs

Total: 97 tests, all passing
2026-02-05 17:24:10 -06:00
76d70dd3f4
Add comprehensive test coverage for SNMPkit modules
Added test suites for previously untested SNMPkit modules:

- ErrorHandler: Circuit breaker, retry logic, error classification (88.70% coverage)
- MIB.AST: AST node creation, validation, pretty printing (100% coverage)
- MIB.Preprocessor: MIB preprocessing, enumeration simplification (48.28% coverage)
- MIB.Utilities: OID resolution, type validation, error handling (85.60% coverage)
- PDU.V3Encoder: SNMPv3 message encoding/decoding (36.90% coverage)

All 1090 tests passing with no failures.
2026-02-05 17:03:41 -06:00
4e9a533106
Fix SNMPkit tests and add coverage for bang methods
Fixed 2 failing tests in HostParser that were using unreliable hostname resolution. Changed tests to use malformed IP addresses that will always fail validation consistently.

Added tests for SnmpKit.SNMP bang methods (get_bulk!, bulk_walk!) which have actual implementation logic beyond delegation.

All 954 SNMPkit tests now pass (0 failures).
2026-02-05 16:46:36 -06:00
8ee39a2d36
Add comprehensive tests for API authentication and authorization
Implemented tests for critical security modules with significant coverage improvements:
- ApiAuth plug: 0% → 100% (12 tests)
- Permissions module: 0% → 85% (32 tests)
- Devices API controller: 0% → 95% (22 tests)

Enhanced test fixtures to support membership roles and device creation with proper organization scoping.
2026-02-05 16:39:01 -06:00
c3d952148e
fix test warnings and failures
- Remove unused Ecto.Query import from device_poller_worker_test
- Update route paths from /orgs/:slug to /dashboard after navigation refactor
- Fix HostParser tests to match actual hostname resolution behavior
- Update UserAuth redirect assertions to expect /dashboard instead of /devices
- Fix DashboardLiveTest missing organization context
- Fix OrgLive.NewTest to verify organization creation correctly

All 4850 tests now passing with zero failures and zero warnings.
2026-02-05 15:24:41 -06:00
5342be99db
fix device count 2026-02-05 15:04:34 -06:00
156d9a47bf
UI improvements 2026-02-05 14:57:11 -06:00
2ef85161dd
fix airfiber identification 2026-02-05 14:08:34 -06:00
cb0cc66768
fix mistaken poller ids 2026-02-05 13:57:15 -06:00
472482c4f5
fix nil firmware comparison 2026-02-05 13:47:56 -06:00
a803ddb893
more dialyzer specs 2026-02-05 13:11:18 -06:00
6e730c6558
performance and security improvements 2026-02-05 12:42:35 -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
987eae0408
fix: improve agent-based live polling with better logging and validation
- Added Logger.require for debug logging
- Refactored fetch_latest_agent_data to reduce nesting depth
- Added debug logging to trace agent assignment detection
- Check for nil/stale sensor readings and log appropriately
- Use actual reading timestamp instead of current time for data points

This will help diagnose why live polling shows 0 values and why
Phoenix SNMP disabled messages appear for agent-assigned devices.
2026-02-05 09:25:29 -06:00
e0592dbf3d
fix: use agent-collected data for live polling when agent assigned
Modified GraphLive live polling to check for agent assignments and use
agent-collected sensor data from the database instead of doing direct
SNMP polling. This respects the agent assignment and prevents Phoenix
from bypassing the agent for live graph updates.

Also refactored handle_params to reduce nesting depth.
2026-02-05 09:21:43 -06:00
dd8c97a45f
fix: handle devices without sites in GraphLive live polling
Devices can belong directly to organizations without sites. Fixed
perform_live_poll to check device.organization_id instead of
device.site.organization_id which caused BadMapError when site is nil.
Also removed unused Repo alias.
2026-02-05 09:16:11 -06:00
912cb8d280
fix: add missing handle_info for state_sensors_updated in GraphLive.Show
Adds handler to reload graph data when state sensors are updated via PubSub,
preventing GenServer crash when viewing graph page during sensor updates.
2026-02-05 09:14:21 -06:00
0d6caa897f
refactor: remove debug logging from SNMPv3 credential handling
Discovery is now working successfully with SNMPv3 after increasing
agent timeout to 60s. Removing the temporary debug logging that was
added to verify credentials were being properly decrypted and sent
to the agent.
2026-02-05 09:00:42 -06:00
b36da6f327
debug: log SNMPv3 credential lengths sent to agent
Added logging to show what SNMPv3 parameters are being sent from Phoenix
to the agent, including password lengths to verify they're decrypted
properly.
2026-02-05 08:35:09 -06:00
ae64ec2576
feat: add automatic polling job cleanup on deployment
Added JobCleanupTask that runs on production startup to cancel all
existing polling jobs and reschedule them with the latest worker code.

This ensures:
- No stale jobs run with old code after deployment (e.g., missing SNMPv3 credentials)
- All devices get fresh polling jobs with current logic
- Production deployments are seamless without manual intervention

The task:
- Only runs in production environment (skipped in dev/test)
- Runs asynchronously after supervisor initialization
- Cancels all DevicePollerWorker and DeviceMonitorWorker jobs
- Reschedules polling for all SNMP-enabled devices
- Is idempotent and safe to run multiple times

Removed debug logging from Client and DevicePollerWorker as SNMPv3
implementation is now verified and working correctly.
2026-02-05 08:28:27 -06:00
197d52096d
debug: add DevicePollerWorker client opts logging
Added logging to show what options are being built in DevicePollerWorker,
including whether security_name (v3) or community (v2c) credentials are
being included.
2026-02-05 08:18:35 -06:00
e1c4930bea
debug: add SNMPv3 parameter logging
Added info-level logging to show what parameters are being passed to
SnmpKit for SNMPv3 requests. This will help diagnose encoding errors.
2026-02-05 08:14:49 -06:00
ed16033ac4
include changelog 2026-02-05 08:07:33 -06:00
d1ff581d85
fix: add SNMPv3 credentials to DevicePollerWorker
The DevicePollerWorker was only passing SNMPv2c credentials (community
string) to the SNMP client, causing KeyError when polling SNMPv3 devices.

Changes:
- Updated build_client_opts in device_poller_worker.ex to detect version "3"
- Added same SNMPv3 credential handling as discovery.ex
- Includes: security_name, security_level, auth_protocol, auth_password,
  priv_protocol, priv_password

This completes the SNMPv3 implementation - both discovery and polling now
support v3 authentication alongside the existing v2c support.
2026-02-05 08:07:11 -06:00
129bc9a8f4
fix: handle nil site in graph_live access check
Similar to previous fix - use device.organization_id directly instead of
device.site.organization_id to avoid BadMapError when device has no site.
2026-02-04 18:25:48 -06:00
95c6f53d15
fix: handle nil sys_descr in profile matching
Fixes FunctionClauseError when sys_descr is nil during device profile
matching. Added nil check before attempting String.contains? comparison.
2026-02-04 18:22:12 -06:00
ff89415ed3
feat: add SNMPv3 support to discovery and SNMP client
The discovery process was only passing SNMPv2c credentials (community
string) to the SNMP client, causing SNMPv3 devices to fail discovery
even when v3 credentials were configured.

Changes:
- Updated build_client_opts in discovery.ex to include SNMPv3 credentials
  (security_name, security_level, auth_protocol, auth_password,
   priv_protocol, priv_password) when version is "3"
- Updated build_snmp_opts in client.ex to pass v3 credentials to SnmpKit
- Added parse functions for security_level, auth_protocol, and priv_protocol
- Updated connection_opts typespec to include v3 parameters
- Fixed parameter names to match SnmpKit expectations (security_name vs sec_name)

This enables full SNMPv3 discovery on devices like MikroTik routers that
use v3 authentication, allowing them to discover the same sensors and
data that SNMPv2c would show.
2026-02-04 18:18:37 -06:00
8e0fad599e
fix: handle nil site in list_neighbors_with_equipment
Fixes BadMapError when loading device show page for devices without
an assigned site. Changed to use device.organization_id directly
instead of device.site.organization_id since site can be nil but
organization is always present.
2026-02-04 18:09:36 -06:00
c70b385db1
refactor: consolidate reorder handlers in device_live
Extract common pattern from perform_site_reorder/4 and perform_device_reorder/4
into a single perform_reorder/4 helper function.

Both reorder handlers now delegate to the shared helper, reducing duplication
and making the reload/regroup/flash pattern consistent.

- Reduces code from 40 lines to 28 lines
- Maintains identical behavior (all tests pass)
- Uses static gettext strings to satisfy compile-time requirements
2026-02-04 18:02:13 -06:00
aa0e7f3d05
help update 2026-02-04 17:56:48 -06:00
6f6627a54d
refactor: consolidate device count calculations in agent_live
Remove duplicate device counting logic by consolidating three identical
implementations into a single reusable function.

**Changes:**
- Refactor agent_live/index.ex mount/3 to use calculate_device_counts/1
- Delete duplicate calculate_cloud_poller_counts/1 function
- Replace all usages with calculate_device_counts/1

**Before:**
- Lines 31-47: Inline counting for agent_tokens and cloud_pollers
- Lines 312-318: calculate_device_counts/1
- Lines 320-326: calculate_cloud_poller_counts/1 (identical logic)

**After:**
- Single calculate_device_counts/1 function used everywhere
- ~20 lines removed

**Benefits:**
- Eliminates triple duplication of counting logic
- Single source of truth for device counting
- Easier to maintain and test

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 17:53:18 -06:00
6aab59dcf5
refactor: centralize LiveView access control checks
Extract duplicate access control logic from multiple LiveView files into
a reusable AccessControl helper module.

**Changes:**
- NEW: lib/towerops_web/live/helpers/access_control.ex
- NEW: test/towerops_web/live/helpers/access_control_test.exs
- Refactor device_live/index.ex to use AccessControl.verify_site_access/2
  and verify_device_access/2
- Refactor device_live/form.ex to use AccessControl.verify_device_access/2
- Refactor alert_live/index.ex to use AccessControl.verify_alert_access/2
- Refactor device_live/show.ex to use AccessControl.verify_device_access/2
- Remove unused Repo aliases from refactored files

**Benefits:**
- Reduces code duplication across 7+ locations
- Centralizes security-critical access checks
- Improves testability (helper module has >90% coverage)
- Consistent error handling across all LiveViews

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 17:51:05 -06:00
d16f09666f
snmp v3 ui fixes 2026-02-04 17:41:15 -06:00
dbb2412e89
tcp snmp test 2026-02-04 17:28:14 -06:00
277a06864c
doc cleanup 2026-02-04 16:58:42 -06:00
89911bae9c
Device list bug fix 2026-02-04 16:49:17 -06:00
4f936d5549
device edit fix 2026-02-04 16:28:15 -06:00
6689eb27b4
prevent poller fallback when assigned poller is selected 2026-02-04 16:24:19 -06:00
031880c954
fix device page 2026-02-04 16:17:07 -06:00
fc66109f19
Add default organization feature
Features:
- Users can set a default organization in org settings
- First organization created is automatically set as default
- Default org selector only shown if user has 2+ organizations
- Migration auto-sets first org as default for existing users

Database changes:
- Added is_default boolean field to organization_memberships
- Added partial index for efficient default org lookups
- Migration sets oldest org as default for each existing user

UI changes:
- Organization settings page shows default org toggle
- Green badge displayed when org is already default
- Button to set org as default if it's not current default

Backend:
- Organizations.set_default_organization/2 manages defaults
- Organizations.get_default_membership/1 retrieves default
- Auto-set first org as default in create_organization/3
2026-02-04 16:09:43 -06:00
7a1317d0d0
API: Default organization_id to authenticated org when empty
When creating devices via API, organization_id is now properly defaulted
to the authenticated organization's ID even when an empty string is sent.

This fixes Terraform provider compatibility where organization_id may be
sent as "" instead of omitted entirely.

Before: Only checked if key was missing (Map.has_key?)
After: Also handles nil and empty string values
2026-02-04 16:03:20 -06:00
a97ae5ad09
Speed up Kubernetes rollouts
Changes:
- maxSurge: 1 → 100% (start all new pods simultaneously)
- minReadySeconds: 30 → 10 (faster promotion)
- readinessProbe successThreshold: 2 → 1 (faster health checks)

Result: Rollout time reduced from 6+ minutes to ~90 seconds while
maintaining zero downtime (maxUnavailable: 0 unchanged).
2026-02-04 15:16:16 -06:00
8382b5df6a
make devices site optional and many test fix 2026-02-04 15:05:42 -06:00
1a054fd598
make sites optional 2026-02-04 13:05:32 -06:00
4ef4f4fbf6
handle exceptions gracefully on api endpoints 2026-02-04 12:18:14 -06:00
09f2907ede
Remove debugging logs, fix Mix.env call 2026-02-04 12:10:48 -06:00