skip to navigation
skip to content

Not Logged In

ciscoconfparse 0.9.1

Parse through Cisco IOS-style configurations and retrieve portions of the config using a variety of query methods

Latest Version: 0.9.31

INTRO
=====

ciscoconfparse is a Python package 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...

Line01:policy-map QOS_1
Line02: class GOLD
Line03:  priority percent 10
Line04: class SILVER
Line05:  bandwidth 30
Line06:  random-detect
Line07: class default
Line08:!
Line09:interface Serial 1/0
Line10: encapsulation ppp
Line11: ip address 1.1.1.1 255.255.255.252
Line12:!
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
05, 06
10, 11
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.

Methods
-------

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. Methods attached to IOSConfigLine objects
4.1 parent(self):
4.2 children(self):
4.3 has_children(self):
4.4 child_indent(self):
4.5 oldest_ancestor(self):
4.6 family_endpoint(self):
4.7 linenum(self):
4.8 text(self):
4.9 uncfgtext(self):


5. Methods for parsing the configuration: I won't bother explaining here...
You have the source if you are interested :-).


BASIC USAGE
===========

#!/usr/bin/env python
from ciscoconfparse import CiscoConfParse

parse = CiscoConfParse("/tftpboot/bucksnort.conf")

# Return a list of all ATM interfaces and subinterfaces
#
atm_intfs = parse.find_lines("^interface\sATM")

# 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 = list()
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(intf)
      newcfg.append(" mls qos trust cos")


The examples/ directory in the distribution contains more usage cases,
including sample configs to parse.


ADVANCED USAGE
==============

When enforcing configuration standards, the req_cfgspec_excl_diff() method is
very useful.  The following example illustrates how you can require three
syslog servers and unconfigure those you don't want to use.

#!/usr/bin/env python
from ciscoconfparse import CiscoConfParse

## This is the configuration we start with
config = [
    'logging trap debugging',
    'logging 172.28.26.15',
    ]
p = CiscoConfParse(config)
## This is the configuration we need to enforce...
required_lines = [
    "logging 172.16.1.5",
    "logging 1.10.20.30",
    "logging 192.168.1.1",
    ]
# lines matching linespec are enforced
linespec = "logging\s+\d+\.\d+\.\d+\.\d+"
# unconfspec is a template for *how* we remove non-conforming lines...
unconfspec = linespec
diffs = p.req_cfgspec_excl_diff(linespec, unconfspec,
    required_lines)


When you run this code, you will get the following lines stored in diffs...

    no logging 172.28.26.15
    logging 172.16.1.5
    logging 1.10.20.30
    logging 192.168.1.1

If you apply this to the router, now your syslog statements conform to your
expectations.

FAQ
===

Q1: Is there a way to use this module with perl?
A1: Yes, I do this myself. Install the python package as you normally would
and import it into perl with Inline.pm and Inline::Python from CPAN.

Q2: When I use find_children("interface GigabitEthernet3/2"), I'm getting all
interfaces beginning with 3/2, including 3/21, 3/22, 3/23 and 3/24. How can I
limit my results?
A2. There are two ways... the simplest is to use the 'exactmatch' option...
find_children("interface GigabitEthernet3/2", exactmatch=True). Another way is
to utilize regex expansion that is native to many methods...
find_children("interface GigabitEthernet3/2$")


AUTHOR
======

David Michael Pennington


THANKS
------

Thanks to David Muir Sharnoff for his suggestion about making a special case
for IOS banners. Thanks to Alan Cownie for his API suggestions. Thanks to
everyone in advance for their bug reports and patience. Sola Dei Gloria.
 
File Type Py Version Uploaded on Size
ciscoconfparse-0.9.1-py2.6.egg (md5) Python Egg 2.6 2013-01-01 27KB
ciscoconfparse-0.9.1.tar.gz (md5) Source 2013-01-01 47KB
  • Downloads (All Versions):
  • 99 downloads in the last day
  • 1692 downloads in the last week
  • 8596 downloads in the last month