Skip to content

Commit

Permalink
docs: update TAC webinar03
Browse files Browse the repository at this point in the history
Change-Id: I82d8ba6d96ab8403137ac493ea96e4ff2a1fcfff
  • Loading branch information
noredistribution committed Sep 4, 2024
1 parent 8555880 commit ec05318
Show file tree
Hide file tree
Showing 10 changed files with 317 additions and 232 deletions.
36 changes: 32 additions & 4 deletions docsrc/examples/layer2_and_layer3/webinar03_bgp.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
TAC Webinar03 2023 - BGP States
-------------------------------

This dashboards helps to provide current and historical BGP status and provides link flap counters.

.. note::
Some of the BGP states are not streamed by default and the ``/Smash/routing/bgp/bgpPeerInfoStatus/default/bgpPeerStatisticsEntry`` needs to be added to the TerminAttr include list using the tastreaming.TerminattrStreaming service API.
Examples can be found `here <../../index_examples.html#terminattrstreamingpermitlistnote>`_

Pre-requisites
^^^^^^^^^^^^^^

* Devices will need to be tagged with tag label ``site_name`` and the label value of the site's name, for example a customer has 3 sites: ABC, DEF, XYZ

* Tag ``site_name:ALL`` to all devices
* Tag ``site_name:ABC`` to ABC devices
* repeat for DEF and XYZ

* Devices with multiple supervisors upon supervisor failover might not show the correct states

BGP Summary
^^^^^^^^^^^

.. literalinclude:: webinar03_bgp_states_bgp_sum.aql
:language: aql

.. image:: webinar03_bgp1.png
:width: 600
:alt: IBGP Summary
:width: 1400
:alt: BGP Summary
:align: center

.. image:: webinar03_bgp1_2.png
:width: 1400
:alt: BGP Summary2
:align: center

.. image:: webinar03_bgp1_3.png
:width: 1400
:alt: BGP Summary23
:align: center

BGP Sessions Flaps
^^^^^^^^^^^^^^^^^^
Expand All @@ -24,7 +52,7 @@ BGP Historical state tracker
:language: aql

.. image:: webinar03_bgp2.png
:width: 600
:width: 1400
:alt: BGP Flaps and Historical state tracker

BGP Syslog Messages
Expand All @@ -34,7 +62,7 @@ BGP Syslog Messages
:language: aql

.. image:: webinar03_bgp3.png
:width: 600
:width: 1400
:alt: BGP Syslog Messages

:download:`Download the Dashboard JSON here <webinar03_bgp_states.json>`
Binary file modified docsrc/examples/layer2_and_layer3/webinar03_bgp1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
333 changes: 162 additions & 171 deletions docsrc/examples/layer2_and_layer3/webinar03_bgp_states.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
let devices = merge(`analytics:/tags/labels/devices/pod_name/value/<_POD_NAME>/elements`)

