Skip to main content

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 device

host-XYZ.  intf1:  Type: DeadInterval: HelloInterval: Load : Cost
                    intf2:  Type: DeadInterval: HelloInterval: Load : Cost
                    intf3:  Type: DeadInterval: HelloInterval: Load : Cost

host-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 hello-interval 5
// load-interval 30
// ip ospf cost 500

pattern = ```
interface {IntName:string}
ip ospf network {type:string}
ip ospf dead-interval {deadInterval:number}
ip ospf hello-interval {helloInterval:number}
load-interval {load:number}
ip ospf cost {cost:number}
```;

foreach device in network.devices
// filter things as you'd like
// where "Branch" in device.tagNames && "Core" in device.tagNames && "C9500" in device.tagNames
let outputs = device.outputs
foreach command in outputs.commands
where command.commandType == CommandType.CONFIG
let parsed = parseConfigBlocks(OS.IOS_XE , command.response)
foreach match in blockMatches(parsed, pattern)
let x = blockMatches(device.files.config, pattern)
let type = (foreach ip in x where match.data.type == ip.data.type select distinct toString(ip.data.type))
let dead = (foreach ip in x where match.data.deadInterval == ip.data.deadInterval select distinct toString(ip.data.deadInterval))
let hello = (foreach ip in x where match.data.helloInterval == ip.data.helloInterval select distinct toString(ip.data.helloInterval))
let load = (foreach ip in x where match.data.load == ip.data.load select distinct toString(ip.data.load))
let cost = (foreach ip in x where match.data.cost == ip.data.cost select distinct toString(ip.data.cost))
select distinct{
Hostname:device.name,
Intf:match.data.IntName,
"OSPF Net Type":type,
"OSPF dead-interval":dead,
"OSPF hello-interval":hello,
"OSPF load-interval":load,
"OSPF cost":cost,
Tag: device.tagNames
}



results:

 

@cariddir That is a great idea.  However, I do see something to keep in mind with this approach.  The “blockMatches” treats everything in the pattern as a Logical AND.  If you have any interfaces that are missing parts of this pattern, then they will not be found. 

I would not scrap that query you have.  But maybe another query would use this pattern.

pattern = ```
interface {IntName:string}
ip ospf
```;

things to the right can be thought of like a wildcard match.  This would look for all commands that start with “ip ospf”.  You could then create a violation for interfaces that are missing any one of the expected config lines.

These two NQE queries could then be used as companions.  You could probably put more work and combine them into a single query.  However, it might be easier to just keep them separate.


Tyson, Thank you as always.
I’ll give this a run and compare results, I’m a wild card proponent!

 


Reply