Problem Statement
Our company had issues where some network leafs were not connected to all our spines within an ACI fabric.Traditional methods to validate this were time consuming so we developed a basic NQE query to assist.
How it works
we leverage the LLDP information for the network leaves and match this to our spines. In our case, we rely on the device naming convention to match LLDP entries to spines. Our spines have SP within the name.
NQE Script
Function to gather the links to spines for a given device
/*
* function: countSpineNeighbours
*
* parameters: device: Device
*
* purpose
* -------
*
* count the number of links that are between the spines and the leafs
*
* spines are matched based on the SP in the device name, at position 8
*
* returns: dict
*
* {
* deviceName: string
* interfaceName: string
* }
*/
countSpineNeighbours(device) =
foreach interface in device.interfaces
where interface.interfaceType == IfaceType.IF_ETHERNET
foreach n in interface.lldp.neighbors
where length(n.deviceName) >= 10 && substring(n.deviceName, 8, 10) == "SP"
select {
deviceName: n.deviceName,
intefaceName: interface.name
};
Main script iterates over all devices, picking out any leaf nodes based on a tags, device type and naming convention. These are then processed using the function countSpineNeighbours to see if there are 3 spines connected. Anything other than 3 is a violation.
foreach device in network.devices
where device.platform.vendor == Vendor.CISCO &&
device.platform.deviceType == DeviceType.SWITCH &&
"deviceType:fabric" in device.tagNames &&
length(device.name) >= 10 &&
substring(device.name, 8, 10) == "SL"
let spines = countSpineNeighbours(device)
let violation = length(spines) != 3
let violationReason = if violation
then join(" ", toString(3 - length(spines)),
"misisng link(s) from spines to leaf",
device.name
])
else ""
select {
device: device.name,
connectedSpines: (foreach spine in spines
select spine.deviceName),
count: length(spines),
violation: length(spines) != 3,
violationReason: violationReason
}
Extension
Be great to see how this could be extended to identify the missing spines name.