feat(isn): VLAN-4 routed sub-interface + addr on spine ISN ospfIf; ISN-CSW LLDP neighbor (v0.19.0)

Real ACI multi-site spines carry the OSPF address toward the ISN on a
routed sub-interface, not the bare port: ospfIf id/dn are now
eth1/{49+si}.4 with addr=172.16.{site}.{si+1}/24 (same /24 as the
existing .254 peer); ospfAdjEp nests under the sub-if. Each spine ISN
uplink physical port also gets an ISN-CSW lldpAdjEp/cdpAdjEp
(sysName ISN-CSW{site}, portIdV Ethernet1/{si+1}, model N9K-C9364C,
locally-administered 02:1B:0D MAC hashed from site.id). Single-site
fabrics build none of this. Closes the autoACI Fabric (physical) gap
where spine uplink rows showed blank Local IP / Neighbor Port.
908 tests green.
This commit is contained in:
dtzp555-max
2026-07-07 08:17:23 +10:00
parent ff838e2467
commit f6c95a0105
12 changed files with 257 additions and 21 deletions
+7 -1
View File
@@ -105,7 +105,7 @@ def test_fabric_links_reference_real_nodes(store, site_a):
# Test: LLDP/CDP neighbor set matches cabling graph
# ---------------------------------------------------------------------------
def test_lldp_cdp_matches_cabling(store, site_a):
def test_lldp_cdp_matches_cabling(store, site_a, topo):
"""lldpAdjEp sysName values on each node match what the cabling graph predicts."""
pod = site_a.pod
node_map = {n.id: n for n in site_a.all_nodes()}
@@ -124,6 +124,12 @@ def test_lldp_cdp_matches_cabling(store, site_a):
for leaf in site_a.leaf_nodes()[:2]:
expected_lldp.add((leaf.id, f"{site_a.name}-ACI-APIC{cid:02d}"))
# v0.19.0: multi-site fabrics also see the ISN CSW on each spine's
# dedicated uplink port (fabric.py's ISN-CSW add_adjacency block).
if len(topo.sites) > 1:
for spine in site_a.spine_nodes():
expected_lldp.add((spine.id, f"ISN-CSW{site_a.id}"))
actual_lldp: set[tuple[int, str]] = set()
for mo in store.by_class("lldpAdjEp"):
dn = mo.attrs["dn"]