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>
This commit is contained in:
2026-05-13 17:49:47 +00:00
parent 237c45ddfc
commit 75d4eeb062
+19 -6
View File
@@ -96,19 +96,32 @@ def upsert_switch(chassis_id, hostname, mgmt_ip, description, firmware='', vendo
conn.close()
def _port_num(port):
"""Trailing port digit(s): 'Gi1/9''9', 'Te1/10''10', '9''9'."""
m = re.search(r'(\d+)$', (port or '').strip())
return m.group(1) if m else (port or '').strip()
def upsert_link(chassis_a, port_a, chassis_b, port_b):
# Normalize order so A→B and B→A are treated as the same link
if chassis_a > chassis_b:
chassis_a, chassis_b = chassis_b, chassis_a
port_a, port_b = port_b, port_a
conn = get_conn()
# Check both orderings before inserting
# Exact match first
existing = conn.execute("""
SELECT id FROM links WHERE
(chassis_a=? AND port_a=? AND chassis_b=? AND port_b=?) OR
(chassis_a=? AND port_a=? AND chassis_b=? AND port_b=?)
""", (chassis_a, port_a, chassis_b, port_b,
chassis_b, port_b, chassis_a, port_a)).fetchone()
SELECT id FROM links WHERE chassis_a=? AND port_a=? AND chassis_b=? AND port_b=?
""", (chassis_a, port_a, chassis_b, port_b)).fetchone()
if not existing:
# Fuzzy match: same chassis pair, same trailing port numbers
# handles 'Gi1/9' vs '9' reported by different vendors for the same cable
rows = conn.execute("""
SELECT port_a, port_b FROM links WHERE chassis_a=? AND chassis_b=?
""", (chassis_a, chassis_b)).fetchall()
for r in rows:
if _port_num(port_a) == _port_num(r[0]) and _port_num(port_b) == _port_num(r[1]):
existing = True
break
if not existing:
conn.execute("""
INSERT OR IGNORE INTO links (chassis_a, port_a, chassis_b, port_b)