def update_config_file_parse(item_remove, config_file, type): """Update config file with unused object-group, ACL, and group-policy statements removed; ciscoconfparse library needed to remove child objects""" parse = CiscoConfParse(config_file) for i in item_remove: if type == 'obg': for obj in parse.find_objects(r"^object-group network %s" %i): obj.delete(r"^object-group network %s" %i) elif type == 'acl': for obj in parse.find_objects(r"^access-list %s" %i): obj.delete(r"^access-list %s" %i) elif type == 'gp': for obj in parse.find_objects(r"^group-policy %s" %i): obj.delete(r"^group-policy %s" %i) config_file_new = [] for line in parse.ioscfg: config_file_new.append(line) return config_file_new
def testValues_parent_child_parsing_02(self): cfg = CiscoConfParse(self.c01) # Expected child / parent line numbers before the insert parent_intf_before = { # Line 11 is Serial1/0, child is line 13 13: 11, # Line 15 is GigabitEthernet4/1 16: 15, 17: 15, 18: 15, 19: 15, # Line 21 is GigabitEthernet4/2 22: 21, 23: 21, 24: 21, 25: 21, } # Expected child / parent line numbers after the insert # Validate line numbers *before* inserting for obj in cfg.find_objects(''): result_correct = parent_intf_before.get(obj.linenum, False) if result_correct: test_result = obj.parent.linenum ## Does this object parent's line number match? self.assertEqual(result_correct, test_result) # Insert lines here... for intf_obj in cfg.find_objects('^interface\sGigabitEthernet'): # Configured with an access vlan... if ' switchport access vlan 100' in set(map(attrgetter('text'), intf_obj.children)): intf_obj.insert_after(' spanning-tree portfast') cfg.atomic() parent_intf_after = { # Line 11 is Serial1/0, child is line 13 13: 11, # Line 15 is GigabitEthernet4/1 16: 15, 17: 15, 18: 15, 19: 15, # Line 22 is GigabitEthernet4/2 23: 22, 24: 22, 25: 22, 26: 22, } # Validate line numbers *after* inserting for obj in cfg.find_objects(''): result_correct = parent_intf_after.get(obj.linenum, False) if result_correct: test_result = obj.parent.linenum ## Does this object parent's line number match? self.assertEqual(result_correct, test_result)
def update_config_file_parse(item_remove, config_file, type): parse = CiscoConfParse(config_file) for i in item_remove: if type == 'obg': for obj in parse.find_objects(r"^object-group network %s" %i): obj.delete(r"^object-group network %s" %i) elif type == 'acl': for obj in parse.find_objects(r"^access-list %s" %i): obj.delete(r"^access-list %s" %i) config_file_new = [] for line in parse.ioscfg: config_file_new.append(line) return config_file_new
def testValues_banner_delete_01(): # Ensure multiline banners are correctly deleted CONFIG = ['!', 'banner motd ^', ' trivial banner1 here ^', 'interface GigabitEthernet0/0', ' ip address 192.0.2.1 255.255.255.0', 'banner exec ^', ' trivial banner2 here ^', 'end'] parse = CiscoConfParse(CONFIG) for obj in parse.find_objects('^banner'): obj.delete() parse.commit() assert parse.find_objects('^banner')==[]
def netcompare(origin, target, vendor, config): origin_file = CiscoConfParse(origin, comment=config[vendor] ['CiscoConfParse_comment'], syntax=config[vendor] ['CiscoConfParse_syntax'], factory=False) target_file = CiscoConfParse(target, comment=config[vendor] ['CiscoConfParse_comment'], syntax=config[vendor] ['CiscoConfParse_syntax'], factory=False) result = {} for line_origin in origin_file.objs: eq_lines = (target_file.find_objects( '^' + re.escape(line_origin.text) + '$')) for line_target in eq_lines: if line_origin.geneology_text == line_target.geneology_text: break else: # Delete needed pointer = result index = len(line_origin.geneology_text) for cmd in line_origin.geneology_text: index = index - 1 if ('NO', cmd) in pointer: break if ('_CR', cmd) in pointer: pointer = pointer.get(('_CR', cmd)) elif index == 0: pointer[('NO', cmd)] = {} pointer = pointer.get(('NO', cmd)) else: pointer[('_CR', cmd)] = {} pointer = pointer.get(('_CR', cmd)) for line_target in target_file.objs: find = 0 eq_lines = (origin_file.find_objects( '^' + re.escape(line_target.text) + '$')) for line_origin in eq_lines: if line_origin.geneology_text == line_target.geneology_text: find = 1 if find == 0: # Create needed pointer = result for cmd in line_target.geneology_text: if not ('_CR', cmd) in pointer: pointer[('_CR', cmd)] = {} pointer = pointer.get(('_CR', cmd)) return result
def main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") map_list = cisco_cfg.find_objects(r"^crypto map CRYPTO") for cryptoMap in map_list: print cryptoMap.text mapChildren = cryptoMap.children for child in mapChildren: print child.text print '\nCrypto maps using PFS group 2:\n' pfs2_list = cisco_cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"set pfs group2") for cryptoMap in pfs2_list: print cryptoMap.text print '\nCrypto maps not using AES:\n' noaes_list = cisco_cfg.find_objects_wo_child(parentspec=r"^crypto map CRYPTO", childspec=r"set transform-set AES-SHA") for cryptoMap in noaes_list: print cryptoMap.text mapChildren = cryptoMap.children transformSetLine = mapChildren[1] (head,transformSet) = transformSetLine.text.split('set transform-set') print transformSet
def main() : parse = CiscoConfParse("cisco_ipsec.txt") # Find all crypto map entries and print parent and child print ("The crypto maps in the parsed config are : \n" ) crypto_objs = parse.find_objects(r"^crypto map CRYPTO") for obj in crypto_objs : print (obj.text) child_obj = (obj.re_search_children(r".*")) for obj2 in child_obj : print (obj2.text) print ("\n") # Find crypto maps with pfs group2 pfsg2 = parse.find_parents_w_child("crypto map CRYPTO", "set pfs group2" ) print ("The following crypto maps have pfs set to group 2: \n") for obj in pfsg2 : print (obj) # Find crypto maps without AES encryptions print ("\n") trans_set = parse.find_parents_wo_child("^crypto map CRYPTO", "set transform-set AES-SHA") print ("The crypto maps that do not have AES-SHA transform set are : \n") for obj in trans_set : print (obj)
def get_interfaces(device): """Get the Interfaces off a device""" conf_file = conf_dir + device['Device'] + "-confg" if device['Type'] == 'Primary' or device['Type'] == 'Standby': try: parse = CiscoConfParse(conf_file) except: return else: default_shut = False if len(parse.find_objects('no shutdown')): default_shut = True vlan_ints = parse_vlan_interfaces(parse, device['Device'], default_shut) for en in vlan_ints: en['MgmtGroup'] = device['MgmtGroup'] if device['Type'] == 'Standby': en['Standby'] = True else: en['Standby'] = False interface_list.append(en) l3_ints = parse_l3_interfaces(parse, device['Device'], default_shut) for en in l3_ints: en['MgmtGroup'] = device['MgmtGroup'] if device['Type'] == 'Standby': en['Standby'] = True else: en['Standby'] = False interface_list.append(en)
def main(): cisco_ios = CiscoConfParse("cisco_ipsec.txt") crypto_map = cisco_ios.find_objects(r'crypto map') for child in crypto_map: print child.text for i in child.children: print i.text
def testVal_IOSIntfLine_in_ipv4_subnets(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': True, 'interface Serial 1/1': True, 'interface GigabitEthernet4/1': None, 'interface GigabitEthernet4/2': None, 'interface GigabitEthernet4/3': None, 'interface GigabitEthernet4/4': None, 'interface GigabitEthernet4/5': None, 'interface GigabitEthernet4/6': None, 'interface GigabitEthernet4/7': None, 'interface GigabitEthernet4/8.120': True, 'interface ATM5/0/0': None, 'interface ATM5/0/0.32 point-to-point': True, 'interface ATM5/0/1': None, } test_result = dict() ## Parse all interface objects in self.c01 and check in_ipv4_subnets test_network1 = IPv4Obj('1.1.0.0/23', strict=False) test_network2 = IPv4Obj('1.1.2.0/23', strict=False) networks = set([test_network1, test_network2]) for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.in_ipv4_subnets(networks) self.maxDiff = None self.assertEqual(result_correct, test_result)
def testVal_IOSIntfLine_ipv4_network_object(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': IPv4Obj('1.1.1.0/30', strict=False), 'interface Serial 1/1': IPv4Obj('1.1.1.8/31', strict=False), 'interface GigabitEthernet4/1': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/2': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/3': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/4': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/5': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/6': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/7': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/8.120': IPv4Obj('1.1.2.0/24', strict=False), 'interface ATM5/0/0': IPv4Obj('127.0.0.1/32', strict=False), 'interface ATM5/0/0.32 point-to-point': IPv4Obj('1.1.1.4/30', strict=False), 'interface ATM5/0/1': IPv4Obj('127.0.0.1/32', strict=False), } test_result = dict() ## Parse all interface objects in self.c01 and check ipv4_network_object for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.ipv4_network_object self.assertEqual(result_correct, test_result)
def testValues_find_objects_replace_01(): """test whether find_objects we can correctly replace object values using native IOSCfgLine object methods""" config01 = ['!', 'boot system flash slot0:c2600-adventerprisek9-mz.124-21a.bin', 'boot system flash bootflash:c2600-adventerprisek9-mz.124-21a.bin', '!', 'interface Ethernet0/0', ' ip address 172.16.1.253 255.255.255.0', '!', 'ip route 0.0.0.0 0.0.0.0 172.16.1.254', '!', 'end', ] result_correct = ['!', '! old boot image flash slot0:c2600-adventerprisek9-mz.124-21a.bin', '! old boot image flash bootflash:c2600-adventerprisek9-mz.124-21a.bin', '!', 'interface Ethernet0/0', ' ip address 172.16.1.253 255.255.255.0', '!', 'ip route 0.0.0.0 0.0.0.0 172.16.1.254', '!', 'end', ] cfg = CiscoConfParse(config01) for obj in cfg.find_objects('boot system'): obj.replace('boot system', '! old boot image') test_result = cfg.ioscfg assert result_correct==test_result
def testVal_object_group_network_02(): """Test recursion through a group object""" conf = ['!', 'name 1.1.2.20 loghost01', 'name 1.2.2.20 loghost02', '!', 'object-group network INSIDE_recurse', ' network-object host loghost02', 'object-group network INSIDE_addrs', ' network-object host loghost01', ' network-object host 1.1.2.1', ' network-object 1.1.2.2 255.255.255.255', ' network-object 1.1.2.0 255.255.255.0', ' group-object INSIDE_recurse', '!',] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'object-group\snetwork')[1] result_correct_01 = [IPv4Obj('1.1.2.20/32'), IPv4Obj('1.1.2.1/32'), IPv4Obj('1.1.2.2/32'), IPv4Obj('1.1.2.0/24'), IPv4Obj('1.2.2.20/32')] result_correct_02 = ['1.1.2.20', '1.1.2.1', '1.1.2.2', '1.1.2.0/255.255.255.0', '1.2.2.20'] # Ensure obj.name is set correctly assert obj.name=="INSIDE_addrs" assert obj.networks==result_correct_01 assert obj.network_strings==result_correct_02 ## Test obj.networks again to test the result_cache assert obj.networks==result_correct_01
def testValues_IOSIntfLine_find_objects_factory_02(self): """test whether find_objects() returns correct IOSIntfLine objects and tests IOSIntfLine methods""" with patch('__main__.IOSIntfLine') as mock: # the mock pretends to be an IOSCfgLine so we can test against it result_correct01 = mock result_correct01.linenum = 12 result_correct01.text = 'interface Serial 2/0' result_correct01.classname = 'IOSIntfLine' result_correct01.ipv4_addr_object = IPv4Network('1.1.1.1/30') result_correct02 = self.c01_insert_serial_replace cfg = CiscoConfParse(self.c01, factory=True) # Insert a line above the IOSIntfLine object cfg.insert_before('interface Serial 1/0', 'default interface Serial 1/0') # Replace text in the IOSIntfLine object cfg.replace_lines('interface Serial 1/0', 'interface Serial 2/0', exactmatch=False) test_result01 = cfg.find_objects('^interface Serial 2/0')[0] test_result02 = cfg.ioscfg # Check attributes of the IOSIntfLine object self.assertEqual(result_correct01.linenum, test_result01.linenum) self.assertEqual(result_correct01.text, test_result01.text) self.assertEqual(result_correct01.classname, test_result01.classname) self.assertEqual(result_correct01.ipv4_addr_object, test_result01.ipv4_addr_object) # Ensure the text configs are exactly what we wanted self.assertEqual(result_correct02, test_result02)
def testValues_find_objects_factory_01(self): """Test whether find_objects returns the correct objects""" with patch('__main__.IOSIntfLine') as mock: vals = [('interface GigabitEthernet4/1', 15), ('interface GigabitEthernet4/2', 21), ('interface GigabitEthernet4/3', 27), ('interface GigabitEthernet4/4', 32), ('interface GigabitEthernet4/5', 35), ('interface GigabitEthernet4/6', 39), ('interface GigabitEthernet4/7', 43), ('interface GigabitEthernet4/8', 47), ] ## Build fake IOSIntfLine objects to validate unit tests... result_correct = list() # deepcopy a unique mock for every val with itertools.repeat() mockobjs = map(deepcopy, repeat(mock, len(vals))) # mock pretends to be an IOSCfgLine so we can test against it for idx, obj in enumerate(mockobjs): obj.text = vals[idx][0] # Check the text obj.linenum = vals[idx][1] # Check the line numbers # append the fake IOSIntfLine object to result_correct result_correct.append(obj) cfg = CiscoConfParse(self.c01, factory=True) test_result = cfg.find_objects('^interface GigabitEther') for idx, test_result_object in enumerate(test_result): # Check line numbers self.assertEqual(result_correct[idx].linenum, test_result_object.linenum) # Check text self.assertEqual(result_correct[idx].text, test_result_object.text)
def testValues_insert_after_atomic_factory_01(self): """Ensure that comments which are added, assert is_comment""" with patch('__main__.IOSCfgLine') as mock: # the mock pretends to be an IOSCfgLine so we can test against it result_correct01 = mock result_correct01.linenum = 16 result_correct01.text = ' ! TODO: some note to self' result_correct01.classname = 'IOSCfgLine' result_correct01.is_comment = True result_correct02 = [ 'interface GigabitEthernet4/1', ' ! TODO: some note to self', ' switchport', ' switchport access vlan 100', ' switchport voice vlan 150', ' power inline static max 7000', ] linespec = 'interface GigabitEthernet4/1' cfg = CiscoConfParse(self.c01, factory=True) cfg.insert_after(linespec, ' ! TODO: some note to self', exactmatch=True, atomic=True) test_result01 = cfg.find_objects('TODO')[0] self.assertEqual(result_correct01.linenum, test_result01.linenum) self.assertEqual(result_correct01.text, test_result01.text) self.assertEqual(result_correct01.classname, test_result01.classname) self.assertEqual(result_correct01.is_comment, test_result01.is_comment) # FIXME: this fails... maybe because I don't parse comments as children correctly??? test_result02 = cfg.find_children(linespec) self.assertEqual(result_correct02, test_result02)
def testValues_banner_delimiter_05(): # Test multiple banners CONFIG = ['!', 'banner motd ^', ' trivial banner1 here ^', 'banner exec ^', ' trivial banner2 here ^', 'end'] parse = CiscoConfParse(CONFIG) bannerobj = parse.find_objects('^banner\smotd')[0] BANNER_LINE_NUMBER = 1 assert bannerobj.linenum == BANNER_LINE_NUMBER for obj in bannerobj.children: assert obj.parent.linenum == BANNER_LINE_NUMBER bannerobj = parse.find_objects('^banner\sexec')[0] BANNER_LINE_NUMBER = 3 assert bannerobj.linenum == BANNER_LINE_NUMBER for obj in bannerobj.children: assert obj.parent.linenum == BANNER_LINE_NUMBER
def Cisco_Parser(filename): cisco_cfg=CiscoConfParse(filename) interfaces=cisco_cfg.find_objects(r"^interface") vtys=cisco_cfg.find_objects(r"^line vty ") for intf in interfaces: output= str(intf) output+= '\n' + str(intf.children) for vty in vtys: output+= '\n' + '#' * 80 output+= "Configuration for Line vty is: \n {}".format(vty.children) l2_interfaces=cisco_cfg.find_objects_w_child(parentspec=r"^interface", childspec="no ip address") l3_interfaces=cisco_cfg.find_objects_wo_child(parentspec=r"^interface", childspec="no ip address") output+= '\n' +'#' * 80 output+= "\nL2 Interfaces are {}".format(l2_interfaces) output+= '\n' +'#' * 80 output+= "\nL3 Interfaces are {}".format(l3_interfaces) return output
def parse_conf_file(file1): cisco_conf = CiscoConfParse(file1) target = cisco_conf.find_objects(r'^' + PARSE_STRING) for p_elmt in target: print 'Found target:\n{}'.format(p_elmt.text) for c_elmt in p_elmt.all_children: print c_elmt.text print ''
def testValues_find_objects_delete_01(self): """Test whether IOSCfgLine.delete() recurses through children correctly""" result_correct = ['!', '!', '!'] cfg = CiscoConfParse(self.c04) for intf in cfg.find_objects(r'^interface'): intf.delete(recurse=True) # recurse=True is the default test_result = cfg.ioscfg self.assertEqual(result_correct, test_result)
def testValues_banner_delimiter_04(): # Test multiple banner delimiters on different lines CONFIG = ['!', 'banner motd ^', ' trivial banner here ^^', 'end'] parse = CiscoConfParse(CONFIG) bannerobj = parse.find_objects('^banner')[0] BANNER_LINE_NUMBER = 1 assert bannerobj.linenum == BANNER_LINE_NUMBER for obj in bannerobj.children: assert obj.parent.linenum == BANNER_LINE_NUMBER
def main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") cryptomaps = cisco_cfg.find_objects(r"^crypto map CRYPTO") print "\n crypto maps:" for entry in cryptomaps: print "{0}" .format(entry.text) for childtext in entry.children: print childtext.text
def conf_to_xml(f): ccp = CiscoConfParse(f) print ccp hostname = ccp.find_lines("^hostname")[0].lower() hostname = re.sub("hostname ", "", hostname) xmlroot = etree.Element('add') doc = etree.Element('doc') xmlroot.append(doc) f_id = etree.Element('field') f_id.attrib["name"] = "id" f_id.text = hostname doc.append(f_id) f_type = etree.Element('field') f_type.attrib["name"] = "doctype" f_type.text = "full config" doc.append(f_type) f_content = etree.Element('field') f_content.attrib["name"] = "content" f_content.text = "\n".join(ccp.find_lines(".*")) doc.append(f_content) types = ['interface', 'router', 'ip vrf', 'ip access-list', 'class-map', 'policy-map'] for t in types: for obj in ccp.find_objects(r"^"+t): subdoc = etree.Element('doc') subid = hostname + " " + obj.text subf_id = etree.Element('field') subf_id.attrib["name"] = "id" subf_id.text = subid subdoc.append(subf_id) subf_type = etree.Element('field') subf_type.attrib["name"] = "doctype" subf_type.text = t subdoc.append(subf_type) subf_content = etree.Element('field') subf_content.attrib["name"] = "content" subf_content.text = "\n".join(ccp.find_all_children("^" + obj.text)) subdoc.append(subf_content) doc.append(subdoc) xmlstring = etree.tostring(xmlroot, pretty_print=True) etree.ElementTree(xmlroot).write(xmldir + "/" + hostname + ".xml")
def pog_cd(filename): pog_all = {} mycfg = CiscoConfParse(filename) lines = mycfg.find_objects(r'^object-group protocol') if lines != []: for parent_item in lines: list_child_items = [] for child_item in parent_item.all_children: list_child_items.append(child_item.text) pog_all[parent_item.text] = list_child_items lines = mycfg.find_objects(r'^object protocol') if lines != []: for parent_item in lines: list_child_items = [] for child_item in parent_item.all_children: list_child_items.append(child_item.text) pog_all[parent_item.text] = list_child_items return pog_all
def update_conf(item_remove, config_file, object_type): """Update config file with unused object-group, ACL, and group-policy statements removed; ciscoconfparse library needed to remove child objects""" parse = CiscoConfParse(config_file) for i in item_remove: for obj in parse.find_objects(r"^%s %s" % (object_type, i)): obj.delete(r"^%s %s" % (object_type, i)) return generate_conf(parse)
def run_ifanalysis(iftext): print ('Analyzing logs files for desired keyword....!') for i in os.listdir('logs/'): outf = open('analysis/' + i, 'w') parse = CiscoConfParse('logs/'+ i) for obj in parse.find_objects(iftext): for i in obj.geneology_text: outf.write((i +'\n')) outf.close() print ('Analyzing Done....!')
def main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") intf = cisco_cfg.find_objects(r"^crypto map CRYPTO") for i in intf: print i.text for j in i.children: print j.text print
def main(): cfg=CiscoConfParse('Config-file.txt') temp_list=cfg.find_objects(r"^crypto map CRYPTO") for entry in temp_list: print "Entry ", entry.text temporary=entry.children for item in temporary: print item.text
def sog_cd(filename): sog_all = {} mycfg = CiscoConfParse(filename) lines = mycfg.find_objects(r'^object-group service') if lines != []: for parent_item in lines: list_child_items = [] for child_item in parent_item.all_children: list_child_items.append(child_item.text) sog_all[parent_item.text] = list_child_items return sog_all
def testVal_ipv4_addr(): conf = ['!', 'interface Ethernet0/0', ' nameif OUTSIDE', ' ip address 198.101.172.106 255.255.255.128 standby 198.101.172.107', '!', 'interface Ethernet0/1', ' nameif INSIDE', ' ip address 192.0.2.254 255.255.255.0', '!', ] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'^interface\sEthernet0\/0$')[0] # Ensure obj.ipv4_addr is set correctly assert obj.ipv4_addr=='198.101.172.106' assert obj.ipv4_standby_addr=='198.101.172.107' obj = cfg_factory.find_objects(r'^interface\sEthernet0\/1$')[0] assert obj.ipv4_addr=='192.0.2.254'
def validateconfigLAN(devconfig): parse = CiscoConfParse(io.StringIO(devconfig), syntax='ios') intf_hostname = parse.re_match_iter_typed(r'^hostname\s+(\S+)', default='') interfaces = [] 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_policy = intf_obj.re_match_iter_typed(r'service-policy\sinput\s(\w+\-\w+\-\w+)\s', result_type=str, group=1, default='') if intf_policy: interfaces.append(intf_name) writefile = intf_hostname + '\t' + intf_name + '\t' + intf_policy with open('C:\\scripts_logs\\QoS2\\LAN\\' + username + '.log', 'a') as f: f.write(writefile) f.write('\n') return [intf_hostname, interfaces]
def testVal_IOSIntfLine_ipv4_masklength(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': 30, 'interface Serial 1/1': 31, 'interface GigabitEthernet4/1': 0, 'interface GigabitEthernet4/2': 0, 'interface GigabitEthernet4/3': 0, 'interface GigabitEthernet4/4': 0, 'interface GigabitEthernet4/5': 0, 'interface GigabitEthernet4/6': 0, 'interface GigabitEthernet4/7': 0, 'interface GigabitEthernet4/8.120': 24, 'interface ATM5/0/0': 0, 'interface ATM5/0/0.32 point-to-point': 30, 'interface ATM5/0/1': 0, } test_result = dict() ## Parse all interface objects in self.c01 and check ipv4_masklength for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.ipv4_masklength self.maxDiff = None self.assertEqual(result_correct, test_result)
def testVal_IOSIntfLine_has_no_icmp_redirects(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': False, 'interface Serial 1/1': False, 'interface GigabitEthernet4/1': False, 'interface GigabitEthernet4/2': False, 'interface GigabitEthernet4/3': False, 'interface GigabitEthernet4/4': False, 'interface GigabitEthernet4/5': False, 'interface GigabitEthernet4/6': False, 'interface GigabitEthernet4/7': False, 'interface GigabitEthernet4/8.120': False, 'interface ATM5/0/0': False, 'interface ATM5/0/0.32 point-to-point': True, 'interface ATM5/0/1': False, } test_result = dict() ## Parse all interface objects in self.c01 and check has_no_icmp_redirects for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.has_no_icmp_redirects self.maxDiff = None self.assertEqual(result_correct, test_result)
def ios_get_int_attrib(conf_file,int): int_dict = {'name': '', 'desc': '', 'encap': '', 'ip': '', 'mask': '', 'ser_in' : '', 'ser_out' : '', 'mtu' : '', 'shut': True, 'vrf':'default'} int_regex = '^interface '+int #buff = CiscoConfParse(conf_file).find_all_children(int_regex) buff = CiscoConfParse(CiscoConfParse(conf_file).find_all_children(int_regex), factory=True) obj = buff.find_objects('^interface')[0] int_dict['ip'] = obj.ipv4_addr int_dict['mask'] = obj.ipv4_netmask int_dict['name'] = obj.name int_dict['mtu'] = obj.manual_mtu int_dict['desc'] = obj.description if CiscoConfParse(obj.ioscfg).find_objects(r'ip\svrf'): int_dict['vrf'] = str(CiscoConfParse(obj.ioscfg).find_objects(r'ip\svrf')[0].ioscfg).strip("'[]'").replace(' ip vrf forwarding ','') if CiscoConfParse(obj.ioscfg).find_objects(r'service-policy\sinput'): int_dict['ser_in'] = str(CiscoConfParse(obj.ioscfg).find_objects(r'service-policy\sinput')[0].ioscfg).strip("'[]'").replace(' service-policy input ','') if CiscoConfParse(obj.ioscfg).find_objects(r'service-policy\soutput'): int_dict['ser_out'] = str(CiscoConfParse(obj.ioscfg).find_objects(r'service-policy\soutput')[0].ioscfg).strip("'[]'").replace(' service-policy output ','') if not CiscoConfParse(obj.ioscfg).find_objects(r'shutdown'): int_dict['shut'] = False if CiscoConfParse(obj.ioscfg).find_objects(r'encapsulation\sdot1Q'): int_dict['encap'] = str(CiscoConfParse(obj.ioscfg).find_objects(r'encapsulation\sdot1Q')[0].ioscfg).strip("'[]'").strip().replace('encapsulation dot1Q ','') int_dict['desc'] = obj.description return int_dict
def get_interface_vlans(config, syntax): from ciscoconfparse import CiscoConfParse interfaces = list() parse = CiscoConfParse(config.splitlines(), syntax=syntax) for interface_obj in parse.find_objects('^interface'): if not interface_obj.is_virtual_intf: interface = {'name': None, 'mode': None, 'access-vlan': None, 'trunk-vlans': None, 'native-vlan': None, 'tagged-native-vlan': None} interface_name = normalize_interface_names(interface_obj.re_match_typed(r'^interface\s+(\S.+?)$')) interface_mode = interface_obj.re_match_iter_typed(r'switchport mode (.*)', recurse=True) interface_access_vlan = interface_obj.re_match_iter_typed(r'switchport access vlan (.*)', recurse=True) interface_trunk_vlans = interface_obj.re_match_iter_typed(r'switchport trunk allowed vlan.*? (\d.*)', recurse=True).split(',') interface_native_vlan = interface_obj.re_match_iter_typed(r'switchport trunk native vlan (\d*)', recurse=True) interface_tagged_native_vlan = 'vlan dot1q tag native' in config interfaces.append({'name': interface_name, 'mode': interface_mode, 'access-vlan': interface_access_vlan, 'trunk-vlans': interface_trunk_vlans, 'native_vlan': interface_native_vlan, 'tagged-native-vlan': interface_tagged_native_vlan}) return interfaces
def get_outer_config(filename, vrf, outer_encap, basedir, bgpid, fw): data = [] vrfmember = 'vrf ' + vrf parse = CiscoConfParse(basedir + filename) # Create L2 VLAN data.append("vlan " + str(outer_encap)) # SVI for obj in parse.find_objects("interface Vlan" + str(outer_encap)): svi = obj.text data.append(svi) if obj.hash_children != 0: for c in obj.children: if bool(re.search('ip address', c.text)): ip = c.text ip = ip.replace("ip address ", "") ip = ip.replace("/30", "") ip = ip.strip() data.append(c.text) # BGP bgp_details = parse.find_all_children("^router bgp") for d in bgp_details: data.append(d) # Trunk Link if bool(re.search('RES-MMP', vrf)): data.append("interface Ethernet2/9") else: data.append("interface Ethernet2/10") data.append(" switchport") data.append(" switchport mode trunk") data.append(" switchport trunk allowed vlan add " + str(outer_encap)) data.append(" no shutdown") return (ip, data)
def testVal_object_group_network_01(): """Test object group network results""" conf = ['!', 'name 1.1.2.20 loghost01', '!', 'object-group network INSIDE_addrs', ' network-object host loghost01', ' network-object host 1.1.2.1', ' network-object 1.1.2.2 255.255.255.255', ' network-object 1.1.2.0 255.255.255.0', '!',] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'object-group\snetwork')[0] result_correct_01 = [IPv4Obj('1.1.2.20/32'), IPv4Obj('1.1.2.1/32'), IPv4Obj('1.1.2.2/32'), IPv4Obj('1.1.2.0/24')] result_correct_02 = ['1.1.2.20', '1.1.2.1', '1.1.2.2', '1.1.2.0/255.255.255.0'] # Ensure obj.name is set correctly assert obj.name=="INSIDE_addrs" assert obj.networks==result_correct_01 assert obj.network_strings==result_correct_02 ## Test obj.networks again to test the result_cache assert obj.networks==result_correct_01
def config_backup(task): r = task.run(task=networking.napalm_get, getters=["config"]) #with open(f"backup/{task.host.name}.txt", "w") as f: # f.write(r.result['config']['running']) confile = r.result['config']['running'] #with open(f"backup/{task.host.name}.txt", "r") as f: # confile = f.read() parse = CiscoConfParse(confile.splitlines()) print(parse) CL_RE = re.compile(r'^\sclass\s\S*') data = {} cl = [] for obj in parse.find_objects(CL_RE): c = {} cl_name = obj.re_match(r'^\sclass\s(\S*)') cir = obj.re_match_iter_typed(r'^\s+police\scir\s(\d*).+', default='') if cir: c['class'] = cl_name c['cir'] = cir cl.append(c) data['host'] = task.host.name data['result'] = cl task.host['qos'] = cl return data
def vrfs_from_device(): with open("backup/MV1_N7K_AGG_PE_01.txt", "r") as f: confile = f.read() parse = CiscoConfParse(confile.splitlines()) print(parse) VRF_RE = re.compile(r'^vrf\scontext\s\S*\d*') #VRF_RE = re.compile(r'^vrf\scontext\sVR184000') routes = [] vrfs = [] for obj in parse.find_objects(VRF_RE): v = {} v['name'] = obj.re_match(r'vrf context (.+)') v['rd'] = "{}000".format( obj.re_match_iter_typed(r'^\s+rd\s(.+)', default='')[:-3]) v['description'] = obj.re_match_iter_typed(r'^\s+description\s(.+)', default='') vrfs.append(v) keys = vrfs[0].keys() with open("files/mv2_vrf_list", "w") as f: dict_writer = csv.DictWriter(f, keys) dict_writer.writeheader() dict_writer.writerows(vrfs) json.dump(vrfs, f)
def get_configs(**device): """ Получает конфиг из вывода команды show run и сохраняет его в файл с именем <device_name>_<current_date> Название устройства берет из конфигурации. Если не задан hostname, то используется host из inventory. """ config = device["con"].enable() config = device["con"].send_command("show running-config") parser = CiscoConfParse(config.splitlines()) objs = parser.find_objects(r"^hostname\s") if len(objs) == 0: device_name = device["host"] else: device_name = objs[0].re_match(r"^hostname\s(.+)$") current_date = datetime.now().strftime("%Y-%m-%d") file_name = join(CONFDIR, f"{device_name}_{current_date}.conf") with open(file_name, 'w') as f: f.write(config) return f"Config saved to {file_name}"
def testVal_object_group_network(self): conf = [ '!', 'name 1.1.2.20 loghost01', '!', 'object-group network INSIDE_addrs', ' network-object host loghost01', ' network-object host 1.1.2.1', ' network-object 1.1.2.2 255.255.255.255', ' network-object 1.1.2.0 255.255.255.0', '!', ] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'object-group\snetwork')[0] # Ensure obj.name is set correctly self.assertEqual(obj.name, "INSIDE_addrs") result_correct = [ IPv4Obj('1.1.2.20/32'), IPv4Obj('1.1.2.1/32'), IPv4Obj('1.1.2.2/32'), IPv4Obj('1.1.2.0/24') ] self.assertEqual(obj.networks, result_correct)
cat2nexus.py --version cat2nexus.py -c <config_file> -v <variables> Options: -h --help Show this screen. -c <config_file> Config File: ej( -c 'PATH/config-file.py') -v <variables> CSV file with variables to be replaced (first row with variable names) --version Show version. """ from ciscoconfparse import CiscoConfParse from docopt import docopt import csv if __name__ == '__main__': arguments = docopt(__doc__, version='Listado de VLANs 1.0') config_file = arguments['-c'] variables = arguments ['-v'] parse = CiscoConfParse(config_file) with open(variables) as csvfile: reader = csv.DictReader(csvfile) for row in reader: search_pattern = r"^interface " + row['old_int'] objetos = parse.find_objects(search_pattern) for i in objetos: print "interface " + row['new_int'] for child in i.children: print child.text
print("IPs from config file: %s" % str(sys.argv[1])) raw_input("Press Return to continue to Other IP Section...") ipint2 = config.find_children_w_parents("^interface\s", "ip address") lipint2 = len(ipint2) print ipint2 for i in ipint2: print i print("Number of items in list: %s" % lipint2) print("IPs from config file: %s" % str(sys.argv[1])) raw_input("Press Return to continue to static routes...") sroute = config.find_objects(r"^ip\sroute") lsroute = len(sroute) print sroute for r in sroute: print r print("Number of items in list: %s" % lsroute) print("IPs from config file: %s" % str(sys.argv[1])) raw_input("Press Return to continue to routing configuration...") router = config.find_all_children(r"^router") lrouter = len(router) print router for r in router: print r
elif ipv6config[0].re_search_children(r'.*neighbor ' + neighbor + ' route-map .* in'): rmpre = ipv6config[0].re_search_children(r'.*neighbor ' + neighbor + ' route-map .* in')[0].text rmlist = rmpre.split(' ') else: return return rmlist[5] for file in files: parse = CiscoConfParse(file) routeMapDict = {} iflist = {} # find interfaces interfaces = parse.find_objects('^interface ') hostnameregex = parse.find_objects('^hostname (.*)') #get hostname for item in hostnameregex: hostname = item.text hostname = hostname.strip('hostname') hostname = hostname.strip() #get interface IP addressing #print '-------------Interfaces--------------' for obj in interfaces: if obj.re_search_children( r"ip address [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.*" ): ifname = obj.text.strip('interface ') iplist = [] secondarylist = []
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse from pprint import pprint as pp config_dump = CiscoConfParse('cisco_config.txt') ff_parents = config_dump.find_objects(r'crypto map CRYPTO') for i in ff_parents: print i.text for j in i.all_children: print j.text
out = net_connect.send_command('show run | sec interface Gi') ## save the original configuration for each device and overwrite file with every execution original_config_filename = "old_config" + "_" + ip_address_of_device original_config = open(original_config_filename, "a") original_config.seek(0) original_config.truncate() original_config.write(out) original_config.close() parse = CiscoConfParse(original_config_filename) # Add required configuration under interface configuration (reading new commands from file) for intf in parse.find_objects(r'^interface.+?thernet'): is_access_vlan_users = intf.has_child_with( r'switchport access vlan ' + str(vlan)) if is_access_vlan_users: for cmd in commands_list: intf.append_to_family(" " + str(cmd)) ## save the new configuration in file new_config_filename = "new_config" + "_" + ip_address_of_device parse.save_as(new_config_filename) ## delete unnecessary lines 'Building configuration' 'size' .. lines = open(new_config_filename).readlines() open(new_config_filename, 'w').writelines(lines[3:-1])
class Cfgrep: def __init__(self, file_name): self.parse = CiscoConfParse(file_name) self.os = 'ios' self.__check_os() def __check_os(self): xr = self.parse.find_lines('!!\s+IOS\sXR\sConfiguration') if len(xr): self.os = 'xr' return self.os ios = self.parse.find_lines('^version\s\d') if len(ios): self.os = 'ios' return self.os @staticmethod def __print_str_list(str_list): for str_print in str_list: print(str_print) return @staticmethod def __print_notice(string): print('!') print('!!!!!!!!!!!!!!!!!!!!!!!!!!!') print('! {}'.format(string)) print('!!!!!!!!!!!!!!!!!!!!!!!!!!!') @staticmethod def __append_ip_address(address, prefix_length, line_num, ip_list, ip_list_num): __network = IPNetwork(address + '/' + str(prefix_length)) ip_list.append(__network) ip_list_num.append(line_num) return ip_list, ip_list_num def __search_interface_ip_address(self, line, ip_v4_list, ip_v4_line_num_list, ip_v6_list, ip_v6_line_num_list): __address_match = re.match( r'^\s+ip(v4)?\saddress\s(\d+\.\d+\.\d+\.\d+)\s(\d+\.\d+\.\d+\.\d+)', line.text) if __address_match: __host_address = __address_match.group(2) prefix_length = IPAddress(__address_match.group(3)).netmask_bits() self.__append_ip_address(__host_address, prefix_length, line.linenum, ip_v4_list, ip_v4_line_num_list) __address_match = re.match( r'^\s+ipv6\saddress\s([\w:]*::[\w:]*)/(\d+)', line.text) if __address_match: __host_address = __address_match.group(1) prefix_length = __address_match.group(2) self.__append_ip_address(__host_address, prefix_length, line.linenum, ip_v6_list, ip_v6_line_num_list) return ip_v4_list, ip_v4_line_num_list, ip_v6_list, ip_v6_line_num_list @staticmethod def __append_bgp(regexp, line, bgp_list): __bgp_match = re.match(regexp, line.text) if __bgp_match: bgp_list.append(__bgp_match.group(1)) return bgp_list def __search_bgp(self, line, bgp_policy_list, bgp_group_list): if self.os == 'xr': regexp = re.compile(r'^\s+route-policy\s(\S+)\s(in|out)') self.__append_bgp(regexp, line, bgp_policy_list) regexp = re.compile(r'^\s+default-originate\sroute-policy\s(\S+)$') self.__append_bgp(regexp, line, bgp_policy_list) regexp = re.compile(r'^\s+use\sneighbor-group\s(\S+)') self.__append_bgp(regexp, line, bgp_group_list) else: regexp = re.compile( r'^\s+neighbor\s\S+\sroute-map\s(\S+)\s(in|out)') self.__append_bgp(regexp, line, bgp_policy_list) regexp = re.compile( r'^\s+neighbor\s\S+\sdefault-originate\sroute-map\s(\S+)$') self.__append_bgp(regexp, line, bgp_policy_list) regexp = re.compile(r'^\s+neighbor\s\S+\speer-group\s(\S+)$') self.__append_bgp(regexp, line, bgp_group_list) return bgp_policy_list, bgp_group_list def __print_ios_neighbor(self, string, result_str=None): __count = True find_list = self.parse.find_objects( r'^\s+neighbor\s{}\s'.format(string)) for find in find_list: if ' neighbor' in find.text and __count: if result_str: result_str.append(find.parent.text) else: print(result_str.append(find.parent.text)) __count = False if result_str: result_str.append(find.text) else: print(find.text) def __print_interface_ip_address(self, ip_list, ip_list_num, regexp_parse, regexp, string): if not len(ip_list): return __target_addresses = [] __addresses_line = self.parse.find_objects(regexp_parse) for network in ip_list: for address_line in __addresses_line: address_match = re.findall(regexp, address_line.text) for address in address_match: if IPAddress( address ) in network and address_line.linenum not in ip_list_num: __target_addresses.append(address_line.text) if len(__target_addresses): self.__print_notice(string) for target_address in set(__target_addresses): self.config_parse(target_address) def config_parse(self, pattern, mode_interface=False, mode_bgp_neighbor=False, mode_description=False): option_dict = defaultdict(list) old_line_num = -1 result_str = [] def __recursive_parent(__line): parent = __line.parent if parent.linenum != __line.linenum: __recursive_parent(parent) result_str.append(parent.text) else: result_str.append('!') return def __recursive_child(__line): if mode_bgp_neighbor and self.os == 'ios': self.__search_bgp(__line, option_dict['bgp_policy'], option_dict['bgp_group']) for __child in __line.children: result_str.append(__child.text) if mode_interface: self.__search_interface_ip_address( __child, option_dict['ip_v4'], option_dict['ip_v4_line_num'], option_dict['ip_v6'], option_dict['ip_v6_line_num']) # ios-xr (ios has no grandchild) if mode_bgp_neighbor: self.__search_bgp(__child, option_dict['bgp_policy'], option_dict['bgp_group']) __recursive_child(__child) return originals = self.parse.find_objects(pattern) for original in originals: """ description mode """ if mode_description: if 'description' not in original.text: continue # case of ios neighbor_address = re.match( r'^\s+neighbor\s(\d+\.\d+\.\d+\.\d+|[\w:]+::[\w:]*)\sdescription\s', original.text) if neighbor_address: result_str.append('!') result_str.append(original.parent.text) self.__print_ios_neighbor(neighbor_address.group(1), result_str) continue original = original.parent # omit duplications if original.linenum == old_line_num: continue old_line_num = original.linenum __recursive_parent(original) result_str.append(original.text) __recursive_child(original) self.__print_str_list(result_str) regexp_parse = re.compile(r'\s(\d+\.\d+\.\d+\.\d+)(\s|/|$)') regexp = re.compile(r'\d+\.\d+\.\d+\.\d+') self.__print_interface_ip_address(option_dict['ip_v4'], option_dict['ip_v4_line_num'], regexp_parse, regexp, 'ipv4 address search') regexp_parse = re.compile(r'\s([\w:]*::[\w:]*)(\s|/|$)') regexp = re.compile(r'[\w:]*::[\w:]*') self.__print_interface_ip_address(option_dict['ip_v6'], option_dict['ip_v6_line_num'], regexp_parse, regexp, 'ipv6 address search') if len(option_dict['bgp_policy']): if self.os == 'xr': self.__print_notice('route-policy search') for bgp_policy in set(option_dict['bgp_policy']): self.config_parse( r'^route-policy\s{}(\s|$)'.format(bgp_policy)) print('end-policy') else: self.__print_notice('route-map search') for bgp_policy in set(option_dict['bgp_policy']): self.config_parse(r'^route-map\s{}\s'.format(bgp_policy)) if len(option_dict['bgp_group']): self.__print_notice('neighbor-group search') if self.os == 'xr': for bgp_group in set(option_dict['bgp_group']): self.config_parse( r'^\s+neighbor-group\s{}(\s|$)'.format(bgp_group), mode_bgp_neighbor=True) else: for bgp_group in set(option_dict['bgp_group']): # print router bgp <asn> neighbor_group_list = self.parse.find_objects( r'^\s+neighbor\s{}\speer-group'.format(bgp_group)) for neighbor_group in neighbor_group_list: print(neighbor_group.parent.text) self.__print_ios_neighbor(bgp_group) return result_str
#!/usr/bin/var python from ciscoconfparse import CiscoConfParse if __name__ == "__main__": cisco_file = 'cisco_config.txt' cisco_cfg = CiscoConfParse(cisco_file) intf_obj = cisco_cfg.find_objects(r"^interf") for intf in intf_obj: print print intf.text for child in intf.children: print child.text break print
try: CONFIG_PATH = glob(sys.argv[1]) except IndexError: raise ValueError( "This script must be called with a config path-glob to be audited as the argument" ) secret = getpass('Enable Secret: ') for filename in CONFIG_PATH: print "--- {0} ---".format(filename) parse = CiscoConfParse(filename) # Print out simple diff conditions - i.e. no regexp matching... print os.linesep.join(parse.sync_diff(RECOMMENDED, '', remove_lines=False)) # Default enable secret config... default_enab_sec = 'enable secret {0}'.format(secret) try: # Build an enable secret string... enab_sec_regex = r'^enable\s+secret\s+(\d+)\s+\S+' # Get the encryption level as an int... enab_sec_level = parse.find_objects( enab_sec_regex, )[0].re_match_typed(enab_sec_regex, group=1, default=-1, result_type=int) if enab_sec_level == 0: print default_enab_sec except IndexError: print default_enab_sec
'username': '******', 'password': password, 'secret': password, } connection = ConnectHandler(**switch) connection.enable() config = connection.send_command('show run') #formatting to ciscoconfparse requirements (list) config = config.splitlines() #parse config to make objects p = CiscoConfParse(config) #filter interfaces only interfaces = p.find_objects(r'interface GigabitEthernet\S') #making empty lists where i'll put interface names based on qualifiers. user_ports = [] auth_open_ports_list = [] no_dot1x_ports = [] #loop through interface objects for intf in interfaces: #making a boolean if the port in the current iteration has dot1x configured on it authentication_ports = intf.has_child_with(r'authentication') #dot1x is configured but auth open means its usually not a user port auth_open_ports = intf.has_child_with(r'authentication open') # finding user ports that dont have auth open if authentication_ports and not auth_open_ports: print( f"Found user port [{intf.text}] without auth open, adding to a list"
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse cfg = CiscoConfParse("cisco_ipsec.txt") crypto_maps = cfg.find_objects("^crypto map CRYPTO") #Excercise 8, part1 #find all lines that begin with 'crypto map CRYPTO'& for each crypto map entry print out its children print "These are cryto map lines" for crypto in crypto_maps: print crypto.text for child in crypto.children: print child.text #Excercise 8, part2:show crypto maps that have pfs group 2 print "These Crypto maps have pfs group 2" pfs2 = cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"set pfs group2") for i in pfs2: print i.text #Excercise 8, part2:show crypto maps that aren't using AES and also print transform set print "Find MAPS not using AES" #aes = cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"AES-SHA") aes = cfg.find_objects_wo_child(parentspec=r"^crypto map CRYPTO", childspec="set transform-set AES-SHA") for each in aes: print each.text for child in each.children: print child.text
from ciscoconfparse import CiscoConfParse conf_ref = CiscoConfParse("lb1-bo-acc4.log") vs_ref=conf_ref.find_objects(r"virtual-server") def func_parse(vs_ref): for j in vs_ref: print j.text with open("vs_list.txt", 'a') as f: f.write(j.text) f.write("\n") func_parse(j.children) func_parse(vs_ref) for j in vs_ref: for p in j.children: if "pfs group2" in p.text: print " " for j in vs_ref: for p in j.children: if "transform-set" in p.text: if "AES-SHA" not in p.text: r = p.text.split() for q in r: if "transform-set" == q: print "%s : encrption is %s" %(j.text, r[r.index(q)+1])
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse("cisco_config.txt") print cisco_cfg intf = cisco_cfg.find_objects(r"^interface") print intf for i in intf: print i.text interface_4 = intf[4] print interface_4 print interface_4.children for child in interface_4.children: print child.text no_ip = cisco_cfg.find_objects_w_child(parentspec=r"interface", childspec=r"no ip address") print no_ip with_ip = cisco_cfg.find_objects_wo_child(parentspec=r"interface", childspec=r"no ip address") print with_ip
#new_name = '{}_{}'.format(f.parent.name, f.name) new_name = '{}'.format(f.parent.name, f.name) f.rename(os.path.join(NEW_DIR, new_name)) #print(" ") #print("-------------------Finshed removing -Running.config from file name-------------------") #print(" ") header = "Switch" + " " + "Port W/O Dot1x" + " " + "Port Description" print(header) # #Start Examining configs for missing port security # for host in os.listdir(NEW_DIR): if host.startswith("p"): config_path = os.path.join(NEW_DIR, host) parse = CiscoConfParse(config_path) all_intfs = parse.find_objects(r"^interf") NoDot1x = list() NoDot1x = parse.find_objects_wo_child(r'^interface', r'authentication') #Remove Non Gig Ports because all user ports are 1 gig GigPorts = [ x.text.split()[1] for x in NoDot1x if x.text.startswith("interface Gig") ] #Remove Cisco 3750 Exansion module final_list = [ w for w in GigPorts if not re.match(r'GigabitEthernet./1/.', w) ] #Gets Port Descriptions for ports in final_list: port = "interface" + " " + ports intconfig = parse.find_children(port, exactmatch=True)
def asa_to_mx(arg_file): # Read port_mappings.csv file for name/number pairs, such as (www, 80) # https://www.cisco.com/c/en/us/td/docs/security/asa/asa82/configuration/guide/config/ref_ports.html#wp1007738 port_mappings = dict() csv_file = open('port_mappings.csv') reader = csv.reader(csv_file, delimiter=',', quotechar='"') next(reader, None) for row in reader: [name, tcpudp, number, description] = row port_mappings[name] = number # Set the CSV output file and write the header row #timenow = '{:%Y%m%d_%H%M%S}'.format(datetime.now()) #filename = 'mx_l3fw_rules_{0}.csv'.format(timenow) filename = 'mx_l3fw_rules_{0}.csv'.format(arg_file) output_file = open(filename, mode='w', newline='\n') field_names = [ 'policy', 'protocol', 'srcCidr', 'srcPort', 'destCidr', 'destPort', 'comment', 'logging' ] csv_writer = csv.DictWriter(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL, fieldnames=field_names) csv_writer.writeheader() # Open "sh run" output file and parse with open(arg_file, 'U') as f: newText = f.read() while more_line_text in newText: newText = newText.replace(more_line_text, '') with open('asa_to_mx_scrubbed.txt', 'w') as f: f.write(newText) parse = CiscoConfParse('asa_to_mx_scrubbed.txt', syntax='asa') print("...scrubbed config") # Parse out name objects for ASA v 7 network_mappings = {} name_objects = parse.find_objects(r'name ') for element in name_objects: name = element.text if name[:5] != 'name ': continue name = name.replace('name ', '').split() network_mappings[name[1]] = name[0] + '/32' print("...looked up names for asa V7") print("...parsing network interfaces...") network_interfaces = {} int_objects = parse.find_objects(r'Port-channel1.') for element in int_objects: lines = element.children intName = element.text text = find_interfaces(intName, lines, network_interfaces) print(network_interfaces) #exit() #parse "object network" solo_objects = parse.find_objects(r'object network') for element in solo_objects: name = element.text.replace('object network ', '') lines = element.children text = asa_to_mx_l3(lines, solo_objects) network_mappings[name] = text print(".. Solo objects parsed") # Parse "object-group network" blocks in lines 143-441 network_objects = parse.find_objects(r'object-group network') for element in network_objects: name = element.text.replace('object-group network ', '') lines = element.children print(lines) text = asa_to_mx_l3(lines, network_mappings) network_mappings[name] = text print("parsed object-groups network") # Parse "object-group service" blocks, in lines 442-571 # Add to loaded port_mappings from file service_objects = parse.find_objects(r'object-group service') for element in service_objects: name = element.text.replace('object-group service ', '') name = name.split()[0] lines = element.children text = asa_to_mx_l4(lines, port_mappings) port_mappings[name] = text print("parsed object-group service") # Default deny rule, to be added at very end network_mappings['any'] = 'Any' default_deny = False f = open("networkmappings_raw.txt", "w+") f.write(str(network_mappings)) f.close() p = open("portmappings_raw.txt", "w+") p.write(str(port_mappings)) p.close() print("Checking ACL lists to parse...") # Open acl_list.txt, which determines which extended ACLs to parse acl_list = open('acl_list.txt') for acl_line in acl_list: acl_name = acl_line.strip() acl_block = parse.find_blocks(r'access-list {0}'.format(acl_name)) for command in acl_block: rule = {} line = command.strip() #line = line.split('extended ')[1] line = line.replace('extended', '') line = line.split(acl_name)[1] # finished edits command = line fields = line.split() # Remove irrelevant terms fields = [ x for x in fields if x not in ('eq', 'object-group', 'echo-reply', 'unreachable', 'time-exceeded', 'object') ] policy = fields.pop(0) if policy == 'permit': rule['policy'] = 'allow' elif policy == 'deny': rule['policy'] = 'deny' elif policy == 'remark': #print("Remark found and ignored") continue else: print("error(ACL): allow/deny") print(fields) sys.exit(command) protocol = fields.pop(0) if protocol == 'ip': rule['protocol'] = 'any' elif protocol == 'TCPUDP': rule['protocol'] = 'any' elif protocol == 'icmp': rule['protocol'] = 'icmp' elif protocol == 'udp': rule['protocol'] = 'udp' elif protocol == 'tcp': rule['protocol'] = 'tcp' else: print("error(ACL): protocol expected [" + protocol + "]") print(str(fields)) if protocol in port_mappings: print("YUP its a PORT range") print(port_mappings[protocol]) #rule['protocol'] = 'any' rule['destPort'] = port_mappings[protocol] print(str(rule)) #exit() else: print("Unknown protocol") exit() #fields.insert(0,protocol) srcCidr = fields.pop(0) if srcCidr == "any4": srcCidr = "any" if srcCidr in network_mappings: rule['srcCidr'] = network_mappings[srcCidr] elif isIP(srcCidr) and isIP(fields[0]): # print("ADDY:" + srcCidr +"/"+ fields[0]) ip = ipaddress.ip_interface('{0}/{1}'.format( srcCidr, nm_bits(fields[0]))) newSrc = ip.with_prefixlen if isIP(newSrc): next_field = fields.pop(0) #burn one off, for netmask # next_field = fields.pop(0) #burn one off, for netmask rule['srcCidr'] = newSrc else: print("Horrific srcDest=" + newDest) print("Command:" + command) print("error(NextField)342:" + next_field) print(str(fields)) print(str(rule)) exit() elif srcCidr == "host" and isIP(fields[0]): rule['srcCidr'] = fields[0] + "/32" next_field = fields.pop(0) # next_field = fields.pop(0) # print(rule['srcCidr']) # print(next_field) # sys.exit(command) next_field = fields.pop(0) # rule['srcPort'] = 'any' #cheater line if next_field in port_mappings: if next_field == 'any': rule['srcPort'] = 'Any' else: rule['srcPort'] = port_mappings[next_field] next_field = fields.pop(0) elif next_field in network_mappings: rule['srcPort'] = 'Any' #HERE rule['destCidr'] = network_mappings[next_field] if len(fields) > 0: next_field = fields.pop(0) elif next_field == 'host': rule['srcPort'] = 'Any' next_field = fields.pop(0) if isIP(next_field): rule['destCidr'] = next_field + "/32" if len(fields) > 0: next_field = fields.pop(0) else: print("error(ACL): insane error") exit() elif next_field.isdigit(): if int(next_field) < 65535 and int(next_field) > 0: rule['srcPort'] = next_field next_field = fields.pop(0) ### this should be destination if len(fields) > 1 and isIP(next_field) and isIP(fields[0]): ip = ipaddress.ip_interface('{0}/{1}'.format( next_field, nm_bits(fields[0]))) newDest = ip.with_prefixlen if isIP(newDest): rule['destCidr'] = newDest next_field = fields.pop(0) #pull off the mask next_field = fields.pop(0) #pull off the mask # if len(fields) > 0: next_field = fields.pop(0) #queue the next one # else: # sys.exit("UNKNOWN") else: print("Horrific newDest=" + newDest) print("Command:" + command) print("error(NextField)DST:" + next_field) print(str(fields)) print(str(rule)) sys.exit(command) else: if 0 == 1: #am i dropping anything here? print("Command:" + command) print("warning(NextField)?!?:" + next_field) print(str(fields)) print(str(rule)) #sys.exit(command) #next_field = fields.pop(0) rule['destPort'] = '' if len(fields) == 0: if not 'destCidr' in rule: rule['destCidr'] = 'Any' rule['destPort'] = 'Any' elif next_field == 'any' or next_field == 'any4': if not 'destCidr' in rule: rule['destCidr'] = 'Any' next_field = fields.pop(0) elif next_field in port_mappings: rule['destPort'] = port_mappings[next_field] elif len(fields) == 1: if next_field.isnumeric(): rule['destPort'] = next_field elif next_field == "log": if rule['destPort'] == '': rule['destPort'] = 'Any' elif not isIP(next_field) and next_field in port_mappings: rule['destPort'] = port_mappings[next_field] else: print("Command:" + command) print("error(NextField):" + next_field) print(str(fields)) print(str(rule)) # sys.exit("ERROR!!@#!@$@!$") if next_field == "any4" or next_field == "any": rule['destCidr'] = 'Any' if len(fields) > 0: next_field = fields.pop(0) elif next_field in network_mappings: #could be a group of device IPs print("status(ACL): Network Object detected [" + str(next_field) + "]") rule['srcPort'] = 'Any' rule['destCidr'] = network_mappings[next_field] rule['destPort'] = 'Any' elif len(fields) > 0 and isIP(next_field) and isIP( fields[0]) and nm_bits(fields[0]) >= 8: #so basically use case of a "10.0.0.0 255.0.0.0 " host #print("warning(ACL): seperate source & mask "+str(next_field)+"/"+str(fields[0])) rule['srcPort'] = 'Any' rule['destCidr'] = next_field + "/" + str(nm_bits(fields[0])) rule['destPort'] = 'Any' # print(rule['destCidr']) elif next_field.isdigit(): print("NextField: " + str(next_field)) if int(next_field) < 65535 and int(next_field) > 0: rule['destPort'] = next_field else: print("err(ACL): is digit, not in range") print("fields: " + str(fields)) sys.exit(command) elif next_field in port_mappings: rule['destPort'] = port_mappings[next_field] else: #ANYTHING landing here should be fixed print("warning(ACL): keyword[" + next_field + "]") print("fields: " + str(fields)) print(next_field) print(rule) # sys.exit(command) if next_field == "range": if fields[0] in port_mappings or fields[1] in port_mappings: print("error(ACL): Named Object in range") sys.exit("BARF") else: print("we're good") rule['destPort'] = fields[0] + '-' + fields[1] # rule['destPort'] = enumerate_ports(fields[0] + "-" + fields[1]) #adding a fix here to solve for range "135-netbios" next_field = fields.pop(0) next_field = fields.pop(0) if len(fields) > 0: next_field = fields.pop(0) #cheater function (looks for empty fields and sets to any) if len(fields) > 0 and rule['destPort'] == "": next_field = fields.pop(0) print('') if next_field == "log": if rule['destPort'] == "": rule['destPort'] = 'Any' elif next_field.isdigit(): rule['destPort'] = next_field elif next_field == "range": port_range = (fields[0] + "-" + fields[1]) # rule['destPort'] = enumerate_ports(port_range) rule['destPort'] = port_range elif next_field in port_mappings: rule['destPort'] = port_mappings[next_field] else: print("error(emptyField): No DestPort") print("Current Command: " + next_field) print("Fields:" + str(fields)) print("RULES:" + str(rule)) print("Commands:" + str(command)) sys.exit(command) elif rule['destPort'] == "": rule['destPort'] = "Any" for r in rule: if len(rule[r]) < 2: print("error(Fields): Empty field") print("RULES:" + str(rule)) print("Commands:" + str(command)) sys.exit(command) if not 'destCidr' in rule: print(rule) print("error(end): No destCIDR, something went terribly wrong") sys.exit(command) if not 'protocol' in rule: rule['protocol'] = 'Any' if not 'srcPort' in rule: print(rule) print("error(end): No sourcePort ") rule['srcPort'] = 'Any' print("******") print("Command:" + command) print(str(fields)) print("FinalRule: " + str(rule)) print("******") if rule == { 'policy': 'deny', 'protocol': 'any', 'srcCidr': 'Any', 'srcPort': 'Any', 'destCidr': 'Any', 'destPort': 'Any' }: default_deny = True continue rule['comment'] = command rule['logging'] = SYSLOG_ENABLED csv_writer.writerow(rule) if default_deny: csv_writer.writerow({ 'policy': 'deny', 'protocol': 'any', 'srcCidr': 'Any', 'srcPort': 'Any', 'destCidr': 'Any', 'destPort': 'Any', 'comment': 'Default deny ip any any', 'logging': SYSLOG_ENABLED }) output_file.close() print('Output CSV written to file {0}'.format(filename))
''' 8. Write a Python program using ciscoconfparse that parses this config file. Note, this config file is not fully valid (i.e. parts of the configuration are missing). The script should find all of the crypto map entries in the file (lines that begin with 'crypto map CRYPTO') and for each crypto map entry print out its children. ''' from ciscoconfparse import CiscoConfParse config = CiscoConfParse('cisco_ipsec.txt') crypto_map = config.find_objects(r"^crypto map CRYPTO") for crypto in crypto_map: print crypto.text for child in crypto.children: print child.text print "!"
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse("cisco_ipsec.txt") crypto_maps = cisco_cfg.find_objects(r"crypto map CRYPTO") for i in crypto_maps: print i.text for child in i.children: print child.text
for device in devices: row = row + 1 column = device.split() ip = column[1] print column[0] try: ssh.connect(column[1], username=username, password=password, timeout=5, allow_agent=False, look_for_keys=False) stdin, stdout, stderr = ssh.exec_command('sh run') hostname = stdout.readlines() runconfigparse = CiscoConfParse(hostname) hostnamefind = runconfigparse.find_objects("^hostname") for hostname in hostnamefind: hostnameval = re.search(r'(?<=hostname\s)(\S*)', hostname.text) sheet.write(row, 0, hostnameval.group(0)) sheet.write(row, 1, column[1]) ssh.connect(column[1], username=username, password=password, timeout=5, allow_agent=False, look_for_keys=False) stdin, stdout, stderr = ssh.exec_command('show run vlan') arpoutput = stdout.readlines() configparse = CiscoConfParse(arpoutput) vlanparams = configparse.find_objects("^vlan") vlanname = configparse.find_objects("name")
from ciscoconfparse import CiscoConfParse conf_ref = CiscoConfParse("../pynet/pyth_ans_ecourse/class1/cisco_ipsec.txt") print conf_ref crypto_map = conf_ref.find_objects(r"^crypto map") print ''' crypto map entries ''' for j in crypto_map: print j.text for p in j.children: print p.text print ''' crypto map entries with pfs group 2 ''' for j in crypto_map: for p in j.children: if "pfs group2" in p.text: print j.text print ''' crypto map entries without AES protection ''' for j in crypto_map: for p in j.children: if "transform-set" in p.text: if "AES-SHA" not in p.text: r = p.text.split() for q in r: if "transform-set" == q: print "%s : encrption is %s" % (j.text,