ciscoconfparse is a Python library for parsing through Cisco IOS-style configurations and retrieving portions of the config based on a variety of query methods.
The package will process an IOS-style config and break it into a set of linked parent / child relationships. Then you issue queries against these relationships using a familiar family syntax model. Queries can either be in the form of a simple string, or you can use regular expressions. The API provides powerful query tools, including the ability to find all parents that have or do not have children matching a certain criteria. This means it is easy to find the interface names of all layer2 trunks in a Catalyst 6500, or retrieve a list of all interfaces with cdp disabled. Until this package, I know of no simple config-parsing APIs to do the same; it has traditionally been considered the domain of screen-scraping. In conjunction with python's sophisticated set-manipulation capabilities, your imagination is the limit.
The package also provides a set of methods to query and manipulate the IOSConfigLine objects themselves. This gives you a flexible mechanism to build your own custom queries, because the IOSConfigLine objects store all the parent / child hierarchy in them.
Examples of config family relationships are shown below...
Line02: class GOLD
Line03: priority percent 10
Line04: class SILVER
Line05: bandwidth 30
Line07: class default
Line09:interface Serial 1/0
Line10: encapsulation ppp
Line11: ip address 18.104.22.168 255.255.255.252
Line13:access-list 101 deny tcp any any eq 25 log
Line14:access-list 101 permit ip any any
parents: 01, 02, 04, 09
children: of 01 = 02, 04, 07
of 02 = 03
of 04 = 05, 06
of 09 = 10, 11
siblings: 02, 04, 07
oldest_ancestors: 01, 09
families: 01, 02, 03, 04, 05, 06, 07
09, 10, 11
family_endpoints: 07, 11
Note that 01, 09, 13 and 14 are not considered siblings, nor are they part of the same family. In fact, 13 and 14 do not belong to a family at all; they have no children.
The package provides several types of methods:
1. Query methods returning a list of text lines.
1.1 find_lines( self, linespec, exactmatch=False, ignore_ws=False ):
1.2 find_children( self, linespec, exactmatch=False, ignore_ws=False ):
1.3 find_all_children( self, linespec, exactmatch=False, ignore_ws=False ):
1.4 find_blocks( self, blockspec, exactmatch=False, ignore_ws=False ):
1.5 find_parents_w_child( self, parentspec, childspec, ignore_ws=False ):
1.6 find_parents_wo_child( self, parentspec, childspec, ignore_ws=False ):
1.7 req_cfgspec_all_diff( self, cfgspec ):
1.8 req_cfgspec_excl_diff( self, linespec, uncfgspec, cfgspec ):
2. Query methods returning a list of IOSConfigLine objects.
2.1 find_line_OBJ( self, linespec ):
2.2 find_sibling_OBJ( self, lineobject ):
2.3 find_child_OBJ( self, lineobject):
2.4 find_all_child_OBJ( self, lineobject ):
2.5 find_parent_OBJ( self, lineobject ):
3. Methods for manipulating IOSConfigLine objects
3.1 unique_OBJ( self, objectlist ):
3.2 objects_to_lines( self, objectlist ):
3.3 objects_to_uncfg( self, objectlist, unconflist ):
4. Query methods on IOSConfigLine objects
5. Methods for parsing the configuration: I won't bother explaining here...
You have the source if you are interested.
from ciscoconfparse import *
parse = CiscoConfParse("/tftpboot/bucksnort.conf")
# Return a list of all ATM interfaces and subinterfaces
atm_intfs = parse.find_lines("^interfacesATM")
# Return a list of all interfaces with a certain QOS policy
qos_intfs = parse.find_parents_w_child( "^interf", "service-policy QOS_01" )
# Return a list of all active interfaces (i.e. not shutdown)
active_intfs = parse.find_parents_wo_child( "^interf", "shutdown" )
# Find all interfaces that have voice configured, if they are trusting dscp
# build a new config to trust cos
# You must put a caret (^) sign in front of "interface" below... otherwise you will get matches
# for any command with interface in the syntax. ^ is a regular expression to match the beginning
# of a line.
newcfg = 
voice_intfs = parse.find_parents_w_child("^interface", "switchport voice")
for intf in voice_intfs:
famobj = CiscoConfParse( parse.find_children( intf, exactmatch = True ) )
if( famobj.find_lines("mls qos trust dscp") ):
newcfg.append(" mls qos trust cos")
The examples/ directory in the distribution contains more usage cases, including sample configs to parse. When enforcing configuration standards, the req_cfgspec_excl_diff() method is very useful; examples of its usage are included.