Commit graph

182 commits

Author SHA1 Message Date
6e02dc460a
Add test for ErrorHTML fallback render function
Added test to cover the fallback render/2 function that handles
error codes without custom templates (401, 403, 503, etc.).

This improves ErrorHTML coverage from 0% to 100%.
2026-01-13 07:48:23 -06:00
7e5da340d3
Add comprehensive tests for Accounts.UserCredential
Improved coverage from 28.57% to 100% by adding 13 tests covering:
- Required field validations (user_id, credential_id, public_key, name)
- Name length validation (min 1, max 100 characters)
- Optional field handling (sign_count, last_used_at, aaguid, transports, backup flags, attestation_format)
- Default values for optional fields
- touch_changeset/1 function (updates last_used_at and increments sign_count)

Overall coverage: 66.44%
2026-01-13 07:47:37 -06:00
f5bef9b997
Add comprehensive tests for Organizations.Invitation
Improved coverage from 60.00% to 100% by adding 13 tests covering:
- Required field validations (email, role, organization_id, invited_by_id)
- Email format validation
- Automatic token generation using crypto
- Token preservation when provided
- Automatic expires_at generation (7 days from now)
- Expires_at preservation when provided
- All valid role values (admin, member, viewer)
- Accepted_at field handling

Overall coverage: 66.34%
2026-01-13 07:45:50 -06:00
160007cab1
Add HealthController test (0% → 100%) 2026-01-13 07:39:28 -06:00
e6650833f6
Improve test coverage: AgentLive.Index, UserAuth, Cisco profile
- Added comprehensive tests for ToweropsWeb.AgentLive.Index
  - Tests mount, create_agent, revoke_agent, and close_token_modal events
  - Tests agent status display and last_seen formatting
  - Coverage improved from 57.50% to 80.00%

- Enhanced ToweropsWeb.UserAuth tests
  - Added tests for impersonation functionality
  - Added tests for organization loading and membership verification
  - Added tests for superuser authorization
  - Coverage improved from 51.08% to 61.87%

- Expanded Towerops.Snmp.Profiles.Cisco tests
  - Added tests for all sensor type parsing functions
  - Added tests for different sensor scales, statuses, and error conditions
  - Tests sensor discovery with various data formats
  - Coverage improved from 57.30% to 100.00%

Overall test coverage improved from 64.25% to 65.86%
2026-01-12 18:56:23 -06:00
7cf3e61709
Add comprehensive tests for EquipmentLive.Form and UserCredentialController
- EquipmentLive.Form: 46.73% → 92.52% (+45.79%)
  - Added 27 tests covering form validation, SNMP testing, site selection
  - Tests mount behavior, save/update flows, deletion, and discovery triggers
  - Tests SNMP config changes and agent assignment

- UserCredentialController: 33.93% → 64.29% (+30.36%)
  - Added 7 tests for WebAuthn registration and authentication flows
  - Tests challenge generation, credential registration, and error cases
  - Tests discoverable authentication and account-specific auth

Overall coverage: 60.40% → 63.67% (+3.27%)
2026-01-12 18:46:15 -06:00
3c41f7e132
Enhance EquipmentLive.Show test coverage with additional test cases
Added 5 new test cases for EquipmentLive.Show module:
- Test with tab parameter (interfaces tab)
- Test equipment status with monitoring checks
- Test SNMP device information display
- Test recent events display
- Test handling of missing equipment

Coverage improvement: ToweropsWeb.EquipmentLive.Show 35.51% → 46.38%
Overall coverage: 59.88% → 60.40%

All 21 tests pass successfully.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 18:35:37 -06:00
d21e389b04
Improve test coverage with comprehensive SNMP and monitoring tests
Added extensive test suites to improve overall test coverage from 55.62% to 59.88%:

- Created Towerops.Snmp test suite (38 tests) - coverage: 10.87% → 97.83%
- Created Towerops.Snmp.Profiles.Cisco tests (14 tests) - coverage: 20.22% → 57.30%
- Created Towerops.Snmp.Profiles.NetSnmp tests (13 tests) - coverage: 56.79% → 92.59%
- Created Towerops.Monitoring.Supervisor tests (10 tests) - coverage: 21.21% → 63.64%
- Enhanced Towerops.Monitoring tests with TimescaleDB aggregate tests (skipped in test env)

