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 testValues_sync_diff_06(): """Test diffs against double-spacing for children (such as NXOS)""" ## config_01 is the starting point config_01 = ['!', 'vlan 51', ' state active', 'vlan 53', '!', ] required_config = ['!', 'vlan 51', ' name SOME-VLAN', ' state active', 'vlan 52', ' name BLAH', ' state active', '!',] result_correct = ['no vlan 53', 'vlan 51', ' name SOME-VLAN', 'vlan 52', ' name BLAH', ' state active'] linespec = r'vlan\s+\S+|name\s+\S+|state.+' parse = CiscoConfParse(config_01) test_result = parse.sync_diff(required_config, linespec, linespec) assert result_correct==test_result
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 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 get_int(switch, interface): """ Get a config snippet from a device """ conf_file = conf_dir + switch + extension interface = expand_port(interface) try: parse = CiscoConfParse(conf_file) except: print("Error: could not load config for ", conf_file) sys.exit(1) search_int = "^interface " + interface + "$" if args.match: m = parse.find_objects_w_child(parentspec=search_int, childspec=args.match) if m: print(args.switch + ',' + args.int + ',' + args.match) else: iface = parse.find_all_children(search_int) if iface: print('!' + switch + ' ' + interface) for line in iface: print(line) if iface: print('!')
def testValues_sync_diff_09(): """Test diffs with explicit ignore_order=True""" ## config_01 is the starting point config_01 = ['!', 'vlan 51', ' state active', 'vlan 53', '!', 'vtp mode transparent', ] required_config = ['!', 'vtp mode transparent', 'vlan 51', ' name SOME-VLAN', ' state active', 'vlan 52', ' name BLAH', ' state active', '!',] result_correct = [ 'no vlan 53', 'vlan 51', ' name SOME-VLAN', 'vlan 52', ' name BLAH', ' state active', ] linespec = r'vlan\s+\S+|name\s+\S+|state.+|vtp' parse = CiscoConfParse(config_01) test_result = parse.sync_diff(required_config, linespec, linespec, ignore_order=True) 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 main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") cryptomaps = cisco_cfg.find_objects_w_child(parentspec = r"crypto map CRYPTO", childspec = r"pfs group2") print "\n crypto maps using PFS group2:" for entry in cryptomaps: print " {0}" .format(entry.text)
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 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 main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") crypto_map = cisco_cfg.find_objects_w_child(parentspec=r'crypto map CRYPTO', childspec=r'pfs group2') print "\n the crypto maps with pfs group2 :", "\n" for each_map in crypto_map: print each_map.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_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 testValues_sync_diff_07(): """Test diffs with remove_lines=False""" ## config_01 is the starting point config_01 = ['!', 'vlan 51', ' state active', 'vlan 53', '!', 'vtp mode transparent', ] required_config = ['!', 'vlan 51', ' name SOME-VLAN', ' state active', 'vlan 52', ' name BLAH', ' state active', '!',] result_correct = ['vlan 51', ' name SOME-VLAN', 'vlan 52', ' name BLAH', ' state active'] linespec = r'vlan\s+\S+|name\s+\S+|state.+' parse = CiscoConfParse(config_01) test_result = parse.sync_diff(required_config, linespec, linespec, remove_lines=False) assert result_correct==test_result
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 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 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_cfg = CiscoConfParse('cisco_ipsec.txt') crypto_maps = cisco_cfg.find_objects_w_child(parentspec=r'crypto map CRYPTO', childspec=r'pfs group2') print "Crypto map entries that are using PFS group2:" for crypto_map in crypto_maps: print crypto_map.text
def process_file(fname): with open(fname) as f: print '*** %s ***' % fname parse = CiscoConfParse(f) blockhead = parse.find_blocks('voice translation') for item in blockhead: print item.rstrip()
def cisco_conf_task_3(): print "\n\nCisco parse exersise 3.\n" cfg_file = CiscoConfParse("cisco_ipsec.txt") c_maps = cfg_file.find_parents_wo_child("^crypto map CRYPTO","^ set transform-set AES") x = 1 for element in c_maps: print "entry # %s that are not using AES: %s" % (x, element) x += 1
def cisco_conf_task_2(): print "\n\nCisco parse exersise 2.\n" cfg_file = CiscoConfParse("cisco_ipsec.txt") c_maps = cfg_file.find_parents_w_child("^crypto map CRYPTO","^ set pfs group2") x = 1 for element in c_maps: print "entry # %s that are using PFS group2: %s" % (x, element) x += 1
def testValues_negative_ignore_ws(self): ## test find_lines WITHOUT ignore_ws result_correct = [] cfg = CiscoConfParse(self.c03) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ) self.assertEqual(result_correct, test_result)
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 main(): cisco_cfg = CiscoConfParse("cisco_ipsec.txt") intf = cisco_cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"pfs group2") print "Crypto maps using PFS group2:" for i in intf: print i.text
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 standardizeInt(parsed_config): interfaces = parsed_config.find_lines('^interface.+?thernet') for i in interfaces: famobj = CiscoConfParse(parsed_config.find_children(i, exactmatch=True)) if (famobj.find_lines('switchport mode access')): if (not famobj.find_lines('spanning-tree portfast')): cfgDiffs.append(i) cfgDiffs.append(" spanning-tree portfast")
def main(): ''' Main function ''' my_cisco_cfg = CiscoConfParse("cisco_ipsec.txt") out = my_cisco_cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"set pfs group2") for item in out: print item.text
def main(): cfg=CiscoConfParse('Config-file.txt') temp_list=cfg.find_objects_w_child(parentspec=r"^crypto map", childspec="pfs group2") #for entry in temp_list: for entry in temp_list: print "Crypto Map " , entry.text , " is using PFS Group 2"
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 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
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Using ciscoconfparse find the crypto maps that are not using AES (based-on the transform set name). Print these child entries. """ from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse("cisco_config.txt") crypto_maps_not_AES = cisco_cfg.find_objects_wo_child( parentspec=r"^crypto map CRYPTO", childspec=r"transform-set AES") for i in crypto_maps_not_AES: print i.text for child in i.children: print child.text
print column[0] sheet.write(row, 1, column[0]) not_done = True remote_conn.send("show running-config") remote_conn.send("\n") i = 1 time.sleep(1) while (not_done) and (i <= 30): time.sleep(4) i += 1 if remote_conn.recv_ready(): config = remote_conn.recv(65535) else: not_done = False lines = config.splitlines() parse = CiscoConfParse(lines) match = parse.find_objects_w_child(parentspec=r"^interface", childspec=r"ip helper-address") for parent in match: row = row + 1 print parent.text sheet.write(row, 2, parent.text) for child in parent.children: ipaddress = re.findall(r'(?<=ip address)(.*)', child.text) helpers = re.findall(r'(?<=ip helper-address )(.*)', child.text) for value in ipaddress: print value sheet.write(row, 3, value) for helper in helpers: print helper
#print first row print( \ 'hostname,\ interface,\ description, \ ip_addr, \ network, \ prefix_length, \ shutdown, \ acl_in, \ acl_out' ) for pfile in pdirectory: parse = CiscoConfParse(pfile) #variable hostname = parse.re_match_iter_typed(RE_HOSTNAME) for obj in parse.find_objects_w_child(parentspec=RE_INTF_PARENT, childspec=RE_INTF_CHILDSPEC): #print('Config test: {} '.format(obj.text)) #intf = obj.re_match_iter_typed(RE_INTF_PARENT) try: ip_addr = obj.re_match_iter_typed(RE_ITF_ADDR, result_type=IPv4Obj) itf_des = obj.re_match_iter_typed(RE_ITF_DES) itf_acl_in = obj.re_match_iter_typed(RE_ITF_ACL_IN) itf_acl_out = obj.re_match_iter_typed(RE_ITF_ACL_OUT)
from ciscoconfparse import CiscoConfParse #open the cisco file and store it in a variable cisco_cfg = CiscoConfParse("cisco_ipsec.txt") #search for any line in our confparse object (cisco_cfg) that begins with the word "crypto map CRYPTO" intf = cisco_cfg.find_objects(r"^crypto map CRYPTO") #print type(intf) #Get all children (children and grandchildren) elements for i in intf: print i for child in i.all_children: print child.text print "\n"
from ciscoconfparse import CiscoConfParse import re cisco_cfg = CiscoConfParse("cisco_conf.cfg") maps = cisco_cfg.find_objects(r"^crypto map CRYPTO") for i in maps: print(i.children) print('##########################################') print('##########################################') print('##########################################') group2 = cisco_cfg.find_objects_w_child(parentspec=r"^crypto map", childspec=r"group2") for i in group2: print(i) print('##########################################') print('##########################################') print('##########################################') #Using ciscoconfparse find the crypto maps that are not using AES #(based-on the transform set name). Print these entries and their #corresponding transform set name. not_aes = cisco_cfg.find_objects_wo_child(r'^crypto map', r'set transform-set AES') #for i in not_aes: # print(i) #print(not_aes)
import yaml from os import path from netmiko import ConnectHandler from ciscoconfparse import CiscoConfParse if __name__ == "__main__": home_dir = path.expanduser("~") filename = path.join(home_dir, ".netmiko.yml") with open(filename) as f: yaml_out = yaml.safe_load(f) device = yaml_out["cisco4"] net_connect = ConnectHandler(**device) show_run = net_connect.send_command("show run") # When feeding config directly - CiscoConfParse requires a list cisco_cfg = CiscoConfParse(show_run.splitlines()) interfaces = cisco_cfg.find_objects_w_child(parentspec=r"^interface", childspec=r"^\s+ip address") print() for intf in interfaces: print("Interface Line: {}".format(intf.text)) ip_address = intf.re_search_children(r"ip address")[0].text print("IP Address Line: {}".format(ip_address)) print() print()
def auditdiff_engine(template_list, node_object, auditcreeper, output, remediation): controller = 'get_config' command = '' ### PUSH_CONFIGS IS A LIST OF THE FINAL CONFIGS TO BE PUSHED # push_configs = [] ### INDEX_POSITION IS THE INDEX OF ALL THE MATCHED FILTER_CONFIG AGAINST THE BACKUP_CONFIGS. THE INDEX IS COMING FROM THE BACKUP_CONFIG index_position = 0 ### NODE_INDEX KEEPS TRACK OF THE INDEX IN INITIALIZE.NTW_DEVICE. IF REMEDIATION IS NOT REQUIRED (CONFIGS MATCHES TEMPLATE), THEN THE NODE IS POPPED OFF ### INITIALIZE.NTW_DEVICE AND NOTHING IS CHANGED ON THAT DEVICE node_index = 0 ### AUDIT_FILTER_RE IS THE REGULAR EXPRESSION TO FILTER OUT THE AUDIT FILTER IN EVERY TEMPLATE AUDIT_FILTER_RE = r"\[.*\]" ### TEMPLATE_LIST_COPY TAKE A COPY OF THE CURRENT TEMPLATE_LIST template_list_copy = template_list if (auditcreeper): template_list = template_list_copy[0] print("[+] [COMPUTING DIFF. STANDBY...]") multithread_engine(initialize.ntw_device, controller, command) ### THIS FOR LOOP WILL LOOP THROUGH ALL THE MATCHED ELEMENTS FROM THE USER SEARCH AND AUDIT ON SPECIFIC TEMPLATE OR IF NO ARGUMENT IS GIVEN, ALL TEMPLATES for index in initialize.element: ### NODE_CONFIG IS THE FINALIZED CONFIG TO PUSH TO THE NODE FOR REMEDIATION node_configs = [] ntw_device_pop = True ### TEMPLATE_NAME IS SET TO TRUE IN ORDER TO PRINT OUT THE TEMPLATE HEADING WHEN RECURSING template_name = True if (not remediation): print("Only in the device: -") print("Only in the generated config: +") print("{}".format(node_object[index]['hostname'])) ### THIS WILL LOOP THROUGH ALL THE TEMPLATES SPECIFIED FOR THE PARTICULAR HOST IN NODES.YAML for template in template_list: ### INDEX_LIST IS A LIST OF ALL THE POSITIONS COLLECTED FROM INDEX_POSITION VARIABLE index_list = [] ### FILTER_CONFIG IS A LIST OF COLLECTION OF ALL THE AUDIT FILTERS THAT MATCHED THE LINES IN BACKUP_CONFIG. THESE ENTRIES DO NOT CONTAIN DEPTHS/DEEP CONFIGS filtered_config = [] ### FILTERED_BACKUP_CONFIG IS THE FINAL LIST OF ALL THE AUDIT FILTERS THAT MATCHES THE LINES IN BACKUP_CONFIG. THESE ENTRIES INCLUDE DEPTHS/DEEP CONFIGS filtered_backup_config = [] ### THIS SECTION OF CODE WILL PROCESS THE TEMPLATE AND OUTPUT TO A *.CONF FILE directory = get_directory(node_object[index]['platform'], node_object[index]['os'], node_object[index]['type']) env = Environment(loader=FileSystemLoader("{}".format(directory))) baseline = env.get_template(template) f = open( "/rendered-configs/{}".format(node_object[index]['hostname']) + ".conf", "w") ### GENERATING TEMPLATE BASED ON NODE OBJECT config = baseline.render(nodes=node_object[index]) f.write(config) f.close ### THIS SECTION OF CODE WILL OPEN THE RENDERED-CONFIG *.CONF FILE AND STORE IN RENDERED_CONFIG AS A LIST f = open( "/rendered-configs/{}".format(node_object[index]['hostname']) + ".conf", "r") init_config = f.readlines() ### RENDERED_CONFIG IS A LIST OF ALL THE CONFIGS THAT WAS RENDERED FROM THE TEMPLATES (SOURCE OF TRUTH) rendered_config = [] for config_line in init_config: strip_config = config_line.strip('\n') ### THIS WILL REMOVE ANY LINES THAT ARE EMPTY OR HAS A '!' MARK if (strip_config == '' or strip_config == "!"): continue else: rendered_config.append(strip_config) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("RENDERED CONFIG: {}".format(rendered_config)) ### THIS SECTION OF CODE WILL OPEN BACKUP-CONFIG *.CONF FILE AND STORE IN BACKUP_CONFIG AS A LIST f = open( "/backup-configs/{}".format(node_object[index]['hostname']) + ".conf", "r") init_config = f.readlines() backup_config = [] for config_line in init_config: strip_config = config_line.strip('\n') backup_config.append(strip_config) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("BACKUP CONFIG: {}".format(backup_config)) ### THIS WILL OPEN THE JINJA2 TEMPLATE AND PARSE OUT THE AUDIT_FILTER SECTION VIA REGULAR EXPRESSION directory = get_directory(node_object[index]['platform'], node_object[index]['os'], node_object[index]['type']) f = open("{}".format(directory) + template, "r") parse_audit = f.readline() audit_filter = eval(re.findall(AUDIT_FILTER_RE, parse_audit)[0]) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("AUDIT_FILTER: {}".format(audit_filter)) ### FILTER OUT THE BACKUP_CONFIGS WITH THE AUDIT_FILTER ### THIS WILL TAKE EACH ELEMENT FROM THE AUDIT_FILTER LIST AND SEARCH FOR THE MATCHED LINES IN BACKUP_CONFIG ### MATCHED ENTRIES ARE THEN APPENDED TO FILTER_CONFIG VARIABLE AS A LIST parse_backup_configs = CiscoConfParse( "/backup-configs/{}".format(node_object[index]['hostname']) + ".conf") for audit in audit_filter: current_template = parse_backup_configs.find_objects( r"^{}".format(audit)) for audit_string in current_template: filtered_backup_config.append(audit_string.text) if (audit_string.is_parent): for child in audit_string.all_children: filtered_backup_config.append(child.text) ### UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print("FILTERED BACKUP CONFIG: {}".format(filtered_backup_config)) ### SYNC_DIFF WILL DIFF OUT THE FILTERED_BACKUP_COFNIG FROM THE RENDERED CONFIG AND STORE WHATEVER COMMANDS THAT ### NEEDS TO BE ADDED/REMOVE IN PUSH_CONFIGS VARIABLE parse = CiscoConfParse(filtered_backup_config) push_configs = parse.sync_diff(rendered_config, "", ignore_order=True, remove_lines=True, debug=False) if (len(push_configs) == 0): if (output): print("{}{} (none)".format(directory, template)) print else: ### THIS WILL JUST PRINT THE HEADING OF THE TEMPLATE NAME SO YOU KNOW WHAT IS BEING CHANGED UNDER WHICH TEMPLATE if (output): print("{}{}".format(directory, template)) for line in push_configs: search = parse_backup_configs.find_objects( r"^{}".format(line)) if ('no' in line): line = re.sub("no", "", line) if (not remediation): print("-{}".format(line)) elif (len(search) == 0): if (not remediation): print("+ {}".format(line)) elif (len(search) > 1): if (not remediation): print("+ {}".format(line)) else: if (not remediation): print(" {}".format(line)) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print("PUSH_CONFIGS: {}".format(push_configs)) if (remediation): ### THIS STEP WILL APPEND REMEDIATION CONFIGS FROM TEMPLATE (EXPECTED RESULTS) for config in push_configs: node_configs.append(config) ntw_device_pop = False ### INITIALIZE.COFIGURATION APPENDS ALL THE REMEDIATED CONFIGS AND PREPARES IT FOR PUSH if (auditcreeper == False): initialize.configuration.append(node_configs) node_index = node_index + 1 if (auditcreeper): initialize.configuration.append(node_configs) if (ntw_device_pop == True): initialize.ntw_device.pop(node_index) initialize.configuration.pop(node_index) template_list = get_template(template_list_copy) # if(remediation): # print("[+]: PUSH ENABLED") # print("[!]: PUSH DISABLED") return None
from ciscoconfparse import CiscoConfParse config = CiscoConfParse('cisco.txt') crypto = config.find_objects(r"^crypto map CRYPTO") for obj in crypto: print obj.text for child in obj.children: print child.text
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse config = CiscoConfParse("cisco_ipsec.txt") cmap = config.find_objects(r"^crypto map CRYPTO") for i in range(0, len(cmap)): for child in cmap[i].children: print child.text
# store your config file as config.txt # change whatever you are searching for on line 10 with open('config.txt', 'r') as f: myfile = f.read() print(myfile) from ciscoconfparse import CiscoConfParse x = CiscoConfParse(myfile.splitlines()) interfaces = x.find_objects_w_child( parentspec=r"^interface Vlan", childspec=f"ip dhcp relay address 10.1.25.17") print("These are the interfaces that INCLUDE the searched line : ") for interface in interfaces: print(interface.text) # uncomment to print out all the config for the interfaces that include the searched line #for interface in interfaces: # print ("\n") # print(interface.text) # for z in interface.children: # print (z.text) # uncomment to add or remove config #for interface in interfaces: # print (interface.text) # print ("YOUR CONFIG HERE")
#!/usr/bin/env pytho ''' This script parses cisco.txt file and searches for 'crypto map CRYPTO' lines using CCP module. Then it displays childrens indented multiple times for each element of crypto_map variable (list). ''' import pprint from ciscoconfparse import CiscoConfParse fo = open('cisco.txt', 'r') # Opening text file as FileObject with open() function parse = CiscoConfParse( fo) # Loading the file to CCF module as argument for parsing later crypto_map = parse.find_all_children(r'^crypto map CRYPTO') # In the line above using find_all_children method with regex (parsing) print 'Show the content of crypto_map variable: \n', crypto_map print print 'Show me parent-child relationships for crypto map CRYPTO lines in cisco.txt file: ' # Iterate over elements of crypto_map list and display in a nice human readable format for line in crypto_map: # pprint.pprint(line) # Replaced with the below as suggested by Kirk (clean output) print(line.strip("\n"))
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse import pprint #find and display parent in config def printParent(needle,printNeedle=False): objects = cisco_cfg.find_objects(needle.encode('string-escape')) for i in objects: print i.parent.text if printNeedle: print i.text #prettify def hr(s, c='#'): #not worth figuring the term width cross-platform, assume 80 width = 80 padding = width - 2 - len(s) print c.center(padding/2,c) + ' ' + s + ' ' + c.center(padding/2,c) #Load the cisco cfg cisco_cfg = CiscoConfParse("cisco_ipsec.txt") #Find all of the crypto map entries that are using PFS group2 hr('Crypto Maps using PFS group2') printParent("^ set pfs group2$") #Using ciscoconfparse find the crypto maps that are not using AES (based-on the transform set name). hr('crypto maps that are not using AES') #Print these entries and their corresponding transform set name. printParent("^ set transform-set (?!AES-SHA)", True)
from ciscoconfparse import CiscoConfParse parse_cfg = CiscoConfParse("cisco_ipsec.txt") crypto_objlist = parse_cfg.find_objects(r"^crypto map CRYPTO") for item in crypto_objlist: print item.text for child in item.children: print child.text
def auditdiff_engine(template_list, node_object, auditcreeper): controller = 'get_config' command = '' ### PUSH_CONFIGS IS A LIST OF THE FINAL CONFIGS TO BE PUSHED push_configs = [] ### INDEX_POSITION IS THE INDEX OF ALL THE MATCHED FILTER_CONFIG AGAINST THE BACKUP_CONFIGS. THE INDEX IS COMING FROM THE BACKUP_CONFIG index_position = 0 ### NODE_INDEX KEEPS TRACK OF THE INDEX IN INITIALIZE.NTW_DEVICE. IF REMEDIATION IS NOT REQUIRED (CONFIGS MATCHES TEMPLATE), THEN THE NODE IS POPPED OFF ### INITIALIZE.NTW_DEVICE AND NOTHING IS CHANGED ON THAT DEVICE node_index = 0 ### AUDIT_FILTER_RE IS THE REGULAR EXPRESSION TO FILTER OUT THE AUDIT FILTER IN EVERY TEMPLATE AUDIT_FILTER_RE = r"\[.*\]" ### TEMPLATE_LIST_COPY TAKE A COPY OF THE CURRENT TEMPLATE_LIST template_list_copy = template_list if (auditcreeper): template_list = template_list_copy[0] print("[+] [GATHERING RUNNING-CONFIG. STANDBY...]") multithread_engine(initialize.ntw_device, controller, command) ### THIS FOR LOOP WILL LOOP THROUGH ALL THE MATCHED ELEMENTS FROM THE USER SEARCH AND AUDIT ON SPECIFIC TEMPLATE OR IF NO ARGUMENT IS GIVEN, ALL TEMPLATES for index in initialize.element: ### NODE_CONFIG IS THE FINALIZED CONFIG TO PUSH TO THE NODE FOR REMEDIATION node_configs = [] ntw_device_pop = True ### TEMPLATE_NAME IS SET TO TRUE IN ORDER TO PRINT OUT THE TEMPLATE HEADING WHEN RECURSING template_name = True first_parent = True previous_parent = '' print("Only in the device: -") print("Only in the generated config: +") print("{}".format(node_object[index]['hostname'])) for template in template_list: ### INDEX_LIST IS A LIST OF ALL THE POSITIONS COLLECTED FROM INDEX_POSITION VARIABLE index_list = [] ### FILTER_CONFIG IS A LIST OF COLLECTION OF ALL THE AUDIT FILTERS THAT MATCHED THE LINES IN BACKUP_CONFIG. THESE ENTRIES DO NOT CONTAIN DEPTHS/DEEP CONFIGS filtered_config = [] ### FILTERED_BACKUP_CONFIG IS THE FINAL LIST OF ALL THE AUDIT FILTERS THAT MATCHES THE LINES IN BACKUP_CONFIG. THESE ENTRIES INCLUDE DEPTHS/DEEP CONFIGS filtered_backup_config = [] ### THIS SECTION OF CODE WILL PROCESS THE TEMPLATE AND OUTPUT TO A *.CONF FILE directory = get_directory(node_object[index]['platform'], node_object[index]['os'], node_object[index]['type']) env = Environment(loader=FileSystemLoader("{}".format(directory))) baseline = env.get_template(template) f = open( "/rendered-configs/{}".format(node_object[index]['hostname']) + ".conf", "w") ### GENERATING TEMPLATE BASED ON NODE OBJECT config = baseline.render(nodes=node_object[index]) f.write(config) f.close ### THIS SECTION OF CODE WILL OPEN THE RENDERED-CONFIG *.CONF FILE AND STORE IN RENDERED_CONFIG AS A LIST f = open( "/rendered-configs/{}".format(node_object[index]['hostname']) + ".conf", "r") init_config = f.readlines() ### RENDERED_CONFIG IS A LIST OF ALL THE CONFIGS THAT WAS RENDERED FROM THE TEMPLATES (SOURCE OF TRUTH) rendered_config = [] for config_line in init_config: strip_config = config_line.strip('\n') ### THIS WILL REMOVE ANY LINES THAT ARE EMPTY OR HAS A '!' MARK if (strip_config == '' or strip_config == "!"): continue else: rendered_config.append(strip_config) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("RENDERED CONFIG: {}".format(rendered_config)) ### THIS SECTION OF CODE WILL OPEN BACKUP-CONFIG *.CONF FILE AND STORE IN BACKUP_CONFIG AS A LIST f = open( "/backup-configs/{}".format(node_object[index]['hostname']) + ".conf", "r") init_config = f.readlines() backup_config = [] for config_line in init_config: strip_config = config_line.strip('\n') backup_config.append(strip_config) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("BACKUP CONFIG: {}".format(backup_config)) ### THIS WILL OPEN THE JINJA2 TEMPLATE AND PARSE OUT THE AUDIT_FILTER SECTION VIA REGULAR EXPRESSION directory = get_directory(node_object[index]['platform'], node_object[index]['os'], node_object[index]['type']) f = open("{}".format(directory) + template, "r") parse_audit = f.readline() audit_filter = eval(re.findall(AUDIT_FILTER_RE, parse_audit)[0]) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print ("{}".format(audit_filter)) ### FILTER OUT THE BACKUP_CONFIGS WITH THE AUDIT_FILTER ### THIS WILL TAKE EACH ELEMENT FROM THE AUDIT_FILTER LIST AND SEARCH FOR THE MATCHED LINES IN BACKUP_CONFIG ### MATCHED ENTRIES ARE THEN APPENDED TO FILTER_CONFIG VARIABLE AS A LIST for audit in audit_filter: parse_backup_configs = CiscoConfParse( "/backup-configs/{}".format(node_object[index] ['hostname']) + ".conf") current_template = parse_backup_configs.find_objects( r"^{}".format(audit)) for audit_string in current_template: filtered_backup_config.append(audit_string.text) if (audit_string.is_parent): for child in audit_string.all_children: filtered_backup_config.append(child.text) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print("FILTERED BACKUP CONFIG: {}".format(filtered_backup_config)) ### FILTERED_SET/RENDERED_SET RETURNS A DICTIONARY OF THE NUMBER OF TIMES A CONFIG IS REPEATED IN THE LIST filtered_backup_set = Counter(filtered_backup_config) rendered_set = Counter(rendered_config) minus_commands_counter = filtered_backup_set - rendered_set plus_commands_counter = rendered_set - filtered_backup_set ### MINUS_COMMANDS IS A LIST OF COMMANDS THAT EXIST ON THE NODE THAT SHOULDN'T BE WHEN COMPARED AGAINST THE TEMPLATE ### PLUS_COMMAND IS A LIST OF COMMAND THAT DOESN'T EXIST ON THE NODE THAT SHOULD BE WHEN COMPARED AGAINST THE TEMPLATE minus_commands = list(minus_commands_counter.elements()) plus_commands = list(plus_commands_counter.elements()) # print("MINUS_COMMANDS: {}".format(minus_commands)) # print("PLUS_COMMANDS:: {}".format(plus_commands)) ### THIS SECTION OF CODE CHECKS TO SEE IF THE LENGTH OF THE TWO LIST IS EQUAL TO ZERO, THEN NOTHING HAS TO BE REMEDIATED if (len(minus_commands) == 0 and len(plus_commands) == 0 and auditcreeper == False): print("{}{} (none)".format(directory, template)) print initialize.ntw_device.pop(node_index) if (len(minus_commands) == 0 and len(plus_commands) == 0 and auditcreeper == True): print("{}{} (none)".format(directory, template)) print elif (len(minus_commands) >= 1 or len(plus_commands) >= 1): ### THIS WILL JUST PRINT THE HEADING OF THE TEMPLATE NAME SO YOU KNOW WHAT IS BEING CHANGED UNDER WHICH TEMPLATE print("{}{}".format(directory, template)) ### THIS SECTION OF CODE WILL PRINT THE DIFF OF WHAT CONFIG(S) WILL BE CHANGING for line in difflib.unified_diff(filtered_backup_config, rendered_config, n=5): if (line.startswith("---") or line.startswith("+++") or line.startswith("@")): continue else: print line if (line.startswith("-")): config_line = line.strip() ### THIS IF CONDITION IS TO SATISFY SOME CASES WHERE IT HAS A HYPEN IN BETWEEN A CONFIG. EX SNMP-SERVER if (re.match("-\w.+\-", config_line)): config_line = re.sub("^\-", "no ", config_line) push_configs.append(config_line) elif (re.match("-", config_line)): config_line = re.sub("-", "no ", config_line) push_configs.append(config_line) elif (re.match("-\s\w", line)): config_line = re.sub("-", "no", config_line) push_configs.append(config_line) elif (line.startswith("+")): config_line = line.strip() config_line = line.strip("+") push_configs.append(config_line) else: config_line = line.strip("\n") push_configs.append(config_line) print("") ### THIS SECTION OF CODE WILL CHECK FOR THE WHITE SPACES FROM THE BEGINNING OF THE LIST ### IF THE ELEMENT HAS 1 WHITE SPACE, IT THEN KNOWS IT'S A PARENT CONFIG ### ANYTHING GREATER THAN 1 WHITE SPACE IS A PARENT/CHILD config_index = 0 whitespace = len(push_configs[config_index]) - len( push_configs[config_index].lstrip()) while (whitespace != 1): push_configs.pop(config_index) whitespace = len(push_configs[config_index]) - len( push_configs[config_index].lstrip()) ###UN-COMMENT THE BELOW PRINT STATEMENT FOR DEBUGING PURPOSES # print("PUSH_CONFIGS: {}".format(push_configs)) ### THIS STEP WILL APPEND REMEDIATION CONFIGS FROM TEMPLATE for config in push_configs: node_configs.append(config) ntw_device_pop = False ### INITIALIZE.COFIGURATION APPENDS ALL THE REMEDIATED CONFIGS AND PREPARES IT FOR PUSH if (auditcreeper == False): initialize.configuration.append(node_configs) node_index = node_index + 1 if (auditcreeper): initialize.configuration.append(node_configs) if (ntw_device_pop == True): initialize.ntw_device.pop(node_index) initialize.configuration.pop(node_index) template_list = get_template(template_list_copy) return None
def main(configfile, verbose): # Initialize data structures networkgroups = {} servicegroups = {} hostname = '' # Open config files and pre-initialized data structures shelvefile = config['NAME_NUMBER_MAPPING'] try: # Name-number mappings db = shelve.open(shelvefile) name2num = db['cisco_port_name_to_number'] num2name = db['cisco_port_number_to_name'] icmptype2num = db['icmp_type_name_to_number'] db.close() except KeyError as e: logging.error( 'Unable to find database entry {0} in shelve file {1}'.format( e, shelvefile)) sys.exit(1) # Check that path to accesslist database exists, try to create it if not shelvefile = config['ACCESSLIST_DATABASE'] if not os.path.isfile(shelvefile): if not os.path.dirname(shelvefile) == '' and not os.path.isdir( os.path.dirname(shelvefile)): try: os.makedirs(os.path.dirname(shelvefile)) except OSError as e: logging.error('Path to accesslist DB file "{0}" does not exists, '.format(shelvefile) + \ 'and I\'m unable to create it. Aborting.') sys.exit(1) try: db = shelve.open(shelvefile) except: logging.error( 'Unable to open or create access-list database "{0}"'.format( shelvefile)) sys.exit(1) try: # Firewall metadata if 'firewalls' in db: firewalls = db['firewalls'] else: firewalls = {} db.close() except KeyError as e: logging.error( 'Unable to find database entry {0} in shelve file {1}'.format( e, shelvefile)) sys.exit(1) # Get config file name and try to initialize CiscoConfParse object try: conf = CiscoConfParse(configfile) except Exception, e: logging.error( 'Unable to initialize CiscoConfParse object. Reason: {0}'.format( e)) sys.exit(1)
from ciscoconfparse import CiscoConfParse config_file = CiscoConfParse('cisco_ipsec.txt') crypto = config_file.find_objects_wo_child(parentspec=r"^crypto map CRYPTO", childspec=r"AES-SHA") no_aes = crypto[0] print('The following crypto maps are not using AES: ') print(no_aes.text) for x in no_aes.children: print(x.text)
time.sleep(2) print(' - Your target MAC-Address was: ' + macaddr) time.sleep(2) print(' Closing connection to: ' + hostname) time.sleep(2) net_connect.disconnect() # Checks that the interface found in the previous check is not a trunk. # Check is performed by doing a show run and checking for 'switchport mode trunk' # If the port is not a trunk it moves to the next step. else: with open(sh_mac, 'a') as f: print((mac_tbl), file=f) print(' - (' + macaddr + ') was found in (' + hostname + '), mac-address table.') parse = CiscoConfParse('.\\sh_mac.txt') obj = parse.find_objects(r'[GT]\S\S\S\S\S\S\S?|Po\d\d?\d?')[0] mac_int = obj.re_match_typed(r'([GT]\S\S\S\S\S\S\S?|Po\d\d?\d?)') sh_run = 'sh_trunk.txt' sh_run_int = net_connect.send_command("show run int " + mac_int) with open(sh_run, 'a') as z: print((sh_run_int), file=z) parse2 = CiscoConfParse('.\\sh_trunk.txt') obj2 = parse2.find_lines(r'(switchport mode trunk)') time.sleep(1) print(' * Verifying (' + macaddr + ') is directly connected to ' + hostname)
from ciscoconfparse import CiscoConfParse from netmiko import ConnectHandler from getpass import getpass import sys host=sys.argv[1] free_num = 0 gam_cfg = CiscoConfParse(gamconfig) password = getpass() gam = { 'device_type': 'cisco_ios', 'ip': host, 'username': '******', 'password': password, } net_connect = ConnectHandler(**gam) output = net_connect.send_command("show interface") gam_cfg = CiscoConfParse(output) free_ports = gam_cfg.find_objects_wo_child(parentspec=r"^Interface g", childspec=r"customer/") #hostname = gam_cfg.find_objects(r"^hostname")[0].text[9:] for my_int in free_ports: free_num = free_num + 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 running-config ') ''' while not stdout.channel.eof_received: if time.time() > endtime: sheet.write(row, 5,"EOF not reached" ) #stdout.channel.close() break ''' config = stdout.readlines() parse = CiscoConfParse(config) match = parse.find_objects_w_child(parentspec=r"^interface", childspec=r"ip helper-address") for parent in match: row = row + 1 print parent.text sheet.write(row, 2, parent.text) for child in parent.children: ipaddress = re.findall(r'(?<=ip address)(.*)', child.text) helpers = re.findall(r'(?<=ip helper-address )(.*)', child.text) for value in ipaddress: print value sheet.write(row, 3, value) for helper in helpers: print helper
from ciscoconfparse import CiscoConfParse parse_cfg = CiscoConfParse("cisco_ipsec.txt") pfs2crypto = parse_cfg.find_objects_w_child(parentspec=r"^crypto map CRYPTO", childspec=r"pfs group2") for item in pfs2crypto: print item.text
from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse("cisco.txt") crypto_map = cisco_cfg.find_objects(r"^crypto map CRYPTO") count = 0 for map in crypto_map: crypto_child = crypto_map[count] count += 1 for child in crypto_child.children: if "transform-set" in child.text: if "AES" not in child.text: print map.text print child.text
def main(host): """See all DHCP helpers defined on a switch\n Example: find_dhcp_helper lca1-s2-csw01.nw.linkedin.com """ command = r'sh run | i "interface|desc|dhcp"' filename = "running_config" print "Please enter your Tacacs password:"******"host {0} | awk '/has address/ {{print $4}}' " .format(host)) host_ip = f.read().strip() def disable_paging(remote_conn): '''Disable paging on a Cisco router''' remote_conn.send("terminal length 0\n") time.sleep(1) # Clear the buffer on the screen output = remote_conn.recv(1000) return output # Create instance of SSHClient object remote_conn_pre = paramiko.SSHClient() # Automatically add untrusted hosts (make sure okay for security policy in your environment) remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # initiate SSH connection remote_conn_pre.connect(host, username=getpass.getuser(), password=tacacs, look_for_keys=False, allow_agent=False) time.sleep(5) print ("SSH connection established to {0}" .format(host_ip)) # Use invoke_shell to establish an 'interactive session' remote_conn = remote_conn_pre.invoke_shell() print "Interactive SSH session established" # Turn off paging disable_paging(remote_conn) remote_conn.send(command + "\n") # wait until the buffer gets some data while not remote_conn.recv_ready(): time.sleep(1) # give channel time to complete sending data time.sleep(5) command_return = remote_conn.recv(200000) f = open(filename, "w") f.write(command_return) f.close() from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse(filename) dhcp_interfaces = cisco_cfg.find_objects_w_child(parentspec=r"^interface", childspec=r"ip dhcp relay address") for interface in dhcp_interfaces: print "\n" + interface.text for child in interface.children: if 'description' in str(child): print child.text if 'ip dhcp relay address' in str(child): print child.text os.remove(filename)
remote-as 42 description pynet-rtr1 address-family ipv4 unicast route-policy ALLOW in route-policy ALLOW out ! ! neighbor 10.220.88.32 remote-as 43 address-family ipv4 unicast route-policy ALLOW in route-policy ALLOW out """ # When feeding config directly - CiscoConfParse requires a list bgp_obj = CiscoConfParse(bgp_config.splitlines()) # Result of find_objects_w_parents will be the child objects bgp_peers = [] neighbors = bgp_obj.find_objects_w_parents( parentspec=r"router bgp", childspec=r"neighbor" ) for neighbor in neighbors: _, neighbor_ip = neighbor.text.split() for child in neighbor.children: if "remote-as" in child.text: _, remote_as = child.text.split() bgp_peers.append((neighbor_ip, remote_as)) print() print("BGP Peers: ")
# http://www.pennington.net/py/ciscoconfparse/intro.html # http://pennington.net/tutorial/ciscoconfparse/ccp_tutorial.html#slide1 # https://github.com/mpenning/ciscoconfparse # pip install CiscoConfParse from ciscoconfparse import CiscoConfParse f = open("./cisco_config_examples/sample01.conf", "r") cisco_cfg = CiscoConfParse(f.read().splitlines(keepends=False)) interfaces = cisco_cfg.find_objects_w_child(parentspec=r"^interface", childspec=r"^\s+ip address") print() for i in interfaces: print("Interface: {}".format(i.text)) ip_address = i.re_search_children(r"ip address")[0].text print("IP Address: {}".format(ip_address)) print() print() print(cisco_cfg)
from ciscoconfparse import CiscoConfParse cisco_cfg = CiscoConfParse("cisco.txt") cryptos = cisco_cfg.find_objects_wo_child(parentspec=r"^crypto map CRYPTO", childspec=r"AES") for crypto in cryptos: # if 'AES' in cryptos: # continue # else: chill = crypto.children print crypto.text for child in chill: print child.text
def show_cmd_parser(path_to_file): """ func show_cmd_parser :param path_to_file: OS Path to file :return: dict with device parameters It is better to provide "show tech-support" for this parser For device atributes such as hostname, model, serial number etc simple regex are used For interface information parsing ciscoconfparse module is used """ parsed_values = {} dict_for_ciscoconfparser = [] with open(path_to_file) as open_file: # This cycle gets info from 'show version' output with simple regex for line in open_file: dict_for_ciscoconfparser.append(line) if re.match('^Model number*', line): value = (line.rstrip()).split()[-1] parsed_values['model'] = value parsed_values['device_type'] = 'SWITCH' if re.match('^.+ bytes of memory', line): value = re.search('\S+ \(.+?\)', line) parsed_values['model'] = value.group(0) parsed_values['device_type'] = 'ROUTER' if re.match('^hostname *', line): value = (line.rstrip()).split()[-1] parsed_values['hostname'] = value if re.match('^System serial number *', line): value = (line.rstrip()).split()[-1] parsed_values['serial_number'] = value if re.match('^Processor board ID *', line): value = (line.rstrip()).split()[-1] parsed_values['serial_number'] = value if re.match('.+ Software .+, Version', line): lic = re.search('\(.+?\)', line) parsed_values['software_license'] = lic.group(0).strip('( , )') softver = re.search(' [0-9]+\.\S+', line) parsed_values['software_version'] = softver.group(0).strip(',') parse = CiscoConfParse(dict_for_ciscoconfparser, factory=True) interface_object_list = parse.find_objects('^interface\s') parsed_values['interfaces'] = {} # This cycle gets information from 'show run' output for obj in interface_object_list: parsed_values['interfaces'][obj.name] = {} parsed_values['interfaces'][obj.name]['int_name'] = obj.name parsed_values['interfaces'][ obj.name]['int_description'] = obj.description parsed_values['interfaces'][obj.name]['int_ip_address'] = obj.ip_addr if obj.is_switchport is True: parsed_values['interfaces'][obj.name]['port_type'] = 'switchport' parsed_values['interfaces'][obj.name]['int_vlan'] = obj.access_vlan parsed_values['interfaces'][ obj.name]['int_trunk'] = obj.has_manual_switch_trunk else: parsed_values['interfaces'][obj.name]['port_type'] = None # This cycles get up/down information form 'show interfaces' output for interface in parsed_values['interfaces']: for element in dict_for_ciscoconfparser: regex_for_match = interface + r' is ((up)|(administratively down)|(down)), line protocol is ((up)|(down))' if re.match(regex_for_match, element): if re.match('^.+ line protocol is up', element): parsed_values['interfaces'][interface]['int_status'] = 'UP' break if re.match('^.+ line protocol is down', element): parsed_values['interfaces'][interface][ 'int_status'] = 'DOWN' break else: parsed_values['interfaces'][interface][ 'int_status'] = 'NOT CONFIGURED' return parsed_values
from ciscoconfparse import CiscoConfParse def conf_int_iterator(list_int): for i in list_int: print i.text with open("r1_fo_acc4_interface_list.txt", "a") as f: f.write(i.text) f.write("\n") conf_int_iterator(i.children) int_ref = CiscoConfParse("r1_fo_acc4.log") list_int = int_ref.find_objects(r"^interface") conf_int_iterator(list_int)
#!/usr/bin/env from ciscoconfparse import CiscoConfParse cfg = CiscoConfParse("config.txt") crypto_map = cfg.find_objects_w_child(parentspec=r"^crypto map", childspec="pfs group2") for i in crypto_map: print i.text for j in i.all_children: print j.text
import re f = open( 'C:\\Users\\RamuGajula\\AppData\\Local\\Programs\\Python\\Python37\\allowed_vlan.txt' ) import ciscoconfparse from ciscoconfparse import CiscoConfParse import sys import openpyxl # wb = openpyxl.load_workbook(r"C:\\Users\\RamuGajula\\Desktop\\Py-portmapping\\Port-Mapping.xlsx") # sheet = wb['Fab7-corp-1'] device_file_name = sys.argv[1] parse = CiscoConfParse( "C:\\Users\\RamuGajula\\Desktop\\Py-portmapping\\show run\\{}".format( device_file_name)) # l3_int = parse.find_objects(r"interface") # L3_int_list = [] # for obj in l3_int: # if obj.re_search_children(r"^\sip address"): # L3_int_list.append(obj) # # print(L3_int_list) # int_name = [] # for i in L3_int_list: # print(i.text) # split_list = i.text.split() # int_name.append(split_list[1]) # # print(int_name) # # for i in range(2,581):
from netmiko import ConnectHandler from getpass import getpass from pprint import pprint infile = input("Where is your device list: ") bgp_config = """ router bgp 44 bgp router-id 10.220.88.38 address-family ipv4 unicast ! neighbor 10.220.88.20 remote-as 42 description pynet-rtr1 address-family ipv4 unicast route-policy ALLOW in route-policy ALLOW out ! ! neighbor 10.220.88.32 remote-as 43 address-family ipv4 unicast route-policy ALLOW in route-policy ALLOW out """ cisco_obj = CiscoConfParse(bgp_config.splitlines()) match_nei = cisco_obj.find_objects_w_child(parentspec=r"^router bgp", childspec=r"^neighbor")