Ejemplo n.º 1
0
def connect():
    """ Here we will user connArgs gathered from get_conn_args \n""" \
    """ and establish connection to WLC                        \n"""
    global conn
    global connArgs
    global savedCredentials
    global connIsAlive
    attempts = 0
    expPrompt = False
    while connIsAlive is False:
        try:
            connArgs = get_conn_args()
            conn = ConnectHandler(ip=connArgs["ip"],
                                  username=connArgs["user"],
                                  password=connArgs["pass"],
                                  device_type="cisco_ios",
                                  session_log="ssh_session_logfile.txt",
                                  session_log_file_mode="write",
                                  session_log_record_writes="True")
        except nm.NetMikoTimeoutException:
            print("-------------------------------------------\n" \
                  "Error: Timeout Error Occured Attempting to \n" \
                  "connect. Check IP/Hostname and try Again   \n" \
                  "-------------------------------------------\n")
        except nm.NetMikoAuthenticationException:
            print("-------------------------------------------\n" \
                  "Error: Authentication Error Occured.       \n" \
                  "Check Credentials and try Again            \n" \
                  "-------------------------------------------\n")
    ##    except:
    ##        print("Unexpected error:", sys.exc_info()[0])
    ##        raise
        else:
            connIsAlive = conn.is_alive()
            if connIsAlive is True:
                print("Connection Successful!")
                getPrompt = conn.find_prompt()
                print("-------------------------------------------\n" \
                      "CONNECTED via SSH- \n" \
                      f"Device returned : {getPrompt}               \n" \
                      "-------------------------------------------\n")
                while expPrompt is False:
                    choice = 0
                    choice = int(input("Is the above CLI prompt the prompt you were\n" \
                                       "expecting from the correct WLC in exec mode? \n" \
                                       "1= Yes | 2=No or Ctrl-C to quit :  "))
                    if choice == 1:
                        conn.disable_paging()
                        expPrompt = True
                        return conn
                    elif choice == 2:
                        savedCredentials = False
                        print(f"Disconnecting Current SSH Session...")
                        conn.disconnect()
                        connIsAlive = conn.is_alive()
                        main2()
            else:
                print("Failure: Unknown Error. Sorry")
Ejemplo n.º 2
0
def connect():
    """ Here we will user connArgs gathered from get_conn_args \n""" \
    """ and establish connection to WLC                        \n"""
    global conn
    global connArgs
    global savedCredentials
    global connIsAlive
    attempts = 0
    expPrompt = False
    while connIsAlive is False:
        try:
            connArgs = get_conn_args()
            conn = ConnectHandler(ip=connArgs["ip"],
                                  username=connArgs["user"],
                                  password=connArgs["pass"],
                                  device_type="cisco_ios",
                                  session_log="ssh_session_logfile.txt",
                                  session_log_file_mode="write",
                                  session_log_record_writes="True")
        except nm.NetMikoTimeoutException:
            print("*********************************************************\n" \
                  "* Error: Timeout Error Occured Attempting to            *\n" \
                  "* connect. Check IP/Hostname and try Again              *\n" \
                  "*********************************************************\n")
        except nm.NetMikoAuthenticationException:
            print("*********************************************************\n" \
                  "* Error: Authentication Error Occured.                  *\n" \
                  "* Check Credentials and try Again                       *\n" \
                  "*********************************************************\n")
    ##    except:
    ##        print("Unexpected error:", sys.exc_info()[0])
    ##        raise
        else:
            connIsAlive = conn.is_alive()
            if connIsAlive is True:
                print(
                    "*********************************************************"
                )
                print(
                    "* Dino | SSH ConneX                                     *"
                )
                print(
                    "*********************************************************"
                )
                print(
                    "* SSH Connection Successful!                            *"
                )
                getPrompt = conn.find_prompt()
                print(
                    "* We need to validate if this is the intended device    *"
                )
                print(
                    "*                                                       *"
                )
                print(
                    f"* Device CLI prompt : {getPrompt}                     \n"
                )
                print(
                    "*                                                       *"
                )
                while expPrompt is False:
                    choice = 0
                    print(
                        "*         [1] Yes | [2] No or Ctrl-C to quit            *"
                    )
                    print(
                        "*********************************************************"
                    )
                    choice = int(input(" Is the above CLI prompt the prompt you were           *\n" \
                                       " expecting from the correct WLC in PRIV EXEC mode? : \n"))
                    if choice == 1:
                        conn.disable_paging()
                        expPrompt = True
                        return conn
                    elif choice == 2:
                        savedCredentials = False
                        print(f"Disconnecting Current SSH Session...")
                        conn.disconnect()
                        connIsAlive = conn.is_alive()
                        main2()
            else:
                print("Failure: Unknown Error. Sorry")
Ejemplo n.º 3
0
#!usr/bin/python
#coding: utf-8

import sys
import csv
from netmiko import ConnectHandler

