def _handleThread(self):
     while not self._deviceQueue.empty():
         try:
             results = []
             device = self._deviceQueue.get_nowait()
             # print('Handling ' + device)
             device_type = self._detect(device)
             if device_type:
                 net_connect = {
                     'device_type': device_type,
                     'host': device,
                     'username': self._username,
                     'password': self._password
                 }
                 if self._global_delay_factor:
                     net_connect[
                         'global_delay_factor'] = self._global_delay_factor
                 connection = ConnectHandler(**net_connect)
                 for command in self._commandList:
                     output = connection.send_command(command)
                     results.append((command, output))
                 connection.disconnect()
                 self._outputQueue.put({
                     'device': device,
                     'results': results,
                     'connected': True
                 })
             else:
                 self._outputQueue.put({
                     'device': device,
                     'results': None,
                     'connected': False
                 })
         except Exception as e:
             self._outputQueue.put({
                 'device': device,
                 'results': None,
                 'connected': False
             })
         finally:
             self._show_progress(self._outputQueue.qsize(),
                                 self._deviceCount)
Ejemplo n.º 2
0
class SSHDetect(object):
    """
    The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
    Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
    all.

    Parameters
    ----------
    *args : list
        The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
    *kwargs : dict
        The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.

    Attributes
    ----------
    connection : netmiko.terminal_server.TerminalServer
        A basic connection to the remote SSH end.
    potential_matches: dict
        Dict of (device_type, accuracy) that is populated through an interaction with the
        remote end.

    Methods
    -------
    autodetect()
        Try to determine the device type.
    """

    def __init__(self, *args, **kwargs):
        """
        Constructor of the SSHDetect class
        """
        if kwargs["device_type"] != "autodetect":
            raise ValueError("The connection device_type must be 'autodetect'")
        self.connection = ConnectHandler(*args, **kwargs)
        # Call the _test_channel_read() in base to clear initial data
        output = BaseConnection._test_channel_read(self.connection)
        self.initial_buffer = output
        self.potential_matches = {}
        self._results_cache = {}

    def autodetect(self):
        """
        Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE

        Returns
        -------
        best_match : str or None
            The device type that is currently the best to use to interact with the device
        """
        for device_type, autodetect_dict in SSH_MAPPER_BASE.items():
            tmp_dict = autodetect_dict.copy()
            call_method = tmp_dict.pop("dispatch")
            autodetect_method = getattr(self, call_method)
            accuracy = autodetect_method(**tmp_dict)
            if accuracy:
                self.potential_matches[device_type] = accuracy
                if accuracy >= 99:  # Stop the loop as we are sure of our match
                    best_match = sorted(self.potential_matches.items(), key=lambda t: t[1],
                                        reverse=True)
                    self.connection.disconnect()
                    return best_match[0][0]

        if not self.potential_matches:
            self.connection.disconnect()
            return None

        best_match = sorted(self.potential_matches.items(), key=lambda t: t[1], reverse=True)
        self.connection.disconnect()
        return best_match[0][0]

    def _send_command(self, cmd=""):
        """
        Handle reading/writing channel directly. It is also sanitizing the output received.

        Parameters
        ----------
        cmd : str, optional
            The command to send to the remote device (default : "", just send a new line)

        Returns
        -------
        output : str
            The output from the command sent
        """
        self.connection.write_channel(cmd + "\n")
        time.sleep(1)
        output = self.connection._read_channel_timing()
        output = self.connection.strip_ansi_escape_codes(output)
        output = self.connection.strip_backspaces(output)
        return output

    def _send_command_wrapper(self, cmd):
        """
        Send command to the remote device with a caching feature to avoid sending the same command
        twice based on the SSH_MAPPER_BASE dict cmd key.

        Parameters
        ----------
        cmd : str
            The command to send to the remote device after checking cache.

        Returns
        -------
        response : str
            The response from the remote device.
        """
        cached_results = self._results_cache.get(cmd)
        if not cached_results:
            response = self._send_command(cmd)
            self._results_cache[cmd] = response
            return response
        else:
            return cached_results

    def _autodetect_std(self, cmd="", search_patterns=None, re_flags=re.I, priority=99):
        """
        Standard method to try to auto-detect the device type. This method will be called for each
        device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
        command and match some regular expression from the ouput for each entry in SSH_MAPPER_BASE
        ('cmd' and 'search_pattern' keys).

        Parameters
        ----------
        cmd : str
            The command to send to the remote device after checking cache.
        search_patterns : list
            A list of regular expression to look for in the command's output (default: None).
        re_flags: re.flags, optional
            Any flags from the python re module to modify the regular expression (default: re.I).
        priority: int, optional
            The confidence the match is right between 0 and 99 (default: 99).
        """
        invalid_responses = [
            r'% Invalid input detected',
            r'syntax error, expecting',
            r'Error: Unrecognized command',
            r'%Error'
        ]
        if not cmd or not search_patterns:
            return 0
        try:
            response = self._send_command_wrapper(cmd)
            # Look for error conditions in output
            for pattern in invalid_responses:
                match = re.search(pattern, response, flags=re.I)
                if match:
                    return 0
            for pattern in search_patterns:
                match = re.search(pattern, response, flags=re_flags)
                if match:
                    return priority
        except Exception:
            return 0
        return 0