Tests use Mox for SNMP client mocking with proper mock expectations for get/walk operations.
All tests follow established patterns and pass successfully.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 18:31:19 -06:00
cb93c02d74
update deps 2026-01-12 17:07:33 -06:00
1b8017dd98
change replicas 2026-01-12 10:43:24 -06:00
f377664e49
add logs helper script 2026-01-11 15:45:02 -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
d8247ec59c
Rename GitLab agent config to match home-cluster-agent 2026-01-11 15:37:49 -06:00
9be221209b
change agent path 2026-01-11 15:27:05 -06:00
18e20ffdb8
update runner 2026-01-11 15:12:57 -06:00
36175be74e
fix dialyzer and credo 2026-01-11 15:01:57 -06:00
5e1a97fcb3
fix tests 2026-01-11 14:58:55 -06:00
f16b0ebabd
awsses 2026-01-11 14:55:07 -06:00
51019e30ce
Update GitLab agent context name for deployment 2026-01-11 13:38:44 -06:00
d382f6a46e
update gitlab ci 2026-01-11 13:33:54 -06:00
1a619b47b2
Add home-cluster-glab-agent configuration 2026-01-11 13:29:02 -06:00
3ef04f261f
protobufs 2026-01-09 17:33:01 -06:00
0f238ac33d
set up ses 2026-01-09 16:52:11 -06:00
d4f963750b
update gitignore 2026-01-09 13:17:43 -06:00
cf77949527
add remote agent setup 2026-01-09 13:15:31 -06:00
4f924ba9a7
add passkey 2026-01-09 12:26:32 -06:00
9228d4a758
add navigation bar to login and registration pages 2026-01-08 09:45:51 -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
d8e29abf09
more tests and logging around email 2026-01-06 16:00:41 -06:00
c3303cc194
moar tests 2026-01-06 15:43:54 -06:00
23a0ba68b9
separate out marketing layouts 2026-01-06 14:46:39 -06:00
b3d2b95200
fix logo 2026-01-06 14:44:05 -06:00
41dcf3084f
add error pages 2026-01-06 14:37:48 -06:00
3b9fffdd07
add marketing site 2026-01-06 14:34:48 -06:00
7b1aa087d2
Add detailed context to SNMP error logs for better diagnostics
Enhance SNMP error logging to include:
- Target IP address
- SNMP version (v1/v2c)
- Timeout value in milliseconds
- OID being queried

Before:
  [warning] SNMP GET failed for "1.3.6.1.2.1.2.2.1.10.15729368": :timeout

After:
  [warning] SNMP GET failed for 192.168.1.1 (v2c, timeout: 5000ms) OID "1.3.6.1.2.1.2.2.1.10.15729368": :timeout

This makes it much easier to diagnose SNMP issues by immediately knowing which
device is timing out and what the network configuration is.

Updated all SNMP operations: GET, WALK, and GET-BULK.
2026-01-06 14:00:14 -06:00
fd317770fe
Fix health check logging with dynamic log level in endpoint
Use Plug.Telemetry's dynamic log level feature to disable logging for
/health requests. This is the proper Phoenix way to exclude specific
endpoints from request logs.

- Add log_level/1 function to endpoint that returns false for /health
- Configure Plug.Telemetry to use dynamic log level
- Remove log: false from router (handled by endpoint now)

This prevents Kubernetes health probe spam in application logs.
2026-01-06 13:57:32 -06:00
673ad13db8
Fix exit impersonation redirect to go to default org equipment page
When exiting impersonation, now redirects to the superuser's default
organization's equipment list page instead of /admin. Falls back to /orgs
if the superuser has no organizations.
2026-01-06 13:55:57 -06:00
139a42531f
Refactor credo issues: reduce complexity and nesting depth
- Refactor check_threshold_violation: extract threshold checks into separate functions (complexity 10→~3)
- Refactor load_sensor_chart_data: extract helper functions to reduce nesting
- Refactor save_equipment: extract SNMP discovery logic into helpers
- Refactor poll_sensors: extract error handling and result processing
- Refactor handle_status_change: extract equipment down/up handlers
- Refactor mount_current_scope: extract session scope building
- Refactor load_traffic_chart_data: extract aggregation and calculation helpers
- Refactor load_overall_traffic_chart_data: similar pattern to traffic chart
- Refactor load_sensor_chart_data in equipment_live/show: extract dataset builders
- Refactor discover_storage_sensors: extract storage sensor building
- Refactor perform_poll: extract device polling logic into separate functions

All 254 tests passing. Credo reports no issues.
2026-01-06 13:55:16 -06:00
02e0744c3c
Disable logging for health check endpoint
- Add log: false option to /health route to prevent K8s probe spam in logs
- Remove incorrect logger filter configuration from runtime.exs
2026-01-06 13:43:57 -06:00
e02c2d2b8f
Fix impersonation crash when session IDs are nil
Critical bug fix: fetch_current_scope_for_user and mount_current_scope
were calling Accounts.get_user(nil) when impersonating session flag was
true but superuser_id or target_user_id were nil.

This caused FunctionClauseError crashes for all logged-out users if they
had stale impersonation session data.

Changes:
- Check if both superuser_id and target_user_id exist before calling get_user
- Clear invalid impersonation state if IDs are missing
- Apply fix to both fetch_current_scope_for_user (controllers) and
  mount_current_scope (LiveViews)

