Esempio n. 1
0
    def add(self, csit_papi_command, history=True, **kwargs):
        """Add next command to internal command list; return self.

        Unless disabled, new entry to papi history is also added at this point.
        The argument name 'csit_papi_command' must be unique enough as it cannot
        be repeated in kwargs.
        The kwargs dict is deep-copied, so it is safe to use the original
        with partial modifications for subsequent commands.

        Any pending conflicts from .api.json processing are raised.
        Then the command name is checked for known CRCs.
        Unsupported commands raise an exception, as CSIT change
        should not start using messages without making sure which CRCs
        are supported.
        Each CRC issue is raised only once, so subsequent tests
        can raise other issues.

        :param csit_papi_command: VPP API command.
        :param history: Enable/disable adding command to PAPI command history.
        :param kwargs: Optional key-value arguments.
        :type csit_papi_command: str
        :type history: bool
        :type kwargs: dict
        :returns: self, so that method chaining is possible.
        :rtype: PapiSocketExecutor
        :raises RuntimeError: If unverified or conflicting CRC is encountered.
        """
        self.crc_checker.report_initial_conflicts()
        if history:
            PapiHistory.add_to_papi_history(self._node, csit_papi_command,
                                            **kwargs)
        self.crc_checker.check_api_name(csit_papi_command)
        self._api_command_list.append(
            dict(api_name=csit_papi_command, api_args=copy.deepcopy(kwargs)))
        return self
Esempio n. 2
0
    def add(self, csit_papi_command=u"vpp-stats", history=True, **kwargs):
        """Add next command to internal command list; return self.

        The argument name 'csit_papi_command' must be unique enough as it cannot
        be repeated in kwargs.
        The kwargs dict is deep-copied, so it is safe to use the original
        with partial modifications for subsequent commands.

        :param csit_papi_command: VPP API command.
        :param history: Enable/disable adding command to PAPI command history.
        :param kwargs: Optional key-value arguments.
        :type csit_papi_command: str
        :type history: bool
        :type kwargs: dict
        :returns: self, so that method chaining is possible.
        :rtype: PapiExecutor
        """
        if history:
            PapiHistory.add_to_papi_history(
                self._node, csit_papi_command, **kwargs
            )
        self._api_command_list.append(
            dict(
                api_name=csit_papi_command, api_args=copy.deepcopy(kwargs)
            )
        )
        return self
Esempio n. 3
0
    def vat_terminal_exec_cmd(self, cmd):
        """Execute command on the opened VAT terminal.

        :param cmd: Command to be executed.

        :returns: Command output in python representation of JSON format or
            None if not in JSON mode.
        """
        PapiHistory.add_to_papi_history(self._node, cmd, papi=False)
        logger.debug(f"Executing command in VAT terminal: {cmd}")
        try:
            out = self._ssh.interactive_terminal_exec_command(
                self._tty, cmd, self.__VAT_PROMPT
            )
            self.vat_stdout = out
        except Exception:
            self._exec_failure = True
            vpp_pid = get_vpp_pid(self._node)
            if vpp_pid:
                if isinstance(vpp_pid, int):
                    msg = f"VPP running on node {self._node[u'host']} " \
                        f"but VAT command {cmd} execution failed."
                else:
                    msg = f"More instances of VPP running on node " \
                        f"{self._node[u'host']}. VAT command {cmd} " \
                        f"execution failed."
            else:
                msg = f"VPP not running on node {self._node[u'host']}. " \
                    f"VAT command {cmd} execution failed."
            raise RuntimeError(msg)

        logger.debug(f"VAT output: {out}")
        if self.json:
            obj_start = out.find(u"{")
            obj_end = out.rfind(u"}")
            array_start = out.find(u"[")
            array_end = out.rfind(u"]")

            if obj_start == -1 and array_start == -1:
                raise RuntimeError(f"VAT command {cmd}: no JSON data.")

            if obj_start < array_start or array_start == -1:
                start = obj_start
                end = obj_end + 1
            else:
                start = array_start
                end = array_end + 1
            out = out[start:end]
            json_out = json.loads(out)
            return json_out

        return None
Esempio n. 4
0
    def vat_terminal_exec_cmd(self, cmd):
        """Execute command on the opened VAT terminal.

        :param cmd: Command to be executed.

        :returns: Command output in python representation of JSON format or
            None if not in JSON mode.
        """
        PapiHistory.add_to_papi_history(self._node, cmd, papi=False)
        logger.debug("Executing command in VAT terminal: {0}".format(cmd))
        try:
            out = self._ssh.interactive_terminal_exec_command(self._tty, cmd,
                                                              self.__VAT_PROMPT)
            self.vat_stdout = out
        except Exception:
            self._exec_failure = True
            vpp_pid = get_vpp_pid(self._node)
            if vpp_pid:
                if isinstance(vpp_pid, int):
                    raise RuntimeError("VPP running on node {0} but VAT command"
                                       " {1} execution failed.".
                                       format(self._node['host'], cmd))
                else:
                    raise RuntimeError("More instances of VPP running on node "
                                       "{0}. VAT command {1} execution failed.".
                                       format(self._node['host'], cmd))
            else:
                raise RuntimeError("VPP not running on node {0}. VAT command "
                                   "{1} execution failed.".
                                   format(self._node['host'], cmd))

        logger.debug("VAT output: {0}".format(out))
        if self.json:
            obj_start = out.find('{')
            obj_end = out.rfind('}')
            array_start = out.find('[')
            array_end = out.rfind(']')

            if obj_start == -1 and array_start == -1:
                raise RuntimeError("VAT command {0}: no JSON data.".format(cmd))

            if obj_start < array_start or array_start == -1:
                start = obj_start
                end = obj_end + 1
            else:
                start = array_start
                end = array_end + 1
            out = out[start:end]
            json_out = json.loads(out)
            return json_out
        else:
            return None
