def Audit():
    ## Parse the config
    parse = CiscoConfParse('conf.txt')

    for i in range(25):
        ## Add a new switchport at the bottom of the config...
        parse.append_line('interface FastEthernet0/' + str(i))
        parse.append_line(' switchport')
        parse.append_line(' switchport mode access')
        parse.append_line('!')
        parse.commit()  # commit() **must** be called before searching again

    ## Search and standardize the interfaces...
    standardize_intfs(parse)
    parse.commit()  # commit() **must** be called before searching again

    ## I'm illustrating regular expression usage in has_line_with()
    if not parse.has_line_with(r'^service\stimestamp'):
        ## prepend_line() adds a line at the top of the configuration
        parse.prepend_line(
            'service timestamps debug datetime msec localtime show-timezone')
        parse.prepend_line(
            'service timestamps log datetime msec localtime show-timezone')

    ## Write the new configuration
    parse.save_as('conf3.txt')
Exemple #2
0
# Script to find what interfaces have an "ip helper-address"
# Uses ciscoconfparse library, make sure its installed
#Importing the necessary modules.
import os
from ciscoconfparse import CiscoConfParse
os.chdir("c:\\configs")
for filename in os.listdir(os.getcwd()):
    parse = CiscoConfParse(filename, factory=True, syntax='ios')
    obj_list = parse.find_objects_dna(r'Hostname')
    inf_w_help = parse.find_parents_w_child(parentspec=r"^interface",
                                            childspec=r"ip helper-address")
    hostn = obj_list[0].hostname
    print hostn
    for interface in inf_w_help:
        print interface

    print("Write results to file...")
    newconfig = CiscoConfParse([])
    newconfig.append_line(hostn)
    for interface in inf_w_help:
        newconfig.append_line(interface)
        newconfig.append_line('ip helper-address my.new.ip.add1')
    newconfig.commit()
    newconfig.save_as(hostn + '_newconfig.txt')
Exemple #3
0
text = config_file
re1 = '(ag)'

rg = re.compile(re1, re.IGNORECASE | re.DOTALL)
l2agg = rg.search(text)

if l2agg:
    for intf in parse.find_objects(r'^interface.+?thernet'):
        has_qos_trust = intf.has_child_with(r' mls qos trust dscp')
        is_switchport_trunk = intf.has_child_with(r'switchport mode trunk')
        is_switchport_infra = intf.has_child_with(r'INFRA:TRUNK*.*')

        if (is_switchport_trunk
                and is_switchport_infra) and (not has_qos_trust):
            cfgdiff.append_line("!")
            cfgdiff.append_line(intf.text)
            cfgdiff.append_line("mls qos trust dscp")
    cfgdiff.save_as(config_file + '_new')
    print("Config Created with _new extension for L2AGG")
else:
    for intf in parse.find_objects(r'^interface.+?thernet'):
        has_qos_trust = intf.has_child_with(r' mls qos trust dscp')
        is_switchport_trunk = intf.has_child_with(r'switchport mode trunk')
        is_switchport_infra = intf.has_child_with(r'INFRA:TRUNK*.*')
        is_switchport_access = intf.has_child_with(r'switchport mode access')
        is_switchport_shutdown = intf.has_child_with(r'shutdown')

        if (is_switchport_trunk
                and is_switchport_infra) and (not has_qos_trust):
            cfgdiff.append_line("!")
Exemple #4
0
        ## Add missing commands
        if is_switchport_access and (not has_stormcontrol):
            intf.append_to_family(' storm-control action trap')
            intf.append_to_family(' storm-control broadcast level 0.4 0.3')

        ## remove dot1q trunk misconfiguration
        elif is_switchport_trunk:
            intf.delete_children_matching('port-security')


## Parse the config
parse = CiscoConfParse('switch.conf')

## Add a new switchport at the bottom of the config...
parse.append_line('interface GigabitEthernet1/0')
parse.append_line(' switchport')
parse.append_line(' switchport mode access')
parse.append_line('!')
parse.commit()

## Search and standardize the interfaces
standardize_interfaces(parse)
parse.commit()

