CiscoConfParse is a library for Cisco device. : pip install ciscoconfparse
Example :
from ciscoconfparse import ciscoconfparse
Cisco_obj = CiscoConfParse(“show_run.txt”)
print(Cisco_obj) <—- this will return all the information about that object
If using Netmiko to pull information from any device into a variable, you need to add the splitlines() method to be able to work with CiscoConfParse.
Cisco_obj = CiscoConfParse(netmiko_output.splitlines()) <—- this is to convert it to a list
dir(Cisco_obj) <—- to find which method to work with ( usually find_something )
Then you can use the help(find_something) to see how to use the commands.
Example :
Cisco_obj.find.objects(r”^interface”) <— this is using raw regular expression, ^ <— everything that begin with interface
intf = Cisco_obj.find.objects(r”^interface”)
intf[0] <— would return the element of the list 0
intf[0].text <— would return the element of the list as text
Then you can use dir(inft[0]) to return what methods we can use example : children
intf[0] <— would return something like that :
interface FastEthernet0/1
intf[0].children <— would return something like that
no ip address
intf[2] <— would return something like that :
interface FastEthernet0/3
intf[3].children <— would return something like that
ip address 10.10.10.1 255.255.255.0
duplex auto
speed auto
So we can loop over an object with the known element, example :
for child_var in intf[3].children:
….print(child.text)
This would result in printing out all line starting with interface and the indented configuration below.
Next example , i would like to have any interface that have an ip configuration on it :
Cisco_obj.find_objects_w_child(parentspec=r”^interface”, childspec=r”^\sip address”) <— regular expression mean that it will match the beginning of the line ” ^ ” one white space ” \s” and the ” + ” indicate one or more characters.
output = Cisco_obj.find_objects_w_child(parentspec=r”^interface”, childspec=r”^\sip address”)
Then we can call out anything we need from that list output.
output[0].text
output[0].children
How to go down a object from a find.objects() :
Cisco_obj.find.objects(r”^line con 0″)
parent = Cisco_obj.find.objects(r”^line con 0″)
To see if this variable have children you can use :
parent.is_parent <— if it return True then you have a list of element to chose from :
children = parent.children
Then you can call any element of that list :
children[0]
logging synchronomous
———————————————————————————————————————————————————–
The Section below is from the creator :
/ciscoconfparse
README.rst
ciscoconfparse
Contents
Introduction: What is ciscoconfparse?
Short answer: ciscoconfparse is a Python library that helps you quickly answer questions like these about your configurations:
- What interfaces are shutdown?
- Which interfaces are in trunk mode?
- What address and subnet mask is assigned to each interface?
- Which interfaces are missing a critical command?
- Is this configuration missing a standard config line?
It can help you:
- Audit existing router / switch / firewall / wlc configurations
- Modify existing configurations
- Build new configurations
Speaking generally, the library examines an IOS-style config and breaks it into a set of linked parent / child relationships. You can perform complex queries about these relationships.
Usage
The following code will parse a configuration stored in ‘exampleswitch.conf’ and select interfaces that are shutdown.
from ciscoconfparse import CiscoConfParse
parse = CiscoConfParse('exampleswitch.conf', syntax='ios')
for intf_obj in parse.find_objects_w_child('^interface', '^\s+shutdown'):
print("Shutdown: " + intf_obj.text)
The next example will find the IP address assigned to interfaces.
from ciscoconfparse import CiscoConfParse
parse = CiscoConfParse('exampleswitch.conf', syntax='ios')
for intf_obj in parse.find_objects('^interface'):
intf_name = intf_obj.re_match_typed('^interface\s+(\S.+?)$')
# Search children of all interfaces for a regex match and return
# the value matched in regex match group 1. If there is no match,
# return a default value: ''
intf_ip_addr = intf_obj.re_match_iter_typed(
r'ip\saddress\s(\d+\.\d+\.\d+\.\d+)\s', result_type=str,
group=1, default='')
print("{0}: {1}".format(intf_name, intf_ip_addr))
What if we don’t use Cisco?
Don’t let that stop you.
As of CiscoConfParse 1.2.4, you can parse brace-delimited configurations into a Cisco IOS style (see Github Issue #17), which means that CiscoConfParse understands these configurations:
- Juniper Networks Junos
- Palo Alto Networks Firewall configurations
- F5 Networks configurations
CiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes:
- Cisco IOS, Cisco Nexus, Cisco IOS-XR, Cisco IOS-XE, Aironet OS, Cisco ASA, Cisco CatOS
- Arista EOS
- Brocade
- HP Switches
- Force 10 Switches
- Dell PowerConnect Switches
- Extreme Networks
- Enterasys
- Screenos
Docs
- The latest copy of the docs are archived on the web
- There is also a CiscoConfParse Tutorial
Pre-requisites
ciscoconfparse requires Python versions 2.7 or 3.5+ (note: version 3.7.0 has a bug – ref Github issue #117, but version 3.7.1 works); the OS should not matter.
Installation and Downloads
You can install into Python2.x with pip:
pip install --upgrade ciscoconfparse
Use pip3
for Python3.x…
pip3 install --upgrade ciscoconfparse
If you don’t want to use pip, you can install with easy_install:
easy_install -U ciscoconfparse
Otherwise download it from PyPi, extract it and run the setup.py
script:
python setup.py install
If you’re interested in the source, you can always pull from the github repo or bitbucket repo:
- From github:
git clone git://github.com/mpenning/ciscoconfparse cd ciscoconfparse/ pip install .
FAQ
- QUESTION: I want to use ciscoconfparse with Python3; is that safe? ANSWER: ANSWER: Yes.
- QUESTION: Some of the code in the documentation looks different than what I’m used to seeing. Did you change something? ANSWER: Yes, starting around ciscoconfparse v0.9.10 I introducted more methods directly on
IOSConfigLine()
objects; going forward, these methods are the preferred way to use ciscoconfparse. Please start using the new methods shown in the example, since they’re faster, and you type much less code this way. - QUESTION: ciscoconfparse saved me a lot of time, I want to give money. Do you have a donation link? ANSWER: I love getting emails like this; helping people get their jobs done is why I wrote the module. However, I’m not accepting donations.
- QUESTION: Is there a way to use this module with perl? ANSWER: Yes, I do this myself. Install the python package as you normally would and import it into perl with
Inline.pm
andInline::Python
from CPAN. - QUESTION: 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? ANSWER: 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$")
Other Resources
- Dive into Python3 is a good way to learn Python
- Team CYMRU has a Secure IOS Template, which is especially useful for external-facing routers / switches
- Cisco’s Guide to hardening IOS devices
- Center for Internet Security Benchmarks (An email address, cookies, and javascript are required)
Bug Tracker and Support
- Please report any suggestions, bug reports, or annoyances with ciscoconfparse through the github bug tracker.
- If you’re having problems with general python issues, consider searching for a solution on Stack Overflow. If you can’t find a solution for your problem or need more help, you can ask a question.
- If you’re having problems with your Cisco devices, you can open a case with Cisco TAC; if you prefer crowd-sourcing, you can ask on the Stack Exchange Network Engineering site.
————————————————————————————————–
From http://www.pennington.net/
CiscoConfParse
Fundamentals: Using Parent / Child Relationships
IOS Parent-child relationships
CiscoConfParse()
reads an IOS configuration and breaks it into a list of parent-child relationships. Used correctly, these relationships can reveal a lot of useful information. The concept of IOS parent and child is pretty intuitive, but we’ll go through a simple example for clarity.
Note
CiscoConfParse assumes the configuration is in the exact format rendered by Cisco IOS devices when you use show runn
or show start
.
Line 1 is a parent:
policy-map QOS_1
class GOLD
priority percent 10
class SILVER
bandwidth 30
random-detect
class default
!
Child lines are indented more than parent lines; thus, lines 2, 4 and 7 are children of line 1:
policy-map QOS_1
class GOLD
priority percent 10
class SILVER
bandwidth 30
random-detect
class default
!
Furthermore, line 3 (highlighted) is a child of line 2:
policy-map QOS_1
class GOLD
priority percent 10
class SILVER
bandwidth 30
random-detect
class default
!
In short:
- Line 1 is a parent, and its children are lines 2, 4, and 7.
- Line 2 is also a parent, and it only has one child: line 3.
CiscoConfParse()
uses these parent-child relationships to build queries. For instance, you can find a list of all parents with or without a child; or you can find all the configuration elements that are required to reconfigure a certain class-map.
IOSCfgLine
objects
When CiscoConfParse()
reads a configuration, it stores parent-child relationships as a special IOSCfgLine
object. These objects are very powerful.
IOSCfgLine
objects remember:
- The original IOS configuration line
- The parent configuration line
- All child configuration lines
IOSCfgLine
objects also know about child indentation, and they keep special configuration query methods in the object itself. For instance, if you found an IOSCfgLine
object with children, you can search the children directly from the parent by using re_search_children()
.
Example: Retrieving text from an IOSCfgLine
object
This example:
- Parses through a configuration
- Finds an
IOSCfgLine
object withfind_objects()
- Retrieves the configuration text from that object (highlighted in yellow)
>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse([
... '!',
... 'interface Serial1/0',
... ' ip address 1.1.1.5 255.255.255.252'
... ])
>>> for obj in parse.find_objects(r"interface"):
... print("Object: " + str(obj))
... print("Config text: " + str(obj.text))
...
Object: <IOSCfgLine # 1 'interface Serial1/0'>
Config text: interface Serial1/0
>>>
>>> quit()
[mpenning@tsunami ~]$
In the example, obj.text
refers to the IOSCfgLine
text
attribute, which retrieves the text of the original IOS configuration statement.
Baseline configuration for these examples
This tutorial will run all the queries against a sample configuration, which is shown below.
! Filename: /tftpboot/bucksnort.conf
!
policy-map QOS_1
class GOLD
priority percent 10
class SILVER
bandwidth 30
random-detect
class default
!
interface Ethernet0/0
ip address 1.1.2.1 255.255.255.0
no cdp enable
!
interface Serial1/0
encapsulation ppp
ip address 1.1.1.1 255.255.255.252
!
interface Serial1/1
encapsulation ppp
ip address 1.1.1.5 255.255.255.252
service-policy output QOS_1
!
interface Serial1/2
encapsulation hdlc
ip address 1.1.1.9 255.255.255.252
!
class-map GOLD
match access-group 102
class-map SILVER
match protocol tcp
!
Example Usage: Finding interface names that match a substring
The following script will load a configuration file from /tftpboot/bucksnort.conf
and use find_objects()
to find the Serial interfaces.
Note that the ^
symbol at the beginning of the search string is a regular expression; ^interface Serial
tells python to limit the search to lines that begin with interface Serial
.
>>> from ciscoconfparse import CiscoConfParse
>>> parse = CiscoConfParse("/tftpboot/bucksnort.conf")
>>> serial_objs = parse.find_objects("^interface Serial")
The assuming we use the configuration in the example above, find_objects()
scans the configuration for matching config objects and stores a list of IOSCfgLine
objects in serial_objs
.
>>> serial_objs
[<IOSCfgLine # 14 'interface Serial1/0'>,
<IOSCfgLine # 18 'interface Serial1/1'>,
<IOSCfgLine # 23 'interface Serial1/2'>]
As you can see, the config statements are stored inside IOSCfgLine
objects. If you want to access the text inside the IOSCfgLine
objects, just call their text
attribute. For example…
>>> for obj in serial_objs:
... print(obj.text)
...
interface Serial1/0
interface Serial1/1
interface Serial1/2
Going forward, I will assume that you know how to use regular expressions; if you would like to know more about regular expressions, O’Reilly’s Mastering Regular Expressions book is very good.
Example Usage: Finding parents with a specific child
Suppose we need to find interfaces with the QOS_1
service-policy applied outbound…
Method 1: for-loop to iterate over objects and search children
>>> parse = CiscoConfParse("/tftpboot/bucksnort.conf")
>>> all_intfs = parse.find_objects(r"^interf")
>>> qos_intfs = list()
>>> for obj in all_intfs:
... if obj.re_search_children(r"service-policy\soutput\sQOS_1"):
... qos_intfs.append(obj)
...
>>> qos_intfs
[<IOSCfgLine # 18 'interface Serial1/1'>]
This script iterates over the interface objects, and searches the children for the qos policy. It’s worth mentioning that Python also has something called a list-comprehension, which makes the script for this task a little more compact…
Method 2: list-comprehension to iterate over objects and search children
>>> parse = CiscoConfParse("/tftpboot/bucksnort.conf")
>>> qos_intfs = [obj for obj in parse.find_objects(r"^interf") \
... if obj.re_search_children(r"service-policy\soutput\sQOS_1")]
...
>>> qos_intfs
[<IOSCfgLine # 18 'interface Serial1/1'>]
Method 3: find_objects_w_child()
>>> parse = CiscoConfParse("/tftpboot/bucksnort.conf")
>>> qos_intfs = parse.find_objects_w_child(parentspec=r"^interf", \
... childspec=r"service-policy\soutput\sQOS_1")
...
>>> qos_intfs
[<IOSCfgLine # 18 'interface Serial1/1'>]
You can choose any of these methods to accomplish your task… some might question why we cover the first two methods when find_objects_w_child()
solves the problem completely. In this case, they have a point; however, find_objects_w_child()
is much slower when you have more than one child line to inspect per interface, because find_objects_w_child()
performs a line-by-line search of the whole configuration line each time it is called. By contrast, Method 1 is more efficient because you could simply call re_search_children()
multiple times for each interface object. re_search_children()
only searches the child lines of that IOSCfgLine()
interface object.
Example Usage: Finding parents without a specific child
Let’s suppose you wanted a list of all interfaces that have CDP enabled; this implies a couple of things:
- CDP has not been disabled globally with
no cdp run
- The interfaces in question are not configured with
no cdp enable
find_objects_wo_child()
is a function to find parents without a specific child; it requires arguments similar to find_objects_w_child()
:
- The first argument is a regular expression to match the parents
- The second argument is a regular expression to match the child’s exclusion
Since we need to find parents that do not have no cdp enable
, we will use find_objects_wo_child()
for this query. Note that the script below makes use of a special property of python lists… empty lists test False in Python; thus, we can use if not bool(parse.find_objects(r'no cdp run'))
to ensure that CDP is running globally on this device.
>>> parse = CiscoConfParse("/tftpboot/bucksnort.conf")
>>> if not bool(parse.find_objects(r'no cdp run')):
... cdp_intfs = parse.find_objects_wo_child(r'^interface',
... r'no cdp enable')
Results:
>>> cdp_intfs
[<IOSCfgLine # 14 'interface Serial1/0'>, <IOSCfgLine # 18 'interface Serial1/1'>, <IOSCfgLine # 23 'interface