Skip to main content

One of the painful parts of trying to audit configurations, is accounting for the variations in the configuration that differ based on Vendor/Model/OS etc… Additionally, accounting for ‘old’ configurations/mis-configuration across these variations adds an extra (sometimes silent, sometimes not) “WTF” as one attempts to isolate the problems.

With initial input from Arica , I wound up writing 2 scripts to find the ‘new’ configuration and one to find the old, then ‘xlookup-ed’ the differences in excel. Not to fun, but it was effective enough.  Then I figured, how hard could it be to combine them? It was harder than I though, so I created the shell, and then asked for some help from a colleague (thanks Ahmed).

@AricaFN

@AhmedKhedr 

The result of the script produces an easily scanned results for the problems.
Model ---- DeviceName ---- GoodConfig --- BadConfig


/**
* @intent Ensure SNMP Communities are correct
* @description 2 columns, one column showing where the "GOOD Strings are, and another column with the "Bad Strings"
**/
GoodStrings = >
"*poll community PRS*",
"*poll community MusicMan*",
"*poll community Ibanez*",
"*version 2c PRS*",
"*version 2c MusicMan*",
"*version 2c Ibanez*",
"snmp-server mib community-map PRS*",
"snmp-server mib community-map MusicMan*",
"snmp-server mib community-map Ibanez*",
"snmp-server community PRS*",
"snmp-server community MusicMan*",
"snmp-server community Ibanez*",
];
BadStrings =
"*version 2c Fender*",
"*version 2c Washburn*",
"*version 2c Gibson*",
"snmp-server community Fender*",
"snmp-server community Washburn*",
"snmp-server community Gibson*",
"*poll community Fender*",
"*poll community Washburn*",
"*poll community Gibson*",
];

Good =
foreach device in network.devices
let lines = (foreach line in device.files.config select line.text)
let config = (foreach item in GoodStrings
foreach line in lines
where matches(line, item)
select line)
select {
Model: device.platform.os,
device: device.name,
good_config: config,
tags:device.tagNames
};

Bad =
foreach device in network.devices
let lines = (foreach line in device.files.config select line.text)
let config = (foreach item in BadStrings
foreach line in lines
where matches(line, item)
select line)
select {
Model: device.platform.os,
device: device.name,
bad_config: config,
tags:device.tagNames
};

// Thanks AhmedK //
FALLBACK=
foreach x in B""]
where x != ""
select x;

combined_results()=
foreach entry in Good
foreach other_entry in Bad


where entry.device == other_entry.device
let good_config = if isPresent(entry.good_config)
then entry.good_config
else FALLBACK

let bad_config = if isPresent(other_entry.bad_config)
then other_entry.bad_config
else FALLBACK

select{
Model: entry.Model,
Device: entry.device,
good_config,
bad_config
};



combined_results()

 

Results:

Device 1 and  configured with GoodConfig and BadConfig

Device 2-4 only the GoodConfig

Device 5 - Only the BadConfig

 

 

Awesome to see the final product, I’m glad I could help! 😃 


@cariddir 

just a little type casting trick, you don’t need that FALLBACK. 

Try this.

foreach entry in Good
foreach other_entry in Bad
where entry.device == other_entry.device
let good_config = if isPresent(entry.good_config)
then entry.good_config
else null : List<String>
let bad_config = if isPresent(other_entry.bad_config)
then other_entry.bad_config
else null : List<String>
select { Model: entry.Model, Device: entry.device, good_config, bad_config }

 


@cariddir 

just a little type casting trick, you don’t need that FALLBACK. 

Try this.

foreach entry in Good
foreach other_entry in Bad
where entry.device == other_entry.device
let good_config = if isPresent(entry.good_config)
then entry.good_config
else null : List<String>
let bad_config = if isPresent(other_entry.bad_config)
then other_entry.bad_config
else null : List<String>
select { Model: entry.Model, Device: entry.device, good_config, bad_config }

 

Thanks GaryB!
That worked perfectly, and more concise. Appreciated.
Rich


Reply