## Add a line to the top of the config if not already there.
if not parse.has_line_with(r'^service\stimestamp'):
    parse.prepend_line(
        'service timestamps debug datetime msec localtime show-timezone')
    parse.prepend_line(
        'service timestamps log datetime msec localtime show-timezone')
        is_switchport_trunk = intf.has_child_with(r'switchport mode trunk')

        ## Add missing commands
        if is_switchport_access and (not has_stormcontrol):
            intf.append_to_family(' storm-control action trap')
            intf.append_to_family(' storm-control broadcast level 0.4 0.3')

        ## remove dot1q trunk misconfiguration
        elif is_switchport_trunk:
            intf.delete_children_matching('port-security')

## Parse the config
parse = CiscoConfParse('switch.conf')

## Add a new switchport at the bottom of the config...
parse.append_line('interface GigabitEthernet1/0')
parse.append_line(' switchport')
parse.append_line(' switchport mode access')
parse.append_line('!')
parse.commit ()

## Search and standardize the interfaces
standardize_interfaces(parse)
parse.commit()

## Add a line to the top of the config if not already there.
if not parse.has_line_with(r'^service\stimestamp'):
    parse.prepend_line('service timestamps debug datetime msec localtime show-timezone')
    parse.prepend_line('service timestamps log datetime msec localtime show-timezone')

## Wrtite the config file now...
        # the current SVI address is used as a HSRP virtual IP
        virtual_ip = ipv4_addr.ip_object

        # at this point we need to determine the next addresses which are used for the primary and secondary switch
        # we will try, if the next two addresses are part of the network, otherwise we will use the previous two
        # addresses
        ipv4_network = IPv4Network(ipv4_addr.network)
        if (ipv4_addr.ip_object + 1) in ipv4_network.hosts():
            primary_ip = ipv4_addr.ip_object + 1
            secondary_ip = ipv4_addr.ip_object + 2
        else:
            primary_ip = ipv4_addr.ip_object - 1
            secondary_ip = ipv4_addr.ip_object - 2

        # now add the configuration to the change scripts
        primary_config.append_line("interface %s" % vlan_interface_string)
        primary_config.append_line(" description *** VLAN SVI %s" % vlan_id)
        primary_config.append_line(" ip address %s %s" % (primary_ip, ipv4_addr.netmask))
        primary_config.append_line(" standby version 2")
        primary_config.append_line(" standby 1 ip %s" % virtual_ip)
        primary_config.append_line(" standby 1 priority 255")
        primary_config.append_line(" standby 1 authentication md5 key-string vl%s" % vlan_id)
        primary_config.append_line("!")

        secondary_config.append_line("interface %s" % vlan_interface_string)
        secondary_config.append_line(" description *** VLAN SVI %s" % vlan_id)
        secondary_config.append_line(" ip address %s %s" % (secondary_ip, ipv4_addr.netmask))
        secondary_config.append_line(" standby version 2")
        secondary_config.append_line(" standby 1 ip %s" % virtual_ip)
        secondary_config.append_line(" standby 1 priority 254")
        secondary_config.append_line(" standby 1 authentication md5 key-string vl%s" % vlan_id)
