Beispiel #1
0
    def _read_channel_timing_or_error(self,
                                      pattern="",
                                      delay_factor=1,
                                      max_loops=150):
        """Read data on the channel based on timing delays.

			Attempt to read channel max_loops number of times. If no data this will cause a 15 second
			delay.

			Once data is encountered read channel for another two seconds (2 * delay_factor) to make
			sure reading of channel is complete.

			:param pattern: the pattern used to identify an error interrupted the read pattern so that \
				quicker resolution can be made before the timeout, preventing long Socket Errors.
			:type pattern: regular expression string

			:param delay_factor: multiplicative factor to adjust delay when reading channel (delays
				get multiplied by this factor)
			:type delay_factor: int or float

			:param max_loops: maximum number of loops to iterate through before returning channel data.
				Will default to be based upon self.timeout.
			:type max_loops: int
			"""
        # Time to delay in each read loop
        loop_delay = 0.1
        final_delay = 2

        # Default to making loop time be roughly equivalent to self.timeout (support old max_loops
        # and delay_factor arguments for backwards compatibility).
        delay_factor = self.select_delay_factor(delay_factor)
        pattern = pattern
        if delay_factor == 1 and max_loops == 150:
            max_loops = int(self.timeout / loop_delay)

        channel_data = ""
        i = 0
        while i <= max_loops:
            time.sleep(loop_delay * delay_factor)
            new_data = self.read_channel()
            if new_data:
                channel_data += new_data
                if pattern in channel_data:
                    log.debug(channel_data)
                    raise ValueError(
                        f"Error pattern in Read_Channel: '{pattern}'")
            else:
                # Safeguard to make sure really done
                time.sleep(final_delay * delay_factor)
                new_data = self.read_channel()
                if not new_data:
                    break
                else:
                    channel_data += new_data
                    if pattern in channel_data:
                        log.debug(channel_data)
                        raise ValueError(
                            f"Error pattern in Read_Channel: '{pattern}'")
            i += 1
        return channel_data
Beispiel #2
0
    def send_config_set(
        self,
        config_commands=None,
        exit_config_mode=False,
        delay_factor=1,
        max_loops=150,
        strip_prompt=False,
        strip_command=False,
        config_mode_command=None,
    ):
        delay_factor = self.select_delay_factor(delay_factor)
        if config_commands is None:
            return ""
        elif isinstance(config_commands, string_types):
            config_commands = (config_commands,)

        if not hasattr(config_commands, "__iter__"):
            raise ValueError("Invalid argument passed into send_config_set")

        # Send config commands
        output = ""
        for cmd in config_commands:
            output += self.send_command(cmd)
            if self.fast_cli:
                pass
            else:
                time.sleep(delay_factor * 0.05)

        output = self._sanitize_output(output)
        log.debug("{}".format(output))
        return output
Beispiel #3
0
    def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1,
                        max_loops=150, strip_prompt=False, strip_command=False):
        """
        Send configuration commands down the SSH channel.

        config_commands is an iterable containing all of the configuration commands.
        The commands will be executed one after the other.

        Does not automatically exit/enter configuration mode.
        """
        delay_factor = self.select_delay_factor(delay_factor)
        if config_commands is None:
            return ''
        elif isinstance(config_commands, string_types):
            config_commands = (config_commands,)

        if not hasattr(config_commands, '__iter__'):
            raise ValueError("Invalid argument passed into send_config_set")

        # Send config commands
        for cmd in config_commands:
            self.write_channel(self.normalize_cmd(cmd))
            time.sleep(delay_factor * .5)

        # Gather output
        output = self._read_channel_timing(delay_factor=delay_factor, max_loops=max_loops)
        output = self._sanitize_output(output)
        log.debug("{0}".format(output))
        return output
