Ejemplo n.º 1
0
    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Comware devices base_pattern is "[\]|>]prompt(\-\w+)?[\]|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off any leading HRP_. characters for USGv5 HA
        prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-1]
        delimiter_right = map(re.escape, type(self)._delimiter_list)
        delimiter_right = r"|".join(delimiter_right)
        delimiter_left = map(re.escape, type(self)._delimiter_left_list)
        delimiter_left = r"|".join(delimiter_left)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(
            delimiter_left=delimiter_left,
            prompt=base_prompt,
            delimiter_right=delimiter_right,
        )
        logger.debug("Host {}: Base Prompt: {}".format(self._host,
                                                       self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(
            self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 2
0
    async def send_config_set(self, config_commands=None, with_commit=True, commit_comment='', exit_config_mode=True):
        """
        Sending configuration commands to device
        By default automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool with_commit: if true it commit all changes after applying all config_commands
        :param string commit_comment: message for configuration commit
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of these commands
        """

        if config_commands is None:
            return ''

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands)
        if with_commit:
            commit = type(self)._commit_command
            if commit_comment:
                commit = type(self)._commit_comment_command.format(commit_comment)

            self._stdin.write(self._normalize_cmd(commit))
            output += await self._read_until_prompt()

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 3
0
    async def send_command(self, command_string, pattern='', re_flags=0, strip_command=True, strip_prompt=True):
        """
        Sending command to device (support interactive commands with pattern)

        :param str command_string: command for executing basically in privilege mode
        :param str pattern: pattern for waiting in output (for interactive commands)
        :param re.flags re_flags: re flags for pattern
        :param bool strip_command: True or False for stripping command from output
        :param bool strip_prompt: True or False for stripping ending device prompt
        :return: The output of the command
        """
        logger.info('Host {}: Sending command'.format(self._host))
        output = ''
        command_string = self._normalize_cmd(command_string)
        logger.debug("Host {}: Send command: {}".format(self._host, repr(command_string)))
        self._stdin.write(command_string)
        output = await self._read_until_prompt_or_pattern(pattern, re_flags)

        # Some platforms have ansi_escape codes
        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)
        output = self._normalize_linefeeds(output)
        if strip_prompt:
            output = self._strip_prompt(output)
        if strip_command:
            output = self._strip_command(command_string, output)

        logger.debug("Host {}: Send command output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 4
0
    async def _set_base_prompt(self):
        """
        Setting two important vars for ASA
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For ASA devices base_pattern is "prompt([\/\w]+)?(\(.*?\))?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Cut off prompt from "prompt/context/other" if it exists
        # If not we get all prompt
        prompt = prompt[:-1].split('/')
        prompt = prompt[0]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(base_prompt, delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host,
                                                       self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(
            self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 5
0
    async def send_config_set(self, config_commands=None):
        """
        Sending configuration commands to device

        The commands will be executed one after the other.

        :param list config_commands: iterable string list with commands for applying to network device
        :return: The output of this commands
        """
        logger.info("Host {}: Sending configuration settings".format(self._host))
        if config_commands is None:
            return ""
        if not hasattr(config_commands, "__iter__"):
            raise ValueError(
                "Host {}: Invalid argument passed into send_config_set".format(
                    self._host
                )
            )

        # Send config commands
        logger.debug("Host {}: Config commands: {}".format(self._host, config_commands))
        output = ""
        for cmd in config_commands:
            self._stdin.write(self._normalize_cmd(cmd))
            output += await self._read_until_prompt()

        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output
Ejemplo n.º 6
0
    async def send_config_set(self,
                              config_commands=None,
                              exit_config_mode=True):
        """
        Sending configuration commands to Cisco IOS like devices
        Automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in conf mode
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands
                                                )

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(
            self._host, repr(output)))
        return output
