def connect(self, driver): """Connect using the SSH protocol specific FSM.""" # 0 1 2 events = [driver.password_re, self.device.prompt_re, driver.unable_to_connect_re, # 3 4 5 6 7 NEWSSHKEY, KNOWN_HOSTS, HOST_KEY_FAILED, MODULUS_TOO_SMALL, PROTOCOL_DIFFER, # 8 9 driver.timeout_re, pexpect.TIMEOUT] transitions = [ (driver.password_re, [0, 1, 4, 5], -1, partial(a_save_last_pattern, self), 0), (self.device.prompt_re, [0], -1, partial(a_save_last_pattern, self), 0), # cover all messages indicating that connection was not set up (driver.unable_to_connect_re, [0], -1, a_unable_to_connect, 0), (NEWSSHKEY, [0], 1, partial(a_send_line, "yes"), 10), (KNOWN_HOSTS, [0, 1], 0, None, 0), (HOST_KEY_FAILED, [0], -1, ConnectionError("Host key failed", self.hostname), 0), (MODULUS_TOO_SMALL, [0], 0, self.fallback_to_sshv1, 0), (PROTOCOL_DIFFER, [0], 4, self.fallback_to_sshv1, 0), (PROTOCOL_DIFFER, [4], -1, ConnectionError("Protocol version differs", self.hostname), 0), (pexpect.TIMEOUT, [0], 5, partial(a_send, "\r\n"), 10), (pexpect.TIMEOUT, [5], -1, ConnectionTimeoutError("Connection timeout", self.hostname), 0), (driver.timeout_re, [0], -1, ConnectionTimeoutError("Connection timeout", self.hostname), 0), ] self.log("EXPECTED_PROMPT={}".format(pattern_to_str(self.device.prompt_re))) fsm = FSM("SSH-CONNECT", self.device, events, transitions, timeout=_C['connect_timeout'], searchwindowsize=160) return fsm.run()
def connect(self, driver): """Connect using console specific FSM.""" # 0 1 2 3 events = [ ESCAPE_CHAR, driver.press_return_re, driver.standby_re, driver.username_re, # 4 5 6 7 driver.password_re, driver.more_re, self.device.prompt_re, driver.rommon_re, # 8 9 10 11 driver.unable_to_connect_re, driver.timeout_re, pexpect.TIMEOUT, PASSWORD_OK ] transitions = [ (ESCAPE_CHAR, [0], 1, partial(a_send, "\r\n"), _C['esc_char_timeout']), (driver.press_return_re, [0, 1], 1, partial(a_send, "\r\n"), 10), (PASSWORD_OK, [0, 1], 1, partial(a_send, "\r\n"), 10), (driver.standby_re, [0, 5], -1, ConnectionError("Standby console", self.hostname), 0), (driver.username_re, [0, 1, 5, 6], -1, partial(a_save_last_pattern, self), 0), (driver.password_re, [0, 1, 5], -1, partial(a_save_last_pattern, self), 0), (driver.more_re, [0, 5], 7, partial(a_send, "q"), 10), # router sends it again to delete (driver.more_re, [7], 8, None, 10), # (prompt, [0, 1, 5], 6, partial(a_send, "\r\n"), 10), (self.device.prompt_re, [0, 5], 0, None, 10), (self.device.prompt_re, [1, 6, 8, 5], -1, partial(a_save_last_pattern, self), 0), (driver.rommon_re, [0, 1, 5], -1, partial(a_save_last_pattern, self), 0), (driver.unable_to_connect_re, [0, 1], -1, a_unable_to_connect, 0), (driver.timeout_re, [0, 1], -1, ConnectionTimeoutError("Connection Timeout", self.hostname), 0), (pexpect.TIMEOUT, [0, 1], 5, partial(a_send, "\r\n"), 10), (pexpect.TIMEOUT, [5], -1, ConnectionTimeoutError("Connection timeout", self.hostname), 0) ] logger.debug("EXPECTED_PROMPT={}".format( pattern_to_str(self.device.prompt_re))) fsm = FSM("CONSOLE-SERVER-CONNECT", self.device, events, transitions, timeout=_C['connect_timeout'], init_pattern=self.last_pattern) return fsm.run()
def spawn_session(self, command): """Spawn the session using proper command.""" if self._session and self.isalive(): # pylint: disable=no-member self._connection.log("Executing command: '{}'".format(command)) try: self.send(command) # pylint: disable=no-member self.expect_exact(command, timeout=20) # pylint: disable=no-member self.sendline() # pylint: disable=no-member except (pexpect.EOF, OSError): raise ConnectionError("Connection error", self.hostname) except pexpect.TIMEOUT: raise ConnectionTimeoutError("Timeout", self.hostname) else: self._connection.log("Spawning command: '{}'".format(command)) env = os.environ env['TERM'] = 'vt220' # to avoid color control characters and make sure other env not intact, esp. PATH try: self._session = pexpect.spawn( command, maxread=65536, searchwindowsize=4000, env=env, echo=True # KEEP YOUR DIRTY HANDS OFF FROM ECHO! ) self._session.delaybeforesend = 0.3 self._connection.log("Child process FD: {}".format( self._session.child_fd)) rows, cols = self._session.getwinsize() if cols < 180: self._session.setwinsize(512, 240) nrows, ncols = self._session.getwinsize() self._connection.log( "Terminal window size changed from {}x{} to {}x{}". format(rows, cols, nrows, ncols)) else: self._connection.log("Terminal window size: {}x{}".format( rows, cols)) except pexpect.EOF: raise ConnectionError("Connection error", self.hostname) except pexpect.TIMEOUT: raise ConnectionTimeoutError("Timeout", self.hostname) self.set_session_log(self._logfile_fd) self.connected = True
def a_connection_timeout(ctx): """Check the prompt and update the drivers.""" prompt = ctx.ctrl.after ctx.msg = "Received the jump host prompt: '{}'".format(prompt) print(ctx.msg) ctx.device.connected = False ctx.finished = True raise ConnectionTimeoutError("Unable to connect to the device.", ctx.ctrl.hostname)
def spawn_session(self, command): """Spawn the session using proper command.""" if self._session and self.isalive(): # pylint: disable=no-member logger.debug("Executing command: '{}'".format(command)) try: self.send(command) # pylint: disable=no-member self.expect_exact(command, timeout=20) # pylint: disable=no-member self.sendline() # pylint: disable=no-member except (pexpect.EOF, OSError): raise ConnectionError("Connection error", self.hostname) except pexpect.TIMEOUT: raise ConnectionTimeoutError("Timeout", self.hostname) else: logger.debug("Spawning command: '{}'".format(command)) try: self._session = pexpect.spawn( command, maxread=65536, searchwindowsize=4000, env={"TERM": "VT100"}, # to avoid color control characters echo=True # KEEP YOUR DIRTY HANDS OFF FROM ECHO! ) self._session.delaybeforesend = 0.3 rows, cols = self._session.getwinsize() if cols < 160: self._session.setwinsize(1024, 160) nrows, ncols = self._session.getwinsize() logger.debug("Terminal window size changed from " "{}x{} to {}x{}".format( rows, cols, nrows, ncols)) else: logger.debug("Terminal window size: {}x{}".format( rows, cols)) except pexpect.EOF: raise ConnectionError("Connection error", self.hostname) except pexpect.TIMEOUT: raise ConnectionTimeoutError("Timeout", self.hostname) self._session.logfile_read = self._logfile_fd self.connected = True
def authenticate(self, driver): """Authenticate using the Console Server protocol specific FSM.""" # 0 1 2 3 events = [ driver.username_re, driver.password_re, self.device.prompt_re, driver.rommon_re, # 4 5 6 7 8 driver.unable_to_connect_re, driver.authentication_error_re, pexpect.TIMEOUT, pexpect.EOF ] transitions = [ (driver.username_re, [0], 1, partial(a_send_username, self.username), 10), (driver.username_re, [1], 1, None, 10), (driver.password_re, [0, 1], 2, partial(a_send_password, self._acquire_password()), _C['first_prompt_timeout']), (driver.username_re, [2], -1, a_authentication_error, 0), (driver.password_re, [2], -1, a_authentication_error, 0), (driver.authentication_error_re, [1, 2], -1, a_authentication_error, 0), (self.device.prompt_re, [0, 1, 2], -1, None, 0), (driver.rommon_re, [0], -1, partial(a_send, "\r\n"), 0), (pexpect.TIMEOUT, [0], 1, partial(a_send, "\r\n"), 10), (pexpect.TIMEOUT, [2], -1, None, 0), (pexpect.TIMEOUT, [3, 7], -1, ConnectionTimeoutError("Connection Timeout", self.hostname), 0), (driver.unable_to_connect_re, [0, 1, 2], -1, a_unable_to_connect, 0), ] logger.debug("EXPECTED_PROMPT={}".format( pattern_to_str(self.device.prompt_re))) fsm = FSM("CONSOLE-SERVER-AUTH", self.device, events, transitions, timeout=_C['connect_timeout'], init_pattern=self.last_pattern) return fsm.run()
def connect(self, driver): """Connect using the Telnet protocol specific FSM.""" # 0 1 2 3 events = [ ESCAPE_CHAR, driver.press_return_re, driver.standby_re, driver.username_re, # 4 5 6 7 driver.password_re, driver.more_re, self.device.prompt_re, driver.rommon_re, # 8 9 10 11 12 driver.unable_to_connect_re, driver.timeout_re, pexpect.TIMEOUT, PASSWORD_OK, driver.syntax_error_re ] transitions = [ (ESCAPE_CHAR, [0], 1, None, _C['esc_char_timeout']), (driver.syntax_error_re, [0], -1, CommandSyntaxError("Command syntax error"), 0), (driver.press_return_re, [0, 1], 1, a_send_newline, 10), (PASSWORD_OK, [0, 1], 1, a_send_newline, 10), (driver.standby_re, [0, 5], -1, partial(a_standby_console), 0), (driver.username_re, [0, 1, 5, 6], -1, partial(a_save_last_pattern, self), 0), (driver.password_re, [0, 1, 5], -1, partial(a_save_last_pattern, self), 0), (driver.more_re, [0, 5], 7, partial(a_send, "q"), 10), # router sends it again to delete (driver.more_re, [7], 8, None, 10), # (prompt, [0, 1, 5], 6, a_send_newline, 10), (self.device.prompt_re, [0, 1, 5], 0, None, 10), (self.device.prompt_re, [6, 8, 5], -1, partial(a_save_last_pattern, self), 0), (driver.rommon_re, [0, 1, 5], -1, partial(a_save_last_pattern, self), 0), (driver.unable_to_connect_re, [0, 1, 5], -1, a_unable_to_connect, 0), (driver.timeout_re, [0, 1, 5], -1, ConnectionTimeoutError("Connection Timeout", self.hostname), 0), (pexpect.TIMEOUT, [0, 1], 5, a_send_newline, 10), (pexpect.TIMEOUT, [5], -1, ConnectionTimeoutError("Connection timeout", self.hostname), 0) ] self.log("EXPECTED_PROMPT={}".format( pattern_to_str(self.device.prompt_re))) # setting max_transitions to large number to swallow prompt like strings from prompt fsm = FSM("TELNET-CONNECT", self.device, events, transitions, timeout=_C['connect_timeout'], init_pattern=self.last_pattern, max_transitions=500) return fsm.run()