This ensures graceful handling of corrupted/partial session state.
2026-01-06 13:32:17 -06:00
7df6e8b3b4
Redirect users to default org equipment page on login
Changed signed_in_path to redirect users to their default organization's
equipment page instead of the organization list.

Behavior:
- If user has organizations, redirect to first org's equipment page
- First org is determined by most recently joined (membership.inserted_at)
- If user has no organizations, redirect to /orgs to create one

This provides a better UX by landing users directly at their equipment
list instead of requiring an extra click through the org selector.
2026-01-06 13:30:07 -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
806b293ead
Fix impersonation to show correct user data and banner
Two issues were preventing impersonation from working correctly:

1. Templates were not passing current_scope to Layouts.authenticated,
   so the impersonation banner never displayed.

2. fetch_current_scope_for_user was looking up the user from the
   session token, which always pointed to the superuser. This caused
   the superuser to see their own organizations and equipment instead
   of the impersonated user's data.

Changes:
- Pass current_scope={@current_scope} to all Layouts.authenticated calls
- Store target_user_id in session during impersonation
- Fetch target user directly from database using target_user_id
- Update both fetch_current_scope_for_user (for controllers) and
  mount_current_scope (for LiveViews) to properly handle impersonation
- Clean up target_user_id from session when impersonation ends

Now when a superuser impersonates a user, they correctly see:
- The impersonation banner at the top with exit link
- The target user's organizations and equipment
- All data scoped to the impersonated user
2026-01-06 13:22:13 -06:00
a1e163d3ee
Add dialyzer type specs to refactored functions
Added comprehensive type specifications to all recently refactored
functions to improve type safety and enable dialyzer checking:

PollerWorker:
- detect_sensor_changes/3
- extract_thresholds/1
- detect_and_log_changes/4

EquipmentLive.Form:
- extract_snmp_config/1
- normalize_port/1
- test_snmp_connection/1

EquipmentLive.Show:
- seconds_to_weeks/1, seconds_to_days/1
- seconds_to_hours/1, seconds_to_minutes/1
- format_time_part/2

All specs use proper Elixir types and handle nil cases appropriately.
2026-01-06 13:12:55 -06:00
fb4da2df6d
Refactor handle_event SNMP test to reduce complexity
Extracted SNMP configuration extraction and connection testing
into separate helper functions, reducing cyclomatic complexity
from 11 to ~5.

- extract_snmp_config/1: Consolidates form data and params
- normalize_port/1: Handles port type conversion
- test_snmp_connection/1: Performs test and formats result

This makes the handle_event callback simpler and each concern
easier to test independently.
2026-01-06 13:11:07 -06:00
b328dfb96e
Refactor complex functions to reduce cyclomatic complexity
Refactored three highly complex functions to improve code maintainability:

1. PollerWorker.detect_sensor_changes (complexity 33 -> ~9):
   - Extracted threshold checking logic into separate functions
   - Split event creation into focused helper functions
   - Reduced nesting by using pipe operator pattern

2. PollerWorker.detect_and_log_changes (complexity 16 -> ~5):
   - Created separate functions for each interface change type
   - Extracted event building logic into dedicated functions
   - Improved readability with clear function names

3. EquipmentLive.Show.format_duration (complexity 13 -> ~5):
   - Extracted time unit conversion into separate functions
   - Simplified pluralization logic with pattern matching
   - Reduced nested conditionals

These changes make the code easier to test, maintain, and understand
while preserving all existing functionality.
2026-01-06 13:09:51 -06:00
77b41e0b24
Fix poller worker to use debug level for missing SNMP OIDs
The poller was re-logging SNMP errors from Client.get as warnings,
even though the client now logs them at debug level. Updated the
poller to also use debug level for expected errors like :no_such_object.

This completes the fix to reduce SNMP logging noise for devices
that don't support certain MIB objects.
2026-01-06 13:05:22 -06:00
20101201c6
Fix admin layout to use proper Phoenix component pattern
The admin layout was incorrectly defined as a separate .html.heex file
using @inner_content. Phoenix components should use render_slot(@inner_block).

Moved admin layout definition into layouts.ex as a proper function
component, matching the pattern used by app/1 and authenticated/1 layouts.
2026-01-06 13:04:22 -06:00
354e500405
Reduce SNMP logging noise for missing OIDs
Changed SNMP Client to use debug level for expected errors
(:no_such_object, :no_such_instance, :end_of_mib_view) and
only use warning level for actual communication errors.

This prevents log spam when polling interfaces that don't
support certain MIB objects, which is normal behavior.
2026-01-06 13:02:08 -06:00
837e2ea13f
Fix CSRF token error in impersonation banner
Replace raw HTML form with Phoenix .link helper using method="delete" to properly handle CSRF token in LiveView context. This fixes the UndefinedFunctionError when accessing /admin route.
2026-01-06 12:58:17 -06:00