def main():

    #YAML file
    cisco_cfg = CiscoConfParse("./cisco_file.txt")

    transform_set = cisco_cfg.find_objects(r"^crypto ipsec transform-set")
    t_set_list = []
    for t_set in transform_set:
        if ('esp-aes' not in t_set.text):
            t_set_list.append(t_set.text)

    print 'Transform sets found without AES are:', t_set_list

    print '\nCrypto Maps without AES are:\n'

    for t_set in t_set_list:
        var_tmp1 = t_set.split()
        reference = var_tmp1[3].strip()
        #print 'reference es', reference
        var_tmp1 = cisco_cfg.find_objects_w_child(r"^crypto map ", reference)
        #print 'var_tmp1 es', var_tmp1[0].text

        for index in range(0, len(var_tmp1)):
            config_crypto_map = cisco_cfg.find_children(var_tmp1[index].text)
            for item in config_crypto_map:
                print ' ', item
    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 print_lab_ip_management_addresses(self):
        """
        Print to the console information about IP addresses assigned to management interfaces.
        """
        # For each link we need to store 2 values. We use List of Dictionaries for this. Each link is described by
        # following structure:
        # {
        #   Device: String,
        #   ManagementIP: String
        # }
        TOutput = PrettyTable()
        TOutput.field_names = ['Device name', 'Management IP']

        for nodenum, nodedef in enumerate(self.lab_conf['nodes']):

            if self._get_node_type(nodenum) in self._node_types_supported:
                interface_record = {
                    'Device': nodedef['label'],
                    'ManagementIPAddress': None
                }

                node_config = self._get_node_config(nodenum)
                node_parsed_config = CiscoConfParse(node_config.split('\n'))

                if self._iface_ip_addr_defined(
                        node_parsed_config.find_children(
                            r'^interface\s' +
                            self._node_management_interface_name[
                                self._get_node_type(nodenum)])):
                    interface_record[
                        'ManagementIPAddress'] = self._get_iface_ip_addr(
                            node_parsed_config.find_children(
                                r'^interface\s' +
                                self._node_management_interface_name[
                                    self._get_node_type(nodenum)]))
                else:
                    interface_record['ManagementIPAddress'] = None
                TOutput.add_row([
                    interface_record['Device'],
                    interface_record['ManagementIPAddress']
                ])

        print("\nManagement interfaces addressing")
        print(TOutput)
