def wait_for_string(self, expected_string, timeout=60): """Wait for string FSM.""" # 0 1 2 3 events = [self.syntax_error_re, self.connection_closed_re, expected_string, self.press_return_re, # 4 5 6 7 self.more_re, pexpect.TIMEOUT, pexpect.EOF, self.buffer_overflow_re] # add detected prompts chain events += self.device.get_previous_prompts() # without target prompt logger.debug("Expecting: {}".format(pattern_to_str(expected_string))) transitions = [ (self.syntax_error_re, [0], -1, CommandSyntaxError("Command unknown", self.device.hostname), 0), (self.connection_closed_re, [0], 1, a_connection_closed, 10), (pexpect.TIMEOUT, [0], -1, CommandTimeoutError("Timeout waiting for prompt", self.device.hostname), 0), (pexpect.EOF, [0, 1], -1, ConnectionError("Unexpected device disconnect", self.device.hostname), 0), (self.more_re, [0], 0, partial(a_send, " "), 10), (expected_string, [0, 1], -1, a_expected_prompt, 0), (self.press_return_re, [0], -1, a_stays_connected, 0), # TODO: Customize in XR driver (self.buffer_overflow_re, [0], -1, CommandSyntaxError("Command too long", self.device.hostname), 0) ] for prompt in self.device.get_previous_prompts(): transitions.append((prompt, [0, 1], 0, a_unexpected_prompt, 0)) fsm = FSM("WAIT-4-STRING", self.device, events, transitions, timeout=timeout) return fsm.run()
def config(self, config_text, plane): """Apply config.""" nol = config_text.count('\n') config_lines = iter(config_text.splitlines()) events = [self.prompt_re, self.syntax_error_re] transitions = [(self.prompt_re, [0], 0, partial(a_send_line, config_lines), 10), (self.syntax_error_re, [0], -1, CommandSyntaxError("Configuration syntax error."), 0)] self.device.ctrl.send_command(self.config_cmd) fsm = FSM("CONFIG", self.device, events, transitions, timeout=10, max_transitions=nol + 5) fsm.run() # after the configuration the hostname may change. Need to detect it again try: self.device.send("", timeout=2) except CommandTimeoutError: prompt = self.device.ctrl.detect_prompt() self.device.prompt_re = self.make_dynamic_prompt(prompt) self.device.update_config_mode(prompt) if self.device.mode == "config": self.device.send("end") self.device.send("write memory") return "NO-COMMIT-ID"
def config(self, configlet, plane, **attributes): """Apply config to the device.""" try: config_text = configlet.format(**attributes) except KeyError as exp: raise CommandSyntaxError("Configuration template error: {}".format( str(exp))) return self.driver.config(config_text, plane)
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 10 driver.timeout_re, pexpect.TIMEOUT, driver.syntax_error_re ] transitions = [ (driver.password_re, [0, 1, 4, 5], -1, partial(a_save_last_pattern, self), 0), (driver.syntax_error_re, [0], -1, CommandSyntaxError("Command syntax error"), 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 wait_for_string(self, expected_string, timeout=60): """Wait for string FSM for XR 64 bit.""" # Big thanks to calvados developers for make this FSM such complex ;-) # 0 1 2 3 events = [ self.syntax_error_re, self.connection_closed_re, expected_string, self.press_return_re, # 4 5 6 7 8 self.more_re, pexpect.TIMEOUT, pexpect.EOF, self.calvados_re, self.calvados_connect_re, # 9 self.calvados_term_length ] # add detected prompts chain events += self.device.get_previous_prompts() # without target prompt logger.debug("Expecting: {}".format(pattern_to_str(expected_string))) logger.debug("Calvados prompt: {}".format( pattern_to_str(self.calvados_re))) transitions = [ (self.syntax_error_re, [0], -1, CommandSyntaxError("Command unknown", self.device.hostname), 0), (self.connection_closed_re, [0], 1, a_connection_closed, 10), (pexpect.TIMEOUT, [0, 2], -1, CommandTimeoutError("Timeout waiting for prompt", self.device.hostname), 0), (pexpect.EOF, [0, 1], -1, ConnectionError("Unexpected device disconnect", self.device.hostname), 0), (self.more_re, [0], 0, partial(a_send, " "), 10), (expected_string, [0, 1], -1, a_expected_prompt, 0), (self.calvados_re, [0], -1, a_expected_prompt, 0), (self.press_return_re, [0], -1, a_stays_connected, 0), (self.calvados_connect_re, [0], 2, None, 0), # admin command to switch to calvados (self.calvados_re, [2], 3, None, _C['calvados_term_wait_time']), # getting the prompt only (pexpect.TIMEOUT, [3], 0, partial(a_send, "\r"), 0), # term len (self.calvados_term_length, [3], 4, None, 0), # ignore for command start (self.calvados_re, [4], 5, None, 0), # ignore for command start (self.calvados_re, [5], 0, a_store_cmd_result, 0), ] for prompt in self.device.get_previous_prompts(): transitions.append((prompt, [0, 1], 0, a_unexpected_prompt, 0)) fsm = FSM("WAIT-4-STRING", self.device, events, transitions, timeout=timeout) 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()
def wait_for_string(self, expected_string, timeout=60): """Wait for string FSM for XR 64 bit.""" ADMIN_USERNAME_PROMPT = re.compile("Admin Username:"******"Password:"******"Expecting: {}".format(pattern_to_str(expected_string))) self.log("Calvados prompt: {}".format(pattern_to_str( self.calvados_re))) transitions = [ (ADMIN_USERNAME_PROMPT, [0], 6, partial(a_send_username, self.device.node_info.username), 5), (ADMIN_PASSWORD_PROMPT, [0, 6], 0, partial(a_send_password, self.device.node_info.password), 5), (self.authentication_error_re, [0], -1, ConnectionAuthenticationError("Admin plane authentication failed", self.device.hostname), 0), (self.syntax_error_re, [0], -1, CommandSyntaxError("Command unknown", self.device.hostname), 0), (self.connection_closed_re, [0], 1, a_connection_closed, 10), (pexpect.TIMEOUT, [0, 2], -1, CommandTimeoutError("Timeout waiting for prompt", self.device.hostname), 0), (pexpect.EOF, [0, 1], -1, ConnectionError("Unexpected device disconnect", self.device.hostname), 0), (self.more_re, [0], 0, partial(a_send, " "), 10), (expected_string, [0, 1], -1, a_expected_prompt, 0), (self.calvados_re, [0], -1, a_expected_prompt, 0), (self.press_return_re, [0], -1, a_stays_connected, 0), (self.calvados_connect_re, [0], 2, None, 0), # admin command to switch to calvados (self.calvados_re, [2], 3, None, _C['calvados_term_wait_time']), # getting the prompt only (pexpect.TIMEOUT, [3], 0, partial(a_send, "\r\r"), timeout), # term len (self.calvados_term_length, [3], 4, None, 0), # ignore for command start (self.calvados_re, [4], 5, None, 0), # ignore for command start (self.calvados_re, [5], 0, a_store_cmd_result, 0), ] for prompt in self.device.get_previous_prompts(): transitions.append((prompt, [0, 1], 0, a_unexpected_prompt, 0)) fsm = FSM("WAIT-4-STRING", self.device, events, transitions, timeout=timeout) return fsm.run()