ip = '192.168.73.137'
un = 'cisco'
pw = 'cisco'
platform = 'cisco_ios'
device = ConnectHandler(device_type=platform, ip=ip, username=un, password=pw)
disable_paging = device.disable_paging()
#fo = open ("show_version.txt","a")
output = device.send_command('show version', delay_factor=20)
print output
#fo.write(output)
#fo.close
close_ssh = device.disconnect()
Ejemplo n.º 4
0
class DLDriver(NetworkDriver):
    """NAPALM  D-Link Handler."""

    def __init__(self, hostname, username, password, timeout=60, optional_args=None):
        """NAPALM  D-Link Handler."""

        self.device = None
        self.hostname = hostname
        self.username = username
        self.password = password
        self.timeout = timeout
        self.disable_paging = True
        self.platform = "dlink"
        self.profile = [self.platform]
        self.default_clipaging_status = 'enable'

        # Get optional arguments
        if optional_args is None:
            optional_args = {}

        self.inline_transfer = optional_args.get("inline_transfer", False)

        self.transport = optional_args.get("transport", "ssh")
        if self.transport == "telnet":    # Telnet only supports inline_transfer
            self.inline_transfer = True

        self.port = optional_args.get('port', 22)
        default_port = {"ssh": 22, "telnet": 23}

        # Netmiko possible arguments
        netmiko_argument_map = {
            'port': default_port[self.transport],
            'verbose': False,
            'timeout': self.timeout,
            'global_delay_factor': 1,
            'use_keys': False,
            'key_file': None,
            'ssh_strict': False,
            'system_host_keys': False,
            'alt_host_keys': False,
            'alt_key_file': '',
            'ssh_config_file': None,
            'allow_agent': False
        }
        # Build dict of any optional Netmiko args
        self.netmiko_optional_args = {
            k: optional_args.get(k, v)
            for k, v in netmiko_argument_map.items()
        }

    def _parse_output(self, output, parser_regexp):
        result_list = []
        for line in output.split("\n"):
            search_result = re.search(parser_regexp, line)
            if search_result:
                result_list.append(search_result.groupdict())
        return result_list

    @staticmethod
    def _parse_uptime(uptime_str):
        """Return the uptime in seconds as an integer."""
        (years, weeks, days, hours, minutes, seconds) = (0, 0, 0, 0, 0, 0)

        years_regx = re.search(r"(?P<year>\d+)\syear", uptime_str)
        if years_regx is not None:
            years = int(years_regx.group(1))
        weeks_regx = re.search(r"(?P<week>\d+)\sweek", uptime_str)
        if weeks_regx is not None:
            weeks = int(weeks_regx.group(1))
        days_regx = re.search(r"(?P<day>\d+)\sday", uptime_str)
        if days_regx is not None:
            days = int(days_regx.group(1))
        hours_regx = re.search(r"(?P<hour>\d+)\shour", uptime_str)
        if hours_regx is not None:
            hours = int(hours_regx.group(1))
        minutes_regx = re.search(r"(?P<minute>\d+)\sminute", uptime_str)
        if minutes_regx is not None:
            minutes = int(minutes_regx.group(1))
        seconds_regx = re.search(r"(?P<second>\d+)\ssecond", uptime_str)
        if seconds_regx is not None:
            seconds = int(seconds_regx.group(1))

        uptime_sec = (years * YEAR_SECONDS) + (weeks * WEEK_SECONDS) + (days * DAY_SECONDS) + \
                     (hours * 3600) + (minutes * 60) + seconds
        return uptime_sec

    def _get_clipaging_status(self):
        try:
            self.device.send_command("show switch", 'Next Page')
            self.device.send_command("q")  # For exit
            return 'enable'
        except IOError:
            return 'disable'

    def open(self):
        """Open a connection to the device."""
        try:
            device_type = 'cisco_ios'
            if self.transport == "telnet":
                device_type = "cisco_ios_telnet"

            self.device = ConnectHandler(device_type=device_type,
                                         host=self.hostname,
                                         username=self.username,
                                         password=self.password,
                                         **self.netmiko_optional_args)
            self.default_clipaging_status = self._get_clipaging_status()
            if self.disable_paging and self.default_clipaging_status == 'enable':
                self.device.disable_paging(command="disable clipaging")

        except NetMikoTimeoutException:
            raise ConnectionException('Cannot connect to {}'.format(self.hostname))

    def close(self):
        """Close the connection to the device."""
        if self.disable_paging and self.default_clipaging_status == 'enable':
            self.device.disable_paging(command="enable clipaging")

        self.device.disconnect()
        self.device = None

    def is_alive(self):
        """Returns a flag with the state of the connection."""
        null = chr(0)
        if self.device is None:
            return {"is_alive": False}
        if self.transport == "telnet":
            try:
                # Try sending IAC + NOP (IAC is telnet way of sending command
                # IAC = Interpret as Command (it comes before the NOP)
                self.device.write_channel(telnetlib.IAC + telnetlib.NOP)
                return {"is_alive": True}
            except UnicodeDecodeError:
                # Netmiko logging bug (remove after Netmiko >= 1.4.3)
                return {"is_alive": True}
            except AttributeError:
                return {"is_alive": False}
        else:
            # SSH
            try:
                # Try sending ASCII null byte to maintain the connection alive
                self.device.write_channel(null)
                return {"is_alive": self.device.remote_conn.transport.is_active()}
            except (socket.error, EOFError):
                # If unable to send, we can tell for sure that the connection is unusable
                return {"is_alive": False}

    def cli(self, commands):
        """
        Execute a list of commands and return the output in a dictionary format using the command
        as the key.
        """
        cli_output = dict()
        if type(commands) is not list:
            raise TypeError("Please enter a valid list of commands!")

        for command in commands:
            output = self.device.send_command(command)
            cli_output.setdefault(command, {})
            cli_output[command] = output
        return cli_output

    def get_facts(self):
        """Return a set of facts from the devices."""
        show_switch = self.device.send_command("show switch")

        switch_facts = {}
        for line in show_switch.splitlines():
            if line:
                name, value = line.split(":")
                switch_facts[name.strip()] = value.strip()

        if switch_facts.get("Device Uptime"):
            switch_facts['Device Uptime'] = self._parse_uptime(switch_facts['Device Uptime'])

        return switch_facts

    def get_config(self, retrieve='all'):
        """ Get config from device. """
        config = {
            'startup': '',
            'running': '',
            'candidate': ''
        }
        if retrieve.lower() in ('running', 'all'):
            command = 'show config current_config'
            config['running'] = py23_compat.text_type(self.device.send_command(command))
            # Some D-link switch need run other command
            if "Configuration" not in config['running']:
                command = 'show config active'
                config['running'] = py23_compat.text_type(self.device.send_command(command))
        if retrieve.lower() in ('candidate', 'all'):
            command = 'show config config_in_nvram'
            config['candidate'] = py23_compat.text_type(self.device.send_command(command))

        return config

    def get_arp_table(self):
        """
        Get arp table information.

        Sample output:
            [
                {u'interface': u'System',
                        u'ip': u'10.12.16.0',
                       u'mac': u'FF-FF-FF-FF-FF-FF',
                      u'type': u'Local/Broadcast'},
                {u'interface': u'System',
                        u'ip': u'10.12.16.1',
                       u'mac': u'00-1F-9D-48-72-51',
                      u'type': u'Dynamic'},
            ]
        """

        output = self.device.send_command('show arpentry')
        parser_regexp = ("(?P<interface>^\w+)\s+"
                         "(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+"
                         "(?P<mac>([0-9A-F]{2}[:-]){5}([0-9A-F]{2}))\s+"
                         "(?P<type>(\w+(/\w+)*))")

        return self._parse_output(output, parser_regexp)

    def get_mac_address_table(self):
        """
        Return the MAC address table.

        Sample output:
        [
        {'status': 'Forward',
             'vid': '1',
       'vlan_name': 'default',
             'mac': '00-0F-E2-21-35-20',
            'type': 'Dynamic',
            'port': '9'},

         {'status': 'Forward',
             'vid': '1',
       'vlan_name': 'default',
             'mac': '00-0F-E2-21-35-2A',
            'type': 'Dynamic',
            'port': '9'},

        {'status': 'Forward',
            'vid': '1',
      'vlan_name': 'default',
            'mac': '00-1D-E5-48-34-81',
           'type': 'Dynamic',
           'port': '9'},
        ]
        """

        output = self.device.send_command('show fdb')
        parser_regexp = ("(?P<vid>\d+)\s+"
                         "(?P<vlan_name>\w+)\s+"
                         "(?P<mac>([0-9A-F]{2}[:-]){5}([0-9A-F]{2}))\s+"
                         "(?P<port>\d+)\s+"
                         "(?P<type>\w+)\s+"
                         "(?P<status>\w+)\s+")

        return self._parse_output(output, parser_regexp)