Ejemplo n.º 7
0
    async def send_config_set(self, config_commands=None):
        """
        Sending configuration commands to device

        The commands will be executed one after the other.

        :param list config_commands: iterable string list with commands for applying to network device
        :return: The output of this commands
        """
        logger.info("Host {}: Sending configuration settings".format(self._host))
        if config_commands is None:
            return ''
        if not hasattr(config_commands, '__iter__'):
            raise ValueError("Host {}: Invalid argument passed into send_config_set".format(self._host))

        # Send config commands
        logger.debug("Host {}: Config commands: {}".format(self._host, config_commands))
        output = ''
        for cmd in config_commands:
            self._stdin.write(self._normalize_cmd(cmd))
            output += await self._read_until_prompt()

        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 8
0
    async def send_command(self, command_string, pattern='', re_flags=0, strip_command=True, strip_prompt=True):
        """
        Sending command to device (support interactive commands with pattern)

        :param str command_string: command for executing basically in privilege mode
        :param str pattern: pattern for waiting in output (for interactive commands)
        :param re.flags re_flags: re flags for pattern
        :param bool strip_command: True or False for stripping command from output
        :param bool strip_prompt: True or False for stripping ending device prompt
        :return: The output of the command
        """
        logger.info('Host {}: Sending command'.format(self._host))
        output = ''
        command_string = self._normalize_cmd(command_string)
        logger.debug("Host {}: Send command: {}".format(self._host, repr(command_string)))
        self._stdin.write(command_string)
        output = await self._read_until_prompt_or_pattern(pattern, re_flags)

        # Some platforms have ansi_escape codes
        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)
        output = self._normalize_linefeeds(output)
        if strip_prompt:
            output = self._strip_prompt(output)
        if strip_command:
            output = self._strip_command(command_string, output)

        logger.debug("Host {}: Send command output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 9
0
    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually username or hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For JunOS devices base_pattern is "user(@[hostname])?[>|#]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        prompt = prompt[:-1]
        # Strip off trailing terminator
        if '@' in prompt:
            prompt = prompt.split('@')[1]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host,
                                                       self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(
            self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 10
0
    async def send_config_set(self,
                              config_commands=None,
                              exit_system_view=False):
        """
        Sending configuration commands to device
        Automatically exits/enters system-view.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool exit_system_view: If true it will quit from system view automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ''

        # Send config commands
        output = await self._system_view()
        output += await super().send_config_set(config_commands=config_commands
                                                )

        if exit_system_view:
            output += await self._exit_system_view()

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(
            self._host, repr(output)))
        return output
Ejemplo n.º 11
0
 async def _establish_connection(self):
     """Establishing SSH connection to the network device"""
     logger.info(
         "Host {}: Establishing connection to port {}".format(self._host, self._port)
     )
     output = ""
     # initiate SSH connection
     fut = asyncssh.connect(**self._connect_params_dict)
     try:
         self._conn = await asyncio.wait_for(fut, self._timeout)
     except asyncssh.DisconnectError as e:
         raise DisconnectError(self._host, e.code, e.reason)
     except asyncio.TimeoutError:
         raise TimeoutError(self._host)
     self._stdin, self._stdout, self._stderr = await self._conn.open_session(
         term_type="Dumb", term_size=(200, 24)
     )
     logger.info("Host {}: Connection is established".format(self._host))
     # Flush unnecessary data
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     output = await self._read_until_pattern(delimiters)
     logger.debug(
         "Host {}: Establish Connection Output: {}".format(self._host, repr(output))
     )
     return output
Ejemplo n.º 12
0
    async def _set_base_prompt(self):
        """
        Setting two important vars:

            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. It's platform specific parameter

        For Cisco devices base_pattern is "prompt(\(.*?\))?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()

        # Strip off trailing terminator
        self._base_prompt = prompt[:-1]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt,
                                            delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host,
                                                       self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(
            self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 13
0
    def _strip_ansi_escape_codes(string_buffer):
        """
        Remove some ANSI ESC codes from the output

        http://en.wikipedia.org/wiki/ANSI_escape_code

        Note: this does not capture ALL possible ANSI Escape Codes only the ones
        I have encountered

        Current codes that are filtered:
        ESC = '\x1b' or chr(27)
        ESC = is the escape character [^ in hex ('\x1b')
        ESC[24;27H   Position cursor
        ESC[?25h     Show the cursor
        ESC[E        Next line (HP does ESC-E)
        ESC[2K       Erase line
        ESC[1;24r    Enable scrolling from start to row end
        ESC7         Save cursor position
        ESC[r        Scroll all screen
        ESC8         Restore cursor position
        ESC[nA       Move cursor up to n cells
        ESC[nB       Move cursor down to n cells

        require:
            HP ProCurve
            F5 LTM's
            Mikrotik
        """
        logger.info("Stripping ansi escape codes")
        logger.debug("Unstripped output: {}".format(repr(string_buffer)))

        code_save_cursor = chr(27) + r'7'
        code_scroll_screen = chr(27) + r'\[r'
        code_restore_cursor = chr(27) + r'8'
        code_cursor_up = chr(27) + r'\[\d+A'
        code_cursor_down = chr(27) + r'\[\d+B'

        code_position_cursor = chr(27) + r'\[\d+;\d+H'
        code_show_cursor = chr(27) + r'\[\?25h'
        code_next_line = chr(27) + r'E'
        code_erase_line = chr(27) + r'\[2K'
        code_enable_scroll = chr(27) + r'\[\d+;\d+r'

        code_set = [
            code_save_cursor, code_scroll_screen, code_restore_cursor,
            code_cursor_up, code_cursor_down, code_position_cursor,
            code_show_cursor, code_erase_line, code_enable_scroll
        ]

        output = string_buffer
        for ansi_esc_code in code_set:
            output = re.sub(ansi_esc_code, '', output)

        # CODE_NEXT_LINE must substitute with '\n'
        output = re.sub(code_next_line, '\n', output)

        logger.debug('Stripped output: {}'.format(repr(output)))

        return output
Ejemplo n.º 14
0
    async def _check_multiple_mode(self):
        """Check mode multiple. If mode is multiple we adding info about contexts"""
        logger.info("Host {}:Checking multiple mode".format(self._host))
        out = await self.send_command('show mode')
        if 'multiple' in out:
            self._multiple_mode = True

        logger.debug("Host {}: Multiple mode: {}".format(self._host, self._multiple_mode))
Ejemplo n.º 15
0
 async def _set_base_prompt(self):
     """Setting base pattern"""
     logger.info("Host {}: Setting base prompt".format(self._host))
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     pattern = type(self)._pattern
     self._base_pattern = pattern.format(delimiters)
     logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
     return self._base_prompt
Ejemplo n.º 16
0
    async def _check_multiple_mode(self):
        """Check mode multiple. If mode is multiple we adding info about contexts"""
        logger.info("Host {}:Checking multiple mode".format(self._host))
        out = await self.send_command('show mode')
        if 'multiple' in out:
            self._multiple_mode = True

        logger.debug("Host {}: Multiple mode: {}".format(
            self._host, self._multiple_mode))
Ejemplo n.º 17
0
    async def send_config_set(
        self,
        config_commands=None,
        with_commit=True,
        commit_comment="",
        exit_config_mode=True,
    ):
        """
        Sending configuration commands to device
        By default automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool with_commit: if true it commit all changes after applying all config_commands
        :param string commit_comment: message for configuration commit
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of these commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super(IOSLikeDevice, self).send_config_set(
            config_commands=config_commands
        )
        if with_commit:
            commit = type(self)._commit_command
            if commit_comment:
                commit = type(self)._commit_comment_command.format(commit_comment)

            self._stdin.write(self._normalize_cmd(commit))
            output += await self._read_until_prompt_or_pattern(
                r"Do you wish to proceed with this commit anyway\?"
            )
            if "Failed to commit" in output:
                show_config_failed = type(self)._show_config_failed
                reason = await self.send_command(
                    self._normalize_cmd(show_config_failed)
                )
                raise CommitError(self._host, reason)
            if "One or more commits have occurred" in output:
                show_commit_changes = type(self)._show_commit_changes
                self._stdin.write(self._normalize_cmd("no"))
                reason = await self.send_command(
                    self._normalize_cmd(show_commit_changes)
                )
                raise CommitError(self._host, reason)

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output
Ejemplo n.º 18
0
    def _strip_ansi_escape_codes(string_buffer):
        """
        Remove some ANSI ESC codes from the output

        http://en.wikipedia.org/wiki/ANSI_escape_code

        Note: this does not capture ALL possible ANSI Escape Codes only the ones
        I have encountered

        Current codes that are filtered:
        ESC = '\x1b' or chr(27)
        ESC = is the escape character [^ in hex ('\x1b')
        ESC[24;27H   Position cursor
        ESC[?25h     Show the cursor
        ESC[E        Next line (HP does ESC-E)
        ESC[2K       Erase line
        ESC[1;24r    Enable scrolling from start to row end
        ESC7         Save cursor position
        ESC[r        Scroll all screen
        ESC8         Restore cursor position
        ESC[nA       Move cursor up to n cells
        ESC[nB       Move cursor down to n cells

        require:
            HP ProCurve
            F5 LTM's
            Mikrotik
        """
        logger.info("Stripping ansi escape codes")
        logger.debug("Unstripped output: {}".format(repr(string_buffer)))

        code_save_cursor = chr(27) + r'7'
        code_scroll_screen = chr(27) + r'\[r'
        code_restore_cursor = chr(27) + r'8'
        code_cursor_up = chr(27) + r'\[\d+A'
        code_cursor_down = chr(27) + r'\[\d+B'

        code_position_cursor = chr(27) + r'\[\d+;\d+H'
        code_show_cursor = chr(27) + r'\[\?25h'
        code_next_line = chr(27) + r'E'
        code_erase_line = chr(27) + r'\[2K'
        code_enable_scroll = chr(27) + r'\[\d+;\d+r'

        code_set = [code_save_cursor, code_scroll_screen, code_restore_cursor, code_cursor_up, code_cursor_down,
                    code_position_cursor, code_show_cursor, code_erase_line, code_enable_scroll]

        output = string_buffer
        for ansi_esc_code in code_set:
            output = re.sub(ansi_esc_code, '', output)

        # CODE_NEXT_LINE must substitute with '\n'
        output = re.sub(code_next_line, '\n', output)

        logger.debug('Stripped output: {}'.format(repr(output)))

        return output
Ejemplo n.º 19
0
 async def _set_base_prompt(self):
     """Setting base pattern"""
     logger.info("Host {}: Setting base prompt".format(self._host))
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     pattern = type(self)._pattern
     self._base_pattern = pattern.format(delimiters=delimiters)
     logger.debug("Host {}: Base Pattern: {}".format(
         self._host, self._base_pattern))
     return self._base_prompt
Ejemplo n.º 20
0
 async def _disable_paging(self):
     """Disable paging method"""
     logger.info("Host {}: Trying to disable paging".format(self._host))
     command = type(self)._disable_paging_command
     command = self._normalize_cmd(command)
     logger.debug("Host {}: Disable paging command: {}".format(self._host, repr(command)))
     self._stdin.write(command)
     output = await self._read_until_prompt()
     logger.debug("Host {}: Disable paging output: {}".format(self._host, repr(output)))
     if self._ansi_escape_codes:
         output = self._strip_ansi_escape_codes(output)
     return output
Ejemplo n.º 21
0
 async def _disable_paging(self):
     """Disable paging method"""
     logger.info("Host {}: Trying to disable paging".format(self._host))
     command = type(self)._disable_paging_command
     command = self._normalize_cmd(command)
     logger.debug("Host {}: Disable paging command: {}".format(self._host, repr(command)))
     self._stdin.write(command)
     output = await self._read_until_prompt()
     logger.debug("Host {}: Disable paging output: {}".format(self._host, repr(output)))
     if self._ansi_escape_codes:
         output = self._strip_ansi_escape_codes(output)
     return output
Ejemplo n.º 22
0
 async def _find_prompt(self):
     """Finds the current network device prompt, last line only."""
     logger.info("Host {}: Finding prompt".format(self._host))
     self._stdin.write("\r")
     prompt = ''
     prompt = await self._read_until_prompt()
     prompt = prompt.strip()
     if self._ansi_escape_codes:
         prompt = self._strip_ansi_escape_codes(prompt)
     if not prompt:
         raise ValueError("Unable to find prompt: {0}".format(prompt))
     logger.debug("Host {}: Prompt: {}".format(self._host, prompt))
     return prompt
Ejemplo n.º 23
0
 async def _find_prompt(self):
     """Finds the current network device prompt, last line only."""
     logger.info("Host {}: Finding prompt".format(self._host))
     self._stdin.write("\r")
     prompt = ""
     prompt = await self._read_until_prompt()
     prompt = prompt.strip()
     if self._ansi_escape_codes:
         prompt = self._strip_ansi_escape_codes(prompt)
     if not prompt:
         raise ValueError("Unable to find prompt: {0}".format(prompt))
     logger.debug("Host {}: Prompt: {}".format(self._host, prompt))
     return prompt
Ejemplo n.º 24
0
 async def _find_prompt(self):
     """Finds the current network device prompt, last line only"""
     logger.info("Host {}: Finding prompt".format(self._host))
     self._stdin.write(self._normalize_cmd("\n"))
     prompt = ''
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     prompt = await self._read_until_pattern(delimiters)
     prompt = prompt.strip()
     if self._ansi_escape_codes:
         prompt = self._strip_ansi_escape_codes(prompt)
     if not prompt:
         raise ValueError("Host {}: Unable to find prompt: {}".format(self._host, repr(prompt)))
     logger.debug("Host {}: Found Prompt: {}".format(self._host, repr(prompt)))
     return prompt
Ejemplo n.º 25
0
 async def _find_prompt(self):
     """Finds the current network device prompt, last line only"""
     logger.info("Host {}: Finding prompt".format(self._host))
     self._stdin.write(self._normalize_cmd("\n"))
     prompt = ''
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     prompt = await self._read_until_pattern(delimiters)
     prompt = prompt.strip()
     if self._ansi_escape_codes:
         prompt = self._strip_ansi_escape_codes(prompt)
     if not prompt:
         raise ValueError("Host {}: Unable to find prompt: {}".format(self._host, repr(prompt)))
     logger.debug("Host {}: Found Prompt: {}".format(self._host, repr(prompt)))
     return prompt
Ejemplo n.º 26
0
 async def _read_until_pattern(self, pattern='', re_flags=0):
     """Read channel until pattern detected. Return ALL data available"""
     output = ''
     logger.info("Host {}: Reading until pattern".format(self._host))
     if not pattern:
         pattern = self._base_pattern
     logger.debug("Host {}: Reading pattern: {}".format(self._host, pattern))
     while True:
         fut = self._stdout.read(self._MAX_BUFFER)
         try:
             output += await asyncio.wait_for(fut, self._timeout)
         except asyncio.TimeoutError:
             raise TimeoutError(self._host)
         if re.search(pattern, output, flags=re_flags):
             logger.debug("Host {}: Reading pattern '{}' was found: {}".format(self._host, pattern, repr(output)))
             return output
Ejemplo n.º 27
0
 async def _read_until_pattern(self, pattern='', re_flags=0):
     """Read channel until pattern detected. Return ALL data available"""
     output = ''
     logger.info("Host {}: Reading until pattern".format(self._host))
     if not pattern:
         pattern = self._base_pattern
     logger.debug("Host {}: Reading pattern: {}".format(self._host, pattern))
     while True:
         fut = self._stdout.read(self._MAX_BUFFER)
         try:
             output += await asyncio.wait_for(fut, self._timeout)
         except asyncio.TimeoutError:
             raise TimeoutError(self._host)
         if re.search(pattern, output, flags=re_flags):
             logger.debug("Host {}: Reading pattern '{}' was found: {}".format(self._host, pattern, repr(output)))
             return output
Ejemplo n.º 28
0
    async def _establish_connection(self):
        """Establish SSH connection to the network device"""
        logger.info('Host {}: Establishing connection to port {}'.format(self._host, self._port))
        output = ""
        # initiate SSH connection
        try:
            self._conn = await asyncssh.connect(**self._connect_params_dict)
        except asyncssh.DisconnectError as e:
            raise DisconnectError(self._host, e.code, e.reason)

        self._stdin, self._stdout, self._stderr = await self._conn.open_session(term_type='dumb')
        logger.info("Host {}: Connection is established".format(self._host))
        # Flush unnecessary data
        output = await self._read_until_prompt()
        logger.debug("Host {}: Establish Connection Output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 29
0
    async def _cmdline_mode_enter(self):
        """Entering to cmdline-mode"""
        logger.info('Host {}: Entering to cmdline mode'.format(self._host))
        output = ''
        cmdline_mode_enter = type(self)._cmdline_mode_enter_command
        check_error_string = type(self)._cmdline_mode_check

        output = await self.send_command(cmdline_mode_enter, pattern='\[Y\/N\]')
        output += await self.send_command('Y', pattern='password\:')
        output += await self.send_command(self._cmdline_password)

        logger.debug("Host {}: cmdline mode output: {}".format(self._host, repr(output)))
        logger.info('Host {}: Checking cmdline mode'.format(self._host))
        if check_error_string in output:
            raise ValueError('Failed to enter to cmdline mode')

        return output
Ejemplo n.º 30
0
    async def _cmdline_mode_enter(self):
        """Entering to cmdline-mode"""
        logger.info("Host {}: Entering to cmdline mode".format(self._host))
        output = ""
        cmdline_mode_enter = type(self)._cmdline_mode_enter_command
        check_error_string = type(self)._cmdline_mode_check

        output = await self.send_command(cmdline_mode_enter,
                                         pattern="\[Y\/N\]")
        output += await self.send_command("Y", pattern="password\:")
        output += await self.send_command(self._cmdline_password)

        logger.debug("Host {}: cmdline mode output: {}".format(
            self._host, repr(output)))
        logger.info("Host {}: Checking cmdline mode".format(self._host))
        if check_error_string in output:
            raise ValueError("Failed to enter to cmdline mode")

        return output
Ejemplo n.º 31
0
 async def _establish_connection(self):
     """Establishing SSH connection to the network device"""
     logger.info('Host {}: Establishing connection to port {}'.format(self._host, self._port))
     output = ""
     # initiate SSH connection
     fut = asyncssh.connect(**self._connect_params_dict)
     try:
         self._conn = await asyncio.wait_for(fut, self._timeout)
     except asyncssh.DisconnectError as e:
         raise DisconnectError(self._host, e.code, e.reason)
     except asyncio.TimeoutError:
         raise TimeoutError(self._host)
     self._stdin, self._stdout, self._stderr = await self._conn.open_session(term_type='Dumb', term_size=(200, 24))
     logger.info("Host {}: Connection is established".format(self._host))
     # Flush unnecessary data
     delimiters = map(re.escape, type(self)._delimiter_list)
     delimiters = r"|".join(delimiters)
     output = await self._read_until_pattern(delimiters)
     logger.debug("Host {}: Establish Connection Output: {}".format(self._host, repr(output)))
     return output
Ejemplo n.º 32
0
    async def _set_base_prompt(self):
        """
        Setting two important vars
        * base_prompt - textual prompt in CLI (usually hostname)
        * base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Mikrotik devices base_pattern is "r"\[.*?\] (\/.*?)?\>"
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        self._base_pattern = type(self)._pattern
        prompt = await self._find_prompt()
        user = ''
        # Strip off trailing terminator
        prompt = prompt[1:-3]
        if '@' in prompt:
            prompt = prompt.split('@')[1]
        self._base_prompt = prompt
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 33
0
    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Fujitsu devices base_pattern is "(prompt) (\(.*?\))?[>|#]"
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-3]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(base_prompt, delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 34
0
 async def _read_until_prompt_or_pattern(self, pattern="", re_flags=0):
     """Read until either self.base_pattern or pattern is detected. Return ALL data available"""
     output = ""
     logger.info("Host {}: Reading until prompt or pattern".format(
         self._host))
     if not pattern:
         pattern = self._base_pattern
     base_prompt_pattern = self._base_pattern
     while True:
         fut = self._stdout.read(self._MAX_BUFFER)
         try:
             output += await asyncio.wait_for(fut, self._timeout)
         except asyncio.TimeoutError:
             raise TimeoutError(self._host)
         if re.search(pattern, output, flags=re_flags) or re.search(
                 base_prompt_pattern, output, flags=re_flags):
             logger.debug(
                 "Host {}: Reading pattern '{}' or '{}' was found: {}".
                 format(self._host, pattern, base_prompt_pattern,
                        repr(output)))
             return output
Ejemplo n.º 35
0
    async def send_config_set(
        self,
        config_commands=None,
        with_commit=True,
        commit_comment="",
        exit_config_mode=True,
    ):
        """
        Sending configuration commands to device
        By default automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool with_commit: if true it commit all changes after applying all config_commands
        :param string commit_comment: message for configuration commit
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of these commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands)
        if with_commit:
            commit = type(self)._commit_command
            if commit_comment:
                commit = type(self)._commit_comment_command.format(commit_comment)

            self._stdin.write(self._normalize_cmd(commit))
            output += await self._read_until_prompt()

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output
Ejemplo n.º 36
0
    async def send_config_set(self, config_commands=None, exit_config_mode=True):
        """
        Sending configuration commands to Cisco IOS like devices
        Automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in conf mode
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ''

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands)

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 37
0
    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually username or hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For JunOS devices base_pattern is "user(@[hostname])?[>|#]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        prompt = prompt[:-1]
        # Strip off trailing terminator
        if '@' in prompt:
            prompt = prompt.split('@')[1]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 38
0
    async def send_config_set(self, config_commands=None, exit_system_view=False):
        """
        Sending configuration commands to device
        Automatically exits/enters system-view.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool exit_system_view: If true it will quit from system view automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ''

        # Send config commands
        output = await self._system_view()
        output += await super().send_config_set(config_commands=config_commands)

        if exit_system_view:
            output += await self._exit_system_view()

        output = self._normalize_linefeeds(output)
        logger.debug("Host {}: Config commands output: {}".format(self._host, repr(output)))
        return output
Ejemplo n.º 39
0
    async def _set_base_prompt(self):
        """
        Setting two important vars for ASA
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For ASA devices base_pattern is "prompt([\/\w]+)?(\(.*?\))?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Cut off prompt from "prompt/context/other" if it exists
        # If not we get all prompt
        prompt = prompt[:-1].split('/')
        prompt = prompt[0]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(base_prompt, delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt
Ejemplo n.º 40
0
    async def send_command(
        self,
        command_string,
        pattern="",
        re_flags=0,
        strip_command=True,
        strip_prompt=True,
        use_textfsm=False
    ):
        """
        Sending command to device (support interactive commands with pattern)

        :param str command_string: command for executing basically in privilege mode
        :param str pattern: pattern for waiting in output (for interactive commands)
        :param re.flags re_flags: re flags for pattern
        :param bool strip_command: True or False for stripping command from output
        :param bool strip_prompt: True or False for stripping ending device prompt
        :return: The output of the command
        """
        logger.info("Host {}: Sending command".format(self._host))
        output = ""
        command_string = self._normalize_cmd(command_string)
        logger.debug(
            "Host {}: Send command: {}".format(self._host, repr(command_string))
        )
        self._stdin.write(command_string)
        output = await self._read_until_prompt_or_pattern(pattern, re_flags)

        # Some platforms have ansi_escape codes
        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)
        output = self._normalize_linefeeds(output)
        if strip_prompt:
            output = self._strip_prompt(output)
        if strip_command:
            output = self._strip_command(command_string, output)

        logger.debug(
            "Host {}: Send command output: {}".format(self._host, repr(output))
        )
        # If both TextFSM and Genie are set, try TextFSM then Genie
        if use_textfsm:
            structured_output = get_structured_data(
                output, platform=self._device_type, command=command_string
            )
            # If we have structured data; return it.
            if not isinstance(structured_output, str):
                return structured_output
        logger.debug(f"send_command_timing final output: {output}")
        return output