Find answers to your NQE questions and share NQEs you've developed.
Recently active
Using the same logic in my previous post to grab ip helper addresses, I was thinking what else could I re-use this kind of script to grab, and it was for our OSPF configuration. If you are configuring OSPF type/timers/intervals/cost on interfaces, you can use this script to grab the values on each interface. This will make it easy to set up a violation check for anyone that wants. What would be ideal is if I could group the interfaces per devicehost-XYZ. intf1: Type: DeadInterval: HelloInterval: Load : Cost intf2: Type: DeadInterval: HelloInterval: Load : Cost intf3: Type: DeadInterval: HelloInterval: Load : Costhost-ABC. intf1: Type: DeadInterval: HelloInterval: Load : Cost intf2: Type: DeadInterval: HelloInterval: Load : Cost intf3: Type: DeadInterval: HelloInterval: Load : Cost // standard config// interface {ifaceName:string}// ip ospf network point-to-point// ip ospf dead-interval 20// ip ospf h
when going through devices with interface descriptions, for exampledescription “to site x interface gi0/0”;description “to site y interfaace gi0/1”:block pattern is description {desc:string}Since it is a description with multiple words and space delimited, is there a way to get the entire description no matter how many words there are? As the above would only get the first word.similar to the way I would use grep for example:grep '^description' ciscoconfig.txtor if I wanted specific columns or text within lines beginning with description, I would grep and use awk like belowgrep '^description' ciscoconfig.txt | awk '{print $2}'grep '^description' ciscoconfig.txt | awk '{print $2 $4}'grep '^description' ciscoconfig.txt | awk '{print $4 $2}'Etc.can anybody provide an NQE Example, Thanks
The API can be used to perform most functions available in the GUI. To perform complex queries of data in the API, it is necessary to insert an NQE query into the API call, or reference an existing NQE query in the Repository.In this example, we first create an NQE query in the Org Repository called list-interfaces. This NQE query will iterate through each device, interface, and sub-interface and list the IP addresses and MAC addresses for each interface.foreach device in network.devicesforeach interface in device.interfacesforeach subinterface in interface.subinterfaceslet ipv4 = subinterface.ipv4foreach address in ipv4.addressesselect { deviceName: device.name, interfaceName: interface.name, subinterfaceName: subinterface.name, ip: ipSubnet(address.ip, address.prefixLength), macAddress: interface.ethernet.macAddress}The output of the NQE in the GUI looks like this: In order to access this information via the API, you must first commit the query. Then get the Query ID and the Com
Using NQE to do Configurations Compliance checks require having the proper structure for the searched text pattern.Ex: this will not match eventhough that line exists within the configurations, but it’s not in the root levelPATTERN=```set admintimeout 10```;So, to match this line we have to provide the proper structure, or recusively add an extra level until a match is foundSo, modifing that example to one of the below patterns should workPATTERN1=```config system global set admintimeout 10```;PATTERN2=```{(string)+} set admintimeout 10```;So, in this example it was only 1 level down, so it’s straight forward to fix.But having to work with different patterns with different nesting levels the below code can be used to automatically modify the provided pattern and recursively search all the different levels Beware that there are many limitations due to the actual version of the language.ex: splitting a string is not straight forward, so the pattern has to be provided as a list of strings
One of my colleagues told me that some of our devices had licence issues.output from show licence usage shows the issue easily, so custom command is the way to go SOMEDEVICE# show license usageFeature Ins Lic Status Expiry Date Comments Count--------------------------------------------------------------------------------….NXOS_ESSENTIALS_M4 No - Unused - -FC_PORT_ACTIVATION_PKG No 0 Unused -LAN_ENTERPRISE_SERVICES_PKG No - In use Honor Start 70D 15H-------------------------------------------------------------------------------- The key part is to extract the features for the device, and check that the No is present, with In Use also present.This is done via the following function, which determines valid input and detects violation.blockData =```{feature:string} {active:string} {licenceCount:string} {status:string}```;customCommand = "show license usage";getRe
For the networks I work on there are a lot of different servers, mainly due to environmental conditions such as NAT that are used for the basic management of the devices. This include authentication, snmp-traps, ntp, syslog and so on.The following code allows us to see at a glance all the unique servers ip addresses, along with a reference to each device being used.It’s very easy to list this as individual records, but sometimes it’s nice to consolidate this to show the number of servers, and how many devices are using them. One such use case, may be when moving device from old/demising servers to new servers.This script is a skeleton for Tacacs, it does not deal with the various different command syntax across the various vendors and is just shown as an example. In this case for Cisco.Firstly a function to get the information from each device, namely the authentication server and the device name.getTacacsDeviceEntry(device) = foreach match in patternMatches(device.files.config, `t
Hello,With the actual version of NQE not providing direct way to initialise an Empty list ex:let empty_list = []orempty_list = [] A workaround for this is to construct the creation of that list and providing a value with the same data type you need// an empty List<String>FALLBACK =foreach x in [""]where x != ""select x; // an empty list of NumbersFALLBACK_NUMBERS=foreach x in [0]where x != 0select x; Taking this logic further we can create a function that provides us an empty list of whatever generic type. by taking a default value of that type as an input, then comparing against that value The below block contains the full PoC code// an empty List<String>FALLBACK =foreach x in [""]where x != ""select x;// an empty list of NumbersFALLBACK_NUMBERS=foreach x in [0]where x != 0select x;// An empty list of a generic type TemptyListT(default_val)=foreach x in [default_val]where x != default_valselect x;foreach a in [""]let empty_list_of_strings = FALLBACKlet empty_list_of_number
As part of doing configuration audits for our NX-OS devices, I needed a check to see if two conditions were met in a configuration to check compliance.If both conditions were present → GoodIf one condition was met and the other wasn’t → BADElse if → Both conditions were not present → Also good.This is relatively simple with a single condition, but adding another variable, kind of stumped me. Credit to Glen Turner @FN for solving the logic puzzle on this.The example below is for OSPF enabled and SNMP traps for OSPF is enabled. This logic can be used for many other two condition checks such as //VarsPatternNetFlow = ```feature netflow```;PatternNetFlow_Config = ```flow timeout active 60```;//FunctionsCheckPattern(config , pattern) = !hasBlockMatch(config, pattern);&& //VarsPatternBFD = ```feature bfd```;PatternBFD_Config = ```bfd interval 300 min_rx 300 multiplier 3```;//FunctionsCheckPattern(config , pattern) = !hasBlockMatch(config, pattern); /** * @intent Ensure DC NX-OS Devic
I have a problem where the two lines of this module output are not the same. How can I put in essentially null place holders so that they resultant patterns are the "same"?example outputNotice that module 2 does not have Fw or Sw.Mod MAC addresses Hw Fw Sw Status 1 a03d.6f81.0740 to a03d.6f81.074f 1.1 15.0(1r)SG12 03.07.03.E Ok 2 b0aa.777d.d010 to b0aa.777d.d017 1.0 Ok I was trying to use these two patterns and tried to put in placeholds of Fw and Sw at the end of "pattern03". But the NQE does not like this.pattern02 = ```Mod MAC addresses {modNum:number} {string} to {string} {hwVer:string} {fwVer:string} {swVer:string} {modStatus:string}```;pattern03 = ```Mod MAC addresses {modNum:number} {string} to {string} {hwVer:string} {modStatus:string} {fwVer: null:string} {swVer: null:string}```;getMacAddrList(parsedOutput) = foreach pattern in [pattern02, pattern03] foreach match in blockMatches
Problem StatementOur 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 workswe 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 ScriptFunction 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
Sean Deveci, Federal Systems EngineerAndreas Voellmy, Sr. Director of Engineering Join me, @devecis, and @Andreas as we show you how to upgrade your NQEs, making them easier to troubleshoot, more scalable, and more resilient. These techniques are not only great for NQE, but will also up improve your Python and Javascript. Work side-by-side with us as we show you how to:Improve the results of your scripts to maximize the end-user experience. Streamline your scripts so they're easier to read, manage and share. Make your scripts more resilient so they can keep up with your changing environment. Ask questions below and let us know what you'd like to see in future demos!
Forward Networks includes serial numbers in its model as part of the component object. So if you want to see the serial number for a device, you must iterate through the components of that device. The serial number for the device itself usually belongs to the chassis, but some vendors may have multiple controller cards. The serial numbers for line cards, power supplies, etc will also be listed as components with serial numbers.There is a build-in NQE query in the Forward Library called Device Hardware that is included in Inventory+ by default. If it has been deleted from Inventory+, you can add it back by clicking on Inventory+ > Add NQE Queries and then selecting the Device Hardware NQE and clicking add and then Add.Note the foreach component in platform.components loop and the component.serialNumber entry in the NQE query code below:/** * @intent Information about device hardware */foreach device in network.deviceslet platform = device.platformforeach component in platform.compone
I am trying to create a NQE query for all the F5 devices. The query searches for SSL profile on custom command. Custom Command is : show ltm virtual detail recursive | grep -E "Ltm::ClientSSL Profile:" -E "Virtual Server:"The NQE should return SSL Profiles and the VIPs associated with them.
This is a script to pull switch port stats from our access switches in our network. The data pulled in this script is used for ‘right sizing’ and network planning. We can then export the results, and pivot table them to see the % of switch ports in use/not-in use. I’ll add this attachment later./*** @intent Show int counters on Arista & IOS-XE Switches * @description * 1. Check to see what switch ports have had no traffic accross the wire for sizing and planning. * 2. Match on platform.os* 3. Use the information from the custom command 'show int counters'.* 4. Get counts of switch ports on that device so we can use to calculate % in use**/// Pattern of output// Arista & Cisco Same ColumnsTraffic = ```{Port:string} {InOctets:number} {InUcastPkts:number} {InMcastPkts:number} {InBcastPkts:number}```;// Arista FunctionEOS_Stats = foreach device in network.deviceswhere device.platform.os == OS.ARISTA_EOSforeach command in device.outputs.commandswhere command.commandText == "sh int
AWS - Public IPv4 charge changes Back on Jul 28, 2023, AWS announced forthcoming changes to their billing for IPv4 public IP usage, which take effect as of Feb 1, 2024. In summary, AWS says, "Effective February 1, 2024, there will be a charge of $0.005 per IP per hour for all public IPv4 addresses, whether attached to a service or not (there is already a charge for public IPv4 addresses you allocate in your account but don’t attach to an EC2 instance).". More information can be viewed here: https://aws.amazon.com/blogs/aws/new-aws-public-ipv4-address-charge-public-ip-insights/. Update Apr. 2, 2024: In light of this, Forward Networks can assist with keeping track of your Public IP usage via an improved NQE Query located in “NQE->Library->Forward Library->Cloud->AWS->Public IPv4 Cloud Cost” that will show you what's being used: /** * @intent Shows the number and cost of AWS public IPv4 IP addresses */import "L3/IpAddressUtils";// $0.005 per hour per IPcostPerIpPerDay = 24.
Hi,I wrote an NQE query which is expected to return devices with CRITICAL severity only. The query returns almost a million results which is unlikely. Each device has so many rows with CRITICAL CVEs. foreach cveDatabase in [network.cveDatabase]foreach cve in cveDatabase.cvesforeach device in network.deviceslet platform = device.platformlet Severity = Severity.CRITICALselect { "Device Name": device.name, "CVE ID": cve.cveId, "Severity": Severity.CRITICAL, "Vendor": platform.vendor, "Model": platform.model}
This is a simple NQE to run a custom command to report on the ABOOT Version and Platform of Arista Devices. From Arista:In a small set of cases systems may experience an unexpected reboot. The reload is due to an uncorrectable ECC error caused by a corner case timing conflict on the CPU sub-system tracked by bugID 419257. This bug affects the range of CPU models present in these products. The affected systems are not restricted by specific serial numbers or date code ranges and the reload is unpredictable. Systems running Aboot6 BIOS revision lower than 6.1.7 or 6.0.9 and Aboot4 BIOS revision lower than 4.1.1 or 4.0.7 are susceptible to this issue. There are currently 4 release trains of Aboot across these systems: 4.0.x and 4.1.x, 6.0.x, and 6.1.x. A single common patch file will introduce the update across all release trains and is not platform or version-specific----------------------------------------------------------------------------------------------------------The custom Comma
foreach d in network.devicesforeach i in d.interfaceswhere length(i.links) != 0where i.adminStatus == AdminStatus.DOWNselect {deviceName:d.name, interface:i.name}
An FW engineer was looking to get the results from the command, “show firewall vip”, from all Fortinet Firewalls in Forward Networks. Command: show firewall vipconfig firewall vip edit "x-7.6.254.158-dns" set uuid d60c0a52-2630-51eb-9d53-bc032ca5e1c0 set extip x.x.x.x set mappedip "y.y.y.y" set extintf "any" next edit "x.x.x.1/32" set uuid 796a2ac2-2251-51ec-5c82-26b2e049a7a7 set comment "Voice LAB" set extip x.x.x.1 set mappedip "y.y.y.1" set extintf "any" next edit "x.x.x.2-y.y.y.2" set uuid 9ea63058-47ac-51ec-2a7f-5b0d00a1d142 set comment "Cloud" set extip x.x.x.2 set mappedip "y.y.y.2" set extintf "any" next Finding the command in the data model /** Thank you Danny Ramirez with the Smarts on this * * @intent Grap VIP's on Fortinets command.output of "show firewall vip" * @description Define VIP format, and then iterate through to pull the VIP * Name and theMapped
As network engineers, we have few tools that can help us correlate the actual state of our network devices, and our intent. In many cases maybe our intent is not clearly defined: How many EIGRP neighbors is the set of core switches really supposed to have? How many neighbors should I be learning a specific prefix from? How many entries should I have for prefix x in my EIGRP Topology or my OSPF Database? Is my intent to have all the entries installed in the Route Table as ECMP paths or should I only ever have 1 next-hop that only changes if a path becomes unavailable? In the network engineering realm specifically, even with automation tools like Ansible - without structuring your playbook logic very specifically - there are assumptions being made about the current state of the network. Even if your Ansible repos & playbooks are structured in a declarative and idempotent fashion, they are not exactly a consumable way for a network engineer to learn about the network - and you are re
Morning folks! We recently got the opportunity to leverage Forward Networks NQE for a Cyber Security ask. They want to verify that EC2 Instances are not being assigned the default Security Group. This should be a simple enough task. AWS creates the security group with the name ‘default’ so all we need to do is create an NQE Query that checks our Cloud Objects with a type of ‘instance’ and verify that the list (I’m assuming it is a list type) of security groups does not contain ‘default’. However, after reviewing the NQE Data Model I’m not convinced the ‘Cloud Objects’ are exposed in such a way we can correlate instance to security group. Can someone confirm or deny this?I do see that the instance tags are exposed as part of the ComputeInstance data model, so a workaround would be for us to edit our Terraform code so that security groups assigned to the instance are also created as tags on the instance so we can expose that correlation for consumption in NQE.
Forward Networks parse, processes and normalizes the snapshot details gathered. You have heard this term over and over again. Let’s use this method to see all of the subnets across all AWS, GCP and Azure deployments. This NQE query is based upon the example in the DataModel for network → cloudAccounts → vpcs → subnets → ifaces /** * @intent Enumerate the Routing Table for all Cloud Providers * @description Enumerate the Routing Table for all Cloud Providers. The notModeled column indicates the ipAddress is not modeled. */ipModeled(ipAddress) = foreach cloudAccount in network.cloudAccounts foreach vpc in cloudAccount.vpcs foreach subnet in vpc.subnets foreach iface in subnet.ifaces where ipAddress in iface.ipAddresses select iface.ipAddresses;foreach cloudAccount in network.cloudAccountsforeach vpc in cloudAccount.vpcsforeach routeTable in vpc.routeTablesforeach route in routeTable.routeswhere isPresent(route.nextHop)let nextHop = route.nextHoplet ipAddress = when nextHop is
Azure VNet peering and Global VNet peering routes the subnets in each VNet as defined by the VNet routing table. In some cases the Cloud Account configured in the Forward Networks platform does not have permission to enumerate all the necessary VNets. One needs to update the Microsoft Azure subscriptions service principals to include the missing VNets. But how does one find the VNets that are not modeled but referenced by other VNets? NQE, of course. The method of finding missing VNets is fairly straightforward. Similar to using the widely used “check for missing next hop route peers” NQE query, this NQE performs a similar task./** * @intent List VPCs / Microsoft Azure VNets that are not modeled. * @description Need the Microsoft subscriptions to be added to the service principal. See the VPC / VNet values in the destinationVPCId column. */idsOfCollectedVpcs = foreach cloudAccount in network.cloudAccounts foreach vpc in cloudAccount.vpcs select distinct vpc.id;foreach cloudAcc
Forward Networks NQE is very powerful. The information is there. The examples are clearly written for copying and pasting to create or combine new queries. This NQE lists the AWS Hosts / Instances with MAC address(es). Listing the instance type (ex: t2.micro) enables sorting by size. Or, finding whether the instance is up or down. Or simply listing all instances across all accounts. /** * @intent List all AWS Hosts and MAC Addresses * @description List all AWS Hosts and MAC Addresses */foreach cloudAccount in network.cloudAccountsforeach vpc in cloudAccount.vpcsforeach computeInstance in vpc.computeInstancesforeach iface in computeInstance.instanceIfacesforeach subnet in vpc.subnetswhere subnet.id == iface.subnetIdforeach subnetIface in subnet.ifaceswhere subnetIface.id == iface.ifaceIdselect { cloudAccountName: cloudAccount.name, vpcId: vpc.id, computeInstanceId: computeInstance.id, name: computeInstance.name, tags: computeInstance.tags, isUp: computeInstance.isUp, imag
The method of using the Forward Networks search bar to list all devices where a subnet is learned or advertised is very useful. This NQE lists the route, egress interface, interface description and a bit more. Displaying the next hop MAC address and associated OUI vendor is useful in determining whether the next hop is a router or firewall. /** * @intent List IP Prefixes / Route Table entries for all Routers * @description List the Route Table and egress interfaces detailes. Useful to determine where a particular route is, and what routes egress a device or interface. */getNextHopDesc(deviceName, interfaceName) = foreach interface in deviceName.interfaces where interface.name == interfaceName select interface.description;getNextHopMac(deviceName, interfaceName, ipNextHop) = foreach interface in deviceName.interfaces foreach subinterface in interface.subinterfaces let ipv4 = subinterface.ipv4 foreach neighbor in ipv4.neighbors where neighbor.ip == ipNextHop select neighbor.li
Already have an account? Login
No account yet? Create an account
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.