def body(session, apic, username, password):

    leaf_array = []
    leaf_dict = {}
    vlans = []
    vlan_vxlan_array = []
    vxlan_array = []
    wrong_dict = {}
    correct_dict = {}
    vlan_pool = collections.defaultdict(list)
    phys_doms = collections.defaultdict(list)
    aaeps = collections.defaultdict(list)
    location = collections.defaultdict(list)
    path = collections.defaultdict(list)

    time.sleep(1)
    clear()  # Clear terminal

    print("\n")
    print("|-Target Leafs--------------------|")
    print("|-CTRL + C When Complete----------|")
    print("\n")

    while True:
        try:
            leaf = input("Leaf: ")  # Input target leafs
            ipaddress.IPv4Address(leaf)  # Check for valid IP
            leaf_array.append(leaf)  # If valid IP, store to array
        except (ipaddress.AddressValueError,
                ValueError):  # Exception for invalid IP
            print("Invalid IP Address\n")
            continue  # Continue loop, prompt again
        except KeyboardInterrupt:  # Break the loop using CTRL-C
            print("\n")
            break

    clear()
    print("Gathering VLAN to VXLAN Mappings...")
    time.sleep(2)
    clear()

    module_mode = "vsh_lc"  # Command used by netmiko ti access module smode
    show_infra_mappings = "show system internal eltmc info vlan brief"  # Command used to get vlan to vxlan mappings

    try:
        for leaf in leaf_array:  # Iterate through leaf array/fabric leafs

            vlan_vxlan_array = []
            vxlan_array = []
            vlans_array = []
            wrong_vlans = []

            credentials = {  # Netmiko credential dictionary
                'device_type': 'cisco_ios',
                'host': leaf,
                'username': username,
                'password': password,
                'session_log': 'my_file.out'
            }

            try:
                device_connect = ConnectHandler(
                    **credentials
                )  # Connect to device/leaf using crdential dictionary
            except (ValueError, ssh_exception.AuthenticationException,
                    ssh_exception.NetmikoTimeoutException) as error:
                print(error)  # Print error
                pass

            switch_to_hardware = device_connect.send_command(
                module_mode, expect_string="module-1#"
            )  # Send command store in variable to device
            device_connect.disable_paging(
                command='terminal length 0')  # Disable paging on device CLI
            get_infra_mappings = device_connect.send_command(
                show_infra_mappings
            )  # Send command store in variable to device

            with open(get_file_1, "w") as report:  # Write ouput to file
                report.write(get_infra_mappings
                             )  # Variable create during netmiko session

            with open(get_file_1, "r") as report:
                for line in report:  # Read file as report
                    if "802.1q" in line:  # Check if 802.1q in line
                        L2_info = (re.findall(r"q\b.*\s\b", line)
                                   )  # Grab text borded by q and whitespace
                        cleanup = L2_info[0].replace(
                            "q", "")  # Remove q from string
                        cleanup = cleanup.replace(
                            "VXLAN", "")  # Remove VXLAN from string
                        final_L2 = (
                            re.findall(r"\b[0-9].*?[0-9]\b", cleanup)
                        )  # Grab vlan - bordered by anything [0-9] ending in [0-9]
                        if len(
                                final_L2
                        ) == 1:  # Since final_2 cariable creates a list, see if the list length == 1
                            vlan = (re.findall(r"\b[0-9]\b", final_L2[0])
                                    )  # Find the vlan in final_2 index 0
                            vxlan = (re.findall(r"\b[0-9][0-9].*?[0-9]\b",
                                                final_L2[0])
                                     )  # Find the vxlan in final_2 index 0
                            vlan_vxlan = str(vlan[0] + " " +
                                             vxlan[0])  # Concatinate the two
                            vlan_split = vlan_vxlan.split(
                                " ")  # Create list of two using split.
                            vlans_array.append(
                                vlan_split[0])  # Index vlan, store to array
                            vxlan_array.append(
                                vlan_split[1])  # Index vxlan, store to array
                            vlan_vxlan_array.append(
                                vlan_split)  # Grab whole list, store to array
                        else:
                            vlans_array.append(
                                final_L2[0]
                            )  # If final_2 len != 1 index vlan, store to array
                            vxlan_array.append(
                                final_L2[1]
                            )  # If final_2 len != 1 index vxlan, store to array
                            vlan_vxlan_array.append(
                                final_L2)  # Grab whole list, store to array
                    else:
                        pass

                leaf_dict[
                    leaf] = vlan_vxlan_array  # Store list in dictionaries. Keys being leaf IPs

                remove_duplicates_vlans = list(
                    dict.fromkeys(vlans_array)
                )  # Clear of duplicates in list. This allows us to have all assigned vlans across the fabric
                remove_duplicates_vxlans = list(
                    dict.fromkeys(vxlan_array)
                )  # Clear of duplicates in list. This allows us to have all assigned vxlans across the fabric

                clear()

                print("\n")
                for k, v in leaf_dict.items(
                ):  # Iterate through key/value pairs
                    wrong_array = []  # List will be reset every k interation
                    correct_array = []  # List will be reset every k interation
                    for v in v:
                        for vlan, vxlan in zip(remove_duplicates_vlans,
                                               remove_duplicates_vxlans):

                            if vlan == v[0] and vxlan == v[1]:
                                correct_array.append(
                                    " Leaf IP: " + k +
                                    "    |    VLAN: {:7} |   VXLAN ID: {:15}   "
                                    .format(vlan, vxlan))
                            if vlan == v[0] and vxlan != v[1]:
                                wrong_vlans.append(vlan)
                                wrong_array.append(
                                    " Leaf IP: " + k +
                                    "    |    VLAN: {:7} |   VXLAN ID: {:15}   "
                                    .format(v[0], v[1]))
                            else:
                                pass
                    if len(wrong_array) == 0:
                        correct_dict[k] = correct_array
                    else:
                        wrong_dict[k] = wrong_array

        remove_dups = list(dict.fromkeys(wrong_vlans))
        for vlan in remove_dups:
            pools = vlanPool.aci_gets.find_duplicatee_vlan(session, apic, vlan)
            vlan_pool[vlan].append(pools[0])
            phys_doms[vlan].append(pools[1])
            aaeps[vlan].append(pools[2])
            location[vlan].append(pools[3])
            path[vlan].append(pools[4])

        for key_1, v in wrong_dict.items():  # unpack k, v pairs
            if not v:  # If the key has no value, continue at the top of the loop
                continue
            else:
                for string in v:
                    vlan_1 = re.search(r'(?<=VLAN:\s).*?[0-9]\b', string)
                    print(
                        "   Fabric VLAN to VXLAN Mapping                               *Leaf Perspective"
                    )
                    print(
                        "--------------------------------------------------------------------------------\n"
                    )
                    print("   *" + string)
                    for key_2, v in correct_dict.items():
                        for string_2 in v:
                            vlan_2 = re.search(r'(?<=VLAN:\s).*?[0-9]\b',
                                               string_2)
                            try:
                                if vlan_1.group(0) == vlan_2.group(0):
                                    if string == string_2:
                                        pass
                                    else:
                                        print("    " + string_2)
                                else:
                                    pass
                            except AttributeError:
                                pass

                    unpacked_vlan_pools = [
                        v for k, v in vlan_pool.items() if vlan_1.group(0) == k
                        for v in v for v in v
                    ]
                    unpacked_phys_doms = [
                        v for k, v in phys_doms.items() if vlan_1.group(0) == k
                        for v in v for v in v
                    ]
                    unpacked_aaep = [
                        v for k, v in aaeps.items() if vlan_1.group(0) == k
                        for v in v for v in v
                    ]
                    unpacked_location = [
                        v for k, v in location.items() if vlan_1.group(0) == k
                        for v in v for v in v
                    ]
                    unpacked_path = [
                        v for k, v in path.items() if vlan_1.group(0) == k
                        for v in v for v in v
                    ]

                    print("\n")
                    print("   Access Policy Details:\n")
                    print("     VLAN Pool(s): " +
                          "\n                   ".join(unpacked_vlan_pools))
                    print("\n")
                    print("     Phys Dom(s):  " +
                          "\n                   ".join(unpacked_phys_doms))
                    print("\n")
                    print("     AAEP(s):      " +
                          "\n                   ".join(unpacked_aaep))
                    print("\n")
                    print("     Encap Loc.:   " +
                          "\n                   ".join(unpacked_location))
                    print("\n")
                    print("     Path Attach:  " +
                          "\n                   ".join(unpacked_path))
                    print("\n")

    except (UnboundLocalError, OSError):
        print(
            "Something Went Wrong. Please Verify Connectivity and Credentials\n"
        )
        pass

    stop = input("Program Ended")