Beispiel #4
0
 def is_alive(self):
     """Returns a boolean flag with the state of the connection."""
     null = chr(0)
     if self.remote_conn is None:
         log.error("Connection is not initialised, is_alive returns False")
         return False
     if self.protocol == 'telnet':
         try:
             # Try sending IAC + NOP (IAC is telnet way of sending command
             # IAC = Interpret as Command (it comes before the NOP)
             log.debug("Sending IAC + NOP")
             self.device.write_channel(telnetlib.IAC + telnetlib.NOP)
             return True
         except AttributeError:
             return False
     else:
         # SSH
         try:
             # Try sending ASCII null byte to maintain the connection alive
             log.debug("Sending the NULL byte")
             self.write_channel(null)
             return self.remote_conn.transport.is_active()
         except (socket.error, EOFError):
             log.error("Unable to send", exc_info=True)
             # If unable to send, we can tell for sure that the connection is unusable
             return False
     return False
Beispiel #5
0
    def send_config_set(self,
                        config_commands=None,
                        exit_config_mode=True,
                        delay_factor=1,
                        max_loops=150,
                        strip_prompt=False,
                        strip_command=False):
        """
        Send configuration commands down the SSH channel.

        config_commands is an iterable containing all of the configuration commands.
        The commands will be executed one after the other.

        Does not automatically exit/enter configuration mode.
        """
        delay_factor = self.select_delay_factor(delay_factor)
        if config_commands is None:
            return ''
        elif isinstance(config_commands, string_types):
            config_commands = (config_commands, )

        if not hasattr(config_commands, '__iter__'):
            raise ValueError("Invalid argument passed into send_config_set")

        # Send config commands
        for cmd in config_commands:
            self.write_channel(self.normalize_cmd(cmd))
            time.sleep(delay_factor * .5)

        # Gather output
        output = self._read_channel_timing(delay_factor=delay_factor,
                                           max_loops=max_loops)
        output = self._sanitize_output(output)
        log.debug("{0}".format(output))
        return output
Beispiel #6
0
    def disable_paging(self,
                       disable_window_config=[
                           "config system", "cli-settings", "window-height 0",
                           "exit"
                       ],
                       delay_factor=.5):
        """This is designed to disable window paging which prevents paged command 
		output from breaking the script.
		
		:param disable_window_config: Command, or list of commands, to execute.
		:type disable_window_config: str
		
		:param delay_factor: See __init__: global_delay_factor
		:type delay_factor: int
		
		"""
        self.enable()
        delay_factor = self.select_delay_factor(delay_factor)
        time.sleep(delay_factor * 0.1)
        self.clear_buffer()
        disable_window_config = disable_window_config
        log.debug("In disable_paging")
        self.send_config_set(disable_window_config, True, .25, 150, False,
                             False, None, False, False)
        log.debug("Exiting disable_paging")
Beispiel #7
0
    def set_base_prompt(
        self,
        pri_prompt_terminator: str = ">",
        alt_prompt_terminator: str = "]",
        delay_factor: float = 1.0,
        pattern: Optional[str] = None,
    ) -> str:
        """
        Sets self.base_prompt

        Used as delimiter for stripping of trailing prompt in output.

        Should be set to something that is general and applies in multiple contexts.
        For Huawei this will be the router prompt with < > or [ ] stripped off.

        This will be set on logging in, but not when entering system-view
        """

        prompt = super().set_base_prompt(
            pri_prompt_terminator=pri_prompt_terminator,
            alt_prompt_terminator=alt_prompt_terminator,
            delay_factor=delay_factor,
            pattern=pattern,
        )

        # Strip off any leading HRP_. characters for USGv5 HA
        prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)

        # Strip off leading terminator
        prompt = prompt[1:]
        prompt = prompt.strip()
        self.base_prompt = prompt
        log.debug(f"prompt: {self.base_prompt}")
        return self.base_prompt
Beispiel #8
0
 def check_config_mode(self, check_string='', pattern=''):
     """Checks if the device is in configuration mode or not."""
     log.debug("pattern: {0}".format(pattern))
     self.write_channel('\n')
     output = self.read_until_pattern(pattern=pattern)
     log.debug("check_config_mode: {0}".format(repr(output)))
     return check_string in output
Beispiel #9
0
    def exit_config_mode(self,
                         exit_config: str = "exit",
                         pattern: str = r"#") -> str:
        """
        Exit config mode.

        Like the Mellanox equipment, the TP-Link Jetstream does not
        support a single command to completely exit the configuration mode.

        Consequently, need to keep checking and sending "exit".
        """
        output = ""
        check_count = 12
        while check_count >= 0:
            if self.check_config_mode():
                self.write_channel(self.normalize_cmd(exit_config))
                output += self.read_until_pattern(pattern=pattern)
            else:
                break
            check_count -= 1

        if self.check_config_mode():
            raise ValueError("Failed to exit configuration mode")
            log.debug(f"exit_config_mode: {output}")

        return output