if str(_POD_NAME) == "" {
let data =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/default/bgpPeerInfoStatusEntry/*`[4h]
} else {
let data =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/default/bgpPeerInfoStatusEntry/*`[4h] | where(dictHasKey(devices, complexKey("{\"deviceID\": \""+_key+"\"}")))
}

let data =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/default/bgpPeerInfoStatusEntry/*`[24h]
let devices = merge(`analytics:/tags/labels/devices/site_name/value/<_SITE_NAME>/elements`)
let data = data | where(dictHasKey(devices, complexKey("{\"deviceID\": \""+_key+"\"}")))
let result = newDict()
for sn, deviceValues in data{
let count = 0
for ip, tseries in deviceValues{
for timestamp, values in tseries {
if dictHasKey(values, "bgpState"){
if values["bgpState"]["Name"] == "Established"{
let count = count +1

for device, deviceValues in data {
let establishedNeighbors = newDict()
let flapCount = 0
for ip, tseries in deviceValues{
for timestamp, values in tseries {
if dictHasKey(values, "bgpState"){
if values["bgpState"]["Name"] == "Established"{
let flapCount = flapCount +1
establishedNeighbors[ip] = true
}
}
}
}
}
result[sn] = newDict() | setFields("Flaps", count-1)
let count = flapCount - length(establishedNeighbors)
if count > 0 {
result[device] = newDict() | setFields("Flaps", count )
}

}

result
96 changes: 63 additions & 33 deletions docsrc/examples/layer2_and_layer3/webinar03_bgp_states_bgp_sum.aql
Original file line number Diff line number Diff line change
@@ -1,48 +1,78 @@
let devices = merge(`analytics:/tags/labels/devices/pod_name/value/<_POD_NAME>/elements`)
let bgpPeerInfoStatusEntry = `*:/Sysdb/cell/1/routing/bgp/export/vrfBgpPeerInfoStatusEntryTable/default/bgpPeerInfoStatusEntry/*`
if str(_POD_NAME) == "" {
let bgpNeighbors =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/default/bgpPeerInfoStatusEntry/*`
} else {
let bgpNeighbors =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/default/bgpPeerInfoStatusEntry/*` | where(dictHasKey(devices, complexKey("{\"deviceID\": \""+_key+"\"}")))
}
let bgpPeerStatisticsEntry = `*:/Smash/routing/bgp/bgpPeerInfoStatus/default/bgpPeerStatisticsEntry`
# set vars
let afis = newDict()
let afi_name = newDict()
let bgpPeerAfiSafiActive = newDict() | setFields("l2vpnEvpn", 3, "ipv4Unicast", 1)
let bgpPeerAfiSafiActiveName = newDict() | setFields("l2vpnEvpn","L2VPN EVPN", "ipv4Unicast", "IPv4 Unicast")

# Get all devices from a specific site
let devices = merge(`analytics:/tags/labels/devices/site_name/value/<_SITE_NAME>/elements`)

let bgpNeighbors =`analytics:/Devices/*/versioned-data/routing/bgp/status/vrf/*/bgpPeerInfoStatusEntry/*`
if _device != "" {
let bgpNeighbors = bgpNeighbors | fields(_device)
} else {
if str(_SITE_NAME) != "" {
let bgpNeighbors = bgpNeighbors | where(dictHasKey(devices, complexKey("{\"deviceID\": \""+_key+"\"}")))
}
}

let bgpPeerInfoStatusEntry = `*:/Sysdb/cell/1/routing/bgp/export/vrfBgpPeerInfoStatusEntryTable/*/bgpPeerInfoStatusEntry/*`
let bgpPeerStatisticsEntry = `*:/Smash/routing/bgp/bgpPeerInfoStatus/*/bgpPeerStatisticsEntry`

# This is the table
let result = newDict()
let id = 0
# Lets loop over every device
for device, deviceSessions in bgpNeighbors{
for deviceKey, deviceSessions in bgpNeighbors{
# And each session on the devices
for ip, sessionData in deviceSessions{
let data = merge(sessionData)
# Add one to the ID
let id = id + 1
result[id] = newDict()
# This is where we add the various columns
result[id]["0. Device"] = device
result[id]["1. Status"] = data["bgpState"]["Name"]
result[id]["2. Peering Address"] = data["bgpPeerLocalAddr"]
result[id]["3. Neighbor Address"] = data["key"]
result[id]["4. Neighbor AS"] = data["bgpPeerAs"]["value"]
if dictHasKey(bgpPeerInfoStatusEntry, device) && dictHasKey(bgpPeerStatisticsEntry, device) {
let test = merge(bgpPeerInfoStatusEntry[device][ip])
for kafi, kval in test["bgpPeerAfiSafiActive"]{
if kval == true {
afis[device] = bgpPeerAfiSafiActive[kafi]
afi_name[device] = bgpPeerAfiSafiActiveName[kafi]
if _device == "" || deviceKey == _device {
for vrfKey, vrfValue in deviceSessions{
# Check if _vrf is empty or if the current vrfKey is in _vrf
if length(_vrf) == 0 || _vrf == vrfKey {
for ip, sessionData in vrfValue {
let data = merge(sessionData)
# Add one to the ID
let id = id + 1
result[id] = newDict()
# This is where we add the various columns
result[id]["0. Device"] = deviceKey
result[id]["1. Status"] = data["bgpState"]["Name"]
result[id]["2. Peering Address"] = data["bgpPeerLocalAddr"]
result[id]["3. Neighbor Address"] = data["key"]
result[id]["4. Neighbor AS"] = data["bgpPeerAs"]["value"]
result[id]["6. VRF"] = vrfKey
if dictHasKey(bgpPeerInfoStatusEntry, deviceKey) && dictHasKey(bgpPeerStatisticsEntry, deviceKey) {
if dictHasKey(bgpPeerInfoStatusEntry[deviceKey], vrfKey) {
let test = merge(bgpPeerInfoStatusEntry[deviceKey][vrfKey][ip])
for kafi, kval in test["bgpPeerAfiSafiActive"]{
if kval == true {
afis[deviceKey] = bgpPeerAfiSafiActive[kafi]
afi_name[deviceKey] = bgpPeerAfiSafiActiveName[kafi]
result[id]["7. AFI/SAFI"] = afi_name[deviceKey]
}
}
result[id]["5. Peer Description"] = test["bgpPeerDescription"]
}
if dictHasKey(bgpPeerStatisticsEntry[deviceKey], vrfKey) {
let bgpPeerAfiSafiStats = merge(bgpPeerStatisticsEntry[deviceKey][vrfKey])
if dictHasKey(afis, deviceKey) && dictHasKey(bgpPeerAfiSafiStats, ip){
result[id]["8. PfxRcd"] = bgpPeerAfiSafiStats[ip]["bgpPeerAfiSafiStats"][afis[deviceKey]]["prefixIn"]
result[id]["9. PfxAcc"] = bgpPeerAfiSafiStats[ip]["bgpPeerAfiSafiStats"][afis[deviceKey]]["prefixAcceptedIn"]
}
}


} else {
# need to figure out why sometimes there's no prefix info
result[id]["8. PfxRcd"] = "N/A"
result[id]["9. PfxAcc"] = "N/A"
}
if dictHasKey(data, "bgpPeerIntoOrOutOfEstablishedTime") {
result[id]["10. Up/Down"] = str(duration(1000000000*round(num(now() - time(data["bgpPeerIntoOrOutOfEstablishedTime"]*1000000000))/1000000000)))
}
}
}
let bgpPeerAfiSafiStats = merge(bgpPeerStatisticsEntry[device])
if dictHasKey(afis, device){
result[id]["6. PfxRcd"] = bgpPeerAfiSafiStats[ip]["bgpPeerAfiSafiStats"][afis[device]]["prefixIn"]
result[id]["7. PfxAcc"] = bgpPeerAfiSafiStats[ip]["bgpPeerAfiSafiStats"][afis[device]]["prefixAcceptedIn"]
}
result[id]["8. Up/Down"] = str(duration(1000000000*round(num(now() - time(data["bgpPeerIntoOrOutOfEstablishedTime"]*1000000000))/1000000000)))
}
}
}
result
result
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let data = `<_bgpDevice>:/Logs/var/log/messages`[4h] | field("line") | where(reMatch(_value, "BGP"))
let data = `<_bgpDevice>:/Logs/var/log/messages`[48h] | field("line") | where(reMatch(_value, "BGP"))
let logs = newDict()
for timest, logentry in data {
logs[str(timest)] = newDict()
logs[str(timest)]["Log"] = logentry
logs[str(timest+(_tz_offset))] = newDict()
logs[str(timest+(_tz_offset))]["Log"] = logentry
}
logs
logs
39 changes: 36 additions & 3 deletions docsrc/index_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,42 @@ AQL Examples
.. _terminattrStreamingPermitlistNote:

.. note::
Some telemetry states are not streamed by default and they would need to be added to the TerminAttr include list using the tastreaming.TerminattrStreaming service API, e.g.:
Some telemetry states are not streamed by default and they would need to be added to the TerminAttr include list using the tastreaming.TerminattrStreaming service API, which can be done either through the UI or through the CLI e.g.:

On-prem example:
Using the Service Explorer UI:

1. Access Service Explorer by going to https://x.x.x.x/cv/settings/service-explorer , where x.x.x.x is the CVP IP/FQDN or the CVaaS regional URL

2. Fill out the request:

Service Name: ``tastreaming.TerminattrStreaming``

Method Name: ``SubscribeTAPaths``

3. Copy and paste like the screen below:

Parameters:

::

{
"filter": {
"app_name": "allowbgpstates",
"include_paths": ["/Smash/routing/bgp/bgpPeerInfoStatus/default/bgpPeerStatisticsEntry"],
"exclude_paths": []
}
}

4. Click on ``Send Request`` and check on the right hand side that the result is ``root: {} 0 keys``.

.. image:: service_explorer_example.png
:width: 1400
:alt: Service Explorer Example
:align: center

Alternatively, you can use the CLI to add the path to the TerminAttr include list using a cURL request.

On-prem cURL example:

::

Expand All @@ -23,7 +56,7 @@ AQL Examples

-d '{ "filter": { "app_name": "app1", "include_paths": [ "/Sysdb/bridging/igmpsnooping" ]}}'

CVaaS example:
CVaaS cURL example:

::

Expand Down
Binary file added docsrc/service_explorer_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ec05318

Please sign in to comment.