Ejemplo n.º 6
0
def device_login(username, password):

    clear()
    print("|-Target Layer--------------------|")
    print("|---------------------------------|")
    print("\n")

    # Commands sent to the CLI depend on the layer you want to capture at. As seen under the if staement, CLI code is different

    layer_selection = " "
    while layer_selection == "1" or "2":

        layer_selection = input(
            " 1. L3 capture\n 2. L2 Capture\n\n Selection: ")

        if layer_selection == "1":
            src_dst_iter = [ip for ip in EPCollect.endpoint_array]
            set_layer = "set outer ipv4 src_ip {} dst_ip {}".format(
                src_dst_iter[0], src_dst_iter[1])
            get_report_1 = "show platform internal hal ep l3 all | grep %s" % src_dst_iter[
                1]
            get_report_2 = "show platform internal hal ep l3 all | grep %s" % src_dst_iter[
                0]
            dst_ep = " show endpoint ip %s" % src_dst_iter[1]
            src_ep = " show endpoint ip %s" % src_dst_iter[0]
            break
        elif layer_selection == "2":
            src_dst_iter = [mac for mac in EPCollect.ep_mac_array]
            set_layer = "set outer l2 src_mac {} dst_mac {}".format(
                src_dst_iter[0], src_dst_iter[1])
            dst_ep = " show endpoint mac %s" % src_dst_iter[1]
            src_ep = " show endpoint mac %s" % src_dst_iter[0]
            break
        else:
            print("\n")
            print("Invalid Input\n")

    clear()

    if layer_selection == "1":

        print("|-Target Port--------------------|")
        print("|--------------------------------|")
        print("\n")

        # If layer 1 is selected above, you will be asked to put in either a source or destination port

        port_selection = " "
        while port_selection == "1" or "2":

            port_selection = input(
                " 1. Source port\n 2. Destionation port:\n\n Selection: ")

            if port_selection == "1":
                target_port = input(" Port: ")
                set_inner_l4_1 = "set outer l4 src-port %s" % target_port
                break
            elif port_selection == "2":
                target_port = input(" Port: ")
                set_inner_l4_1 = "set outer l4 dst-port %s" % target_port
                break
            else:
                print("\n")
                print("Invalid Input\n")
    else:
        pass

    clear()
    print("Capture Configuration:\n")
    print(set_layer)

    try:
        print(set_inner_l4_1)
    except UnboundLocalError:
        pass

    print("\n")
    print("|-Target Leafs--------------------|")
    print("|-CTRL + C When Complete----------|")
    print("\n")

    while True:
        try:
            leaf = input("Leaf: ")
            leaf_array.append(leaf)
        except KeyboardInterrupt:
            break

    time.sleep(1)
    clear()

    # Start the ELAM capture setup using the leaf array created on line 153

    print("\n")
    print("|-Configuring Triggers------------|")
    print("|---------------------------------|\n")

    loop_count = 0
    for i in leaf_array:

        device_dict = {}
        source_dict = {}

        # Netmiko login credentials dictionary. Uses variables carried over from the EPCollect module

        credentials = {
            'device_type': 'cisco_ios',
            'host': i,
            'username': username,
            'password': password,
            'session_log': 'my_file.out'
        }

        # If login fails continue the loop at the next variable, or leaf

        try:
            credentials_array.append(credentials)
            try:
                device_connect = ConnectHandler(**credentials)
            except (ValueError, ssh_exception.AuthenticationException,
                    ssh_exception.NetmikoTimeoutException) as error:
                print(error)
                continue
            ###################################################################################################
            # Gather the destination fabric VLAN, Endpoint VRF, and where the Endpoint was learned from

            # Send command to CLI which gets all endpoint information for with EP IP or MAC

            ep_fabric_vl_1 = device_connect.send_command(dst_ep)

            #Save string to file

            with open(get_file_1, "w") as report:
                report.write(ep_fabric_vl_1)

            # Open file and search lines for infrastructure vlans. Not all leafs will have a vlan
            # In this case store v to key as N/A.
            # If there is a vlan in a line, the regex will seach for the vlan at the begining of the line
            # to the next white space.

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'^[0-9].*?\s', line):
                        if EPCollect.ep_encap_array[1] in line:
                            vlan = re.findall(r'^[0-9].*?\s', line)
                            device_dict["Infra_vl"] = vlan[0]
                            break
                        elif re.findall(r'^[0-9].*?\s', line):
                            vlan = re.findall(r'^[0-9].*?\s', line)
                            device_dict["Infra_vl"] = vlan[0]
                            break
                    else:
                        device_dict["Infra_vl"] = "N/A"

            #Open file and search of the vrf in line. Leafs may have vlans but no vrf. In this case it will use a tunnel
            # to forward to the reporting leaf. Search begingin of line for lower case chars until the chars end with
            # either upper or lowercase chars. Write vrf to dictionary

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'^[a-z].*?[a-zA-Z].*?', line):
                        vrf = re.findall(r'^[a-z].*?:[a-zA-Z].*?\s', line)
                        device_dict["vrf"] = vrf[0]
                        break
                    else:
                        device_dict["vrf"] = "N/A"

            # Find where the endpoint was learned from. Could be ethernet, port-channel, or tunnel
            # search regex \b = border, starting with the interface type, ending in a number 0-9, or \b
            # Write to dictionary

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'\bpo.*?', line):
                        learnedFrom = re.findall(r'\bpo.*?[0-9]\b', line)
                        device_dict["LearnedFrom"] = learnedFrom[0]
                    elif re.findall(r'\beth.*?[0-9]', line):
                        learnedFrom = re.findall(r'\beth.*?[0-9]\b', line)
                        device_dict["LearnedFrom"] = learnedFrom[0]
                    elif re.findall(r'\btun.*?[0-9]', line):
                        learnedFrom = re.findall(r'\btun.*?[0-9]\b', line)
                        device_dict["LearnedFrom"] = learnedFrom[0]
            report.close()

            ##############################################################################################
            # Gather the source fabric VLAN, Endpoint VRF, and where the Endpoint was learned from
            # We are going to repeat the above lines, but write to a source dictionary

            ep_fabric_vl_2 = device_connect.send_command(src_ep)

            with open(get_file_1, "w") as report:
                report.write(ep_fabric_vl_2)

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'^[0-9].*?\s', line):
                        if EPCollect.ep_encap_array[0] in line:
                            vlan = re.findall(r'^[0-9].*?\s', line)
                            source_dict["Infra_vl"] = vlan[0]
                            break
                        elif re.findall(r'^[0-9].*?\s', line):
                            vlan = re.findall(r'^[0-9].*?\s', line)
                            source_dict["Infra_vl"] = vlan[0]
                            break
                    else:
                        source_dict["Infra_vl"] = "N/A"

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'^[a-z].*?[a-zA-Z].*?', line):
                        vrf = re.findall(r'^[a-z].*?:[a-zA-Z].*?\s', line)
                        source_dict["vrf"] = vrf[0]
                        break
                    else:
                        source_dict["vrf"] = "N/A"

            with open(get_file_1, "r") as report:
                for line in report:
                    if re.findall(r'\bpo.*?', line):
                        learnedFrom = re.findall(r'\bpo.*?[0-9]\b', line)
                        source_dict["LearnedFrom"] = learnedFrom[0]
                    elif re.findall(r'\beth.*?[0-9]', line):
                        learnedFrom = re.findall(r'\beth[0-9].*?[0-9]\b', line)
                        source_dict["LearnedFrom"] = learnedFrom[0]
                    elif re.findall(r'\btun.*?[0-9]', line):
                        learnedFrom = re.findall(r'\btun.*?[0-9]\b', line)
                        source_dict["LearnedFrom"] = learnedFrom[0]

            report.close()
            commands = device_connect.send_command(module_mode,
                                                   expect_string="module-1#")
            device_connect.disable_paging(command='terminal length 0')

            ##################################################################################################
            # Gather Destination Endpoint Information Endpoint DB port, Hardware BD. This information is all
            # about hardware, or how the fabric see the path.

            # First we need to decide which commands we need to send to CLI. If an IP is the endpooint we will
            # will validate with the ipaddress module. If not a valid ip, we will use the excpetion as the
            # condition

            try:
                ipaddress.IPv4Address(src_dst_iter[0])
                get_report_1 = "show platform internal hal ep l3 all | grep %s" % src_dst_iter[
                    1]
                get_report_2 = "show platform internal hal ep l3 all | grep %s" % src_dst_iter[
                    0]
                network_report_1 = device_connect.send_command(get_report_1)
                network_report_2 = device_connect.send_command(get_report_2)
                ep_dest = src_dst_iter[0]
                ep_src = src_dst_iter[0]
            except ipaddress.AddressValueError:
                get_l2_src = "show platform internal hal ep l2 mac %s" % src_dst_iter[
                    0]
                get_l2_dst = "show platform internal hal ep l2 mac %s" % src_dst_iter[
                    1]
                network_report_1 = device_connect.send_command(get_l2_dst)
                network_report_2 = device_connect.send_command(get_l2_src)
                ep_dest = src_dst_iter[0].swapcase()
                ep_src = src_dst_iter[0].swapcase()
                pass

            with open(get_file_1, "w") as report:
                report.write(network_report_1)

            with open(get_file_1, "r") as report:
                for line in report:
                    bd = re.findall(r'\bBD-.*?\s', line)
                    if re.findall(r'\bEth.*?[0-9]\s', line):
                        learned_ep_1 = re.findall(r'\bEth[0-9].*?[0-9]\b',
                                                  line)
                        device_dict["EP DB Port"] = learned_ep_1[0]
                        device_dict["EP Hw BD"] = bd[0]
                    elif re.findall(r'\bPo.*?[0-9]\s', line):
                        learned_ep_1 = re.findall(r'\bPo.*?[0-9]\b', line)
                        dst_interface = learned_ep_1[0]
                        device_dict["EP DB Port"] = learned_ep_1[0]
                        device_dict["EP Hw BD"] = bd[0]
                    elif re.findall(r'\bTun.*?[0-9]', line):
                        learned_ep_1 = re.findall(r'\bTun.*?[0-9]\b', line)
                        bd = re.findall(r'\bBD-.*?\s', line)
                        device_dict["EP DB Port"] = learned_ep_1[0]
                        device_dict["EP Hw BD"] = bd[0]
                        device_dict["Sw Port"] = "N/A"

            report.close()

            ###############################################################################################
            # Gather Source Endpoint Information  Endpoint DB port, Hardware BD

            with open(get_file_1, "w") as report:
                report.write(network_report_2)

            with open(get_file_1, "r") as report:
                for line in report:
                    bd = re.findall(r'\bBD-.*?\s', line)
                    if re.findall(r'\bEth.*?[0-9]\b', line):
                        learned_ep_1 = re.findall(r'\bEth[0-9].*?[0-9]\b',
                                                  line)
                        src_interface = learned_ep_1[0]
                        source_dict["EP DB Port"] = learned_ep_1[0]
                        source_dict["EP Hw BD"] = bd[0]
                    elif re.findall(r'\bPo.*?[0-9]\s', line):
                        learned_ep_1 = re.findall(r'\bPo.*?[0-9]\b', line)
                        src_interface = learned_ep_1[0]
                        source_dict["EP DB Port"] = learned_ep_1[0]
                        source_dict["EP Hw BD"] = bd[0]
                    elif re.findall(r'\bTun.*?[0-9]\s', line):
                        learned_ep_1 = re.findall(r'\bTun.*?[0-9]\b', line)
                        source_dict["EP DB Port"] = learned_ep_1[0]
                        source_dict["EP Hw BD"] = bd[0]
                        source_dict["Sw Port"] = "N/A"

            exit_module = device_connect.send_command(exit, expect_string="")

            ###############################################################################################
            # Gather Source Endpoint Information  Endpoint Software port.

            port_channel = device_connect.send_command(get_port_channel)

            with open(get_file_1, "w") as report:
                report.write(port_channel)

            try:
                if "Tunnel" not in learned_ep_1[0]:

                    with open(get_file_1, "r") as report:
                        for line in report:
                            try:
                                if dst_interface in line:
                                    learned_phy_ports = re.findall(
                                        r'\bEth[0-9].*?[0-9]\b', line)
                                    if len(learned_phy_ports) > 1:
                                        join_ints = ", ".join(
                                            learned_phy_ports)
                                        device_dict["Sw Port"] = join_ints
                                        break
                                    else:
                                        device_dict[
                                            "Sw Port"] = learned_phy_ports[0]
                                        break
                                else:
                                    device_dict["Sw Port"] = dst_interface
                            except UnboundLocalError:
                                pass

                    with open(get_file_1, "r") as report:
                        for line in report:
                            try:
                                if src_interface in line:
                                    learned_phy_ports = re.findall(
                                        r'\bEth[0-9].*?[0-9]\b', line)
                                    if len(learned_phy_ports) > 1:
                                        join_ints = ", ".join(
                                            learned_phy_ports)
                                        source_dict["Sw Port"] = join_ints
                                        break
                                    else:
                                        source_dict[
                                            "Sw Port"] = learned_phy_ports[0]
                                        break
                                else:
                                    source_dict["Sw Port"] = src_interface
                            except UnboundLocalError:
                                pass
                else:
                    device_dict["Sw Port"] = "N/A"
                    source_dict["Sw Port"] = "N/A"

            except UnboundLocalError:
                pass

            ###############################################################################################
            # Setup ELAM capture perameters and intialize the capture

            commands = device_connect.send_command(module_mode,
                                                   expect_string="")
            device_connect.disable_paging(command='terminal length 0')
            debug = device_connect.send_command(debug_mode, expect_string="")
            reset_trigger = device_connect.send_command(trigger_reset,
                                                        expect_string="")
            init_trigger = device_connect.send_command(initializer,
                                                       expect_string="")
            layer_three = device_connect.send_command(set_layer,
                                                      expect_string="")

            try:
                layer_four = device_connect.send_command(set_inner_l4_1,
                                                         expect_string="")
            except UnboundLocalError:
                pass

            init = device_connect.send_command(start, expect_string="")
            stat = device_connect.send_command(status, expect_string="ed")

            print(" IP (Leaf): {} Status: {}".format(i, "Armed"))

            device_dict_nested_2.update({i: source_dict})
            device_dict_nested.update({i: device_dict})
            loop_count = loop_count + 1

        except (OSError, UnboundLocalError, TypeError) as error:
            print("Failed to initialize ELAM capture for leaf: %s") % i
            print("Error: " + error)
            continue

    print("\n")
    holder = input("Hit enter to check status: ")

    print("\n")
    print("Checking Trigger...")
    clear()

    ###############################################################################################
    # Present Endpoint ACI confiurations with external vlan tags

    print("Endpoints:\n")
    for endpoint_1, endpoint_2 in zip(EPCollect.query_array_1,
                                      EPCollect.query_array_2):
        print("{:54}{}".format(endpoint_1, endpoint_2))
    print("\n")

    ###############################################################################################
    # Present Endpoint hardware configuration create by the internal fabric

    try:
        print(" Source Endpoint Fabric Information:\n")
        for k, v in device_dict_nested_2.items():
            print(" {:1} {:<25} {:<20} {:<30} {:<20} {:<20} {:<27} {}".format(
                " ", "Leaf : " + k, "Infra_vl : " + v["Infra_vl"],
                "vrf: " + v["vrf"], "EP DB Port: " + v["EP DB Port"],
                "EP hw BD: " + v["EP Hw BD"],
                "LearningPort: " + v["LearnedFrom"],
                "Phys Port: " + v["Sw Port"]))

        print("\n")
    except KeyError as error:
        print(error)
        pass

    ###############################################################################################
    # Check to see if any of our ELAM traps have been triggered. If so crab the ovec hex, gther the report,
    # and find which port is associated the the hex.

    for leaf in leaf_array:
        try:
            credentials = {
                'device_type': 'cisco_ios',
                'host': leaf,
                'username': username,
                'password': password,
                'session_log': 'my_file.out'
            }

            try:
                device_connect = ConnectHandler(**credentials)
            except (ValueError, ssh_exception.AuthenticationException,
                    ssh_exception.NetmikoTimeoutException) as error:
                continue

            commands = device_connect.send_command(module_mode,
                                                   expect_string="")
            device_connect.disable_paging(command='terminal length 0')
            debug = device_connect.send_command(debug_mode, expect_string="")
            init_trigger = device_connect.send_command(initializer,
                                                       expect_string="")
            stat = device_connect.send_command(status, expect_string="ed")

            if "Triggered" in stat:

                print(" IP (Leaf): {} Status: {}\n".format(
                    leaf, "Triggered ####"))

                ###############################################################################################
                # Request the ovec report from CLI and use regex to get the hex. Since the right of the x
                # is the the important char, we will create a variable with only those chars. Here we
                # are searching directly from string.

                ovec_report = device_connect.send_command(get_ovec)
                if re.compile(r'\b0x.\b').findall(ovec_report):
                    hex = re.compile(r'\b0x.').findall(ovec_report)
                    hex_strip = str(hex[0].replace("0x", "")).swapcase()
                elif re.compile(r'\b0x..\b').findall(ovec_report):
                    hex = re.compile(r'\b0x..').findall(ovec_report)
                    hex_strip = str(hex[0].replace("0x", "")).swapcase()
                ###############################################################################################
                # Get full report, open it and scan for the port associated with the hex string.

                get_port = "show platform internal hal l2 port gpd"
                report_filtered = device_connect.send_command(get_port)
                with open("C:\\Python\ELAM_Report.txt", "w") as report:
                    report.write(report_filtered)

                try:
                    with open("C:\\Python\ELAM_Report.txt", "r") as report:
                        print("\n")
                        for line in report:
                            if re.findall(
                                    r'\b' + hex_strip + '.' + hex_strip + '\s',
                                    line):
                                ovec_port = re.findall(r'\bEth[0-9].*?[0-9]\b',
                                                       line)
                                device_dict_nested[leaf]["ovec"] = ovec_port[0]

                            elif re.findall(
                                    r'\b' + hex_strip + '..' + hex_strip +
                                    '\s', line):
                                ovec_port = re.findall(r'\bEth[0-9].*?[0-9]\b',
                                                       line)
                                device_dict_nested[leaf]["ovec"] = ovec_port[0]

                                ###############################################################################################
                                # Present the destination Endpoints fabric forwarding information with ovec. If the final 3
                                # values show association then the forwarding path is correct.

                        print(
                            " Infra_vl: {}    vrf: {}    EP hw BD: {}    EP DB Fw: {}    [LearningPort: {}    Phys Port: {}    Ovec Port: {}]"
                            .format(device_dict_nested[leaf]["Infra_vl"],
                                    device_dict_nested[leaf]["vrf"],
                                    device_dict_nested[leaf]["EP Hw BD"],
                                    device_dict_nested[leaf]["EP DB Port"],
                                    device_dict_nested[leaf]["LearnedFrom"],
                                    device_dict_nested[leaf]["Sw Port"],
                                    device_dict_nested[leaf]["ovec"]))

                        print("\n")
                except (NameError) as error:
                    continue
            else:
                continue
        except (UnboundLocalError, OSError) as error:
            print("Failed to initialize ELAM capture for leaf: %s") % leaf
            print("Error: " + error)
            continue

    complete = input("Capture Complete")
