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
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
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
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
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
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")
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
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
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
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)))
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)))
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
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
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
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
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
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
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
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
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
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
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
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))
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
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
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
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
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
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)
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
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
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
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
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
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
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
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")
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")
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