Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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"
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
    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()
Ejemplo n.º 7
0
    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()