class DhcpConfig:
    def __init__(self, config_file):
        self.config_file = config_file
        self.parse = CiscoConfParse(self.config_file)

    def get_dhcppool_config(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return find_result

    def get_dhcppoolname_list(self):
        dhcppoolname_list = []
        find_result = self.parse.find_parents_w_child('^ip dhcp pool', 'host')
        for parent in find_result:
            dhcppoolname_list.append(parent.split()[3])
        return dhcppoolname_list

    def get_ipaddr(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return find_result[1].split()[1]

    def get_ipaddrmask(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return find_result[1].split()[2]

    def get_macaddr(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return find_result[2].split()[1]

    def get_defaultrouter(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return find_result[3].split()[1]

    def get_dns(self, pool_name):
        find_result = self.parse.find_children(pool_name)
        return [find_result[4].split()[1], find_result[4].split()[2]]
    def testValues_insert_after_nonatomic_02(self):
        """Negative test.  We expect insert_after(atomic=False) to miss any children added like this at some point in the future I might fix insert_after so it knows how to correctly parse children"""
        result_correct = ['interface GigabitEthernet4/1', 
            #' shutdown',   <--- Intentionally commented out
            ' switchport', 
            ' switchport access vlan 100', 
            ' switchport voice vlan 150', 
            ' power inline static max 7000',
            ]
        linespec = 'interface GigabitEthernet4/1'
        cfg = CiscoConfParse(self.c01, factory=False)
        cfg.insert_after(linespec, ' shutdown', exactmatch=True, atomic=False)
        test_result = cfg.find_children(linespec)

        self.assertEqual(result_correct, test_result)
    def testValues_insert_after_atomic_01(self):
        """We expect insert_after(atomic=True) to correctly parse children"""
        ## See also -> testValues_insert_after_nonatomic_02()
        result_correct = [
            'interface GigabitEthernet4/1', 
            ' shutdown',
            ' switchport', 
            ' switchport access vlan 100', 
            ' switchport voice vlan 150', 
            ' power inline static max 7000',
            ]
        linespec = 'interface GigabitEthernet4/1'
        cfg = CiscoConfParse(self.c01, factory=False)
        cfg.insert_after(linespec, ' shutdown', exactmatch=True, atomic=True)
        test_result = cfg.find_children(linespec)

        self.assertEqual(result_correct, test_result)
Exemple #7
0
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()
    def print_lab_ip_peer_addresses(self):
        """
        Print to the console information about IP addresses and link of L3 interfaces in the lab.
        """

        # For each link we need to store 6 values. We use List of Dictionaries for this. Each link is described by
        # following structure:
        # {
        #   DeviceA: String,
        #   DeviceB: String,
        #   InterfaceA: String,
        #   InterfaceB: String,
        #   IPAddressA: netaddr.IPNetwork,
        #   IPAddressB: netaddr.IPNetwork
        # }
        links_database = []

        try:
            for linknum, link in enumerate(self.lab_conf["links"]):
                # We need to ignore connections to 'external_connector' and 'iosvl2' objects and continue to the
                # next object on list
                if self._get_node_type(
                        self._get_node_index_by_id(link['n1'])
                ) in self._node_types_ignored or self._get_node_type(
                        self._get_node_index_by_id(
                            link['n2'])) in self._node_types_ignored:
                    continue

                link_record = {
                    'InterfaceA':
                    self._get_interface_name_by_id(
                        self._get_node_index_by_id(link["n1"]), link["i1"]),
                    'InterfaceB':
                    self._get_interface_name_by_id(
                        self._get_node_index_by_id(link["n2"]), link["i2"]),
                    'DeviceA':
                    self._get_node_label_by_id(link["n1"]),
                    'DeviceB':
                    self._get_node_label_by_id(link["n2"]),
                    'IPAddressA':
                    None,
                    'IPAddressB':
                    None,
                }

                if self._get_node_type(self._get_node_index_by_id(
                        link["n1"])) in self._node_types_supported:
                    node_config = self._get_node_config(
                        self._get_node_index_by_id(link["n1"]))
                    node_parsed_config = CiscoConfParse(
                        node_config.split('\n'))

                    if self._iface_ip_addr_defined(
                            node_parsed_config.find_children(
                                r'^interface\s' +
                                self._get_interface_name_by_id(
                                    self._get_node_index_by_id(link["n1"]),
                                    link["i1"]))):
                        link_record['IPAddressA'] = self._get_iface_ip_addr(
                            node_parsed_config.find_children(
                                r'^interface\s' +
                                self._get_interface_name_by_id(
                                    self._get_node_index_by_id(link["n1"]),
                                    link["i1"])))

                if self._get_node_type(self._get_node_index_by_id(
                        link["n2"])) in self._node_types_supported:
                    node_config = self._get_node_config(
                        self._get_node_index_by_id(link["n2"]))
                    node_parsed_config = CiscoConfParse(
                        node_config.split('\n'))
                    if self._iface_ip_addr_defined(
                            node_parsed_config.find_children(
                                r'^interface\s' +
                                self._get_interface_name_by_id(
                                    self._get_node_index_by_id(link["n2"]),
                                    link["i2"]))):
                        link_record['IPAddressB'] = self._get_iface_ip_addr(
                            node_parsed_config.find_children(
                                r'^interface\s' +
                                self._get_interface_name_by_id(
                                    self._get_node_index_by_id(link["n2"]),
                                    link["i2"])))

                links_database.append(link_record)
        except IndexError as e:
            raise IndexError("peer-range: Not enough IP addresses provided")

        TOutput = PrettyTable()
        TOutput.field_names = [
            'Device A', 'Interface A', 'IP Address A', 'Device B',
            'Interface B', 'IP Address B'
        ]
        for r in links_database:
            TOutput.add_row([
                r['DeviceA'], r['InterfaceA'], r['IPAddressA'], r['DeviceB'],
                r['InterfaceB'], r['IPAddressB']
            ])
        print("\nL3 interfaces addressing")
        print(TOutput)
Exemple #9
0
def get_asa_net_obj(asa_config):
    '''
    receives a text asa configuration file as a string, returns a list with network object definitions

    Network objects include:
        FQDNs
        Network Objects
        Host Objects
        IP Address Ranges
    '''

    # create the CiscoConfParse class object
    parsed_conf = CiscoConfParse(asa_config.splitlines())
    # create a list containg the network object lines and thier children
    obj_list = parsed_conf.find_children( "^object network\s" )

    # network object name regex string
    _RE_NETOBJ_NAME_STR = r'^object\s+network\s+(.*)'
    # compiled network object name compiled regex
    _RE_NETOBJ_NAME = re.compile(_RE_NETOBJ_NAME_STR)

    #network object type regex string, returns the type and data from this string
    _RE_NETOBJ_TYPE_STR = r'^(subnet|range|host|fqdn)\s+(.*)'
    #network compiled regex
    _RE_NETOBJ_TYPE = re.compile(_RE_NETOBJ_TYPE_STR)

    #network object description regex
    _RE_NETOBJ_DESC_STR = r'^description\s(.*)'
    #network object description
    _RE_NETOBJ_DESC = re.compile(_RE_NETOBJ_DESC_STR)

    #\s+(subnet|range|host|fqdn)\s+(.*)

    # dictionary of objects
    obj_dict = {}

    for line in obj_list: # for each object in the list
        line = line.lstrip() #remove the leading whitespace


        #get the important facts from the configuration lines
        if re.search(_RE_NETOBJ_NAME, line):
            obj_name = re.search(_RE_NETOBJ_NAME, line).group(1)
            obj_dict[obj_name] = {}
        elif re.search(_RE_NETOBJ_TYPE_STR, line):
            obj_type, obj_data = re.search(_RE_NETOBJ_TYPE_STR, line).group(1, 2)
            obj_dict[obj_name]['type'] = obj_type
            #obj_data needs to be further parsed
            if obj_type == "fqdn":
                obj_dict[obj_name]["fqdn"] = re.split("\s|/", obj_data).pop()
            elif obj_type == "host":
                obj_dict[obj_name]["host"] = obj_data
            elif obj_type == "subnet":
                network, subnet = re.split("\s|/", obj_data)
                obj_dict[obj_name]["network"] = network
                obj_dict[obj_name]["prefixlen"] = str(ipaddress.ip_network(network + '/' + subnet).prefixlen) #works for ipv4 and 6
            elif obj_type == "range":
                range_first, range_last = obj_data.split(" ")
                obj_dict[obj_name]["range first"] = range_first
                obj_dict[obj_name]["range last"] = range_last

        elif re.search(_RE_NETOBJ_DESC, line):
            obj_desc = re.search(_RE_NETOBJ_DESC, line).group(1)
            obj_dict[obj_name]["desc"] = obj_desc

    # return the dictionary of objects
    return obj_dict
    # Search the config for Interfaces, QoS and ACLs

    class_map_p = []
    interfaces = [obj for obj in parse.find_objects("^interface") if obj.re_search_children(r"service-policy\soutput\s") ]

    # Create a regex that matches service policy but groups the policy-map name
    
    SERVICEPOLICY_RE = re.compile(r'service-policy\soutput\s(\S+)')
    INTERFACE_RE = re.compile(r'^interface\s(\S+)')
    CLASS_MAP_RE = re.compile(r'^class-map\smatch-any\s(\S+)')
    # Loop through the interfaces, looking for service-policy output.
    for intobj in interfaces:
        # if the interface has an output service-policy jump in
        if intobj.re_search_children("service-policy output"):
            # Find the class-map children of the policy-map - line terminated to stop half matches
            class_maps_t = parse.find_children("policy-map " + intobj.re_match_iter_typed(SERVICEPOLICY_RE, result_type=str) + "$")
            # CiscoConfParse helpfully includes the parent config, which we don't need so we remove it.
            class_maps_t.remove ("policy-map " + intobj.re_match_iter_typed(SERVICEPOLICY_RE, result_type=str))
            # If there's only on class-map, it's a parent policy in a hirearchical shaper
            if len(class_maps_t) == 1:
                policy_map_parent = intobj.re_match_iter_typed(SERVICEPOLICY_RE, result_type=str)
                # Find all the children of the parent policy
                policy_map_c = parse.find_all_children("policy-map " + intobj.re_match_iter_typed(SERVICEPOLICY_RE, result_type=str))
                # Step through them looking for the child policy-map name
                for pmap_p_child in policy_map_c:
                    pmap_p_child_policy = re.search(r"service-policy (\S+)", pmap_p_child)
                    if pmap_p_child_policy:
                         # We've found it - set the child policy name
                         child_policy = pmap_p_child_policy.group(1)
                         class_maps_t = []
                         # Get the class maps for the policy-map
Exemple #11
0
######################
### install necessary modules
######################

import os
from ciscoconfparse import CiscoConfParse
import pprint

# Enter your TFTP server path here
tftp_path = '/var/lib/tftpboot/'


#######################
### Begin parsing through configurations
#######################

#create empty dictionary
testdict = {}

#change working directory to TFTP server location
os.chdir(tftp_path)

#look in each file for the parent's stanza text
for filename in os.listdir(tftp_path):
	parse = CiscoConfParse(filename)
	line_con = parse.find_children("line con 0")   # this is the "parent" text you are looking for
	testdict[filename] = line_con

pprint.pprint(testdict)
 def testValues_find_children(self):
     ## test find_chidren
     for config, args, result_correct in self.find_children_Values:
         cfg = CiscoConfParse(config)
         test_result = cfg.find_children(**args)
         self.assertEqual(result_correct, test_result)
#Purpose: Compare latest Pingdom probe IP's to ASA configs and print if any differences are seen

from ciscoconfparse import CiscoConfParse

pingdom = []
sensors = []
ip = []
ips = []

with open('/mnt/c/users/me/Documents/misc/asa-configs') as configs:
    config_parse = CiscoConfParse(configs.readlines())

with open('/mnt/c/users/me/Documents/misc/pingdom-ips.txt') as ping:
    ping_ips = ping.readlines()

pingdom = config_parse.find_children(
    "object-group network Pingdom_NA_Probes_grp")

for item in pingdom:
    if "network-object object" in item:
        object = "object network " + item.split().pop()
        if object.split().pop() == item.split().pop():
            sensors.append(config_parse.find_children(object))

for line in sensors:
    ip.append(line[1].strip().split().pop())

for line in ping_ips:
    ips.append(line.split("\",\"").pop().strip("\"\n"))

print("IP's added: " + " ".join(set(ips).difference(set(ip))))
print("IP's removed: " + " ".join(set(ip).difference(set(ips))))
Exemple #14
0
            'peer': linelist[index + 4].strip(),
            'map_id': linelist[index + 1]
        })

    for line in crypto_maps:
        linelist = line.text.split(" ")
        index = linelist.index("Outside_map")
        for vpn in vpns:
            if linelist[index + 1] == vpn.get('map_id'):
                vpn['crypto_map'] = linelist[index + 4].strip()

    for vpn in vpns:
        vpn['groups'] = []
        vpn['grp_obj'] = []
        vpn['legacy'] = False
        for item in config_parse.find_children(vpn['crypto_map']):
            if len(item) >= 7 and item.split().pop(6) == "Prod_grp":
                vpn['legacy'] = True
            if item.split().pop(1) == vpn['crypto_map'] and item.split().pop(
                    8) and item.split().pop(8) not in vpn[
                        'groups'] and item.strip().split().pop() != "inactive":
                vpn['groups'].append(item.split().pop(8))

    for vpn in vpns:
        for grp in vpn['groups']:
            vpn['grp_obj'].append(grp_search(grp))

    for vpn in vpns:
        print("*** Peer: " + vpn['peer'] + " Map-Seq: " + vpn['map_id'] +
              " LegacyIP: " + str(vpn['legacy']) + " Groups: " +
              " ".join(vpn['groups']) + " ***")
            result_dict[switch] = output_list

            target.disconnect()

    for key in result_dict.keys():
        outputfile = open('{0}.cfg'.format(key),'w')
        for line in result_dict[key]:
            outputfile.write(line + '\n')
        outputfile.close()


    parsed_switch_config = CiscoConfParse('{0}.cfg'.format(device_list[0]))
    parsed_fex_config = CiscoConfParse('{0}.cfg'.format(device_list[1]))


    switch_config_list = parsed_switch_config.find_children('^interface GigabitEthernet{0}/0/[0-9][0-9]*'.format(stack_number))
    fex_config_list = parsed_fex_config.find_children('^interface')

    sw_intf_dict = {}
    fex_intf_dict = {}

    for line in switch_config_list:
        if 'interface' in line:
            i,intf = line.split()
            intf = intf[intf.rfind('/'):].strip('/')
            sw_intf_dict[intf] = []
        else:
            sw_intf_dict[intf].append(line)

    for line in fex_config_list:
        if 'interface' in line:
Exemple #16
0
#print("-------------------Finshed removing -Running.config from file name-------------------")
#print(" ")
header = "Switch" + "        " + "Port W/O Dot1x" + "          " + "Port Description"
print(header)
#
#Start Examining configs for missing port security
#
for host in os.listdir(NEW_DIR):
    if host.startswith("p"):
        config_path = os.path.join(NEW_DIR, host)
        parse = CiscoConfParse(config_path)
        all_intfs = parse.find_objects(r"^interf")
        NoDot1x = list()
        NoDot1x = parse.find_objects_wo_child(r'^interface', r'authentication')
        #Remove Non Gig Ports because all user ports are 1 gig
        GigPorts = [
            x.text.split()[1] for x in NoDot1x
            if x.text.startswith("interface Gig")
        ]
        #Remove Cisco 3750 Exansion module
        final_list = [
            w for w in GigPorts if not re.match(r'GigabitEthernet./1/.', w)
        ]
        #Gets Port Descriptions
        for ports in final_list:
            port = "interface" + " " + ports
            intconfig = parse.find_children(port, exactmatch=True)
            desc = [x for x in intconfig if re.search("description", x)]
            result = host + '   ' + ''.join(ports) + '   ' + ''.join(desc)
            print(result.replace('description', ''))
                len(all_addresses)),
            debug=debug,
            indent=2)

        # if "vpnmonitor" in instance:
        #     script_logger(data=interfaces, debug=debug)
        #     script_logger(data=addresses, debug=debug)
        #     script_logger(data=vrf_duplicate, debug=debug)

        if vrf_duplicate:
            return all_addresses, vrf_duplicate
        else:
            return all_addresses, "NO_DUPLICATES"


interfaces = parse.find_children(r"^interfaces ")[1:]

print("**Getting All addresses from the configuration")
all_addresses = get_all_addresses(interfaces)

routing_instances = parse.find_children('^routing-instances')
# pprint(routing_instances)

ri_vrfs = []
for ri in routing_instances:
    ri_config = parse.find_children(ri)

    if "instance-type vrf" in ri_config[1]:
        ri_vrfs.append(ri)

last_instance = ri_vrfs[-1]