Ejemplo n.º 3
0
class SSHDetect(object):
    """
    The SSHDetect class tries to automatically guess the device type running on the SSH remote end.
    Be careful that the kwargs 'device_type' must be set to 'autodetect', otherwise it won't work at
    all.

    Parameters
    ----------
    *args : list
        The same *args that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.
    *kwargs : dict
        The same *kwargs that you might provide to the netmiko.ssh_dispatcher.ConnectHandler.

    Attributes
    ----------
    connection : netmiko.terminal_server.TerminalServerSSH
        A basic connection to the remote SSH end.
    potential_matches: dict
        Dict of (device_type, accuracy) that is populated through an interaction with the
        remote end.

    Methods
    -------
    autodetect()
        Try to determine the device type.
    """
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        """
        Constructor of the SSHDetect class
        """
        if kwargs["device_type"] != "autodetect":
            raise ValueError("The connection device_type must be 'autodetect'")
        # Always set cmd_verify to False for autodetect
        kwargs["global_cmd_verify"] = False
        self.connection = ConnectHandler(*args, **kwargs)
        # Call the _test_channel_read() in base to clear initial data
        output = BaseConnection._test_channel_read(self.connection)
        self.initial_buffer = output
        self.potential_matches: Dict[str, int] = {}
        self._results_cache: Dict[str, str] = {}

    def autodetect(self) -> Union[str, None]:
        """
        Try to guess the best 'device_type' based on patterns defined in SSH_MAPPER_BASE

        Returns
        -------
        best_match : str or None
            The device type that is currently the best to use to interact with the device
        """
        for device_type, autodetect_dict in SSH_MAPPER_BASE:
            tmp_dict = autodetect_dict.copy()
            call_method = tmp_dict.pop("dispatch")
            assert isinstance(call_method, str)
            autodetect_method = getattr(self, call_method)
            accuracy = autodetect_method(**tmp_dict)
            if accuracy:
                self.potential_matches[device_type] = accuracy
                if accuracy >= 99:  # Stop the loop as we are sure of our match
                    best_match = sorted(self.potential_matches.items(),
                                        key=lambda t: t[1],
                                        reverse=True)
                    # WLC needs two different auto-dectect solutions
                    if "cisco_wlc_85" in best_match[0]:
                        best_match[0] = ("cisco_wlc", 99)

                    self.connection.disconnect()
                    return best_match[0][0]

        if not self.potential_matches:
            self.connection.disconnect()
            return None

        best_match = sorted(self.potential_matches.items(),
                            key=lambda t: t[1],
                            reverse=True)
        self.connection.disconnect()
        return best_match[0][0]

    def _send_command(self, cmd: str = "") -> str:
        """
        Handle reading/writing channel directly. It is also sanitizing the output received.

        Parameters
        ----------
        cmd : str, optional
            The command to send to the remote device (default : "", just send a new line)

        Returns
        -------
        output : str
            The output from the command sent
        """
        self.connection.write_channel(cmd + "\n")
        time.sleep(1)
        output = self.connection.read_channel_timing()
        output = self.connection.strip_backspaces(output)
        return output

    def _send_command_wrapper(self, cmd: str) -> str:
        """
        Send command to the remote device with a caching feature to avoid sending the same command
        twice based on the SSH_MAPPER_BASE dict cmd key.

        Parameters
        ----------
        cmd : str
            The command to send to the remote device after checking cache.

        Returns
        -------
        response : str
            The response from the remote device.
        """
        cached_results = self._results_cache.get(cmd)
        if not cached_results:
            response = self._send_command(cmd)
            self._results_cache[cmd] = response
            return response
        else:
            return cached_results

    def _autodetect_remote_version(self,
                                   search_patterns: Optional[List[str]] = None,
                                   re_flags: int = re.IGNORECASE,
                                   priority: int = 99,
                                   **kwargs: Any) -> int:
        """
        Method to try auto-detect the device type, by matching a regular expression on the reported
        remote version of the SSH server.

        Parameters
        ----------
        search_patterns : list
            A list of regular expression to look for in the reported remote SSH version
            (default: None).
        re_flags: re.flags, optional
            Any flags from the python re module to modify the regular expression (default: re.I).
        priority: int, optional
            The confidence the match is right between 0 and 99 (default: 99).
        """
        invalid_responses = [r"^$"]

        if not search_patterns:
            return 0

        try:
            remote_conn = self.connection.remote_conn
            assert isinstance(remote_conn, paramiko.Channel)
            assert remote_conn.transport is not None
            remote_version = remote_conn.transport.remote_version
            for pattern in invalid_responses:
                match = re.search(pattern, remote_version, flags=re.I)
                if match:
                    return 0
            for pattern in search_patterns:
                match = re.search(pattern, remote_version, flags=re_flags)
                if match:
                    return priority
        except Exception:
            return 0
        return 0

    def _autodetect_std(
        self,
        cmd: str = "",
        search_patterns: Optional[List[str]] = None,
        re_flags: int = re.IGNORECASE,
        priority: int = 99,
    ) -> int:
        """
        Standard method to try to auto-detect the device type. This method will be called for each
        device_type present in SSH_MAPPER_BASE dict ('dispatch' key). It will attempt to send a
        command and match some regular expression from the ouput for each entry in SSH_MAPPER_BASE
        ('cmd' and 'search_pattern' keys).

        Parameters
        ----------
        cmd : str
            The command to send to the remote device after checking cache.
        search_patterns : list
            A list of regular expression to look for in the command's output (default: None).
        re_flags: re.flags, optional
            Any flags from the python re module to modify the regular expression (default: re.I).
        priority: int, optional
            The confidence the match is right between 0 and 99 (default: 99).
        """
        invalid_responses = [
            r"% Invalid input detected",
            r"syntax error, expecting",
            r"Error: Unrecognized command",
            r"%Error",
            r"command not found",
            r"Syntax Error: unexpected argument",
            r"% Unrecognized command found at",
        ]
        if not cmd or not search_patterns:
            return 0
        try:
            # _send_command_wrapper will use already cached results if available
            response = self._send_command_wrapper(cmd)
            # Look for error conditions in output
            for pattern in invalid_responses:
                match = re.search(pattern, response, flags=re.I)
                if match:
                    return 0
            for pattern in search_patterns:
                match = re.search(pattern, response, flags=re_flags)
                if match:
                    return priority
        except Exception:
            return 0
        return 0
