Reputation: 21
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
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
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