Beispiel #10
0
 def write_channel(self, out_data):
     """Generic handler that will write to both SSH and telnet channel."""
     if self.protocol == 'ssh':
         self.remote_conn.sendall(write_bytes(out_data))
     elif self.protocol == 'telnet':
         self.remote_conn.write(write_bytes(out_data))
     else:
         raise ValueError("Invalid protocol specified")
     log.debug("write_channel: {}".format(write_bytes(out_data)))
Beispiel #11
0
 def _write_channel(self, out_data):
     """Generic handler that will write to both SSH and telnet channel."""
     if self.protocol == 'ssh':
         self.remote_conn.sendall(write_bytes(out_data))
     elif self.protocol == 'telnet':
         self.remote_conn.write(write_bytes(out_data))
     else:
         raise ValueError("Invalid protocol specified")
     log.debug("write_channel: {}".format(write_bytes(out_data)))
Beispiel #12
0
 def exit_config_mode(self, exit_config='exit', pattern='#'):
     """Exit from configuration mode."""
     output = ''
     if self.check_config_mode():
         self.write_channel(self.normalize_cmd(exit_config))
         output = self.read_until_pattern(pattern=pattern)
         if self.check_config_mode():
             raise ValueError("Failed to exit configuration mode")
     log.debug("exit_config_mode: {0}".format(output))
     return output
Beispiel #13
0
 def disable_paging(self, delay_factor=1, **kwargs):
     """Disable paging is only available with specific roles so it may fail."""
     disable_paging_commands = [
         "config global", "config system console", "set output standard",
         "end", "end"
     ]
     output = self.send_config_set(disable_paging_commands, True, .25, 150,
                                   False, False, None, False, False)
     log.debug("***Window Paging Disabled***")
     return output
Beispiel #14
0
 def exit_config_mode(self, exit_config='', pattern=''):
     """Exit from configuration mode."""
     output = ''
     if self.check_config_mode():
         self.write_channel(self.normalize_cmd(exit_config))
         output = self.read_until_pattern(pattern=pattern)
         if self.check_config_mode():
             raise ValueError("Failed to exit configuration mode")
     log.debug("exit_config_mode: {0}".format(output))
     return output
Beispiel #15
0
    def _read_channel_expect(self, pattern='', re_flags=0, max_loops=None):
        """
        Function that reads channel until pattern is detected.

        pattern takes a regular expression.

        By default pattern will be self.base_prompt

        Note: this currently reads beyond pattern. In the case of SSH it reads MAX_BUFFER.
        In the case of telnet it reads all non-blocking data.

        There are dependencies here like determining whether in config_mode that are actually
        depending on reading beyond pattern.
        """
        debug = False
        output = ''
        if not pattern:
            pattern = re.escape(self.base_prompt)
        if debug:
            print("Pattern is: {}".format(pattern))

        # Will loop for self.timeout time (override with max_loops argument)
        i = 1
        loop_delay = .1
        if not max_loops:
            max_loops = self.timeout / loop_delay
        while i < max_loops:
            if self.protocol == 'ssh':
                try:
                    # If no data available will wait timeout seconds trying to read
                    self._lock_netmiko_session()
                    new_data = self.remote_conn.recv(MAX_BUFFER)
                    if len(new_data) == 0:
                        raise EOFError(
                            "Channel stream closed by remote device.")
                    new_data = new_data.decode('utf-8', 'ignore')
                    log.debug(
                        "_read_channel_expect read_data: {}".format(new_data))
                    output += new_data
                except socket.timeout:
                    raise NetMikoTimeoutException(
                        "Timed-out reading channel, data not available.")
                finally:
                    self._unlock_netmiko_session()
            elif self.protocol == 'telnet':
                output += self.read_channel()
            if re.search(pattern, output, flags=re_flags):
                if debug:
                    print("Pattern found: {} {}".format(pattern, output))
                return output
            time.sleep(loop_delay * self.global_delay_factor)
            i += 1
        raise NetMikoTimeoutException(
            "Timed-out reading channel, pattern not found in output: {}".
            format(pattern))
 def enable(self, cmd='enable', pattern='password', re_flags=re.IGNORECASE,
            default_username='******'):
     """Enter enable mode"""
     output = self.send_command_timing(cmd)
     if 'username' in output.lower():
         output += self.send_command_timing(default_username)
     if 'password' in output.lower():
         output += self.send_command_timing(self.secret)
     log.debug("{0}".format(output))
     self.clear_buffer()
     return output
