Skip to main content

In todays NQE Video, I will show you the basics of using if expressions and how to use them when you want to create your own multi-vendor parser.

Code examples used in video

This particular parser is going to look at DNS servers and check to make sure that they are configured with the appropriate servers.

dns_addresses = [ipAddress("1.1.1.1"), ipAddress("1.0.0.1")];

ios_xe = ```
ip name-server {dns:ipv4Address+}
```;

arista = ```
ip name-server vrf {string} {dns:ipv4Address+}
```;

palo_alto = ```
config
devices
localhost.localdomain
deviceconfig
system
dns-setting
servers
primary {dns:ipv4Address+}
```;

cisco_asa = ```
dns server-group {string}
name-server {dns:ipv4Address+}
```;

generic = ```
dns {dns:ipv4Address+}
```;

foreach device in network.devices
let os = device.platform.os
let dns_pattern = if os == OS.PAN_OS then palo_alto
else if os == OS.IOS_XE then ios_xe
else if os == OS.ARISTA_EOS then arista
else if os == OS.ASA then cisco_asa
else generic
let dns_result = blockMatches(device.files.config, dns_pattern)
foreach result in dns_result
foreach r in result.data
let inCompliance = r.dns in dns_addresses

select {
"Device Name": device.name,
"Device OS": os,
"Configured DNS Server": r.dns,
violation: !inCompliance
}

Alternate to If Expression

If expressions are one way to write a multi-vendor parser, another way is using the when expression. When can be used when you are looking at parts of the data model that are enumerated constants. Wait, say what? Think about this, what if you wanted to group a bunch of electric car manufacturers and be able to let people select from data that is already stored? This would be am enumerated constant. As an example, If we had the following values, Tesla, Rivian, Polestar and Lucid, assigned to a enumerated datatype named ElectricCars, when executing the query, they would only have access to those 4. Similarly in NQE, we have a enumerated constants that users can use in their queries for example device.platform.os. device.platform.os is an enumeration, and it holds named constants, like ASA, PAN_OS, IOS_XR, etc. Taking our example using the if expression, if we just look at the actual NQE query, the command parsing will not change, we are left with something that might be a little more readable

foreach device in network.devices
let os = device.platform.os
let dns_pattern = when os is
PAN_OS -> palo_alto;
IOS_XE -> ios_xe;
ARISTA_EOS -> arista;
ASA -> cisco_asa;
otherwise generic
let dns_result = blockMatches(device.files.config, dns_pattern)
foreach result in dns_result
foreach r in result.data
let inCompliance = r.dns in dns_addresses

select {
"Device Name": device.name,
"Device OS": os,
"Configured DNS Server": r.dns,
violation: !inCompliance
}

What have you used if or when expressions for in your network? Share your queries with us in the comments below 👇🏻!

 

 

Be the first to reply!

Reply