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:
@@ -178,6 +178,36 @@ def upsert_link(chassis_a, port_a, chassis_b, port_b):
|
|||||||
conn.close()
|
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):
|
def clear_stale_switches(since_dt):
|
||||||
"""Remove switches not seen since the given datetime string."""
|
"""Remove switches not seen since the given datetime string."""
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
|
|||||||
+5
-1
@@ -4,7 +4,7 @@ import threading
|
|||||||
from nocodb_client import get_switches
|
from nocodb_client import get_switches
|
||||||
from ssh_client import scan_all_switches
|
from ssh_client import scan_all_switches
|
||||||
from db import (
|
from db import (
|
||||||
upsert_switch, upsert_link, clear_links,
|
upsert_switch, upsert_link, clear_links, prune_stale_links,
|
||||||
log_scan_start, log_scan_finish, merge_duplicate_switches
|
log_scan_start, log_scan_finish, merge_duplicate_switches
|
||||||
)
|
)
|
||||||
from parser import parse_neighbor_description
|
from parser import parse_neighbor_description
|
||||||
@@ -126,6 +126,10 @@ def run_scan(dept: str = None, workers: int = 5, login_delay: int = 3):
|
|||||||
chassis_b=neighbor["chassis_id"],
|
chassis_b=neighbor["chassis_id"],
|
||||||
port_b=neighbor["remote_port"],
|
port_b=neighbor["remote_port"],
|
||||||
)
|
)
|
||||||
|
prune_stale_links(
|
||||||
|
result["chassis_id"],
|
||||||
|
{(n["local_port"], n["chassis_id"]) for n in result["neighbors"]},
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
scan_state["fail"] += 1
|
scan_state["fail"] += 1
|
||||||
error = result.get("error", "Unknown error")
|
error = result.get("error", "Unknown error")
|
||||||
|
|||||||
Reference in New Issue
Block a user