Implements Phase 1 of network topology discovery using LLDP (Link Layer Discovery Protocol) via SNMP, inspired by concepts from lldp2map. New Features: - LLDP-MIB walker for discovering network neighbors via SNMP - Database schema for storing neighbor relationships - Functions to discover, store, and query device neighbors - Automatic device linking when neighbors are found in database Components Added: - Migration: device_neighbors table with unique constraint on (device_id, local_port, neighbor_name) - Schema: Towerops.Topology.DeviceNeighbor for neighbor relationships - Module: Towerops.Topology.Lldp for SNMP LLDP-MIB walking - Functions: discover_lldp_neighbors/1, list_lldp_neighbors/1, remove_stale_lldp_neighbors/1 in Topology context LLDP-MIB OIDs: - 1.0.8802.1.1.2.1.3.3.0 (lldpLocSysName) - 1.0.8802.1.1.2.1.3.7.1.4 (lldpLocPortDesc) - 1.0.8802.1.1.2.1.4.1.1.7 (lldpRemPortId) - 1.0.8802.1.1.2.1.4.1.1.8 (lldpRemPortDesc) - 1.0.8802.1.1.2.1.4.1.1.9 (lldpRemSysName) - 1.0.8802.1.1.2.1.4.2.1.3 (lldpRemManAddr) CI Fix: - Updated config/test.exs to use DATABASE_URL from environment in CI - Fixes "connection refused to localhost:5432" errors in CI builds - Falls back to localhost config for local development Code Quality: - Refactored LLDP module to reduce cyclomatic complexity - Extracted helper functions to improve readability - Used 'with' statement to reduce nesting in parse_management_address - All Credo checks passing Next Steps (Phase 2): - Background worker for automated topology discovery - Topology visualization in LiveView - Recursive discovery from seed devices
93 lines
2.9 KiB
Elixir
93 lines
2.9 KiB
Elixir
import Config
|
|
|
|
alias Ecto.Adapters.SQL.Sandbox
|
|
|
|
# Only in tests, remove the complexity from the password hashing algorithm
|
|
config :argon2_elixir,
|
|
t_cost: 1,
|
|
m_cost: 8
|
|
|
|
config :error_tracker, enabled: false
|
|
|
|
# Suppress log output during tests (tests that need logs use capture_log)
|
|
config :logger, :default_handler, false
|
|
config :logger, level: :error
|
|
|
|
# Initialize plugs at runtime for faster test compilation
|
|
config :phoenix, :plug_init_mode, :runtime
|
|
|
|
# Sort query params output of verified routes for robust url comparisons
|
|
config :phoenix,
|
|
sort_verified_routes_query_params: true
|
|
|
|
# Enable helpful, but potentially expensive runtime checks
|
|
config :phoenix_live_view,
|
|
enable_expensive_runtime_checks: true
|
|
|
|
# Disable swoosh api client as it is only required for production adapters
|
|
config :swoosh, :api_client, false
|
|
|
|
# Disable Oban job processing in tests (use testing mode)
|
|
config :towerops, Oban,
|
|
repo: Towerops.Repo,
|
|
testing: :manual,
|
|
queues: false,
|
|
plugins: false
|
|
|
|
# In test we don't send emails
|
|
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Test
|
|
|
|
# Configure your database
|
|
#
|
|
# The MIX_TEST_PARTITION environment variable can be used
|
|
# to provide built-in test partitioning in CI environment.
|
|
# Run `mix help test` for more information.
|
|
#
|
|
# In CI, DATABASE_URL is set and will be used automatically by Ecto.
|
|
# Locally, fall back to individual connection parameters.
|
|
if database_url = System.get_env("DATABASE_URL") do
|
|
config :towerops, Towerops.Repo,
|
|
url: database_url,
|
|
pool: Sandbox,
|
|
pool_size: System.schedulers_online() * 2
|
|
else
|
|
config :towerops, Towerops.Repo,
|
|
username: "postgres",
|
|
password: "postgres",
|
|
hostname: "localhost",
|
|
database: "towerops_test#{System.get_env("MIX_TEST_PARTITION")}",
|
|
pool: Sandbox,
|
|
pool_size: System.schedulers_online() * 2
|
|
end
|
|
|
|
# Configure Cloak encryption for testing
|
|
# Use a fixed test key (same as dev for simplicity)
|
|
config :towerops, Towerops.Vault,
|
|
ciphers: [
|
|
default: {
|
|
Cloak.Ciphers.AES.GCM,
|
|
# Test key - same as dev for consistency
|
|
tag: "AES.GCM.V1", key: Base.decode64!("nQWmgQYhoCNXA3PAxwriKxLyPHAOWH9VgpLkBOXrowM=")
|
|
}
|
|
]
|
|
|
|
# We don't run a server during test. If one is required,
|
|
# you can enable the server option below.
|
|
config :towerops, ToweropsWeb.Endpoint,
|
|
http: [ip: {127, 0, 0, 1}, port: 4002],
|
|
secret_key_base: "XDSSqVUtRXUjEfzxefIAaPIzBfonpNMOrCRyP1a0kjPzzyOpVNSRmMBVae/bwTqj",
|
|
server: false
|
|
|
|
# Webhook secret for CI-triggered agent updates
|
|
config :towerops, :agent_webhook_secret, "test-webhook-secret"
|
|
|
|
# Set environment identifier for runtime checks
|
|
config :towerops, :env, :test
|
|
|
|
config :towerops,
|
|
ping_module: Towerops.Monitoring.PingMock,
|
|
poller_module: Towerops.Snmp.PollerMock,
|
|
snmp_adapter: Towerops.Snmp.SnmpMock,
|
|
sql_sandbox: true,
|
|
# Disable rate limiting in tests to avoid blocking concurrent test requests
|
|
rate_limiting_enabled: false
|