Beispiel #17
0
 def enable(self, cmd='enable', pattern='password', re_flags=re.IGNORECASE,
            default_username='******'):
     """Enter enable mode"""
     output = self.send_command_timing(cmd)
     if 'username' in output.lower():
         output += self.send_command_timing(default_username)
     if 'password' in output.lower():
         output += self.send_command_timing(self.secret)
     log.debug("{0}".format(output))
     self.clear_buffer()
     return output
Beispiel #18
0
    def find_prompt(self, delay_factor=1):
        """Finds the current network device prompt, last line only.

		:param delay_factor: See __init__: global_delay_factor
		:type delay_factor: int
		"""
        delay_factor = self.select_delay_factor(delay_factor)
        self.clear_buffer()
        self.write_channel(self.RETURN)
        sleep_time = delay_factor * 0.1
        time.sleep(sleep_time)

        # Created parent loop to counter wrong prompts due to spamming alarm logs into terminal.
        max_loops = 20
        loops = 0
        prompt = ""
        while loops <= max_loops:
            # Initial attempt to get prompt
            prompt = self.read_channel().strip()

            # Check if the only thing you received was a newline
            count = 0
            while count <= 12 and not prompt:
                prompt = self.read_channel().strip()
                if not prompt:
                    self.write_channel(self.RETURN)
                    time.sleep(sleep_time)
                    if sleep_time <= 3:
                        # Double the sleep_time when it is small
                        sleep_time *= 2
                    else:
                        sleep_time += 1
                count += 1

            # If multiple lines in the output take the last line
            prompt = self.normalize_linefeeds(prompt)
            prompt = prompt.split(self.RESPONSE_RETURN)[-1]
            prompt = prompt.strip()

            # This verifies a valid prompt has been found before proceeding.
            if loops == 20:
                raise ValueError(f"Unable to find prompt: {prompt}")
            elif "/>" in prompt:
                break
            self.write_channel(self.RETURN)
            loops += 1
            time.sleep(1)

        if not prompt:
            raise ValueError(f"Unable to find prompt: {prompt}")
        time.sleep(delay_factor * 0.1)
        self.clear_buffer()
        log.debug(f"[find_prompt()]: prompt is {prompt}")
        return prompt
Beispiel #19
0
 def _read_channel(self):
     """Generic handler that will read all the data from an SSH or telnet channel."""
     if self.protocol == 'ssh':
         output = ""
         while True:
             if self.remote_conn.recv_ready():
                 output += self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
             else:
                 break
     elif self.protocol == 'telnet':
         output = self.remote_conn.read_very_eager().decode('utf-8', 'ignore')
     log.debug("read_channel: {}".format(output))
     return output
Beispiel #20
0
 def read_channel(self):
     """Generic handler that will read all the data from an SSH or telnet channel."""
     if self.protocol == 'ssh':
         output = ""
         while True:
             if self.remote_conn.recv_ready():
                 output += self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
             else:
                 break
     elif self.protocol == 'telnet':
         output = self.remote_conn.read_very_eager().decode('utf-8', 'ignore')
     log.debug("read_channel: {}".format(output))
     return output
Beispiel #21
0
 def _write_channel(self, out_data):
     """Generic handler that will write to both SSH and telnet channel."""
     if self.protocol == 'ssh':
         self.remote_conn.sendall(write_bytes(out_data))
     elif self.protocol == 'telnet':
         self.remote_conn.write(write_bytes(out_data))
     else:
         raise ValueError("Invalid protocol specified")
     try:
         log.debug("write_channel: {}".format(write_bytes(out_data)))
     except UnicodeDecodeError:
         # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
         pass
