Fix PromQL regex escaping for hyphenated hostnames
re.escape() escapes '-' as '\-', which Python's regex engine accepts but PromQL's RE2 engine rejects outright (every hostname in this lab is hyphenated, e.g. dc-leaf1). All 4 panel targets were failing with "unknown escape sequence U+002D" until now. Also swaps the dashboard to the newly-created NetLab datasource, which actually has gnmic data (the previously-wired external Prometheus datasource had none). Refs #48
This commit is contained in:
@@ -24,43 +24,43 @@
|
|||||||
},
|
},
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "aflu2t514uf40a"
|
"uid": "cfrlusac89se8a"
|
||||||
},
|
},
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
"refId": "A",
|
"refId": "A",
|
||||||
"expr": "min by (device) (network_instances_network_instance_protocols_protocol_bgp_neighbors_neighbor_state_session_state{network_instance_name=\"default\", device=~\"campus\\-spine1|dc\\-spine1|dc\\-spine2|campus\\-spine2|campus\\-border\\-leaf1|dc\\-leaf1|campus\\-border\\-leaf2|dc\\-leaf4|dc\\-leaf3|dc\\-leaf5|dc\\-border\\-leaf1|dc\\-leaf6|dc\\-access1|dc\\-access2|dc\\-leaf8|dc\\-leaf7|dc\\-access4|dc\\-access3|dc\\-border\\-leaf2|dc\\-leaf2|campus\\-leaf1|campus\\-access1|campus\\-leaf2|campus\\-leaf3|campus\\-access2|campus\\-leaf4|core1|core2\"})",
|
"expr": "min by (device) (network_instances_network_instance_protocols_protocol_bgp_neighbors_neighbor_state_session_state{network_instance_name=\"default\", device=~\"campus-spine1|dc-spine1|dc-spine2|campus-spine2|campus-border-leaf1|dc-leaf1|campus-border-leaf2|dc-leaf4|dc-leaf3|dc-leaf5|dc-border-leaf1|dc-leaf6|dc-access1|dc-access2|dc-leaf8|dc-leaf7|dc-access4|dc-access3|dc-border-leaf2|dc-leaf2|campus-leaf1|campus-access1|campus-leaf2|campus-leaf3|campus-access2|campus-leaf4|core1|core2\"})",
|
||||||
"legendFormat": "BGP {{device}}",
|
"legendFormat": "BGP {{device}}",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "aflu2t514uf40a"
|
"uid": "cfrlusac89se8a"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "B",
|
"refId": "B",
|
||||||
"expr": "rate(interfaces_interface_state_counters_out_octets{device=~\"campus\\-spine1|dc\\-spine1|dc\\-spine2|campus\\-spine2|campus\\-border\\-leaf1|dc\\-leaf1|campus\\-border\\-leaf2|dc\\-leaf4|dc\\-leaf3|dc\\-leaf5|dc\\-border\\-leaf1|dc\\-leaf6|dc\\-access1|dc\\-access2|dc\\-leaf8|dc\\-leaf7|dc\\-access4|dc\\-access3|dc\\-border\\-leaf2|dc\\-leaf2|campus\\-leaf1|campus\\-access1|campus\\-leaf2|campus\\-leaf3|campus\\-access2|campus\\-leaf4|core1|core2\", interface=~\"Ethernet1|Ethernet10|Ethernet11|Ethernet12|Ethernet13|Ethernet14|Ethernet2|Ethernet3|Ethernet4|Ethernet5|Ethernet6|Ethernet7|Ethernet8|Ethernet9\"}[5m]) * 8",
|
"expr": "rate(interfaces_interface_state_counters_out_octets{device=~\"campus-spine1|dc-spine1|dc-spine2|campus-spine2|campus-border-leaf1|dc-leaf1|campus-border-leaf2|dc-leaf4|dc-leaf3|dc-leaf5|dc-border-leaf1|dc-leaf6|dc-access1|dc-access2|dc-leaf8|dc-leaf7|dc-access4|dc-access3|dc-border-leaf2|dc-leaf2|campus-leaf1|campus-access1|campus-leaf2|campus-leaf3|campus-access2|campus-leaf4|core1|core2\", interface=~\"Ethernet1|Ethernet10|Ethernet11|Ethernet12|Ethernet13|Ethernet14|Ethernet2|Ethernet3|Ethernet4|Ethernet5|Ethernet6|Ethernet7|Ethernet8|Ethernet9\"}[5m]) * 8",
|
||||||
"legendFormat": "{{device}} {{interface}} tx",
|
"legendFormat": "{{device}} {{interface}} tx",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "aflu2t514uf40a"
|
"uid": "cfrlusac89se8a"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "C",
|
"refId": "C",
|
||||||
"expr": "rate(interfaces_interface_state_counters_in_octets{device=~\"campus\\-spine1|dc\\-spine1|dc\\-spine2|campus\\-spine2|campus\\-border\\-leaf1|dc\\-leaf1|campus\\-border\\-leaf2|dc\\-leaf4|dc\\-leaf3|dc\\-leaf5|dc\\-border\\-leaf1|dc\\-leaf6|dc\\-access1|dc\\-access2|dc\\-leaf8|dc\\-leaf7|dc\\-access4|dc\\-access3|dc\\-border\\-leaf2|dc\\-leaf2|campus\\-leaf1|campus\\-access1|campus\\-leaf2|campus\\-leaf3|campus\\-access2|campus\\-leaf4|core1|core2\", interface=~\"Ethernet1|Ethernet10|Ethernet11|Ethernet12|Ethernet13|Ethernet14|Ethernet2|Ethernet3|Ethernet4|Ethernet5|Ethernet6|Ethernet7|Ethernet8|Ethernet9\"}[5m]) * 8",
|
"expr": "rate(interfaces_interface_state_counters_in_octets{device=~\"campus-spine1|dc-spine1|dc-spine2|campus-spine2|campus-border-leaf1|dc-leaf1|campus-border-leaf2|dc-leaf4|dc-leaf3|dc-leaf5|dc-border-leaf1|dc-leaf6|dc-access1|dc-access2|dc-leaf8|dc-leaf7|dc-access4|dc-access3|dc-border-leaf2|dc-leaf2|campus-leaf1|campus-access1|campus-leaf2|campus-leaf3|campus-access2|campus-leaf4|core1|core2\", interface=~\"Ethernet1|Ethernet10|Ethernet11|Ethernet12|Ethernet13|Ethernet14|Ethernet2|Ethernet3|Ethernet4|Ethernet5|Ethernet6|Ethernet7|Ethernet8|Ethernet9\"}[5m]) * 8",
|
||||||
"legendFormat": "{{device}} {{interface}} rx",
|
"legendFormat": "{{device}} {{interface}} rx",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "aflu2t514uf40a"
|
"uid": "cfrlusac89se8a"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "D",
|
"refId": "D",
|
||||||
"expr": "count by (device, vlan) (network_instances_network_instance_fdb_mac_table_entries_entry_vlan{device=~\"campus\\-leaf1|campus\\-leaf2|campus\\-leaf3|campus\\-leaf4|dc\\-leaf1|dc\\-leaf2|dc\\-leaf5|dc\\-leaf6\"})\n* on(device, vlan) group_left(vlan_to_vni_state_vni)\ninterfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{device=~\"campus\\-leaf1|campus\\-leaf2|campus\\-leaf3|campus\\-leaf4|dc\\-leaf1|dc\\-leaf2|dc\\-leaf5|dc\\-leaf6\"}",
|
"expr": "count by (device, vlan) (network_instances_network_instance_fdb_mac_table_entries_entry_vlan{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"})\n* on(device, vlan) group_left(vlan_to_vni_state_vni)\ninterfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"}",
|
||||||
"legendFormat": "VNI {{device}} {{vlan}}",
|
"legendFormat": "VNI {{device}} {{vlan}}",
|
||||||
"datasource": {
|
"datasource": {
|
||||||
"type": "prometheus",
|
"type": "prometheus",
|
||||||
"uid": "aflu2t514uf40a"
|
"uid": "cfrlusac89se8a"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -149,6 +149,15 @@ def alias_interface(ipf_name):
|
|||||||
return f"{full}{rest}"
|
return f"{full}{rest}"
|
||||||
|
|
||||||
|
|
||||||
|
def promql_escape(s):
|
||||||
|
"""re.escape() escapes '-' as '\\-', which Python's own regex engine
|
||||||
|
accepts but PromQL's RE2-based engine rejects ("unknown escape sequence
|
||||||
|
U+002D '-'") -- and every hostname in this lab contains hyphens. '-' is
|
||||||
|
not a regex metacharacter outside a character class, so it's safe to
|
||||||
|
leave unescaped."""
|
||||||
|
return re.escape(s).replace("\\-", "-")
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# Topology processing
|
# Topology processing
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@@ -211,7 +220,7 @@ def dedupe_links(connectivity_matrix):
|
|||||||
|
|
||||||
def build_weathermap(devices, links, interface_speeds, positions, prometheus_url, mismatches):
|
def build_weathermap(devices, links, interface_speeds, positions, prometheus_url, mismatches):
|
||||||
hostnames = [d["hostname"] for d in devices]
|
hostnames = [d["hostname"] for d in devices]
|
||||||
host_regex = "|".join(re.escape(h) for h in hostnames)
|
host_regex = "|".join(promql_escape(h) for h in hostnames)
|
||||||
|
|
||||||
known_pairs = known_interface_pairs(prometheus_url)
|
known_pairs = known_interface_pairs(prometheus_url)
|
||||||
vtep_vlan_pairs = known_vtep_vlan_pairs(prometheus_url)
|
vtep_vlan_pairs = known_vtep_vlan_pairs(prometheus_url)
|
||||||
@@ -259,8 +268,8 @@ def build_weathermap(devices, links, interface_speeds, positions, prometheus_url
|
|||||||
for link in links:
|
for link in links:
|
||||||
a_gnmic_int = resolve_and_check(link["a_host"], link["a_int"], "side A")
|
a_gnmic_int = resolve_and_check(link["a_host"], link["a_int"], "side A")
|
||||||
z_gnmic_int = resolve_and_check(link["z_host"], link["z_int"], "side Z")
|
z_gnmic_int = resolve_and_check(link["z_host"], link["z_int"], "side Z")
|
||||||
interface_regex_parts.add(re.escape(a_gnmic_int))
|
interface_regex_parts.add(promql_escape(a_gnmic_int))
|
||||||
interface_regex_parts.add(re.escape(z_gnmic_int))
|
interface_regex_parts.add(promql_escape(z_gnmic_int))
|
||||||
|
|
||||||
a_bw = interface_speeds.get((link["a_host"], link["a_int"]), DEFAULT_LINK_BANDWIDTH_BPS)
|
a_bw = interface_speeds.get((link["a_host"], link["a_int"]), DEFAULT_LINK_BANDWIDTH_BPS)
|
||||||
z_bw = interface_speeds.get((link["z_host"], link["z_int"]), DEFAULT_LINK_BANDWIDTH_BPS)
|
z_bw = interface_speeds.get((link["z_host"], link["z_int"]), DEFAULT_LINK_BANDWIDTH_BPS)
|
||||||
@@ -311,7 +320,7 @@ def build_weathermap(devices, links, interface_speeds, positions, prometheus_url
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
if vtep_hosts:
|
if vtep_hosts:
|
||||||
vtep_regex = "|".join(re.escape(h) for h in vtep_hosts)
|
vtep_regex = "|".join(promql_escape(h) for h in vtep_hosts)
|
||||||
# Verbatim join from #44 "VXLAN (MAC count per VNI)", scoped to VTEP nodes.
|
# Verbatim join from #44 "VXLAN (MAC count per VNI)", scoped to VTEP nodes.
|
||||||
targets.append({
|
targets.append({
|
||||||
"refId": "D",
|
"refId": "D",
|
||||||
|
|||||||
Reference in New Issue
Block a user