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>
The node graph rendered empty because the edges target returned a
string mainstat ('iBGP'/'eBGP'). Grafana's nodeGraph treats edge
mainStat as numeric for layout/labelling; a string value silently
breaks the layout so no nodes are drawn (the working LS map and the
original ls_topo both cast edge mainstat to an integer).
Edge mainstat is now COUNT(DISTINCT feed)::int (BMP peer-feed count
for the router pair); the iBGP/eBGP label moves to secondarystat and
detail__session_type, which accept strings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the route-reflector membership test to
= ANY(ARRAY[${rr_loopbacks:singlequote}]::text[]) — the singlequote
format is the one already proven to interpolate correctly in this
Grafana instance (rr_locrib_diff uses it), and the ARRAY[...]::text[]
wrapper stays valid (empty array) when the variable resolves empty.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The protocol variable has includeAll enabled, so Grafana auto-quotes
its value ('IS-IS_L2'); the SQL then wrapped it again, producing
''IS-IS_L2'' and a syntax error that blanked the node graph. Replace
the quoted equality filter with IN ($protocol) — Grafana already
emits a quoted CSV — and make the variable multi-select so "All"
expands cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the rr_loopbacks variable resolved empty, the IN
(${rr_loopbacks:singlequote}) clause expanded to IN (), a SQL
syntax error that blanked the topology panel. Switch to
= ANY(string_to_array('${rr_loopbacks:csv}', ',')), which yields
a no-match (not a syntax error) on an empty variable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Create a new OBMP-Maps Grafana folder (folderUid 1006) with four
data-visualization dashboards built on nodeGraph and geomap panels:
- BGP Peer Map: routers as nodes, BGP sessions as edges; iBGP/eBGP
edge typing and operator-editable rr_loopbacks variable to denote
route reflectors; companion table for sessions to non-monitored
neighbours.
- IGP / Link-State Topology Map: reworked from LinkState-1004 and
moved here (uid preserved); scoped by peer feed / protocol / AS so
the 489-node BGP-LS topology stays readable; SR-capability rings.
- AS Relationship Map: AS adjacency graph from consecutive AS_PATH
pairs over a 200k-route sample; min-occurrence and focus-AS
variables; nodes enriched from info_asn whois.
- Geographic Prefix Map: geomap of RIB prefixes and origin ASes by
IP geolocation, with a note that lab 10.x loopbacks do not
geolocate; bounded geo_ip join via a sample-size variable.
Also add a data link on the Looking Glass ASN Info panel's origin_as
column that jumps to the ASN View dashboard scoped to that AS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>