dcstephenson 75d4eeb062 Fix duplicate links from mixed vendor port naming
upsert_link now does a secondary fuzzy dedup by trailing port number
so 'Gi1/9' and '9' are treated as the same port on the same chassis
pair. Prevents duplicate edges when an Aruba and FS switch each report
the same cable using different port name formats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 17:49:47 +00:00

LLDP Network Mapper

SSH-based network topology mapper for FS switches (and IOS-like CLIs). Discovers switch topology via LLDP, stores in SQLite, and visualises with Cytoscape.js.

Quick Start

1. Configure

Copy config.py.example to config.py and fill in your values:

cp config.py.example config.py
nano config.py
NOCODB_URL   = "http://your-nocodb-host:8080"
NOCODB_TOKEN = "your-api-token"

SSH_USERNAME = "admin"
SSH_PASSWORD = "your-ssh-password"
SSH_PORT     = 22
SSH_TIMEOUT  = 30
DEVICE_TYPE  = "cisco_ios"

Switch IPs are pulled automatically from NocoDB — no manual list needed. See NocoDB Requirements below.

2. Build and run

docker compose up -d --build

3. Open the UI

Navigate to: http://your-host-ip:5000

Click Scan Now to start discovery.


What it does

  • SSHs into each switch in parallel (up to 10 at once)
  • Runs show lldp neighbors and show ip interface brief
  • Parses neighbors, hostnames, management IPs, chassis IDs
  • Stores everything in SQLite (data/network.db)
  • De-duplicates bidirectional links automatically
  • Renders an interactive Cytoscape.js topology diagram
  • Exports to CSV, Mermaid (.md), and Graphviz PNG

Outputs

All files written to data/exports/:

File Purpose
topology.csv Switch links with hostnames and IPs
topology.md Mermaid diagram (paste into any markdown viewer)
topology.dot Graphviz source
topology.png Rendered network diagram

Auto-scan

Toggle auto-scan on/off from the UI. Set interval (15 min to 6 hours). State persists across container restarts.

NocoDB Requirements

Switch inventory is loaded from NocoDB automatically. The table must have:

Column Description
IP Switch management IP — required
Hostname Switch hostname
Active Must be YES to be included in scans
Dept Department code (e.g. ELEC, GW) — used for filtering
Location Physical location label
Model Switch model
Manufacturer Switch manufacturer
Asset Tag Asset tag

The NocoDB base ID and table ID are hardcoded in nocodb_client.py — update them there if you point this at a different NocoDB instance.

Troubleshooting

No switches loaded: Check NOCODB_URL and NOCODB_TOKEN in config.py. NocoDB must return at least one row with Active=YES and a non-empty IP.

Auth errors: Check SSH_USERNAME / SSH_PASSWORD in config.py.

Timeout errors: Increase SSH_TIMEOUT in config.py (default: 30s).

Wrong device type: If your switch uses a non-IOS CLI, try changing DEVICE_TYPE to "linux" or "generic" in config.py.

No management IP found: The script looks for Vlan interfaces in show ip interface brief. If your switch uses a different command, edit parser.py → parse_mgmt_ip_from_interfaces().

Project Structure

lldp-mapper/
├── app.py              # Flask API + scheduler
├── db.py               # SQLite operations
├── parser.py           # LLDP output parser
├── ssh_client.py       # Netmiko SSH + parallel scan
├── scanner.py          # Orchestrator
├── exports.py          # CSV / Mermaid / Graphviz
├── config.py           # Switch IPs + credentials (not committed)
├── config.py.example   # Config template
├── index.html          # Cytoscape.js frontend
├── data/               # SQLite DB + exports (created at runtime)
├── Dockerfile
├── docker-compose.yml
└── README.md
S
Description
SSH-based network topology mapper for FS switches (IOS-like CLIs). Discovers LLDP neighbors, stores in SQLite, visualises with Cytoscape.js, syncs to NetBox.
Readme 2 MiB
Languages
HTML 93.1%
Python 6.8%