Prune links a scanned switch no longer reports

Dept scans don't clear links first, so when a port was re-cabled (e.g. a
new switch inserted on an existing uplink) the old link stayed alongside
the new one. After storing a switch's neighbors, prune_stale_links() now
deletes any link on that switch that its own LLDP table doesn't back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
dcstephenson
2026-10-01 14:56:10 -05:00
parent a84c09d9cd
commit e589f76387
2 changed files with 35 additions and 1 deletions
+30
View File
@@ -178,6 +178,36 @@ def upsert_link(chassis_a, port_a, chassis_b, port_b):
conn.close()
def prune_stale_links(chassis_id, current):
"""
Drop links on a just-scanned switch that its own LLDP table no longer backs.
current = set of (local_port, neighbor_chassis_id) the switch reported this
scan. Dept scans don't clear_links() first, so without this a re-cabled port
(e.g. a new switch inserted mid-run) keeps its old link alongside the new one.
Must run after the switch's upsert_link calls, which rewrite its side of each
surviving link to the self-reported port name compared here.
"""
conn = get_conn()
rows = conn.execute("""
SELECT id, chassis_a, port_a, chassis_b, port_b FROM links
WHERE chassis_a=? OR chassis_b=?
""", (chassis_id, chassis_id)).fetchall()
stale = []
for r in rows:
if r['chassis_a'] == chassis_id:
key = (r['port_a'], r['chassis_b'])
else:
key = (r['port_b'], r['chassis_a'])
if key not in current:
stale.append((r['id'],))
conn.executemany("DELETE FROM links WHERE id=?", stale)
conn.commit()
conn.close()
if stale:
logger.info(f"prune_stale_links: removed {len(stale)} stale link(s) on {chassis_id}")
return len(stale)
def clear_stale_switches(since_dt):
"""Remove switches not seen since the given datetime string."""
conn = get_conn()