Retrieve Information from Cisco router in Parsable Manner
Automated Cisco IOS config parsing
Alternatively, is there a better way I can retrieve this information that would make it easier to parse?
Parsing router / switch configurations is quite complicated due to the layers of hierarchy in IOS configs; whenever possible, use a tool which specializes in parsing for you. One such tool is ciscoconfparse (docs are here) Note 1. ciscoconfparse has a whole battery of unit tests, which ensure that parsing remains consistent between versions of the tool.
Assuming the configuration comes in the exact format used by Cisco IOS show running-config
or show startup-config
, ciscoconfparse automatically finds the interface-level configurations for you. This means you can automate standardization of interface and global configurations... This is an example switch interface configuration audit in the documentation. ciscoconfparse has a lot of functionality in it; you should spend some time reading the documentation.
There are also some specialized methods which do a lot of specific value parsing for you; these methods are currently in beta - and only visible in the source code... for instance suppose you have a switch configuration saved as c6509.conf
!
interface GigabitEthernet2/8
ip address 192.0.2.1 255.255.255.252
mtu 9000
carrier-delay msec 50
!
You can use a script or the python interpreter to retrieve the IP address and carrier-delay
in native python representations...
[mpenning@tsunami ~]$ python
Python 2.7.3 (default, Jan 2 2013, 13:56:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from ciscoconfparse import CiscoConfParse
>>> config = CiscoConfParse('c6509.conf', factory=True)
>>>
>>> intfs = config.find_objects('interface GigabitEthernet2/8', exactmatch=True)
>>> intfs
[<IOSIntfLine # 1 'GigabitEthernet2/8' info: '192.0.2.1/30'>]
>>>
>>> intfs[0].ip_addr
'192.0.2.1'
>>>
>>> intfs[0].has_manual_carrierdelay
True
>>>
>>> intfs[0].manual_carrierdelay
0.05
>>>
>>> intfs[0].manual_mtu
9000
>>>
If you want the beta functionality, you need to parse the config with factory=True
, as shown above...
Native Cisco IOS parsing capabilities
My goal was to handle settings for interfaces differently from global settings; for example, I can ignore bad settings on interfaces that are disabled.
Are there separate commands for getting global settings and getting interface definitions (e.g. show global settings and a show interface settings type of commands)?
IOS lets you see individual interface-level configs, but it's very painful when you have potentially hundreds of interfaces... imagine running this command for every interface...
CORE01.PUB.DAL02#sh runn int gi1/2
Building configuration...
Current configuration : 242 bytes
!
interface GigabitEthernet1/2
description Link to edge01.pub.dal02
ip address 192.0.2.46 255.255.255.252
ip ospf network point-to-point
media-type rj45
end
CORE01.PUB.DAL02#
Depending on the image you're running, Cisco IOS allows a few other global configuration sections... this is from a router running 12.4...
EDGE01.PUB.DEN#sh running-config ?
brief configuration without certificate data
class-map Show class-map information
full full configuration
interface Show interface configuration
linenum Display line numbers in output
map-class Show map class information
policy-map Show policy-map information
view View options
| Output modifiers
<cr>
EDGE01.PUB.DEN#
It's also possible to get portions of the global configuration using IOS regular expressions from the CLI... for instance...
EDGE01.PUB.DEN#show runn | include ^enable
enable secret 5 $1$mOmQ$sORLRqZQZ/cr7KSyrXUPZ.
EDGE01.PUB.DEN#
FYI, that's an MD5 hash for an enable password of "cisco", which you'd want to flag, if found in production...
Responding to this comment:
Is there a good way to define when an interface definition ends? It appears that all interface lines are indented by one space but I'm not sure if that's standard across configs
Yes, Cisco IOS always indents child configuration elements by an extra space... regardless of whether the child is an interface configuration statement, IP extended ACL line, etc...
End Notes
Note 1Stack Exchange Disclaimer: I am the author.
Since there is context in the format, you should consider parsing it contextually. You might need to write more code to do that. Consider using a model for your code that constructs an object model for the global state, interfaces, and such.
Operationally, removing non-compliant settings from disabled interfaces might be a good idea in case someone enables them.