Ejemplo n.º 7
0
def body():


    leaf_array = [ ]
    leaf_dict = { }
    vlans = [ ]
    vlan_vxlan_array = [ ]
    vxlan_array = [ ]
    wrong_dict = { }
    correct_dict = { }
    wrong_array = [ ]
    correct_array = [ ]

    print("Fabric Credentials:\n.")
    username = input("Username: "******"Password: "******"\n")
    print("|-Target Leafs--------------------|")
    print("|-CTRL + C When Complete----------|")
    print("\n")

    while True:
           try:
            leaf = input("Leaf: ")                                     # Input target leafs
            ipaddress.IPv4Address(leaf)                                # Check for valid IP
            leaf_array.append(leaf)                                    # If valid IP, store to array
           except (ipaddress.AddressValueError, ValueError):           # Exception for invalid IP
               print("Invalid IP Address\n")
               continue                                                # Continue loop, prompt again
           except KeyboardInterrupt:                                   # Break the loop using CTRL-C
               print("\n")
               break

    clear()
    print("Gathering VLAN to VXLAN Mappings...")
    time.sleep(2)
    clear()

    module_mode = "vsh_lc"                                               # Command used by netmiko ti access module smode
    show_infra_mappings = "show system internal eltmc info vlan brief"   # Command used to get vlan to vxlan mappings

    try:
        for leaf in leaf_array:                                          # Iterate through leaf array/fabric leafs

            vlan_vxlan_array = [ ]
            vxlan_array = [ ]
            vlans_array = [ ]

            credentials = {                                             # Netmiko credential dictionary
                'device_type': 'cisco_ios',
                'host': leaf,
                'username': username,
                'password': password,
                'session_log': 'my_file.out'}

            try:
                device_connect = ConnectHandler(**credentials)          # Connect to device/leaf using crdential dictionary
            except (ValueError, ssh_exception.AuthenticationException,  # Catch netmiko exceptions
                    ssh_exception.NetmikoTimeoutException) as error:
                print(error)                                            # Print error
                pass

            switch_to_hardware = device_connect.send_command(module_mode, expect_string="module-1#") # Send command store in variable to device
            device_connect.disable_paging(command='terminal length 0')                               # Disable paging on device CLI
            get_infra_mappings = device_connect.send_command(show_infra_mappings)                    # Send command store in variable to device

            with open(get_file_1, "w") as report:                                       # Write ouput to file
                report.write(get_infra_mappings)                                        # Variable create during netmiko session

            with open(get_file_1, "r") as report:
                for line in report:                                                     # Read file as report
                    if "802.1q" in line:                                                # Check if 802.1q in line
                       L2_info = (re.findall(r"q\b.*\s\b", line))                       # Grab text borded by q and whitespace
                       cleanup = L2_info[0].replace("q", "")                            # Remove q from string
                       cleanup = cleanup.replace("VXLAN", "")                           # Remove VXLAN from string
                       final_L2 = (re.findall(r"\b[0-9].*?[0-9]\b", cleanup))           # Grab vlan - bordered by anything [0-9] ending in [0-9]
                       if len(final_L2) == 1:                                           # Since final_2 cariable creates a list, see if the list length == 1
                           vlan = (re.findall(r"\b[0-9]\b", final_L2[0]))               # Find the vlan in final_2 index 0
                           vxlan = (re.findall(r"\b[0-9][0-9].*?[0-9]\b", final_L2[0])) # Find the vxlan in final_2 index 0
                           vlan_vxlan = str(vlan[0] + " " + vxlan[0])                   # Concatinate the two
                           vlan_split = vlan_vxlan.split(" ")                           # Create list of two using split.
                           vlans_array.append(vlan_split[0])                            # Index vlan, store to array
                           vxlan_array.append(vlan_split[1])                            # Index vxlan, store to array
                           vlan_vxlan_array.append(vlan_split)                          # Grab whole list, store to array
                       else:
                           vlans_array.append(final_L2[0])                              # If final_2 len != 1 index vlan, store to array
                           vxlan_array.append(final_L2[1])                              # If final_2 len != 1 index vxlan, store to array
                           vlan_vxlan_array.append(final_L2)                            # Grab whole list, store to array
                    else:
                        pass

                leaf_dict[leaf] = vlan_vxlan_array                                      # Store list in dictionaries. Keys being leaf IPs

                # The following variables will be used for conditional statements by gathering vlans/vxlans in the fabric, not where there are assigned currently. That wil be checked later

                remove_duplicates_vlans = list(dict.fromkeys(vlans_array))              # Clear of duplicates in list. This allows us to have all assigned vlans across the fabric
                remove_duplicates_vxlans = list(dict.fromkeys(vxlan_array))             # Clear of duplicates in list. This allows us to have all assigned vxlans across the fabric

                clear()

                print("\n")
                for k, v in leaf_dict.items():                                          # Iterate through key/value pairs
                    wrong_array = []                                                    # List will be reset every k interation
                    correct_array = []                                                  # List will be reset every k interation
                    for v in v:
                        for vlan, vxlan in zip(remove_duplicates_vlans, remove_duplicates_vxlans): # Iterate through both list we create on line 133, 134
                            if vlan == v[0] and vxlan == v[1]:                                     # Check see if the variables vlan/vxlan are == to values in the dictionary
                                correct_array.append(" Leaf IP: " + k + "    |    VLAN: {:7} |   VXLAN ID: {:15}   |".format(vlan, vxlan)) # Store value if true
                            if vlan == v[0] and vxlan != v[1]:                                     # Check see if the variables vlan is == to value but vxlan is not
                                wrong_array.append(" Leaf IP: " + k + "    |    VLAN: {:7} |   VXLAN ID: {:15}   |".format(v[0], v[1]))    # Store value if false
                            else:
                                pass
                    if len(wrong_array) == 0:               # If list length == to 0, or if mapping are correct store to dictionary
                        correct_dict[k] = correct_array
                    else:                                   # if list > 1 then a mapping wasnt correct, store to dictionary
                        wrong_dict[k] = wrong_array

        for k, v in wrong_dict.items():                     # unpack k, v pairs
            if not v:                                       # If the key has no value, continue at the top of the loop
                continue
            else:
                for string in v:                            # Else, unpack v (string) from v. This is needed because the v is a list of v(vlan, to vxlan mappings
                    vlan_1 = re.search(r'\bVL.*?[0-9]\b', string)               # Grab the first occurnece of and int, whihc would be the vlan
                    print("Fabric VLAN to VXLAN Mapping                                    *Leaf Perspective")
                    print("---------------------------------------------------------------------------------")
                    print(" *" + string)                                        # Print the value stored in wrong array, or incorrect mapping
                    for k, v in correct_dict.items():                           # Next unpack the correct mappings
                        for string_2 in v:                                      # Get the value in the value, or list in the list
                            vlan_2 = re.search(r'\bVL.*?[0-9]\b', string_2)     # Store the value
                            try:
                                if vlan_1.group(0) == vlan_2.group(0):          # Compare the to variables for correct and incorrect
                                    if string == string_2:                      # If they're equal each other, check if the string in each dict == each other.
                                        pass                                    # If they are, dont print since it was printed in the first unpacking
                                    else:
                                        print("  " + string_2)                  # ELSE, print the string
                                else:
                                    pass
                            except AttributeError:
                                pass
                    print("---------------------------------------------------------------------------------")
                    print("\n")

    except (UnboundLocalError,OSError):
        print("Something Went Wrong. Please Verify Connectivity and Credentials\n")
        pass

    stop = input("Program Ended")