Exemple #7
0
def main():
    confparse = CiscoConfParse(config.USER_CONFIG)
    cfgdiffs = CiscoConfParse([])

    for template in config.TEMPLATES:
        template_dict = load_template(template)
        template_name = template_dict["TEMPLATE_NAME"]
        template_type = template_dict["TEMPLATE_TYPE"]
        print(f'{Fore.BLUE}VERIFYING TEMPlATE: ' + template_name)
        print(f'**************************************{Style.RESET_ALL}')

        for template_section in template_dict["SECTIONS"]:
            regex_pattern = template_section["SECTION_REGEX"]
            sub_regex_patterns = template_section["LINES"]
            section_name = template_section["NAME"]
        #regex_pattern = template_dict["SECTION_REGEX"]
        #sub_regex_patterns = template_dict["LINES"]

            print(f'{Fore.GREEN}-VERIFYING SECTION: {Fore.CYAN}' + section_name + f'{Style.RESET_ALL}')

            ## Find all matching sections (multi line objects)
            objects = confparse.find_objects(regex_pattern)
            ## Verify first if the whole section is missing
            if len(objects) == 0:
                cfgdiffs.append_line(f'{Fore.RED} -> MISSING WHOLE SECTION:')
                cfgdiffs.append_line(f'{Fore.RED}    ' + regex_pattern)
                for subregex in sub_regex_patterns:
                    cfgdiffs.append_line("        " + subregex)
                    is_valid = False

                if (is_valid == False):
                    for line in cfgdiffs.ioscfg:
                        print(f'{Fore.RED}' + line + f'{Style.RESET_ALL}')
                cfgdiffs = CiscoConfParse([])

            ## If the section is there, verify if some parts are missing
            else:
                for object in objects:
                    is_valid = True

                    ## Mark that some lines are missing if we ever have to print that object
                    cfgdiffs.append_line(f'{Fore.RED} -> MISSING OR DIFFERENTLY CONFIGURED LINES')
                    cfgdiffs.append_line(f'   ' + object.text + f'{Style.RESET_ALL}')

                    ## Search children of the object
                    for subregex in sub_regex_patterns:
                        if not (object.re_search_children(subregex)):
                            cfgdiffs.append_line("    " + subregex)
                            is_valid = False

                    if(is_valid==False):
                        for line in cfgdiffs.ioscfg:
                            print(f'{Fore.RED}' + line + f'{Style.RESET_ALL}')
                    else:
                        print(f'{Fore.GREEN} -> SUCCESS - CONFIG SECTION: ' + template_name + ' FOR OBJECT: ' + object.text + f'{Style.RESET_ALL}')

                    #Reset cfgdiffs for next object
                    cfgdiffs = CiscoConfParse([])

        ## Find all single line objects
        if(template_type=='SINGLE_LINE_AND_MULTI_SECTION'):
            is_valid = True
            print(f'{Fore.GREEN}-VERIFYING GENERAL LINES: {Style.RESET_ALL}')
            regex_patterns = template_dict["SINGLE_LINE_REGEXES"]
            for line in regex_patterns:
                if not confparse.has_line_with(line):
                    print(f'{Fore.RED} -> MISSING OR DIFFERENTLY CONFIGURED LINES: ' + line + f'{Style.RESET_ALL}')
                    is_valid = False
            if (is_valid==True):
                print(f'{Fore.GREEN} -> SUCCESS - GENERAL CONFIG PARTS: ' + template_name + f'{Style.RESET_ALL}')

        print(f'{Fore.BLUE}*****************END*********************{Style.RESET_ALL}\n')
        # now we create an IP address object from the ARP entry
        arp_ipv4_addr = IPv4Address(ipv4)

        # assign static arp entry to the VLAN SVI interface
        for vlan_svi in vlan_svis:
            svi_ipv4_network = IPv4Network(vlan_svi['ipv4_addr'] + "/" + vlan_svi['ipv4_netmask'], strict=False)
            if arp_ipv4_addr in svi_ipv4_network.hosts():
                # extend the model if the correct IP network is found
                if "static_arps" not in vlan_svi.keys():
                    vlan_svi['static_arps'] = list()
                record = {
                    'ipv4_host': ipv4,
                    'mac': mac
                }
                vlan_svi['static_arps'].append(record)

                # a static ARP is only defined on a single interface
                break

    print("Write results to file...")
    cisco_nxos_template = CiscoConfParse(['!'])

    for vlan_svi in vlan_svis:
        cisco_nxos_template.append_line("interface Vlan%s" % vlan_svi['vlan_id'])
        for static_arp in vlan_svi['static_arps']:
            cisco_nxos_template.append_line(" ip arp %s %s" % (static_arp['ipv4_host'], static_arp['mac']))
        cisco_nxos_template.append_line('!')

    cisco_nxos_template.save_as(os.path.join(output_dir, "cisco_nxos_config.txt"))
Exemple #9
0
    def convert_vrf(ios_conf_file, new_conf_file, vrf_name):
        xr_conf = CiscoConfParse(new_conf_file)
        vrf_attrib = IosVrfConfigParser.ios_get_vrf_attrib(
            ios_conf_file, vrf_name)

        if vrf_attrib['VRF_NAME']:
            print "create vrf config"
            xr_conf.append_line("vrf " + vrf_attrib['VRF_NAME'])
            xr_conf.append_line(" address-family ipv4 unicast")

        if vrf_attrib['EX_MAP']:
            print "create EXPORT Route-policy"
            for ex_map in vrf_attrib['EX_MAP']:
                xr_conf.append_line(" export route-policy " + ex_map)

        if vrf_attrib['IM_MAP']:
            print "create IMPORT Route-policy"
            for im_map in vrf_attrib['IM_MAP']:
                xr_conf.append_line(" export route-policy " + im_map)

        if vrf_attrib['RT_EXPORT']:
            print "create Export Route-Target "
            for rt_export in vrf_attrib['RT_EXPORT']:
                xr_conf.append_line(" export route-target " + rt_export)

        if vrf_attrib['RT_IMPORT']:
            print "create Import Route-Target "
            for rt_import in vrf_attrib['RT_IMPORT']:
                xr_conf.append_line(" export route-target " + rt_import)
        xr_conf.commit()
        xr_conf.save_as(new_conf_file)