Beispiel #22
0
    def enable(
        self,
        cmd: str = "enable",
        pattern: str = "password",
        enable_pattern: Optional[str] = None,
        re_flags: int = re.IGNORECASE,
        default_username: str = "manager",
    ) -> str:
        """Enter enable mode"""

        if self.check_enable_mode():
            return ""

        output = ""
        username_pattern = r"(username|login|user name)"
        pwd_pattern = pattern
        prompt_pattern = r"[>#]"
        full_pattern = rf"(username|login|user name|{pwd_pattern}|{prompt_pattern})"

        # Send the enable command
        self.write_channel(cmd + self.RETURN)
        new_output = self.read_until_pattern(full_pattern,
                                             read_timeout=15,
                                             re_flags=re_flags)

        # Send the username
        if re.search(username_pattern, new_output, flags=re_flags):
            output += new_output
            self.write_channel(default_username + self.RETURN)
            full_pattern = rf"{pwd_pattern}|{prompt_pattern})"
            new_output = self.read_until_pattern(full_pattern,
                                                 read_timeout=15,
                                                 re_flags=re_flags)

        # Send the password
        if re.search(pwd_pattern, new_output, flags=re_flags):
            output += new_output
            self.write_channel(self.secret + self.RETURN)
            new_output = self.read_until_pattern(prompt_pattern,
                                                 read_timeout=15,
                                                 re_flags=re_flags)

        output += new_output
        log.debug(f"{output}")
        self.clear_buffer()
        msg = ("Failed to enter enable mode. Please ensure you pass "
               "the 'secret' argument to ConnectHandler.")
        if not self.check_enable_mode():
            raise ValueError(msg)
        return output
Beispiel #23
0
    def exit_config_mode(self, exit_config="..", pattern="/>"):
        """Exit from configuration mode.

		:param exit_config: Command to exit configuration mode
		:type exit_config: str

		:param pattern: Pattern to terminate reading of channel
		:type pattern: str
		"""
        output = ""
        if self.check_config_mode():
            self.write_channel(self.normalize_cmd(exit_config))
            output = self.read_until_pattern(pattern=pattern)
            if self.check_config_mode():
                raise ValueError("Failed to exit configuration mode")
        log.debug("exit_config_mode: {}".format(output))
        return output
Beispiel #24
0
    def _read_channel_expect(self, pattern='', re_flags=0):
        """
        Function that reads channel until pattern is detected.

        pattern takes a regular expression.

        By default pattern will be self.base_prompt

        Note: this currently reads beyond pattern. In the case of SSH it reads MAX_BUFFER.
        In the case of telnet it reads all non-blocking data.

        There are dependecies here like determining whether in config_mode that are actually
        depending on reading beyond pattern.
        """
        debug = False
        output = ''
        if not pattern:
            pattern = self.base_prompt
        pattern = re.escape(pattern)
        if debug:
            print("Pattern is: {}".format(pattern))

        # Will loop for self.timeout time (unless modified by global_delay_factor)
        i = 1
        loop_delay = .1
        max_loops = self.timeout / loop_delay
        while i < max_loops:
            if self.protocol == 'ssh':
                try:
                    # If no data available will wait timeout seconds trying to read
                    new_data = self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
                    log.debug("_read_channel_expect read_data: {}".format(new_data))
                    output += new_data
                except socket.timeout:
                    raise NetMikoTimeoutException("Timed-out reading channel, data not available.")
            elif self.protocol == 'telnet':
                output += self.read_channel()
            if re.search(pattern, output, flags=re_flags):
                if debug:
                    print("Pattern found: {} {}".format(pattern, output))
                return output
            time.sleep(loop_delay * self.global_delay_factor)
            i += 1
        raise NetMikoTimeoutException("Timed-out reading channel, pattern not found in output: {}"
                                      .format(pattern))
