Jason
Jason

Reputation: 21

Error message while running python script to parse IOS config files

I have been able to write a python script that parses IOS config files but I am getting an error.

Below is the script:

import glob, os
from ciscoconfparse import CiscoConfParse
os.chdir("T:/")
for cfgfile in glob.glob("*-confg"):
    parse = CiscoConfParse("T:/" + cfgfile, factory=True, syntax='ios')
    host = parse.find_objects_dna(r'Hostname') 
    interfaces_with_helpers = parse.find_parents_w_child( "^interf", "ip helper-address 10.194.35.201")
    if interfaces_with_helpers:
        print (host[0].hostname)
    for interface in interfaces_with_helpers:
        print (interface)

When I run the script it seems to be chugging away fine and then get the below error:

Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "C:\Python34\lib\site-packages\ciscoconfparse-1.2.37-py3.4.egg\ciscoconfparse\ciscoconfparse.py", line 186, in __init__ CiscoConfParse=self)
File "C:\Python34\lib\site-packages\ciscoconfparse-1.2.37-py3.4.egg\ciscoconfparse\ciscoconfparse.py", line 2209, in __init__
self._list = self._bootstrap_obj_init(data)
File "C:\Python34\lib\site-packages\ciscoconfparse-1.2.37-py3.4.egg\ciscoconfparse\ciscoconfparse.py", line 2433, in _bootstrap_obj_init
syntax='ios')
File "C:\Python34\lib\site-packages\ciscoconfparse-1.2.37-py3.4.egg\ciscoconfparse\ciscoconfparse.py", line 2982, in ConfigLineFactory
comment_delimiter=comment_delimiter) # instance of the proper subclass
File "C:\Python34\lib\site-packages\ciscoconfparse-1.2.37-py3.4.egg\ciscoconfparse\models_cisco.py", line 1758, in __init__raise ValueError
ValueError
>>>

Upvotes: 2

Views: 709

Answers (2)

Mike Pennington
Mike Pennington

Reputation: 43097

Your code is fragile because it depends on factory=True, which is considered beta-quality at best. You should do this and not use find_objects_dna()

Also you should use ciscoconfparse2 which simplifies the API quite a bit... I modified to work with it below.

import glob, os
from ciscoconfparse2 import CiscoConfParse

os.chdir("T:/")
for cfgfile in glob.glob("*-confg"):
    parse = CiscoConfParse("T:/" + cfgfile, factory=True, syntax='ios')
    host = parse.find_objects('hostname')[0].split()[-1] # <<< removed find_objects_dna()
    interfaces_with_helpers = parse.find_parent_objects(["^interf",
                                                         "ip helper-address 10.194.35.201"])
    if interfaces_with_helpers:
        print (host[0].hostname)
    for interface in interfaces_with_helpers:
        print (interface)

Upvotes: 0

Martin Konecny
Martin Konecny

Reputation: 59671

Looks like an unexpected config file format to me. If you look at the source where the ValueError is being thrown in the CiscoConfParse library:

    REGEX = r'^aaa\sgroup\sserver\s(?P<protocol>\S+)\s(?P<group>\S+)$'
    mm = re.search(REGEX, self.text)
    if not (mm is None):
        groups = mm.groupdict()
        self.protocol = groups.get('protocol', '')
        self.group = groups.get('group', '')
    else:
        raise ValueError

It looks like it stumbled across a config file where it expected the line to satisfy the regex ^aaa\sgroup\sserver\s(?P<protocol>\S+)\s(?P<group>\S+)$ and failed.

While you are iterating over the results of glob.glob("*-confg"), you will need to print out the filename you are currently working with to see which file is malformed. Then either correct this config file, or narrow down which config files you are trying to parse.

You can also just ignore the error as follows:

import glob, os
from ciscoconfparse import CiscoConfParse
os.chdir("T:/")
for cfgfile in glob.glob("*-confg"):
    try:
        parse = CiscoConfParse("T:/" + cfgfile, factory=True, syntax='ios')
    except ValueError:
        print "Malformed config file found. Skipping " + cfgfile
        continue
    host = parse.find_objects_dna(r'Hostname') 
    interfaces_with_helpers = parse.find_parents_w_child( "^interf", "ip helper-address 10.194.35.201")
    if interfaces_with_helpers:
        print (host[0].hostname)
    for interface in interfaces_with_helpers:
        print (interface)

Upvotes: 1

Related Questions