def convert_cfg_file(config, device_type, out_path, conversion_matrix):
    """Convert cfg file to other cfg file"""

    import os
    import re
    from ciscoconfparse import CiscoConfParse

    # Check if device type exist in conversion matrix
    if device_type in conversion_matrix:
        # Determine new filename
        new_filename = os.path.join(out_path, os.path.basename(config))
        if os.path.isfile(new_filename):  # Remove CFG if it exist
            os.remove(new_filename)

        # Parse cisco configuration with Ciscoconfparse
        parse = CiscoConfParse(config)

        # DELETE
        for item in conversion_matrix[device_type]["delete"]:
            if item[1] == None:  # Check required fields
                continue
            elif item[0] != None:  # Parent cmd is mentionned
                parent_object = parse.find_objects(item[0])
                for parent in parent_object:
                    # Delete child object in parent object
                    parent.delete_children_matching(item[1])
            else:  # parent cmd is not mentionned
                cli_objects = parse.find_objects(item[1])
                for cli_object in cli_objects:
                    # Delete object and all child objects if exist
                    cli_object.delete()

        # ADD
        for item in conversion_matrix[device_type]["add"]:
            if item[2] == None:  # Check required fields
                continue
            elif item[0] != None:  # parent cmd is mentionned
                parent_object = parse.find_objects(item[0])
                parent_object_done = list(
                )  # This is to avoid duplicate added entries
                for parent in parent_object:
                    parent_re = re.compile(parent.text)
                    if parent.has_children == True:  # Add space to child if they are child
                        if parent.text not in parent_object_done:  # Avoid duplicates entries
                            nb_space = len(parent.text) - len(
                                parent.text.lstrip()) + 1
                            parse.insert_after(parent_re,
                                               insertstr=" " * nb_space +
                                               item[2])
                            parent_object_done.append(parent.text)
                    else:  # Entry is at the root of cfg, no space added
                        parse.insert_after(parent_re, insertstr=item[2])
            else:  # parent cmd is not mentionned
                parse.append_line(item[2])  # Write line at the end of the file

        # REPLACE
        for item in conversion_matrix[device_type]["replace"]:
            if item[1] == None or item[2] == None:  # Check required fields
                continue
            if item[0] != None:  # parent cmd is mentionned
                initial_cmd = re.compile(item[1])
                parse.replace_children(item[0], initial_cmd, item[2])
            else:  # parent cmd is not mentionned
                initial_cmd = re.compile(item[1])
                parse.replace_lines(initial_cmd, item[2])

        # Write output to out_file
        parse.save_as(new_filename)
    else:
        new_filename = "Skipped (model unknown)"

    return new_filename
        arp_ipv4_addr = IPv4Address(ipv4)

        # assign static arp entry to the VLAN SVI interface
        for vlan_svi in vlan_svis:
            svi_ipv4_network = IPv4Network(vlan_svi['ipv4_addr'] + "/" +
                                           vlan_svi['ipv4_netmask'],
                                           strict=False)
            if arp_ipv4_addr in svi_ipv4_network.hosts():
                # extend the model if the correct IP network is found
                if "static_arps" not in vlan_svi.keys():
                    vlan_svi['static_arps'] = list()
                record = {'ipv4_host': ipv4, 'mac': mac}
                vlan_svi['static_arps'].append(record)

                # a static ARP is only defined on a single interface
                break

    print("Write results to file...")
    cisco_nxos_template = CiscoConfParse(['!'])

    for vlan_svi in vlan_svis:
        cisco_nxos_template.append_line("interface Vlan%s" %
                                        vlan_svi['vlan_id'])
        for static_arp in vlan_svi['static_arps']:
            cisco_nxos_template.append_line(
                " ip arp %s %s" % (static_arp['ipv4_host'], static_arp['mac']))
        cisco_nxos_template.append_line('!')

    cisco_nxos_template.save_as(
        os.path.join(output_dir, "cisco_nxos_config.txt"))