Beispiel #25
0
 def _read_channel(self):
     """Generic handler that will read all the data from an SSH or telnet channel."""
     if self.protocol == 'ssh':
         output = ""
         while True:
             if self.remote_conn.recv_ready():
                 outbuf = self.remote_conn.recv(MAX_BUFFER)
                 if len(outbuf) == 0:
                     raise EOFError(
                         "Channel stream closed by remote device.")
                 output += outbuf.decode('utf-8', 'ignore')
             else:
                 break
     elif self.protocol == 'telnet':
         output = self.remote_conn.read_very_eager().decode(
             'utf-8', 'ignore')
     log.debug("read_channel: {}".format(output))
     return output
Beispiel #26
0
    def set_terminal_width(self, command="", delay_factor=1):
        """
        CLI terminals try to automatically adjust the line based on the width of the terminal.
        This causes the output to get distorted when accessed programmatically.

        Set terminal width to 511 which works on a broad set of devices.
        """
        if not command:
            return ""
        delay_factor = self.select_delay_factor(delay_factor)
        command = self.normalize_cmd(command)
        self.write_channel(command)
        output = self.read_until_prompt()
        if self.ansi_escape_codes:
            output = self.strip_ansi_escape_codes(output)
        log.debug("{0}".format(output))
        log.debug("Exiting set_terminal_width")
        return output
Beispiel #27
0
 def enable(
     self,
     cmd="enable",
     pattern="password",
     re_flags=re.IGNORECASE,
     default_username="******",
 ):
     """Enter enable mode"""
     if self.check_enable_mode():
         return ""
     output = self.send_command_timing(cmd)
     if ("username" in output.lower() or "login name" in output.lower()
             or "user name" in output.lower()):
         output += self.send_command_timing(default_username)
     if "password" in output.lower():
         output += self.send_command_timing(self.secret)
     log.debug("{}".format(output))
     self.clear_buffer()
     return output
Beispiel #28
0
    def _write_channel(self, out_data):
        """Generic handler that will write to both SSH and telnet channel.

        :param out_data: data to be written to the channel
        :type out_data: str (can be either unicode/byte string)
        """
        if self.protocol == 'ssh':
            self.remote_conn.sendall(write_bytes(out_data))
        elif self.protocol == 'telnet':
            self.remote_conn.write(write_bytes(out_data))
        elif self.protocol == 'serial':
            self.remote_conn.write(write_bytes(out_data))
            self.remote_conn.flush()
        else:
            raise ValueError("Invalid protocol specified")
        try:
            log.debug("write_channel: {}".format(write_bytes(out_data)))
        except UnicodeDecodeError:
            # Don't log non-ASCII characters; this is null characters and telnet IAC (PY2)
            pass
Beispiel #29
0
    def set_base_prompt(self,
                        pri_prompt_terminator=">",
                        alt_prompt_terminator="]",
                        delay_factor=1):
        """
        Sets self.base_prompt

        Used as delimiter for stripping of trailing prompt in output.

        Should be set to something that is general and applies in multiple contexts. For Comware
        this will be the router prompt with < > or [ ] stripped off.

        This will be set on logging in, but not when entering system-view
        """
        log.debug("In set_base_prompt")
        delay_factor = self.select_delay_factor(delay_factor)
        self.clear_buffer()
        self.write_channel(self.RETURN)
        time.sleep(0.5 * delay_factor)

        prompt = self.read_channel()
        prompt = self.normalize_linefeeds(prompt)

        # If multiple lines in the output take the last line
        prompt = prompt.split(self.RESPONSE_RETURN)[-1]
        prompt = prompt.strip()

        # Check that ends with a valid terminator character
        if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
            raise ValueError("Router prompt not found: {0}".format(prompt))

        # Strip off any leading HRP_. characters for USGv5 HA
        prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)

        # Strip off leading and trailing terminator
        prompt = prompt[1:-1]
        prompt = prompt.strip()
        self.base_prompt = prompt
        log.debug("prompt: {0}".format(self.base_prompt))

        return self.base_prompt
Beispiel #30
0
 def cleanup(self, command="quit"):
     """Re-enable paging globally."""
     # Return paging state
     enable_paging_commands = [
         "config global", "config system console", "set output more", "end",
         "end"
     ]
     # Should test output is valid
     output = self.send_config_set(enable_paging_commands, True, .25, 150,
                                   False, False, None, False, False)
     log.debug("***Window Paging Enabled***")
     """Gracefully exit the SSH session."""
     try:
         # The pattern="" forces use of send_command_timing
         if self.check_config_mode(pattern=""):
             self.exit_config_mode()
     except Exception:
         pass
     # Always try to send final 'exit' (command)
     self._session_log_fin = True
     self.write_channel(command + self.RETURN)
