Fix BGP Peer Map blank graph: connect disconnected lab components

The node graph rendered blank because the two CML/PROX labs formed
two disconnected components (iBGP-only meshes within each lab), and
Grafana's nodeGraph layout renders nothing for a disconnected graph.

Match BGP sessions to monitored routers by peer IP as well as peer
BGP-ID, so the real cross-lab eBGP sessions become graph edges. The
graph is now one connected component (30 iBGP + 4 eBGP edges) and
lays out. The companion external-neighbours table uses the same
peer-IP check so those sessions are no longer double-listed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
sam 2026-05-19 01:42:31 -07:00
parent 940f54c553
commit 0190ef5fb8

View File

@ -31,7 +31,7 @@
{ {
"datasource": {"type": "postgres","uid": "obmp_postgres"}, "datasource": {"type": "postgres","uid": "obmp_postgres"},
"format": "table", "format": "table",
"rawSql": "WITH rid AS (\n SELECT DISTINCT router_hash_id, host(localbgpid) AS bgpid\n FROM v_peers WHERE localbgpid IS NOT NULL\n),\nsess AS (\n SELECT\n LEAST(vp.router_hash_id, rid2.router_hash_id)::text AS a,\n GREATEST(vp.router_hash_id, rid2.router_hash_id)::text AS b,\n CASE WHEN vp.peerasn = vp.localasn THEN 'iBGP' ELSE 'eBGP' END AS kind,\n vp.peer_hash_id AS feed\n FROM v_peers vp\n JOIN rid rid2 ON rid2.bgpid = host(vp.peerbgpid)\n WHERE vp.peer_state = 'up' AND vp.router_hash_id <> rid2.router_hash_id\n)\nSELECT a || '-' || b AS id, a AS source, b AS target,\n COUNT(DISTINCT feed)::int AS mainstat,\n MAX(kind) AS secondarystat,\n MAX(kind) AS detail__session_type\nFROM sess GROUP BY a, b", "rawSql": "WITH rid AS (\n SELECT DISTINCT router_hash_id, host(localbgpid) AS bgpid\n FROM v_peers WHERE localbgpid IS NOT NULL\n),\nsess AS (\n SELECT\n LEAST(vp.router_hash_id, rid2.router_hash_id)::text AS a,\n GREATEST(vp.router_hash_id, rid2.router_hash_id)::text AS b,\n CASE WHEN vp.peerasn = vp.localasn THEN 'iBGP' ELSE 'eBGP' END AS kind,\n vp.peer_hash_id AS feed\n FROM v_peers vp\n JOIN rid rid2 ON rid2.bgpid = host(vp.peerbgpid) OR rid2.bgpid = host(vp.peerip)\n WHERE vp.peer_state = 'up' AND vp.router_hash_id <> rid2.router_hash_id\n)\nSELECT a || '-' || b AS id, a AS source, b AS target,\n COUNT(DISTINCT feed)::int AS mainstat,\n MAX(kind) AS secondarystat,\n MAX(kind) AS detail__session_type\nFROM sess GROUP BY a, b",
"refId": "edges" "refId": "edges"
} }
], ],
@ -52,7 +52,7 @@
{ {
"datasource": {"type": "postgres","uid": "obmp_postgres"}, "datasource": {"type": "postgres","uid": "obmp_postgres"},
"format": "table", "format": "table",
"rawSql": "SELECT vp.routername AS \"Router\",\n host(vp.peerip) AS \"Peer\",\n vp.peerasn AS \"Peer AS\",\n CASE WHEN vp.peerasn = vp.localasn THEN 'iBGP' ELSE 'eBGP' END AS \"Type\",\n vp.peer_state AS \"State\"\nFROM v_peers vp\nWHERE vp.peer_state = 'up'\n AND NOT EXISTS (SELECT 1 FROM v_peers r WHERE host(r.localbgpid) = host(vp.peerbgpid))\nORDER BY vp.routername, vp.peerip", "rawSql": "SELECT vp.routername AS \"Router\",\n host(vp.peerip) AS \"Peer\",\n vp.peerasn AS \"Peer AS\",\n CASE WHEN vp.peerasn = vp.localasn THEN 'iBGP' ELSE 'eBGP' END AS \"Type\",\n vp.peer_state AS \"State\"\nFROM v_peers vp\nWHERE vp.peer_state = 'up'\n AND NOT EXISTS (SELECT 1 FROM v_peers r WHERE host(r.localbgpid) = host(vp.peerbgpid) OR host(r.localbgpid) = host(vp.peerip))\nORDER BY vp.routername, vp.peerip",
"refId": "A" "refId": "A"
} }
], ],