Exemple #12
0
        ## Add missing features
        if is_switchport_access and (not has_stormcontrol):
            intf.append_to_family(' storm-control action trap')
            intf.append_to_family(' storm-control broadcast level 0.4 0.3')

        ## Remove dot1q trunk misconfiguration...
        elif is_switchport_trunk:
            intf.delete_children_matching('port-security')


## Parse the config
parse = CiscoConfParse('short.conf')

## Add a new switchport at the bottom of the config...
parse.append_line('interface FastEthernet0/4')
parse.append_line(' switchport')
parse.append_line(' switchport mode access')
parse.append_line('!')
parse.commit()  # commit() **must** be called before searching again

## Search and standardize the interfaces...
standardize_intfs(parse)
parse.commit()  # commit() **must** be called before searching again

## I'm illustrating regular expression usage in has_line_with()
if not parse.has_line_with(r'^service\stimestamp'):
    ## prepend_line() adds a line at the top of the configuration
    parse.prepend_line(
        'service timestamps debug datetime msec localtime show-timezone')
    parse.prepend_line(
Exemple #13
0
        add_ip_addresses = []
        secondary_ipv4_address_lines = vlan_interface.re_search_children(r"^ ip address .* secondary$")
        for sec_ipv4_cmd in secondary_ipv4_address_lines:
            # another way to convert the ip address command
            sec_ipv4_addr = sec_ipv4_cmd.text[len(" ip address "):]
            sec_ipv4_addr = sec_ipv4_addr.rstrip(" secondary")
            sec_ipv4_addr = sec_ipv4_addr.replace(" ", "/")

            # convert it to an IPv4Interface object from the ipaddresss module
            ip_address = IPv4Interface(sec_ipv4_addr)

            # store it for later processing
            add_ip_addresses.append(ip_address)

        # now add the configuration to the change scripts
        primary_config.append_line("interface %s" % vlan_interface_string)
        primary_config.append_line(" description *** VLAN SVI %s" % vlan_id)
        primary_config.append_line(" ip address %s %s" % (primary_ip, ipv4_addr.netmask))
        for ipv4_address in add_ip_addresses:
            # determine primary IP address
            if IPv4Address(ipv4_address.ip + 1) in ipv4_address.network.hosts():
                primary_ip = ipv4_address + 1
            else:
                primary_ip = ipv4_address - 1
            primary_config.append_line(" ip address %s %s secondary" % (primary_ip.ip, ipv4_address.netmask))

        primary_config.append_line(" standby version 2")
        primary_config.append_line(" standby 1 ip %s" % virtual_ip)
        for ipv4_address in add_ip_addresses:
            primary_config.append_line(" standby 1 ip %s secondary" % ipv4_address.ip)
Exemple #14
0
cfgdiff = CiscoConfParse([])

text = config_file
re1='(ag)'

rg = re.compile(re1,re.IGNORECASE|re.DOTALL)
l2agg = rg.search(text)

if l2agg:
    for intf in parse.find_objects(r'^interface.+?thernet'):
        has_qos_trust = intf.has_child_with(r' mls qos trust dscp')
        is_switchport_trunk = intf.has_child_with(r'switchport mode trunk')
        is_switchport_infra = intf.has_child_with(r'INFRA:TRUNK*.*')

        if (is_switchport_trunk and is_switchport_infra) and (not has_qos_trust):
            cfgdiff.append_line("!")
            cfgdiff.append_line(intf.text)
            cfgdiff.append_line("mls qos trust dscp")
    cfgdiff.save_as(config_file+'_new')
    print ("Config Created with _new extension for L2AGG")
else:
    for intf in parse.find_objects(r'^interface.+?thernet'):
        has_qos_trust = intf.has_child_with(r' mls qos trust dscp')
        is_switchport_trunk = intf.has_child_with(r'switchport mode trunk')
        is_switchport_infra = intf.has_child_with(r'INFRA:TRUNK*.*')
        is_switchport_access = intf.has_child_with(r'switchport mode access')
        is_switchport_shutdown = intf.has_child_with(r'shutdown')

        if (is_switchport_trunk and is_switchport_infra) and (not has_qos_trust):
            cfgdiff.append_line("!")
            cfgdiff.append_line(intf.text)