Ejemplo n.º 4
0
from netmiko.ssh_autodetect import SSHDetect
from netmiko.ssh_dispatcher import ConnectHandler

remote_device = {
    'device_type': 'f5_ltm',
    'host': '172.31.200.211',
    'username': '******',
    'password': '******'
}

#guesser = SSHDetect(**remote_device)
#best_match = guesser.autodetect()

#print("device_type: " + best_match)

#remote_device['device_type'] = best_match
connection = ConnectHandler(**remote_device)

file = open('/root/venv/egw-bigip/file/config.scf', 'w')
string = connection.send_command('show running-config ltm data-group')
file.write(string)

connection.disconnect()
Ejemplo n.º 5
0
def find_mac_address(remote_device, mac_address, results_list):
    """Updates list of interfaces that have learnt the specified MAC address"""
    try:
        # Auto-detect device type & establish correct SSH connection
        best_match = guess_device_type(remote_device)
        if best_match is None:
            return
        else:
            remote_device["device_type"] = best_match
        device = ConnectHandler(**remote_device)
    except NetMikoAuthenticationException:
        print(
            f"Failed to execute CLI on {remote_device['host']} due to incorrect credentials."
        )
        return
    except (NetMikoTimeoutException, SSHException):
        print(
            f"Failed to execute CLI on {remote_device['host']} due to timeout or SSH not enabled."
        )
        return
    except ValueError:
        print(
            f"Unsupported platform {remote_device['host']}, {remote_device['device_type']}."
        )
        return
    else:
        # IOS, IOS XE & NX-OS
        if (best_match == "cisco_ios" or best_match == "cisco_xe"
                or best_match == "cisco_nxos"):
            # Grab MAC address table & extract information
            cli_output = device.send_command(
                f"show mac address-table | include {mac_address}")
            if cli_output is None or len(cli_output) == 0:
                device.disconnect()
                return
            cli_output = cli_output.split("\n")
            # Iterate through results
            for cli_line in cli_output:
                cli_items = cli_line.split()
                # Skip empty result lines
                if not cli_items:
                    continue
                cli_output2 = device.send_command(
                    f"show interface {cli_items[-1]}")
                int_description = re.search(r"Description: (.+)", cli_output2)
                int_description = (int_description.group(1).rstrip()
                                   if int_description else "")
                if best_match == "cisco_nxos":
                    results_list.append([
                        remote_device["host"],
                        cli_items[-1],
                        int_description,
                        cli_items[1],
                    ])
                else:
                    results_list.append([
                        remote_device["host"],
                        cli_items[-1],
                        int_description,
                        cli_items[0],
                    ])
            device.disconnect()

        # JunOS
        elif best_match == "juniper" or best_match == "juniper_junos":
            # Switch MAC address format from aaaa.bbbb.cccc to aa:aa:bb:bb:cc:cc
            junos_mac_address = mac_address
            for digit in junos_mac_address:
                if digit in ".:-":
                    junos_mac_address = junos_mac_address.replace(digit, "")
            junos_mac_address = (
                f"{junos_mac_address[0:2]}:{junos_mac_address[2:4]}:{junos_mac_address[4:6]}"
                f":{junos_mac_address[6:8]}:{junos_mac_address[8:10]}:{junos_mac_address[10:12]}"
            )
            # Grab MAC address table & extract information
            cli_output = device.send_command(
                f"show ethernet-switching table brief | match {junos_mac_address}"
            )
            if cli_output is None or len(cli_output) <= 1:
                device.disconnect()
                return
            cli_output = cli_output.split("\n")
            # Iterate through results
            for cli_line in cli_output:
                # Skip empty result lines
                if cli_line is None or len(cli_line) <= 1:
                    continue
                cli_items = cli_line.split()
                if not cli_items:
                    continue
                int_name = re.search(r"(\w.+)\.\d+", cli_items[-1])
                if int_name:
                    int_name = int_name.group(1)
                    cli_output2 = device.send_command(
                        f"show interfaces {int_name}")
                    int_description = re.search(r"Description: (.+)",
                                                cli_output2)
                    int_description = (int_description.group(1).rstrip()
                                       if int_description else "")
                else:
                    continue
                results_list.append([
                    remote_device["host"],
                    cli_items[-1],
                    int_description,
                    cli_items[0],
                ])
            device.disconnect()

        # Arista EOS
        elif best_match == "arista_eos":
            # Grab MAC address table & extract information
            cli_output = device.send_command(
                f"show mac address-table | include {mac_address}")
            if cli_output is None or len(cli_output) == 0:
                device.disconnect()
                return
            cli_output = cli_output.split("\n")
            # Iterate through results
            for cli_line in cli_output:
                cli_items = cli_line.split()
                # Skip empty result lines
                if not cli_items:
                    continue
                cli_output2 = device.send_command(
                    f"show interfaces {cli_items[3]}")
                int_description = re.search(r"Description: (.+)", cli_output2)
                int_description = (int_description.group(1).rstrip()
                                   if int_description else "")
                results_list.append([
                    remote_device["host"], cli_items[3], int_description,
                    cli_items[0]
                ])
            device.disconnect()

        # Unsupported, disconnect
        else:
            device.disconnect()
Ejemplo n.º 6
0
    'ip': '10.108.16.104',
    'username': '******',
    'password': '******',
#	'global_delay_factor':2
}

print("Connecting %s" % jumpserver)

net_connect = ConnectHandler(**jumpserver)
print(net_connect.find_prompt())

filewrite = open("output1.txt", "a")

file_obj = open("officeDevice.txt", "r")
for line in file_obj:
    print("Connecting ***** %s" % line)
    net_connect.write_channel("mtrad " + line)
    time.sleep(1)
    net_connect.read_channel()

    redispatch(net_connect, device_type='cisco_ios_telnet')
    output = net_connect.send_command("show version | i IOS")
    output = net_connect.send_command("show mod | i 10GE")
    print(output)
    net_connect.send_command("exit", expect_string="mobboss2")
    filewrite.write("\n \n" + line + "\n")
    filewrite.write("-------------------------- \n")
    filewrite.write(output)

net_connect.disconnect()
filewrite.close()