Find answers to your NQE questions and share NQEs you've developed.
Recently active
Environment:Forward Networks (self-hosted) ServiceNow CMDB integration via NQE query Target class: cmdb_ci_ip_firewallIssue:When mapping System Criticality (a ServiceNow choice field) from an NQE query to ServiceNow via Forward's native CMDB integration, the field consistently reports "data type mismatched" regardless of the value format used.Attempted formats — all result in data type mismatched:"System Criticality": "2" "System Criticality": 2 "System Criticality": "2 - High" "System Criticality": ["2"] "System Criticality": [2] "System Criticality": ["2 - High"] Top-level named list: systemCriticality = ["2"] referenced in selectQuestion:Is ServiceNow choice field type mapping supported in Forward's NQE→CMDB integration? If so, what is the correct NQE syntax or integration configuration to map to a choice field without a type mismatch?Current workaround being considered:ServiceNow business rule that sets system_criticality = "2" on insert/update when discovery_source == "Forward Net
As part of a network initiative, I’m sharing all the scripts that I have worked on to create an audit program. These files feed are then fed into PowerBi for better visualization by engineers and mgmt.First step is create a utility called, “tag_var_util” to grab tags, of which, will be used as part of the logic to assign a template to different sets of attribtues.This utility will then be imported on all other NQE Audit Scripts. // Create a new NQE Function called: tag_var_util// Add the following utility to extract tags given to devices in Forward Networks Sources// TAGS to identify Environmentexport get_env_from_tags(tags: Bag)= get_list_match_from_tags(tags, ["DC", "CoLo", "Branch", "AWS"]);// TAGS to identify a sub category of locationexport get_SubDc_from_tags(tags: Bag)= get_list_match_from_tags(tags, ["Branch", "DC01", "DC02" ]);// TAGS to identify which managers owns the productexport get_mgr_from_tags(tags: Bag)= get_list_match_from_tags(tags, ["Moe", "Larry", "Curly"]);//
As part of a network initiative, I’m sharing all the scripts that I have worked on to create an audit program. These files feed are then fed into PowerBi for better visualization by engineers and mgmt.Power Bi Display of Forward NQE belowStarting with AAA.First step is create a utility called, “tag_var_util” to grab tags, of which, will be used as part of the logic to assign a template to different sets of attribtues.This utility will then be imported on all other NQE Audit Scripts.// Best practice is to tag all devices with the following:// Environment && Sub-Environment && Manager && Region && Function && VRF && Mgmt-Interface (source interface for mgmt. traffic)// Each Script will import the utilities: import "PROD/Standards_Network/NetworkVars/tag_var_util"; let region = get_region_from_tags(device.tagNames) let deviceFunc = get_function_from_tags(device.tagNames) let environment = get_env_from_tags(device.tagNames) let vrf
There is a specific section of the AFM config which refers to the default action of the firewall, the below query checks that the default action is Drop.F5 AFM Config to check for.}sys db tm.fw.defaultaction { value "drop"} /** * @intent Check that all F5's that are running AFM have the default action set to deny * @description THis will check sys db tm.fw.defaultaction for the value drop and error * if it is not drop. **/// Note {} have been removed as they can not be included in the pattern.defaultPattern = ```sys db tm.fw.defaultaction value "drop"```;foreach device in network.deviceswhere device.platform.os == OS.F5foreach command in device.outputs.commands//Check for only the F5's with AFM Configwhere command.commandType == CommandType.F5_AFM_CONFIG//Extract the command response.let AFMConfig = parseConfigBlocks(OS.F5,command.response)//Match the patternlet match = blockMatches(AFMConfig,defaultPattern)let violation = if length(match) == 0 then true else falselet DropActio
Here are a set of 3 scripts for:NXOSEOSIOS (and IOS-XE)The scripts look for configuration related to source interfaces. Over the years, engineers have used Loopback0, dedicated management interfaces, Loopback10, or other random interfaces to source traffic from. We have an an inititiative to clean these inconsistencies up.These scripts parse through the configs looking anything related to the ‘source-interface’ or ‘local-interface’ etc. Then it finds the associated configuration of those interfaces, such as IP Address, VRF, description.I have also tuned them to ignore parts of the configuration that are not important to the effort , ex:no ip redirectsno ip route-cacheno ip unreachablesno ip proxy-arpip mtu {number}load-interval {number}ip helper-address {string}negotiation autostandbye {string}etc...Cisco NXOS/*** * @intent Source-Interface Extraction (NXOS) * @description Extracts all source-interface configs and interface details from config text.***/// --- 1. Helper Functions ---g
Forward brings in Fortinet firewalls as the device its self and the VDOM’s this becomes challenging when you need to validate the tacacs configuration for the physical device this means quite often the vdoms or even the root vdom will fail even though tacacs is configured on the device.The simple solution is to add a permitted violation list, however this needs to be maintained manually there must be a better solution surely?userTacacs =```config user tacacs+ edit "TACACS" set server [server 1 IP Address] set secondary-server [server 2 IP Address] set key ENC {string} set secondary-key ENC {string} set authorization enable nextend```;systemAdmin = ```config system admin edit "tacacs" set remote-auth enable set accprofile "no_access" set vdom {vdoms:string} set wildcard enable set remote-group "TACACS_ACCESS" set accprofile-override enable```;foreach device in network.deviceswhere device.platform.v
Children LinesThis document aims to improve understanding of how NQE parses Cisco-like configuration. It also provides templates for common NQE checks related to configurations. Forward NQE takes Cisco-like configuration and parses it into a subset of “parent” and “child” lines. The “parent” and “child” relationship is based on the number of indents in front of each line. Each Cisco configuration always starts with a line with no indent in front of it. (e.g. “router bgp 65000”). Some configurations, referred to by Cisco as “global configurations” such as “feature bgp”, do not have additional parameters, and therefore they do not have “children” lines. Others, such as “router bgp 65000”, require additional parameters to configure that particular feature. In the below example, “router bgp 65000” is the main parent line consisting of “children” that are line 2-4, 7, and 10. Furthermore, the child lines 4, 7 and 10 each have additional “children” lines of their own; line 4 has lines 5-6;
A common network configuration is to have hosts(servers) connected to a leaf switch, which in turn is connected to spine switches, and finally to an upstream L3 switch / gateway.Host → Leaf Switch (ToR) → Spine Switch(s) → L3 Switch / Gateway(s)in this scenario, no hosts are directly connected to the spine switch.Suppose the Network Team wanted to upgrade a Spine switch. Ideally, a leaf switch would not be impacted by a single spine switch going offline. However, the Network Team must still notify application owners for servers on downstream switches with potential impact.The following NQE query can be used to list all access switches and their hosts that are downstream from a given switch:import "@fwd/Interfaces/Interface Utilities";@queryquery(deviceName: String) = foreach device in network.devices where device.name == deviceName foreach link in getLinkedInterfaces(device) let remoteDeviceName = link.remoteDeviceName foreach remoteDevice in network.devices where remoteDevice.na
The Problem with “It Doesn’t Hurt Anything”Over time, stale configuration creates real friction:Configs become harder to read and reason about Engineers hesitate to make changes because “something might depend on it” Troubleshooting takes longer because it’s unclear what actually matters The network slowly accumulates configuration debtNone of this usually comes from bad configuration. It comes from old configuration that was never cleaned up.The Core ObjectiveThe primary objective of this approach is not to modify or remove configuration automatically, but to make potential problem areas visible.Identify configuration elements that are likely unused Extract them in a consistent, scalable way Present the results in a form that engineers can easily understandOnce those configs are visible, humans can make informed decisions instead of guessing.NQE for Cisco ASAThis NQE identifies objects that are not used by any ACL entries. This is just one example of how we can quickly identify “conf
Hi TeamI am looking for some help to create a workplace in FN.This workplace will contain only CISCO devices and NQEs (BGP status and Interface Status). I want to auto execute this workspace (snapshot) by every 30 mins so that I can fetch interface and BGP status of cisco devices. Any help on this really appreciated. Thank you.
Sequential Thinking in NQE using State Pipeline One interesting challenge when writing logic in NQE is that the language does not support a traditional sequential programming style (loops, mutable variables, recursion, etc.).But we can emulate iteration by threading state through a series of transformations.This resembles techniques used in functional programming such as state threading or CPS-like transformations, where computation is expressed as a chain of pure transformations.Let’s look at a simple example: computing the integer log₂(i) using a sequential algorithm.Sequential C-like styleint log2(int i) {int e = 32, b = 0;while (e >= 1) { if (i >= 2 ** e) { i /= (2 ** e); b += e; } return b;}Conceptually, each loop iteration transforms the state:(i, e, b) → (i', e/2, b')Since NQE has no while statement, we first unroll the iterations:if (i >= 2^32) { i /= 2^32; b += 32; }if (i >= 2^16) { i /= 2^16; b += 16; }if (i >= 2^8) { i /= 2^8; b += 8; }if (i >= 2
Depracated - please see:For updated version This is a script that @rob helped greatly with. It parses through SNMP configuration on IOS-XE devices. Then does a comparison of the templates in the file and provides:What’s missing, what is extra, and the captured configuration.I’ve added additional functionality to leverage tagging, which helps identify which config block belongs to what kind of devices. I have documented as best I can, hopefully this helps other as much as it’s helping me. /*** * @intent SNMP Validation (IOS) * @description Validates Cisco IOS-XE SNMP configs and extracts community/host details. * * LOGIC SUMMARY: * 1. Checks device against 3 regional patterns (AMRS, EMEA, APAC). * 2. Uses the 'Hybrid Approach': * - Uses 'device.files.config' (Bag) for the blockDiff engine (Accuracy). * - Uses 'configAsString' (String) for Regex extraction (Speed). * 3. Outputs a clean table with missing lines and current settings.***/// Tagging Function to look for tagged devices in or
Continuing scripts to pull more information from Cisco WLC’s. Find my original Cisco WAP post here: Pre-requisites:Add Custom Command to IOS-XE for collection “show ap image | inc None” Add Tag of “WLC” on your Wireless Controllers WLC’s are on c9800 running IOS-XE IOS-XE version is 17.x.x/*** @intent - pull Name & OS Versions from Cisco AP's via Cisco WLC's* @description Log into Cisco WLC's "C9800" and pull AP information from the controllers with "show ap image | inc None"**/// Pattern of output//AP_INFO = ```{APName:string} {PrimaryOS:string} {BackupOS:string}```;foreach device in network.deviceslet platform = device.platformforeach Tag in device.tagNameswhere Tag == "WLC"foreach Command in device.outputs.commandswhere Command.commandText == "show ap image | inc None"let parsed = parseConfigBlocks(OS.IOS_XE, Command.response) //parses text into lineslet matchData = blockMatches(parsed, AP_INFO) //applies pattern to linesforeach x in matchDataselect { name: device.name, Loca
updated Scripts: 1This NQE script audits NTP configuration compliance for IOS-XE Branch devices in the AMRS and EMEA regions. It compares each device's running configuration against locally-defined gold standards (approved NTP server IPs per region, with variants for LAN switches, SDWAN routers, and WLCs — both with and without VRF syntax). For each device it identifies missing NTP servers (present in the standard but absent from the device) using blockDiff, and extra NTP servers (configured on the device but not in the approved list) using set subtraction. The results are output as a compliance table with a violation flag, the missing/extra server details, and device metadata derived from tags (region, environment, function, manager). Edit the IP’s in the xxxx Standard to your own (and remove what you don’t need).Additionally, there is a Utility in here (export_get_list_match_from_tags) at the beginning. The code requires the devices to be tagged with a region (AMRS APAC EMEA LATM) Th
I have raised a support case for this as well, but I was wondering if anyone had seen it when you see different behavior when running a query in the library versus verify.I have created a query to display the vxlan address table, and when run in Verify the result shows 0 however when executed int he library it produces the complete list of passed entries as expected.The Query will always pass and has been added to verify so we can do a diff check on the VXLAN Address table during changes as requested by the engineers.Has anyone else experienced this, or got any suggestions on how to address this.Results from execution in Verify:Results from execution in Library (Sanitized): Code from Script:/** * @intent Display the Mac Address List for VXLAN * @description Will display the VXLAN mac address list and set the violation to false. */import "library/Arista Library";foreach device in network.deviceswhere device.platform.os == OS.ARISTA_EOSlet vxlanTables = vxlanTable(device)foreach item in
Here is a useful combination of a custom command and an NQE query to show the state of all OSPF neighbors.OSPF data is not collected by default in Forward Enterprise, so we add the custom command "sh ip ospf neighbor"Output data for this command from one device looks like this:Command: sh ip ospf neighborNeighbor ID Pri State Dead Time Address Interface10.200.30.42 0 FULL/ - 00:00:35 10.45.6.1 GigE1/0/010.200.30.42 0 FULL/ - 00:00:32 10.45.6.2 GigE1/0/110.200.30.42 0 FULL/ - 00:00:35 10.45.6.3 GigE1/0/210.200.30.42 0 FULL/ - 00:00:31 10.45.6.4 GigE1/0/310.10.10.200 1 FULL/BDR 00:00:03 10.45.6.5 Vlan200This NQE query will list the OSPF neighbors from all devices by parsing the data from the custom command./** * @intent Show OSPF neighbors on all devices collected with custom command 'sh ip ospf neighbor' * @description Show OSPF neighbors on all devices colle
Just putting this up in case anyone has a similar requirement. When we collect ‘show running-config’ from an F5, much of the SNMP configuration is left out. If you need this info you need to define a custom collection group and issue the command show running-config all-properties to get the additional lines of config.Once you have collected this new information, you can match on a pattern like this: f5SnmpLocationPattern = ```sys snmp sys-location {location:string}```;
Manually auditing DNS configuration across a large network is slow, tedious, and error-prone. Engineers are often forced to comb through thousands of lines of device configuration to confirm that every router, firewall, and switch is pointing to the correct name servers. By the time the audit is complete, parts of the network may already be out of compliance again. With Forward Networks’ Network Query Engine (NQE), this kind of validation can be automated and continuously enforced using a simple, declarative query that evaluates the entire network model at once. Why this mattersDNS is a foundational service. A single misconfigured device can: Break application connectivity Bypass security monitoring by resolving through an untrusted resolver Violate regulatory or internal policy that mandates use of controlled DNS infrastructure What this NQE checksThis query verifies that every monitored device is configured with the approved internal DNS servers—and only those servers.In this ex
Using the MLAG_INTERFACE_STATE output that is already provided we will check the interface state in relation to all MLAG configured interfaces, this will warn if their is less than 24 hours since the last state change.To violate the following must occur.The state is not “active-full”The Oper State of the interfaces on the local and remote device is not “up/up”The configuration state is not “ena/ena”/** * @intent Report on the MLAG Interface State * @description Using the show mlag interface detail command which is in commandType MLAG_INTERFACE_STATE * the data is retrieved by calling mlagTable within the arista library. This will violate if the interface * state does not match the expected results. */ //show mlag interfaces detail.mlagInterfaces = ``` local/remote mlag state local remote oper config last change changes-------
This query takes the rather limited show mlag config-sanity command from an arista switch and generates a violation if it does not match the output below.switch#show mlag config-sanityNo global configuration inconsistencies found.No per interface configuration inconsistencies found.The query identifies each line of the output and then creates two variables globalConfig and interfaceConfig, interfaceConfig is identified by check if interface exists in the line. I am only expecting two lines therefore both variables once set won’t be added to. Watch this space if this changes I will update the query.As in my previous queries I have included the extract that is in my “Arista Library” into the query for simplicity.Finally there maybe a better way to do this as I had some fun and games getting this one to work so any feedback is gratefully appreciated./** * @intent Mlag Config Sanity Checks * @description Using the Arista Library we will check the configuration Sanity, there are only two
This NQE uses the show mlag detail command which all that it should be in command.type of MLAG_STATE it did not appear so I added it as a custom command and will violate if the following occur:What I alert on:Mlag state is not AcitveNegotiate Status is not connectedPeer Config is not ConsistentPeer Link and/or local interface are not upIf both the local and peer device are both primary or both secondary admittedly the latter may be impossible but though of capturing it just in case Peer Link is error disabled.If the Agent is not showing as ruinning.What we warn on:We will also Warn on the following:If there any ports disabled, Inactive or Active PartialIf the number of port disabled, inactive or Active partial is the same as the total number of ports configured. /** * @intent Check the MLAG status * @description Using the AristaMLAGDetail function in the Arista Library check to verify the status is as expected * * This query also uses the violationProcessing function from the Utilitie
Using the “show vxlan config-sanity detail” command as a custom command we have a built a query that enables you to verify your vxlan configuration based on the “Result” field being anything other than “OK”, if you wish to accept warnings then simply adjust the relevant if statement in the “AristaVxLanSanity” section of this script./** * @intent Report on the Sanity of VXLAN configuration * @description Using the AristaVxlanSanity module of the Arista Library we will report any vxlan * configuration failures by category per device using the default assumptions of the Module * from the library */AristaVxlanSanity(device: Device) =foreach command in device.outputs.commands where command.commandText == "show vxlan config-sanity detail" //Retrieve only the command show vxlan config-sanity detail let deviceName = device.name let vxlanResponse = command.response let parsed = parseConfigBlocks(OS.UNKNOWN, vxlanResponse) foreach line in parsed foreach child in line.children
Hello,I am trying to create the NQE query, where i want to see the outputs of show module, show platform, depending upon the platform command might be different and then from those outputs i want to see the modules which are in down state.
Any time someone tells me they’re manually reviewing ACLs for compliance, I know they’re fighting a losing battle. That approach might work on a small network, but once you’re dealing with thousands—or tens of thousands—of devices, manual validation simply doesn’t scale. This came up recently in a conversation on specific ACL compliance requirement across an environment. They weren’t looking for advanced analytics or a flashy dashboard. They needed a reliable way to ensure their access control lists consistently met two basic security rules, everywhere, all the time. The compliance problem The first requirement was that every deny statement in an ACL must log. From a security and compliance standpoint, a deny that isn’t logged is effectively invisible. Traffic may be blocked, but without a log entry there’s no audit trail and no way to prove enforcement. The second requirement was that every ACL include an explicit deny-all statement. Most platforms apply an implicit deny at the end of
The new ordered collections feature streamlines how you pull, organize, and present data from your inventory. It helps you quickly surface results—like the top 10 most vulnerable devices—organized the way you want, so you can act faster and share clearer insights with your team.Let’s walk through what ordered collections can do, when they’re most useful, and how to use the new syntax to save time and reduce manual filtering. Introduction: Why Ordered Collections MatterBefore ordered collections, finding and organizing your top results (say, the most vulnerable devices) meant extra filtering and sorting. Reports could show too many results, scattered by category, forcing you to click around or explain sorting steps to others. Now, ordered collections make it easy to: Limit results to exactly what you want (like the top 10) Sort by multiple criteria, such as vulnerability count and operating system Use familiar, flexible SQL-like syntax Handle both ordered (list) and unord
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.