Beispiel #31
0
    def exit_config_mode(self, exit_config="exit", pattern="#"):
        """Mellanox does not support a single command to completely exit configuration mode.

        Consequently, need to keep checking and sending "exit".
        """
        output = ""
        check_count = 12
        while check_count >= 0:
            if self.check_config_mode():
                self.write_channel(self.normalize_cmd(exit_config))
                output += self.read_until_pattern(pattern=pattern)
            else:
                break
            check_count -= 1

        # One last check for whether we successfully exited config mode
        if self.check_config_mode():
            raise ValueError("Failed to exit configuration mode")

        log.debug(f"exit_config_mode: {output}")
        return output
Beispiel #32
0
    def exit_config_mode(self, exit_config="end", pattern1="#", pattern2="$"):
        """Exit from configuration mode.
		:param exit_config: Command to exit configuration mode
		:type exit_config: str
		:param pattern: Pattern to terminate reading of channel
		:type pattern: str
		"""
        output = ""
        if pattern1:
            combined_pattern = pattern1
        if pattern2:
            combined_pattern = r"({}|{})".format(pattern1, pattern2)

        if self.check_config_mode():
            self.write_channel(self.normalize_cmd(exit_config))
            output = self.read_until_pattern(pattern=combined_pattern,
                                             re_flags=0)
            if self.check_config_mode():
                raise ValueError("Failed to exit configuration mode")
        log.debug("exit_config_mode: {}".format(output))
        return output
Beispiel #33
0
    def set_base_prompt(
        self, pri_prompt_terminator=">", alt_prompt_terminator="]", delay_factor=1
    ):
        """
        Sets self.base_prompt

        Used as delimiter for stripping of trailing prompt in output.

        Should be set to something that is general and applies in multiple contexts. For Comware
        this will be the router prompt with < > or [ ] stripped off.

        This will be set on logging in, but not when entering system-view
        """
        log.debug("In set_base_prompt")
        delay_factor = self.select_delay_factor(delay_factor)
        self.clear_buffer()
        self.write_channel(self.RETURN)
        time.sleep(0.5 * delay_factor)

        prompt = self.read_channel()
        prompt = self.normalize_linefeeds(prompt)

        # If multiple lines in the output take the last line
        prompt = prompt.split(self.RESPONSE_RETURN)[-1]
        prompt = prompt.strip()

        # Check that ends with a valid terminator character
        if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
            raise ValueError("Router prompt not found: {0}".format(prompt))

        # Strip off any leading HRP_. characters for USGv5 HA
        prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)

        # Strip off leading and trailing terminator
        prompt = prompt[1:-1]
        prompt = prompt.strip()
        self.base_prompt = prompt
        log.debug("prompt: {0}".format(self.base_prompt))

        return self.base_prompt
Beispiel #34
0
    def enable(
        self,
        cmd="enable",
        pattern="password",
        re_flags=re.IGNORECASE,
        default_username="******",
    ):
        """Enter enable mode"""
        delay_factor = self.select_delay_factor(delay_factor=0)
        if self.check_enable_mode():
            return ""

        output = ""
        i = 1
        max_attempts = 5
        while i <= max_attempts:
            self.write_channel(cmd + self.RETURN)
            time.sleep(0.3 * delay_factor)
            new_output = self.read_channel()
            username_pattern = r"(username|login|user name)"
            if re.search(username_pattern, new_output, flags=re_flags):
                output += new_output
                new_output = self.send_command_timing(default_username)
            if re.search(pattern, new_output, flags=re_flags):
                output += new_output
                self.write_channel(self.normalize_cmd(self.secret))
                new_output = self._read_channel_timing()
                if self.check_enable_mode():
                    output += new_output
                    return output
            output += new_output
            i += 1

        log.debug(f"{output}")
        self.clear_buffer()
        msg = ("Failed to enter enable mode. Please ensure you pass "
               "the 'secret' argument to ConnectHandler.")
        if not self.check_enable_mode():
            raise ValueError(msg)
        return output
