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 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 check_routing_protocol_enabled_and_used( config: typing.List[str], ) -> typing.Optional[CheckResult]: """Check if a routing protocol is actually used - should it be enabled.""" parsed_config = CiscoConfParse(config) for protocol in ["bgp", "ospf", "eigrp", "rip"]: feature_enabled = parsed_config.find_lines(f"^feature {protocol}") if not feature_enabled: return None feature_used = parsed_config.find_lines(f"^router {protocol}") if not feature_used: return CheckResult( text=f"{protocol.upper()} enabled but never used.", lines=feature_enabled + feature_used, ) return None
def testValues_ignore_ws(): ## test find_lines with ignore_ws flag config = ['set snmp community read-only myreadonlystring'] result_correct = config cfg = CiscoConfParse(config) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ignore_ws=True) assert result_correct == test_result
def testValues_negative_ignore_ws(): """test find_lines WITHOUT ignore_ws""" config = ['set snmp community read-only myreadonlystring'] result_correct = list() cfg = CiscoConfParse(config) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ignore_ws=False) assert result_correct == test_result
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 check_telnet_enabled( config: typing.List[str]) -> typing.Optional[CheckResult]: """Check if the telnet feature is explicitly enabled.""" parsed_config = CiscoConfParse(config) lines = parsed_config.find_lines("^feature telnet") if lines: return CheckResult(text="Feature telnet is enabled.", lines=lines) else: return None
def check_ip_http_server( config: typing.List[str]) -> typing.Optional[CheckResult]: """Check if the http server is enabled.""" parsed_config = CiscoConfParse(config) lines = parsed_config.find_lines("^ip http") if lines: return CheckResult(text="HTTP server not disabled.", lines=lines) else: return None
def testValues_ignore_ws(self): ## test find_lines with ignore_ws flag result_correct = self.c03 cfg = CiscoConfParse(self.c03) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ignore_ws = True ) self.assertEqual(result_correct, test_result)
def testValues_ignore_ws(): ## test find_lines with ignore_ws flag config = ['set snmp community read-only myreadonlystring'] result_correct = config cfg = CiscoConfParse(config) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ignore_ws = True ) assert result_correct==test_result
def testValues_negative_ignore_ws(): """test find_lines WITHOUT ignore_ws""" config = ['set snmp community read-only myreadonlystring'] result_correct = list() cfg = CiscoConfParse(config) test_result = cfg.find_lines( 'set snmp community read-only myreadonlystring', ignore_ws = False ) assert result_correct==test_result
def check_password_strength( config: typing.List[str]) -> typing.Optional[CheckResult]: """Check if the password strength check has been disabled.""" parsed_config = CiscoConfParse(config) disabled = parsed_config.find_lines("^no password strength-check") if disabled: return CheckResult(text="Password strength-check disabled.", lines=disabled) else: return None
def get_access_list_usage( config: CiscoConfParse, name: typing.Optional[str] = None) -> typing.List[str]: """Return lines that use access lists. :param config: The config to filter in. :param name: Optionally filter for a specific ACL name. """ access_list_usage = "(ip)? access-(group|class)" if name: access_list_usage += " " + name return config.find_lines(access_list_usage)
def check_bogus_as(config: typing.List[str]) -> typing.Optional[CheckResult]: """Check if any bogus autonomous system is used in the configuration.""" parsed_config = CiscoConfParse(config) bgp_routers = parsed_config.find_lines("^router bgp") bad_lines = [] for line in bgp_routers: as_number = int(line[11:]) if as_number in bogus_as_numbers: bad_lines.append(line) if bad_lines: return CheckResult(text="Bogus AS number in use", lines=bad_lines) else: return None
def check_password_hash_strength( config: typing.List[str], ) -> typing.Optional[CheckResult]: """Check if strong password hash algorithms were used.""" parsed_config = CiscoConfParse(config) lines_with_passwords = parsed_config.find_lines( r"^.*(password|secret)\s\d.*$") bad_lines = [] for line in lines_with_passwords: hash_algorithm = get_password_hash_algorithm(line) if hash_algorithm in c.bad_hash_algorithms: bad_lines.append(line) if bad_lines: return CheckResult("Insecure hash algorithms in use.", lines=bad_lines) else: return None
def parse_c_map(ws): row = 1 # open all .txt files in the current directory for filename in glob.glob('*.txt'): config = CiscoConfParse(filename, factory=True, syntax='ios') hostname = config.find_objects_dna(r'Hostname')[0].hostname ios_ver = config.find_lines('IOS')[0][len('!! IOS XR Configuration '):] print('... %s (IOS XR %s)' % (hostname, ios_ver)) for be in config.find_objects_w_child(r'^interface.+Bundle[^.]+$', 'service-policy output'): for parent in be.re_search_children('service-policy'): parent_policy = parent.text[len(' service-policy output '):] p_map = config.find_all_children(r'^policy-map ' + parent_policy + '$') child_policy = [i for i in p_map if 'service-policy' in i ][0][len(' service-policy '):] for c_policy in config.find_objects('policy-map ' + child_policy + '$'): for c_map in c_policy.re_search_children('class'): # write the hostname in column A ws.write(row, 0, hostname) # write the IOS XR version in column B ws.write(row, 1, ios_ver) # write child policy in column C ws.write(row, 2, child_policy) # write class maps in column D ws.write(row, 3, c_map.text[len(' class '):]) for police_rate in c_map.re_search_children('police'): # write police rate in column E ws.write(row, 4, police_rate.text.strip()) if 'vlan' in c_map.text.lower( ) or 'default' in c_map.text: ws.write(row, 5, 'Ok') else: ws.write(row, 5, 'Incorrect class map.') row += 1 print('... Completed %s class maps.' % row) # set the autofilter ws.autofilter(0, 0, row, 5)
def check_plaintext_passwords( config: typing.List[str]) -> typing.Optional[CheckResult]: """Check if there are any plaintext passwords in the configuration.""" parsed_config = CiscoConfParse(config) lines = parsed_config.find_lines("^username.*password") if lines: # If `service password-encryption` is configured, users are saved to the # config like `username test password 7 $ENCRYPTED. The following for-loop # checks for that. for line in lines: has_hash_algorithm = get_password_hash_algorithm(line) if not has_hash_algorithm: break else: # If the for loop wasn't exited prematurely, no plaintext passwords # are present. return None return CheckResult(text="Plaintext user passwords in configuration.", lines=lines) else: return None
def check_net1660(device): #opening SNMP results file command = "show snmp user" device.connect device.send_command(command) config = open("net1660.conf", "w") config.write(ssh_output) config.close() parse_config("net1660.conf") snmp_show_results = open("net1660.conf", "r") snmp_show_results_str = str(snmp_show_results.readlines()) #REGEX to find violating config for SNMP AES_REG_A = re.findall("3DES|DES|MD5|User name.*?,", snmp_show_results_str) #SNMP violation count COUNT_MD5 = AES_REG_A.count("MD5") COUNT_DES = AES_REG_A.count("DES") COUNT_3DES = AES_REG_A.count("3DES") NET1660_VIOLATION = COUNT_3DES + COUNT_MD5 + COUNT_DES #Looking for SNMP version 1 and 2c related configuration parse = CiscoConfParse(snmp_show_results) snmp_lines = parse.find_lines( "(snmp-server.(user|group).*v(1|2))|(snmp-server community.*)") #Conditional to validate if device is using FIP-140-2 compliant SNMPv3 deployment and no SNMPv2 is being utilized if NET1660_VIOLATION > 0 or snmp_lines: print("NET1660 " + NET1660[0] + " Results: \"SNMPv3 must only Use SHA and AES\" \n" + " Execute 'show snmp user' on system") print(" ") print("NET1660 " + NET1660[0] + " Results: \"SNMPv1 and SNMPv2 must not be used\" \n " + "{0}").format(" ".join(str(i) for i in snmp_lines)) else: print("NET1660:\n no violations detected")
class IOSDevice: """ Represents an IOS Device. Some helper functions here to assist with common stuff :type hostname: str """ def __init__(self, config_filename): self.parsed_switch_config = CiscoConfParse(config_filename) self.hostname = self._getHostname() self.interfaces = self._getNetworkInterfaces() self.router_id = self._getRouterId() def __repr__(self): return "<IOSDevice: %s>" % self.hostname def _getHostname(self): if not self.parsed_switch_config.find_lines('^hostname'): raise RuntimeError('This device has no hostname. This library requires this device has a hostname') return self.parsed_switch_config.find_lines('^hostname')[0].split()[1] def _getRouterId(self): router_id = None router_ids = self.parsed_switch_config.find_lines('router-id') if len(router_ids) > 0: router_id = self.parsed_switch_config.find_lines('router-id')[0].split()[-1] #Assume all mgmt addresses are the same elif len(self.parsed_switch_config.find_lines('^logging source-interface')) > 0: #Little hack. We don't have a router-id so lets use the logging source-id as the switch identifier for interface in self.getNetworkInterfaces(): if interface.name == self.parsed_switch_config.find_lines('^logging source-interface')[0].split()[-1]: return interface.address else: #There is no explicit mgmt address. # The router-id is set by the highest IP Address of a manually created loopback address highestAddress = IPv4Address(u'0.0.0.0') for interface in self.getNetworkInterfaces(): if "loopback" in interface.name.lower(): address = IPv4Address(unicode(interface.address)) if address > highestAddress: highestAddress = address router_id = interface.address # If there is no configured loopback the router id will be the highest IP address of the fist active (on-boot) # physical interface if router_id is None: for interface in self.getNetworkInterfaces(): address = IPv4Address(unicode(interface.address)) if address > highestAddress: highestAddress = address router_id = interface.address return router_id def _getNetworkInterfaces(self): """ Used to generate a list of NetworkInterface for a given config file :type parsed_switch_config: ciscoconfparse.CiscoConfParse :return list of interfaces """ to_return = [] switch_interfaces = self.parsed_switch_config.find_parents_wo_child("^interface", 'shutdown') for interface in switch_interfaces: #Gets the child config for this interface interface_config = CiscoConfParse(self.parsed_switch_config.find_children(interface, exactmatch=True)) #We are only interested in the interface name, not the entire interface command definition interface_name = interface.split()[1] #VRF is in global by default vrf = None description = None if interface_config.find_lines('description'): description = " ".join(interface_config.find_lines('description')[0].strip().split()[1:]) if interface_config.find_lines('^ ip vrf forwarding'): vrf = interface_config.find_lines('^ ip vrf forwarding')[0].strip().split()[-1] elif interface_config.find_lines('^ vrf forwarding'): vrf = interface_config.find_lines('^ vrf forwarding')[0].strip().split()[-1] #We only really care about this interface if it has an IP address on it #interfaces that have no addresses should be skipped if interface_config.find_lines('no ip address'): continue if interface_config.find_lines('^ ip address'): #Create a new network interface object interface = NetworkInterface(self) #In case we want to skip this interface and not show it for some reason should_add_address = True for address in interface_config.find_lines('^ ip address'): #We can have multiple addresses here, have to allow for secondaries if "secondary" in address: secondary_address = SecondaryAddress(interface) secondary_address.address = address.strip().split('ip address')[1].split()[0] secondary_address.netmask = address.strip().split('ip address')[1].split()[1] interface.secondary.append(secondary_address) else: if "no" in address or "negotiated" in address: should_add_address = False break if len(interface_config.find_lines('channel-group')) > 0: should_add_address = False break interface.address = address.strip().split('ip address')[1].split()[0] interface.name = interface_name interface.netmask = address.strip().split('ip address')[1].split()[1] interface.vrf = vrf interface.description = description to_return.append(interface) return to_return def getNetworkInterfaces(self): """ Used to generate a list of NetworkInterface for a given config file :type parsed_switch_config: ciscoconfparse.CiscoConfParse :return list of interfaces """ if self.interfaces is None: self.interfaces = self._getNetworkInterfaces() return self.interfaces def getHostname(self): """ Returns the hostname on this device :rtype: str """ return self.hostname def getParsedSwitchConfig(self): """ Returns a parsed switch config object (CiscoConfParse) for this device :rtype: CiscoConfParse """ return self.parsed_switch_config()
# load templates from files iseGeneralConfig = './switch-ise-config-templates/sample-ise-general-config.txt' iseInterfaceConfig = './switch-ise-config-templates/sample-ise-interface-config.txt' with open(iseGeneralConfig, 'r') as iseGeneralConfig: iseGeneralConfig = iseGeneralConfig.read() with open(iseInterfaceConfig, 'r') as iseInterfaceConfig: iseInterfaceConfig = iseInterfaceConfig.read().splitlines() # create list to contain new config commands new_config_cmds = [] skipped_interfaces = [] parse = CiscoConfParse(configFile.split("\n")) new_config_cmds.append(iseGeneralConfig) # find switch hostname device_name = parse.find_lines("^hostname\s") device_name = device_name[0].replace("hostname ", "") print "-" * 20 print "Issue the command below to apply configuration:" print "copy ftp://myuser:[email protected]/cfgs/%s.txt running-config" % device_name.lower() # for each interface in config for intf in parse.find_objects(r'^interface.+?thernet'): # if the port is not exempt from NAC interface_not_exempt = not intf.has_child_with(r'(?i)mode trunk|^\s+channel|^\s+description.+(Server|Printer|Uplink)|^\s+shutdown') if interface_not_exempt: # add interface to new config commands new_config_cmds.append(intf.text)
def _getNetworkInterfaces(self): """ Used to generate a list of NetworkInterface for a given config file :type parsed_switch_config: ciscoconfparse.CiscoConfParse :return list of interfaces """ to_return = [] switch_interfaces = self.parsed_switch_config.find_parents_wo_child("^interface", 'shutdown') for interface in switch_interfaces: #Gets the child config for this interface interface_config = CiscoConfParse(self.parsed_switch_config.find_children(interface, exactmatch=True)) #We are only interested in the interface name, not the entire interface command definition interface_name = interface.split()[1] #VRF is in global by default vrf = None description = None if interface_config.find_lines('description'): description = " ".join(interface_config.find_lines('description')[0].strip().split()[1:]) if interface_config.find_lines('^ ip vrf forwarding'): vrf = interface_config.find_lines('^ ip vrf forwarding')[0].strip().split()[-1] elif interface_config.find_lines('^ vrf forwarding'): vrf = interface_config.find_lines('^ vrf forwarding')[0].strip().split()[-1] #We only really care about this interface if it has an IP address on it #interfaces that have no addresses should be skipped if interface_config.find_lines('no ip address'): continue if interface_config.find_lines('^ ip address'): #Create a new network interface object interface = NetworkInterface(self) #In case we want to skip this interface and not show it for some reason should_add_address = True for address in interface_config.find_lines('^ ip address'): #We can have multiple addresses here, have to allow for secondaries if "secondary" in address: secondary_address = SecondaryAddress(interface) secondary_address.address = address.strip().split('ip address')[1].split()[0] secondary_address.netmask = address.strip().split('ip address')[1].split()[1] interface.secondary.append(secondary_address) else: if "no" in address or "negotiated" in address: should_add_address = False break if len(interface_config.find_lines('channel-group')) > 0: should_add_address = False break interface.address = address.strip().split('ip address')[1].split()[0] interface.name = interface_name interface.netmask = address.strip().split('ip address')[1].split()[1] interface.vrf = vrf interface.description = description to_return.append(interface) return to_return
def parse_ingress(ws): row = 1 # open all .txt files in the current directory for filename in glob.glob('*.txt'): config = CiscoConfParse(filename, factory=True, syntax='ios') hostname = config.find_objects_dna(r'Hostname')[0].hostname ios_ver = config.find_lines('IOS')[0][len('!! IOS XR Configuration '):] print('... %s (IOS XR %s)' % (hostname, ios_ver)) for ports in config.find_objects_w_child('^interface.+l2transport', 'service-policy input'): # write the hostname in column A ws.write(row, 0, hostname) # write the IOS XR version in column B ws.write(row, 1, ios_ver) # write the ingress port in column C port = ports.text[len('interface '):-len(' l2transport')] ws.write(row, 2, port) for line in ports.re_search_children(r'^ description '): description = line.text[len('description '):] ws.write(row, 3, description) for maps in ports.re_search_children('service-policy'): # write the ingress policy map in column D policy_map = maps.text[len(' service-policy input '):] ws.write(row, 4, policy_map) policy_maps = config.find_all_children(policy_map) policy_rate = [i for i in policy_maps if 'police rate' in i][0].strip() cos = [i for i in policy_maps if 'set cos' in i][0].strip() ws.write(row, 5, policy_rate) # write the COS setting in column F ws.write(row, 6, cos) # determine the circuit type based on the policy names if 'aovl' in policy_map.lower(): circuit_type = 'Adva Overlay' elif ('test' in policy_map.lower()) or ('mef' in policy_map.lower()): circuit_type = 'Test' elif ('nid' in policy_map.lower()) or ('dcn' in policy_map.lower()): circuit_type = 'DCN' else: circuit_type = 'Customer' # write the circuit type in column G ws.write(row, 7, circuit_type) if circuit_type == 'Test': if 'cos 4' in cos: ws.write(row, 8, 'Ok') else: ws.write( row, 8, 'Matched keyword test and/ or MEF.' 'Please confirm if this is a test policy and delete. ' 'If not, change/ add set cos 4.') elif circuit_type == 'Adva Overlay': if 'cos 6' in cos: ws.write(row, 8, 'Ok') else: ws.write(row, 8, 'Change to set cos 6.') elif circuit_type == 'DCN': if ('cos 4' in cos) or ('cos 7' in cos): ws.write(row, 8, 'Ok') else: ws.write(row, 8, 'DCN circuit - change set to cos 7.') elif circuit_type == 'Customer': if 'cos 4' in cos: ws.write(row, 8, 'Ok') else: ws.write(row, 8, 'Change/ add set cos 4.') cos = '' row += 1 print('... Completed %s ingress policies.' % row) # set the autofilter ws.autofilter(0, 0, row, 8)
def parse_cisco_files(Full_Path_File_Nmae,outdirname,csvfilename): with io.open(outdirname + "/" + csvfilename,'w',encoding='ascii',errors='replace') as out_file: writer = csv.writer(out_file) writer.writerow(('Router_Name','Entry_Type','Entry_Type_Seq','Entry_Name','Child_Seq','Child_Name')) for path, dirs, files in os.walk(dirname): for filename in files: if fnmatch.fnmatch(filename, '*.Config'): cfg_file = os.path.abspath(os.path.join(path, filename)) f = open(cfg_file) line = f.read() first_line = line.split('\n', 1)[0] if re.search('^!$', first_line): # parse = CiscoConfParse(Full_Path_File_Nmae) parse = CiscoConfParse(cfg_file) print(parse) router_name = parse.find_lines("^hostname") # writer.writerow(("".join(router_name),'service','Test','Test','NA','NA')) #Return a list of all Header service = parse.find_lines("^service") boot = parse.find_lines("^boot") security = parse.find_lines("^security") logging = parse.find_lines("^logging") no = parse.find_lines("^no") print("\n") for service_i,service_j in enumerate(service): print("".join(router_name),"\t",'service',"\t" ,service_i,"\t",service_j) writer.writerow(("".join(router_name),'service',service_i,service_j,'NA','NA')) for boot_i,boot_j in enumerate(boot): print("".join(router_name),"\t", 'boot',"\t",boot_i,"\t",boot_j) writer.writerow(("".join(router_name),'boot',boot_i,boot_j,'NA','NA')) for security_i,security_j in enumerate(security): print("".join(router_name),"\t", 'security',"\t",security_i,"\t",security_j) writer.writerow(("".join(router_name),'security',security_i,security_j,'NA','NA')) for logging_i,logging_j in enumerate(logging): print("".join(router_name),"\t", 'logging',"\t",logging_i,"\t",logging_j) writer.writerow(("".join(router_name),'logging',logging_i,logging_j,'NA','NA')) for no_i,no_j in enumerate(no): print("".join(router_name),"\t", 'no',"\t",no_i,"\t",no_j) writer.writerow(("".join(router_name),'no',no_i,no_j,'NA','NA')) # Return a list of all policy accounting and subinterfaces aaa = parse.find_lines("^aaa") for aaa_i,aaa_j in enumerate(aaa): # print("\n", i,"\t",j) chld_aaa = parse.find_all_children(aaa_j) # print(len(chld)) if len(chld_aaa) >=1 : for aaa_k,aaa_m in enumerate(chld_aaa): print( "".join(router_name),"\t", 'aaa',"\t",aaa_i,"\t",aaa_j,"\t",aaa_k,"\t",aaa_m) writer.writerow(("".join(router_name),'no',aaa_i,aaa_j,aaa_k,aaa_m)) else: print( "".join(router_name),"\t", 'aaa',"\t",aaa_i,"\t",aaa_j) writer.writerow(("".join(router_name),'aaa',aaa_i,aaa_j,'NA','NA')) # Return a list of all clock clock = parse.find_lines("^clock") for clock_i,clock_j in enumerate(clock): # print("\n", i,"\t",j) chld_clock = parse.find_all_children(clock_j) # print(len(chld)) if len(chld_clock) >=1 : for clock_k,clock_m in enumerate(chld_clock): print( "".join(router_name),"\t", 'clock',"\t",clock_i,"\t",clock_j,"\t",clock_k,"\t",clock_m) writer.writerow(("".join(router_name),'clock',clock_i,clock_j,clock_k,clock_m)) else: print( "".join(router_name),"\t", 'clock',"\t",clock_i,"\t",clock_j) ###### TO DO writer.writerow(("".join(router_name),'clock',clock_i,clock_j,'NA','NA')) # Return a list of all dot dot = parse.find_lines("^dot") for dot_i,dot_j in enumerate(dot): # print("\n", i,"\t",j) chld_dot = parse.find_all_children(dot_j) # print(len(chld)) if len(chld_dot) >=1 : for dot_k,dot_m in enumerate(chld_dot): print( "".join(router_name),"\t", 'dot',"\t",dot_i,"\t",dot_j,"\t",dot_k,"\t",dot_m) writer.writerow(("".join(router_name),'dot',dot_i,dot_j,dot_k,dot_m)) else: print( "".join(router_name),"\t", 'dot',"\t",dot_i,"\t",dot_j) writer.writerow(("".join(router_name),'dot',dot_i,dot_j,'NA','NA')) # Return a list of all ip ip1 = parse.find_lines("^ip ") for ip1_a,ip1_b in enumerate(ip1): # print(a,b) chld_ip = parse.find_all_children(ip1_b) if len(chld_ip) >=1 : for ip1_k,ip1_m in enumerate(chld_ip): print( "".join(router_name),"\t", 'ip',"\t",ip1_a,"\t",ip1_b,"\t",ip1_k,"\t",ip1_m) writer.writerow(("".join(router_name),'ip',ip1_a,ip1_b,ip1_k,ip1_m)) else: print("".join(router_name),"\t", 'ip',"\t",ip1_a,"\t",ip1_b) writer.writerow(("".join(router_name),'ip',ip1_a,ip1_b,'NA','NA')) # Return a list of all multilink multilink = parse.find_lines("^multilink") for multilink_a,multilink_b in enumerate(multilink): # print(a,b) chld_multilink = parse.find_all_children(multilink_b) if len(chld_multilink) >=1 : for multilink_k,multilink_m in enumerate(chld_ip): print( "".join(router_name),"\t", 'multilink',"\t",multilink_a,"\t",multilink_b,"\t",multilink_k,"\t",multilink_m) writer.writerow(("".join(router_name),'multilink',multilink_a,multilink_b,multilink_k,multilink_m)) else: print("".join(router_name),"\t", 'multilink',"\t",multilink_a,"\t",multilink_b) writer.writerow(("".join(router_name),'multilink',multilink_a,multilink_b,'NA','NA')) voice_card = parse.find_lines("^voice-card") for voice_card_a,voice_card_b in enumerate(voice_card): # print(a,b) chld_voice_card = parse.find_all_children(voice_card_b) if len(chld_voice_card) >=1 : for voice_card_k,voice_card_m in enumerate(chld_voice_card): print( "".join(router_name),"\t", 'voice_card',"\t",voice_card_a,"\t",voice_card_b,"\t",voice_card_k,"\t",voice_card_m) writer.writerow(("".join(router_name),'voice_card',voice_card_a,voice_card_b,voice_card_k,voice_card_m)) else: print("".join(router_name),"\t", 'voice_card',"\t",voice_card_a,"\t",voice_card_b) writer.writerow(("".join(router_name),'voice_card',voice_card_a,voice_card_b,'NA','NA')) vtp = parse.find_lines("^vtp") for vtp_a,vtp_b in enumerate(vtp): # print(a,b) chld_vtp = parse.find_all_children(vtp_b) if len(chld_vtp) >=1 : for vtp_k,vtp_m in enumerate(chld_vtp): print( "".join(router_name),"\t", 'vtp',"\t",vtp_a,"\t",vtp_b,"\t",vtp_k,"\t",vtp_m) writer.writerow(("".join(router_name),'vtp',vtp_a,vtp_b,vtp_k,vtp_m)) else: print("".join(router_name),"\t", 'vtp',"\t",vtp_a,"\t",vtp_b) writer.writerow(("".join(router_name),'vtp',vtp_a,vtp_b,'NA','NA')) username = parse.find_lines("^username") for username_a,username_b in enumerate(username): # print(a,b) chld_username = parse.find_all_children(username_b) if len(chld_username) >=1 : for username_k,username_m in enumerate(chld_username): print( "".join(router_name),"\t", 'username',"\t",username_a,"\t",username_b,"\t",username_k,"\t",username_m) writer.writerow(("".join(router_name),'username',username_a,username_b,username_k,username_m)) else: print("".join(router_name),"\t", 'username',"\t",username_a,"\t",username_b) writer.writerow(("".join(router_name),'username',username_a,username_b,'NA','NA')) archive = parse.find_lines("^archive") for archive_a,archive_b in enumerate(archive): # print(a,b) chld_archive = parse.find_all_children(archive_b) if len(chld_archive) >=1 : for archive_k,archive_m in enumerate(chld_archive): print( "".join(router_name),"\t", 'archive',"\t",archive_a,"\t",archive_b,"\t",archive_k,"\t",archive_m) writer.writerow(("".join(router_name),'archive',archive_a,archive_b,archive_k,archive_m)) else: print("".join(router_name),"\t", 'archive',"\t",archive_a,"\t",archive_b) writer.writerow(("".join(router_name),'archive',archive_a,archive_b,'NA','NA')) class1 = parse.find_lines("^class") for class_a,class_b in enumerate(class1): # print(a,b) chld_class = parse.find_all_children(class_b) if len(chld_class) >=1 : for class_k,class_m in enumerate(chld_class): print( "".join(router_name),"\t", 'class',"\t",class_a,"\t",class_b,"\t",class_k,"\t",class_m) writer.writerow(("".join(router_name),'class',class_a,class_b,class_k,class_m)) else: print("".join(router_name),"\t", 'class',"\t",class_a,"\t",class_b) writer.writerow(("".join(router_name),'class',class_a,class_b,'NA','NA')) policy = parse.find_lines("^policy") for policy_a,policy_b in enumerate(policy): # print(a,b) chld_policy = parse.find_all_children(policy_b) if len(chld_policy) >=1 : for policy_k,policy_m in enumerate(chld_policy): print( "".join(router_name),"\t", 'policy',"\t",policy_a,"\t",policy_b,"\t",policy_k,"\t",policy_m) writer.writerow(("".join(router_name),'policy',policy_a,policy_b,policy_k,policy_m)) else: print("".join(router_name),"\t", 'policy',"\t",policy_a,"\t",policy_b) writer.writerow(("".join(router_name),'policy',policy_a,policy_b,'NA','NA')) interface = parse.find_lines("^interface") for interface_a,interface_b in enumerate(interface): # print(a,b) chld_interface = parse.find_all_children(interface_b) if len(chld_interface) >=1 : for interface_k,interface_m in enumerate(chld_interface): print( "".join(router_name),"\t", 'interface',"\t",interface_a,"\t",interface_b,"\t",interface_k,"\t",interface_m) writer.writerow(("".join(router_name),'interface',interface_a,interface_b,interface_k,interface_m)) else: print("".join(router_name),"\t", 'interface',"\t",interface_a,"\t",interface_b) writer.writerow(("".join(router_name),'interface',interface_a,interface_b,'NA','NA')) router1 = parse.find_lines("^router") for router_a,router_b in enumerate(router1): # print(a,b) chld_router = parse.find_all_children(router_b) if len(chld_router) >=1 : for router_k,router_m in enumerate(chld_router): print( "".join(router_name),"\t", 'router',"\t",router_a,"\t",router_b,"\t",router_k,"\t",router_m) writer.writerow(("".join(router_name),'router',router_a,router_b,router_k,router_m)) else: print("".join(router_name),"\t", 'router',"\t",router_a,"\t",router_b) writer.writerow(("".join(router_name),'router',router_a,router_b,'NA','NA')) address = parse.find_lines("^address") for address_a,address_b in enumerate(address): # print(a,b) chld_address = parse.find_all_children(address_b) if len(chld_address) >=1 : for address_k,address_m in enumerate(chld_address): print( "".join(router_name),"\t", 'address',"\t",address_a,"\t",address_b,"\t",address_k,"\t",address_m) writer.writerow(("".join(router_name),'address',address_a,address_b,address_k,address_m)) else: print("".join(router_name),"\t", 'address',"\t",address_a,"\t",address_b) writer.writerow(("".join(router_name),'address',address_a,address_b,'NA','NA')) # Return a list of all Permit access-list 23 permit #============================================================================== all_access_list = parse.find_lines("^access-list*") for a_all_access_list,b_all_access_list in enumerate(all_access_list): # print("".join(router_name),"\t","all_access_list","\t",a_all_access_list,"\t",b_all_access_list) try: chld_all_access_list = parse.find_all_children(b_all_access_list) if len(chld_all_access_list) >=1 : for access_k,access_m in enumerate(chld_all_access_list): print( "".join(router_name),"\t", 'all_access_list',"\t",a_all_access_list,"\t",b_all_access_list,"\t",access_k,"\t",access_m) writer.writerow(("".join(router_name),'all_access_list',a_all_access_list,b_all_access_list,access_k,access_m)) except: print("".join(router_name),"\t","all_access_list","\t",a_all_access_list,"\t",b_all_access_list) writer.writerow(("".join(router_name),'all_access_list',a_all_access_list,b_all_access_list,'NA','NA')) route = parse.find_lines("^route") for route_a,route_b in enumerate(route): # print(a,b) chld_route = parse.find_all_children(route_b) if len(chld_route) >=1 : for route_k,route_m in enumerate(chld_route): print( "".join(router_name),"\t", 'route',"\t",route_a,"\t",route_b,"\t",route_k,"\t",route_m) writer.writerow(("".join(router_name),'route',route_a,route_b,route_k,route_m)) else: print("".join(router_name),"\t", 'route',"\t",route_a,"\t",route_b) writer.writerow(("".join(router_name),'route',route_a,route_b,'NA','NA')) snmp = parse.find_lines("^snmp") for snmp_a,snmp_b in enumerate(snmp): # print(a,b) chld_snmp = parse.find_all_children(snmp_b) if len(chld_snmp) >=1 : for snmp_k,snmp_m in enumerate(chld_snmp): print( "".join(router_name),"\t", 'snmp',"\t",snmp_a,"\t",snmp_b,"\t",snmp_k,"\t",snmp_m) writer.writerow(("".join(router_name),'snmp',snmp_a,snmp_b,snmp_k,snmp_m)) else: print("".join(router_name),"\t", 'snmp',"\t",snmp_a,"\t",snmp_b) writer.writerow(("".join(router_name),'snmp',snmp_a,snmp_b,'NA','NA')) tacacs = parse.find_lines("^tacacs") for tacacs_a,tacacs_b in enumerate(tacacs): # print(a,b) chld_tacacs = parse.find_all_children(tacacs_b) if len(chld_tacacs) >=1 : for tacacs_k,tacacs_m in enumerate(chld_tacacs): print( "".join(router_name),"\t", 'tacacs',"\t",tacacs_a,"\t",tacacs_b,"\t",tacacs_k,"\t",tacacs_m) writer.writerow(("".join(router_name),'tacacs',tacacs_a,tacacs_b,tacacs_k,tacacs_m)) else: print("".join(router_name),"\t", 'tacacs',"\t",tacacs_a,"\t",tacacs_b) writer.writerow(("".join(router_name),'tacacs',tacacs_a,tacacs_b,'NA','NA')) control = parse.find_lines("^control") for control_a,control_b in enumerate(control): # print(a,b) chld_control = parse.find_all_children(control_b) if len(chld_control) >=1 : for control_k,control_m in enumerate(chld_control): print( "".join(router_name),"\t", 'control',"\t",control_a,"\t",control_b,"\t",control_k,"\t",control_m) writer.writerow(("".join(router_name),'control',control_a,control_b,control_k,control_m)) else: print("".join(router_name),"\t", 'control',"\t",control_a,"\t",control_b) writer.writerow(("".join(router_name),'control',control_a,control_b,'NA','NA')) banner = parse.find_lines("^banner") for banner_a,banner_b in enumerate(banner): # print(a,b) chld_banner = parse.find_all_children(banner_b) if len(chld_banner) >=1 : for banner_k,banner_m in enumerate(chld_banner): print( "".join(router_name),"\t", 'banner',"\t",banner_a,"\t",banner_b,"\t",banner_k,"\t",banner_m) writer.writerow(("".join(router_name),'banner',banner_a,banner_b,banner_k,banner_m)) else: print("".join(router_name),"\t", 'banner',"\t",banner_a,"\t",banner_b) writer.writerow(("".join(router_name),'banner',banner_a,banner_b,'NA','NA')) line = parse.find_lines("^line") for line_a,line_b in enumerate(line): # print(a,b) chld_line = parse.find_all_children(line_b) if len(chld_line) >=1 : for line_k,line_m in enumerate(chld_line): print( "".join(router_name),"\t", 'line',"\t",line_a,"\t",line_b,"\t",line_k,"\t",line_m) writer.writerow(("".join(router_name),'line',line_a,line_b,line_k,line_m)) else: print("".join(router_name),"\t", 'line',"\t",line_a,"\t",line_b) writer.writerow(("".join(router_name),'line',line_a,line_b,'NA','NA')) scheduler = parse.find_lines("^scheduler") for scheduler_a,scheduler_b in enumerate(scheduler): # print(a,b) chld_scheduler = parse.find_all_children(scheduler_b) if len(chld_scheduler) >=1 : for scheduler_k,scheduler_m in enumerate(chld_scheduler): print( "".join(router_name),"\t", 'scheduler',"\t",scheduler_a,"\t",scheduler_b,"\t",scheduler_k,"\t",scheduler_m) writer.writerow(("".join(router_name),'scheduler',scheduler_a,scheduler_b,scheduler_k,scheduler_m)) else: print("".join(router_name),"\t", 'scheduler',"\t",scheduler_a,"\t",scheduler_b) writer.writerow(("".join(router_name),'scheduler',scheduler_a,scheduler_b,'NA','NA')) ntp = parse.find_lines("^ntp") for ntp_a,ntp_b in enumerate(ntp): # print(a,b) chld_ntp = parse.find_all_children(ntp_b) if len(chld_ntp) >=1 : for ntp_k,ntp_m in enumerate(chld_ntp): print( "".join(router_name),"\t", 'ntp',"\t",ntp_a,"\t",ntp_b,"\t",ntp_k,"\t",ntp_m) writer.writerow(("".join(router_name),'ntp',ntp_a,ntp_b,ntp_k,ntp_m)) else: print("".join(router_name),"\t", 'ntp',"\t",ntp_a,"\t",ntp_b) writer.writerow(("".join(router_name),'ntp',ntp_a,ntp_b,'NA','NA'))
def parse_egress(ws): row = 1 # open all .txt files in the current directory for filename in glob.glob('*.txt'): config = CiscoConfParse(filename, factory=True, syntax='ios') hostname = config.find_objects_dna(r'Hostname')[0].hostname ios_ver = config.find_lines('IOS')[0][len('!! IOS XR Configuration '):] print('... %s (IOS XR %s)' % (hostname, ios_ver)) # for be in config.find_objects_w_child(r'^interface.+Bundle[^.]+$', 'service-policy output'): for be in config.find_objects(r'^interface.+Bundle[^.]+$'): # write the hostname in column A ws.write(row, 0, hostname) # write the IOS XR version in column B ws.write(row, 1, ios_ver) # write the BE port in column C be_port = be.text[len('interface '):] ws.write(row, 2, be_port) # write the description in column D for line in be.re_search_children(r'^ description '): description = line.text[len('description '):] ws.write(row, 3, description) # pre-fill remarks for be ports without parent policies ws.write(row, 6, 'Missing parent and/ or child policy.') for parent in be.re_search_children('service-policy'): # write the parent policy in column E parent_policy = parent.text[len(' service-policy output '):] parent_policy1 = parent.text[len(' service-policy input '):] ws.write(row, 4, parent.text.strip()) # write the child policy in column F try: p_map = config.find_all_children(r'^policy-map ' + parent_policy + '$') child_policy = [i for i in p_map if 'service-policy' in i ][0][len(' service-policy '):] ws.write(row, 5, child_policy) except Exception: p_map = config.find_all_children(r'^policy-map ' + parent_policy1 + '$') child_policy = [i for i in p_map if 'service-policy' in i ][0][len(' service-policy '):] ws.write(row, 5, child_policy) if 'input' in parent.text: ws.write( row, 6, 'Policy incorrectly applied on ingress instead of egress.' ) elif be_port[len('Bundle-Ether'):] == parent_policy[len('policy_port_BE'):] \ and parent_policy[len('policy_port_BE'):] == child_policy[len('policy_BVID_BE'):]: ws.write(row, 6, 'Ok') else: ws.write(row, 6, 'Incorrect parent and/ or child policy.') row += 1 print('... Completed %s egress policies.' % row) # set the autofilter ws.autofilter(0, 0, row, 6)
mask = mask.replace('\\', '') except: ip = None mask = None if ip and mask: prefix = ipaddress.ip_network('{}/{}'.format(ip, mask), strict=False) else: prefix = 'Not Assigned' return prefix for files in os.listdir(directory): if files.endswith('.rtf'): #load config into parser parse = CiscoConfParse(files) hostname = str(parse.find_lines(r'^hostname')) myhost = hostname.split()[-1].split('\\')[0] for intf in parse.find_objects(r'^interface'): interface = str(intf.text) clean_interface = interface.split()[-1].replace('\\', '') interfaces.append(clean_interface) description = intf.re_search_children( r"^\s+description") #returns list of objects, cannot index[0] for i in description: #loop through objects #print(i) desc = i.re_sub(r'<IOSCfgLine\s\#\s\d+\s+\'\s', r'') #remove junk before description TEST desc = desc[1:].replace('\\', '') #remove space ip_info = str(intf.re_match_iter_typed(IPv4_REGEX))
def parse(filename, subdir): parse = CiscoConfParse('configurations/' + subdir + '/' + filename) # Load in source configuration file output_config = {} # Create master dict for output data # switch stacks stacks = parse.find_objects(r'switch [0-9]+ provision (.*)') if stacks: output_config['switch_stack'] = [] for line in stacks: stack = line.re_match(r'switch [0-9]+ provision (.*)') output_config['switch_stack'].append(stack) # Interfaces interfaces = parse.find_objects(r'interface') # Create interfaces object if interfaces: output_config['interfaces'] = [] # Create list of interfaces for interface in interfaces: # dict for this particular interface interface_dict = {} # Insert interface name interface_name = interface.re_match(r'^interface (\S+)$') if interface_name: interface_dict['name'] = interface_name # switchport # Find list of interfaces with "switchport" config switchport_interfaces = interface.re_search_children(r'switchport') if switchport_interfaces: # Create switchport dict if it does not yet exist if not 'switchport' in interface_dict: interface_dict['switchport'] = {} for line in switchport_interfaces: # access vlan access_vlan = line.re_match( r' switchport access vlan (\S+)') if access_vlan: interface_dict['switchport'][ 'access_vlan'] = access_vlan # switchport mode switchport_mode = line.re_match( r'^ switchport mode (\S+)$') if switchport_mode: interface_dict['switchport']['mode'] = switchport_mode # port-security port_sec = line.re_search(r'^ switchport port-security$') if port_sec: interface_dict['switchport']['port_security'] = True # switchport trunk switchport_trunk = line.re_search(r'^ switchport trunk.*$') if switchport_trunk: # Create the trunk dict if it does not yet exist if not 'trunk' in interface_dict['switchport']: interface_dict['switchport']['trunk'] = {} # native vlan native_vlan = line.re_match( r'^ switchport trunk native vlan (\S+)$') if native_vlan: interface_dict['switchport']['trunk'][ 'native_vlan'] = native_vlan # allowed vlan allowed_vlan = line.re_match( r'^ switchport trunk allowed vlan (\S+)$') if allowed_vlan: interface_dict['switchport']['trunk'][ 'allowed_vlan'] = allowed_vlan # trunk encapsulation encapsulation = line.re_match( r'^ switchport trunk encapsulation (.+)$') if encapsulation: interface_dict['switchport']['trunk'][ 'encapsulation'] = encapsulation # spanning-tree spanning_tree = interface.re_search_children(r'spanning-tree') if spanning_tree: # Create spanning-tree dict if it does not yet exist if not 'spanning_tree' in interface_dict: interface_dict['spanning_tree'] = {} for line in spanning_tree: # portfast portfast = line.re_search(r'^ spanning-tree portfast$') if portfast: interface_dict['spanning_tree']['portfast'] = True # guard_root guard_root = line.re_search(r'^ spanning-tree guard root$') if guard_root: interface_dict['spanning_tree']['guard_root'] = True # ip ip = interface.re_search_children(r'^ ip ') if ip: # Create ip dict if it does not yet exist if not 'ip' in interface_dict: interface_dict['ip'] = {} for line in ip: # ip address ip_address = line.re_match(r'^ ip address (.*)$') if ip_address: interface_dict['ip']['address'] = ip_address # ip access_group access_group = re.match('^ ip access-group (\S+) (\S+)$', line.text) if access_group: # Create access_group sub-dict if it does not yet exist if not 'access_group' in interface_dict['ip']: interface_dict['ip']['access_group'] = {} interface_dict['ip']['access_group'][ access_group.group(1)] = access_group.group(2) # ip dhcp snooping trust dhcp_snooping_trust = line.re_search( r'^ ip dhcp snooping trust$') if dhcp_snooping_trust: interface_dict['ip']['dhcp_snooping_trust'] = True # no ip no_ip = interface.re_search_children(r'^ no ip ') if no_ip: # Create ip dict if it does not yet exist if not 'ip' in interface_dict: interface_dict['ip'] = {} for line in no_ip: # no ip address no_ip = line.re_search(r'^ no ip address$') if no_ip: interface_dict['ip']['ip_address_disable'] = True # no ip route cache no_route_cache = line.re_search(r'^ no ip route-cache$') if no_route_cache: interface_dict['ip']['route_cache_disable'] = True # no ip mroute-cache no_mroute_cache = line.re_search(r'^ no ip mroute-cache$') if no_mroute_cache: interface_dict['ip']['mroute_cache_disable'] = True # ipv6 ipv6 = interface.re_search_children(r'^ ipv6 ') if ipv6: if not 'ipv6' in interface_dict: interface_dict['ipv6'] = [] for line in ipv6: # ra guard ra_guard = line.re_search(r'^ ipv6 nd raguard$') if ra_guard: interface_dict['ipv6'].append('ra_guard') # ipv6 snooping ra_guard = line.re_search(r'^ ipv6 snooping$') if ra_guard: interface_dict['ipv6'].append('ipv6_snooping') # ipv6 dhcp guard ra_guard = line.re_search(r'^ ipv6 dhcp guard$') if ra_guard: interface_dict['ipv6'].append('ipv6_dhcp_guard') # misc misc = interface.re_search_children(r'.*') if misc: for line in misc: # description interface_description = line.re_match( r'^ description (\S+)$') if interface_description: interface_dict['description'] = interface_description # power inline police power_inline_police = line.re_search( r'^ power inline police$') if power_inline_police: interface_dict['power_inline_police'] = True # cdp disable cdp_disable = line.re_search(r'^ no cdp enable$') if cdp_disable: interface_dict['cdp_disable'] = True # shutdown shutdown = line.re_search(r'^ shutdown$') if shutdown: interface_dict['shutdown'] = True # vrf forwarding vrf = line.re_match(r'^ vrf forwarding (.+)$') if vrf: interface_dict['vrf'] = vrf # negotiation negotiation = line.re_match(r'^ negotiation (.+)$') if negotiation: interface_dict['negotiation'] = negotiation # keepalive disable keepalive_disable = line.re_search(r'^ no keepalive$') if keepalive_disable: interface_dict['keepalive_disable'] = True # Append the completed interface dict to the interfaces list output_config['interfaces'].append(interface_dict) # IP Config Elements ip_config = parse.find_objects(r'ip') if ip_config: # Create ip dict if it does not yet exist if not 'ip' in output_config: output_config['ip'] = {} for line in ip_config: # ip dhcp snooping dhcp_snooping = line.re_search(r'^ip dhcp snooping$') if dhcp_snooping: output_config['ip']['dhcp_snooping'] = True # ip default gateway default_gateway = line.re_match(r'^ip default-gateway (\S+)$') if default_gateway: output_config['ip']['default_gateway'] = default_gateway # Banner banner = parse.find_blocks(r'banner') if banner: # Create banner dict if it does not yet exist if not 'banner' in output_config: output_config['banner'] = [] for line in banner: first_line = re.search(r'^banner motd (.*)$', line) if first_line: output_config['banner'].append(first_line.group(1)) else: output_config['banner'].append(line) # acl acl = parse.find_blocks(r'access-list') if acl: if not 'acl' in output_config: output_config['acl'] = [] for line in acl: acl_line = re.search(r'^access-list 10 permit (172.*)$', line) if acl_line: output_config['acl'].append(acl_line.group(1)) # snmp-server snmp = parse.find_blocks(r'snmp-server') if snmp: # Create snmp dict if it does not yet exist if not 'snmp' in output_config: output_config['snmp'] = {} for line in snmp: # community string snmp_community = re.match(r'^snmp-server community (\S+)', line) if snmp_community: output_config['snmp']['community'] = snmp_community.group(1) # location snmp_location = re.match(r'^snmp-server location (.*)$', line) if snmp_location: output_config['snmp']['location'] = snmp_location.group(1) # contact snmp_contact = re.match(r'^snmp-server contact (.*)$', line) if snmp_contact: output_config['snmp']['contact'] = snmp_contact.group(1) # vtp vtp = parse.find_lines(r'vtp') if vtp: vtp_mode = re.match(r'vtp mode (\S+)', vtp[0]) if vtp_mode: output_config['vtp_mode'] = vtp_mode.group(1) # vlans vlans = parse.find_objects('^vlan [0-9]+') if vlans: # Create vlans dict if it does not yet exist if not 'vlans' in output_config: output_config['vlans'] = [] for vlan in vlans: vlan_dict = {} # vlan number vlan_number = re.match('^vlan ([0-9]+)$', vlan.text) if vlan_number: vlan_dict['number'] = vlan_number.group(1) # vlan name vlan_name = vlan.re_search_children(r'name') if vlan_name: name = vlan_name[0].re_match(r' name (\S+)') vlan_dict['name'] = name # Append the completed vlan dict output_config['vlans'].append(vlan_dict) # certificates certificate_chain = parse.find_lines('^crypto pki certificate chain') if certificate_chain: for line in certificate_chain: certificate_chain_search = re.match( '^crypto pki certificate chain (\S+)', line) output_config['crypto_chain_id'] = certificate_chain_search.group( 1) # radius server config radius_servers = parse.find_objects('radius server') if radius_servers: output_config['dot1x'] = True # Screen output # print # print(subdir + '/' + filename + ' YAML Output:') # print # print yaml.dump(output_config, default_flow_style=False, explicit_start=True) print('Outputing ' + filename + ' YAML') # Make sure the directory we're trying to write to exists. Create it if it doesn't out_path = 'yaml/' + subdir + '/' if not exists(out_path): makedirs(out_path) # Write foo.yml to the subdir in yaml/ that corresponds to the dir where we got the input file in configurations/ with open(out_path + splitext(filename)[0] + '.nwid.bris.ac.uk.yml', 'w') as outfile: yaml.dump(output_config, outfile, default_flow_style=False, explicit_start=True)
from ciscoconfparse import CiscoConfParse import sys #Accepts input using command line arguments dname = str(sys.argv[1]) parse = CiscoConfParse(dname) print '---------start----------' print dname print '-------------------' print 'Global Config Audit' print '-------------------' #Requirement - Enabled #vtp mode if parse.find_lines('^vtp\smode\stransparent') or parse.find_lines('^vtp\smode\soff'): print 'vtp mode = PASS' else: print 'vtp mode = FAIL' #service password-encryption if parse.find_lines('^service\spassword-encryption'): print 'service password-encryption = PASS' else: print 'service password-encryption = FAIL' #ip source-route if parse.find_lines('^no\sip\ssource-route'): print 'no ip source-route = PASS' else: print 'no ip source-route = FAIL'
from ciscoconfparse import CiscoConfParse import sys #Accepts input using command line arguments dname = str(sys.argv[1]) parse = CiscoConfParse(dname) print '---------start----------' print dname print '-------------------' print 'Global Config Audit' print '-------------------' #Requirement - Enabled #vtp mode if parse.find_lines('^vtp\smode\stransparent') or parse.find_lines( '^vtp\smode\soff'): print 'vtp mode = PASS' else: print 'vtp mode = FAIL' #service password-encryption if parse.find_lines('^service\spassword-encryption'): print 'service password-encryption = PASS' else: print 'service password-encryption = FAIL' #ip source-route if parse.find_lines('^no\sip\ssource-route'): print 'no ip source-route = PASS' else:
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
cntio = 0 cntxr = 0 cntj = 0 cntu = 0 for router in open(readFile): router = router.rstrip("\n") print router, routerSP = router #nombre del equipo sin ruta router = rutaResp + router existe = 1 try: cisco = CiscoConfParse(router) except: existe = 0 if existe == 1: iversion = cisco.find_lines('^version\s.+[0-9]$') ioversion = cisco.find_lines('^! Version:\s') xrversion = cisco.find_lines('^!! IOS XR\s') jversion = cisco.find_lines('^version\s.+;$') if iversion: cnti += 1 print " iversion " + str(iversion) elif ioversion: cntio += 1 print " ioversion " + str(ioversion) elif xrversion: cntxr += 1 print " xrversion " + str(xrversion) elif jversion: cntj += 1 print " jversion " + str(jversion)
def standardize_configs(ip, chan): print "Downloading running configuration" output = send_command("enable", "!Tmgmt", "skip", "sh run", read=True, chan=chan) # Captures running config capture = re.findall(r"!\r\nver.*end", output, re.S).pop() # Parses running config print "Parsing configuraion" output = CiscoConfParse(capture.splitlines()) # Corrects DNS Setting dns = output.find_lines(r"ip dns server-address.*") output.replace_lines(r"ip dns server-address.*", r"ip dns server-address 10.210.1.214 10.220.1.200") print ("Correcting dns entry") send_command( "no {0}".format(dns.pop()), "ip dns server-address 10.210.1.214 10.220.1.200", configure=True, chan=chan ) # Enables IGMP Snooping globally output.insert_after(r"hostname", r"ip multicast active") print ('Enabling "ip multicast"') send_command("ip multicast active", configure=True, chan=chan) # print 'Searching for interfaces with dhcp helper' # virtual_interfaces = output.find_objects_w_child(r'interface ve.*', r'\s+ip\s+helper.*',) # for intf in virtual_interfaces: # interface = intf.text # print interface # has_dhcp_helper = intf.has_child_with(r'ip helper.*') # for line in intf.all_children: # if 'ip address' in line.text: # address = line.text # print address # if 'helper-address' in line.text: # dhcp = line.text # print dhcp # if has_dhcp_helper: # writer.writerow((ip, interface, address, dhcp)) # # Iterates through interfaces and cleans up misconfigurations for interface in output.find_objects(r"^interface.+"): has_loop_detection = interface.has_child_with(r"loop-detection") has_bpdu_guard = interface.has_child_with(r"stp-bpdu-guard") has_root_protection = interface.has_child_with(r"spanning-tree\sroot-protect") has_no_flow_control = interface.has_child_with(r"no\sflow-control") is_layer3_intf = (interface.has_child_with(r"ip\s+add")) or ("interface ve.*" in interface.text) # Temporarily disabled # Remove loop-detection misconfiguration if has_loop_detection and has_bpdu_guard: interface.delete_children_matching("loop-detection") print ('Removing "loop-detection" from {0}'.format(interface.text)) send_command(interface.text, "no loop-detection", configure=True) # Remove spanning-tree root-protect misconfiguration if has_root_protection: interface.delete_children_matching(r"spanning-tree\sroot-protect") print ('Removing "spanning-tree root-protect" from {0}'.format(interface.text)) send_command(interface.text, "no spanning-tree root", configure=True) # Adds IGMP snooping and QoS to Layer 3 interfaces if is_layer3_intf and not ("loopback" in interface.text or "management" in interface.text): interface.append_to_family(r" trust dscp") print ('Adding "trust dscp" to {0}'.format(interface.text)) send_command(interface.text, "trust dscp", configure=True, chan=chan) interface.append_to_family(r" ip igmp version 2") print ('Adding "ip igmp version 2" to {0}'.format(interface.text)) send_command(interface.text, "ip igmp version 2", configure=True, chan=chan) # enables flow-control if has_no_flow_control: interface.delete_children_matching(r"no\sflow-control.+") print ('Enabling "flow-control" on {0}'.format(interface.text)) send_command(interface.text, "flow-control", configure=True, chan=chan) return output
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse parse = CiscoConfParse("../configs/sample_01.ios") # Return a list of all ATM interfaces and subinterfaces atm_intfs = parse.find_lines("^interface\sATM") # Return a list of all interfaces with a certain QOS policy qos_intfs = parse.find_parents_w_child( "^interf", "service-policy" ) # Return a list of all active interfaces (i.e. not shutdown) active_intfs = parse.find_parents_wo_child( "^interf", "shutdown" )
for subdir, dirs, files in os.walk(folder): for file in files: #print os.path.join(subdir, file) filepath = subdir + file #need to test TRY-EXCEPT section try: parse = CiscoConfParse(filepath, syntax='nxos') except: try: parse = CiscoConfParse(filepath, syntax='ios') except: parse = CiscoConfParse(filepath, syntax='asa') #printing the hostname print(parse.find_lines('^hostname', exactmatch=False, ignore_ws=False)) #For loop for finding the all the interfaces and itrating over them. for intf_obj in parse.find_objects('^interface'): intf_name = intf_obj.re_match_typed('^interface\s+(\S.+?)$') # Search children of all interfaces for a regex match and return # the value matched in regex match group 1. If there is no match, # return a default value: '' intf_ip_addr1 = intf_obj.re_match_iter_typed( r'ip\saddress\s(\d+\.\d+\.\d+\.\d+\/\d+)', result_type=str, group=1, default='') vrf_member = intf_obj.re_match_iter_typed( r'(vrf\smember\s[a-zA-Z-]{0,50})', result_type=str, group=1, default='') shutdown = intf_obj.re_match_iter_typed( r'(no\sshut[a-zA-Z-]{0,50})', result_type=str,
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) # obj2 should be blank. # If obj2 is not blank a warning will print to the user. # If obj2 is blank, will prompt for user input to continue. if obj2 == []: time.sleep(2) print(' - (' + macaddr + ') is attached to interface (' + mac_int + ') ') time.sleep(1) answer = input( ' - Would you like to continue? Press Y for YES and N for NO. '
# vrf_objs = parse.find_objects('^vrf context DMZ') # for obj in vrf_objs: # print (obj.ioscfg) # static_raw = obj.re_match_iter_typed(STATIC_RE) # print(static_raw) DMZ_static_list = parse.find_children_w_parents('^vrf context DMZ',STATIC_RE) for x in DMZ_static_list: static_rawlist = x.split() static_net = static_rawlist[2] static_dst = static_rawlist[3] #static_net = IPNetwork(static_raw) static_routes.append(str(static_net)+' '+str(static_dst)) DMZ_prefix_list = parse.find_lines('^ip prefix-list DMZ_STATIC.*permit.*') for y in DMZ_prefix_list: prefixlist_rawlist = y.split() prefixlist_entry = prefixlist_rawlist[6] prefixlist_entries.append(prefixlist_entry) print("Directly Connected Interface Networks in VRF DMZ") print '\n'.join(directly_connected) print("Static routes under VRF DMZ") print '\n'.join(static_routes) print("Prefix list networks permitted under DMZ_STATIC") print '\n'.join(prefixlist_entries) #static_raw = static_rawlist[2] #print(static_raw)
def testValues_find_lines(self): for config, args, result_correct in self.find_lines_Values: cfg = CiscoConfParse(config) test_result = cfg.find_lines(**args) self.assertEqual(result_correct, test_result)
def get_access_list_definitions(config: CiscoConfParse) -> typing.List[str]: """Return all lines where access lists are defined.""" return config.find_lines(r"^ip(v6)?\saccess-list\s(standard|extended)")
#!/usr/bin/env python from ciscoconfparse import CiscoConfParse parse = CiscoConfParse("../configs/sample_01.ios") # Return a list of all ATM interfaces and subinterfaces atm_intfs = parse.find_lines("^interface\sATM") # Return a list of all interfaces with a certain QOS policy qos_intfs = parse.find_parents_w_child("^interf", "service-policy") # Return a list of all active interfaces (i.e. not shutdown) active_intfs = parse.find_parents_wo_child("^interf", "shutdown")