Esempio n. 5
0
    def add(self, csit_papi_command="vpp-stats", history=True, **kwargs):
        """Add next command to internal command list; return self.

        The argument name 'csit_papi_command' must be unique enough as it cannot
        be repeated in kwargs.

        :param csit_papi_command: VPP API command.
        :param history: Enable/disable adding command to PAPI command history.
        :param kwargs: Optional key-value arguments.
        :type csit_papi_command: str
        :type history: bool
        :type kwargs: dict
        :returns: self, so that method chaining is possible.
        :rtype: PapiExecutor
        """
        if history:
            PapiHistory.add_to_papi_history(self._node, csit_papi_command,
                                            **kwargs)
        self._api_command_list.append(
            dict(api_name=csit_papi_command, api_args=kwargs))
        return self
Esempio n. 6
0
    def execute_script(self,
                       vat_name,
                       node,
                       timeout=120,
                       json_out=True,
                       copy_on_execute=False,
                       history=True):
        """Execute VAT script on remote node, and store the result. There is an
        option to copy script from local host to remote host before execution.
        Path is defined automatically.

        :param vat_name: Name of the vat script file. Only the file name of
            the script is required, the resources path is prepended
            automatically.
        :param node: Node to execute the VAT script on.
        :param timeout: Seconds to allow the script to run.
        :param json_out: Require JSON output.
        :param copy_on_execute: If true, copy the file from local host to remote
            before executing.
        :param history: If true, add command to history.
        :type vat_name: str
        :type node: dict
        :type timeout: int
        :type json_out: bool
        :type copy_on_execute: bool
        :type history: bool
        :raises SSHException: If cannot open connection for VAT.
        :raises SSHTimeout: If VAT execution is timed out.
        :raises RuntimeError: If VAT script execution fails.
        """
        ssh = SSH()
        try:
            ssh.connect(node)
        except:
            raise SSHException(
                f"Cannot open SSH connection to execute VAT command(s) "
                f"from vat script {vat_name}")

        if copy_on_execute:
            ssh.scp(vat_name, vat_name)
            remote_file_path = vat_name
            if history:
                with open(vat_name, u"rt") as vat_file:
                    for line in vat_file:
                        PapiHistory.add_to_papi_history(node,
                                                        line.replace(
                                                            u"\n", u""),
                                                        papi=False)
        else:
            remote_file_path = f"{Constants.REMOTE_FW_DIR}/" \
                f"{Constants.RESOURCES_TPL_VAT}/{vat_name}"

        cmd = f"{Constants.VAT_BIN_NAME}" \
            f"{u' json' if json_out is True else u''} " \
            f"in {remote_file_path} script"
        try:
            ret_code, stdout, stderr = ssh.exec_command_sudo(cmd=cmd,
                                                             timeout=timeout)
        except SSHTimeout:
            logger.error(f"VAT script execution timeout: {cmd}")
            raise
        except Exception:
            raise RuntimeError(f"VAT script execution failed: {cmd}")

        self._ret_code = ret_code
        self._stdout = stdout
        self._stderr = stderr
        self._script_name = vat_name
Esempio n. 7
0
    def execute_script(self, vat_name, node, timeout=120, json_out=True,
                       copy_on_execute=False):
        """Execute VAT script on remote node, and store the result. There is an
        option to copy script from local host to remote host before execution.
        Path is defined automatically.

        :param vat_name: Name of the vat script file. Only the file name of
            the script is required, the resources path is prepended
            automatically.
        :param node: Node to execute the VAT script on.
        :param timeout: Seconds to allow the script to run.
        :param json_out: Require JSON output.
        :param copy_on_execute: If true, copy the file from local host to remote
            before executing.
        :type vat_name: str
        :type node: dict
        :type timeout: int
        :type json_out: bool
        :type copy_on_execute: bool
        :raises SSHException: If cannot open connection for VAT.
        :raises SSHTimeout: If VAT execution is timed out.
        :raises RuntimeError: If VAT script execution fails.
        """
        ssh = SSH()
        try:
            ssh.connect(node)
        except:
            raise SSHException("Cannot open SSH connection to execute VAT "
                               "command(s) from vat script {name}"
                               .format(name=vat_name))

        if copy_on_execute:
            ssh.scp(vat_name, vat_name)
            remote_file_path = vat_name
            with open(vat_name, 'r') as vat_file:
                for line in vat_file:
                    PapiHistory.add_to_papi_history(node,
                                                    line.replace('\n', ''),
                                                    papi=False)
        else:
            remote_file_path = '{0}/{1}/{2}'.format(Constants.REMOTE_FW_DIR,
                                                    Constants.RESOURCES_TPL_VAT,
                                                    vat_name)

        cmd = "{vat_bin} {json} in {vat_path} script".format(
            vat_bin=Constants.VAT_BIN_NAME,
            json="json" if json_out is True else "",
            vat_path=remote_file_path)

        try:
            ret_code, stdout, stderr = ssh.exec_command_sudo(cmd=cmd,
                                                             timeout=timeout)
        except SSHTimeout:
            logger.error("VAT script execution timeout: {0}".format(cmd))
            raise
        except:
            raise RuntimeError("VAT script execution failed: {0}".format(cmd))

        self._ret_code = ret_code
        self._stdout = stdout
        self._stderr = stderr
        self._script_name = vat_name