Beispiel #35
0
 def enable(
     self,
     cmd="enable",
     pattern="password",
     re_flags=re.IGNORECASE,
     default_username="******",
 ):
     """Enter enable mode"""
     if self.check_enable_mode():
         return ""
     output = self.send_command_timing(cmd)
     if (
         "username" in output.lower()
         or "login name" in output.lower()
         or "user name" in output.lower()
     ):
         output += self.send_command_timing(default_username)
     if "password" in output.lower():
         output += self.send_command_timing(self.secret)
     log.debug("{}".format(output))
     self.clear_buffer()
     return output
Beispiel #36
0
 def disable_paging(self, command="terminal length 999", delay_factor=1):
     """Disable paging default to a Cisco CLI method."""
     delay_factor = self.select_delay_factor(delay_factor)
     time.sleep(delay_factor * .1)
     self.clear_buffer()
     command = self.normalize_cmd(command)
     log.debug("In disable_paging")
     log.debug("Command: {0}".format(command))
     self.write_channel(command)
     output = self.read_until_prompt()
     if self.ansi_escape_codes:
         output = self.strip_ansi_escape_codes(output)
     log.debug("{0}".format(output))
     log.debug("Exiting disable_paging")
     return output
Beispiel #37
0
 def disable_paging(self, command="terminal length 0", delay_factor=1):
     """Disable paging default to a Cisco CLI method."""
     delay_factor = self.select_delay_factor(delay_factor)
     time.sleep(delay_factor * .1)
     self.clear_buffer()
     command = self.normalize_cmd(command)
     log.debug("In disable_paging")
     log.debug("Command: {0}".format(command))
     self.write_channel(command)
     output = self.read_until_prompt()
     if self.ansi_escape_codes:
         output = self.strip_ansi_escape_codes(output)
     log.debug("{0}".format(output))
     log.debug("Exiting disable_paging")
     return output
Beispiel #38
0
 def _disable_smart_interaction(self, command="undo smart", delay_factor=1):
     """Disables the { <cr> } prompt to avoid having to sent a 2nd return after each command"""
     delay_factor = self.select_delay_factor(delay_factor)
     time.sleep(delay_factor * 0.1)
     self.clear_buffer()
     command = self.normalize_cmd(command)
     log.debug("In disable_smart_interaction")
     log.debug(f"Command: {command}")
     self.write_channel(command)
     if self.global_cmd_verify is not False:
         output = self.read_until_pattern(
             pattern=re.escape(command.strip()))
     else:
         output = self.read_until_prompt()
     log.debug(f"{output}")
     log.debug("Exiting disable_smart_interaction")
Beispiel #39
0
    def _enable_paging(self,
                       enable_window_config=[
                           "config system", "cli-settings",
                           "window-height automatic", "exit"
                       ],
                       delay_factor=.5):
        """This is designed to reenable window paging.
		
		:param enable_window_config: Command, or list of commands, to execute.
		:type enable_window_config: str
		
		:param delay_factor: See __init__: global_delay_factor
		:type delay_factor: int
		
		"""
        self.enable()
        delay_factor = self.select_delay_factor(delay_factor)
        time.sleep(delay_factor * 0.1)
        self.clear_buffer()
        enable_window_config = enable_window_config
        log.debug("In _enable_paging")
        self.send_config_set(enable_window_config, True, .25, 150, False,
                             False, None, False, False)
        log.debug("Exiting _enable_paging")
Beispiel #40
0
    def check_config_mode(self, check_string=')#', pattern=''):
        """
        Checks if the device is in configuration mode or not.

        Arista, unfortunately, does this:
        loc1-core01(s1)#

        Can also be (s2)
        """
        log.debug("pattern: {0}".format(pattern))
        self.write_channel('\n')
        output = self.read_until_pattern(pattern=pattern)
        log.debug("check_config_mode: {0}".format(repr(output)))
        output = output.replace("(s1)", "")
        output = output.replace("(s2)", "")
        log.debug("check_config_mode: {0}".format(repr(output)))
        return check_string in output