Esempio n. 1
0
    def get_chassis_hardware_info(self, device, **kwargs):
        """Based on command "show chassis hardware" to get all hardware infomation

        :param BOOL force_get:
            *OPTIONAL* Set True will send command to get info every time. If set False, only first time send command to device. Default: False

        :param INT timeout:
            *OPTIONAL* Timeout to run "show chassis hardware" command

        :return:
            Return a DICT value have all hardware info, or return False
        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["force_get"] = kwargs.get("force_get", False)
        options["timeout"] = int(kwargs.get("timeout", self.default["cli_show_timeout"]))
        options["unittest"] = kwargs.get("unittest", None)

        # return immediatelly if have info in previous
        dev_keyword = str(device)
        if dev_keyword not in self.info["chassis_hardware_info"] or options["force_get"] is True:
            self.info["chassis_hardware_info"][dev_keyword] = dev.execute_cli_command_on_device(
                device=device,
                command="show chassis hardware",
                format="xml",
                channel="pyez",
                xml_to_dict=True,
                timeout=options["timeout"],
            )

        device.log(message="{} return value:\n{}".format(func_name, self.tool.pprint(self.info["chassis_hardware_info"][dev_keyword])), level="INFO")
        return self.info["chassis_hardware_info"][dev_keyword]
Esempio n. 2
0
    def fetch_cpu_usage(self, device_handle):
        """
        Function to fetch the Usage percentage of the CPU using the command show system visibility cpu from JDM

        Python Example:
            _cpu_usage_ = fetch_cpu_usage(device_handle=r0_handle)

        Robot Example:
            ${cpu_usage}  Fetch CPU Usage   device_handle=${r0_handle}

        :params str device_handle:
          **REQUIRED** Device Handle of JDM

        :return:
          Dictionary of Logical CPU as keys and percentage usage as values
        """
        try:

            _cmd_ = "show system visibility cpu"
            _output_ = execute_cli_command_on_device(device=device_handle,
                                                     command=_cmd_)

            _cpu_usage_flag_ = False
            _return_dict_ = {}
            _found_ = False
            for _row_ in _output_.split("\n"):

                _match_ = re.match(r".*CPU\s+Usages.*", _row_)
                if _match_ is not None:
                    _cpu_usage_flag_ = True
                    continue

                _match_ = re.match(r".*CPU\s+Pinning.*", _row_)
                if _match_ is not None:
                    _cpu_usage_flag_ = False
                    continue

                if _cpu_usage_flag_ is True:
                    _match_ = re.match(r"(\d+)\s+(\S+)", _row_)
                    if _match_ is not None:
                        _return_dict_[int(_match_.group(1))] = float(
                            _match_.group(2))
                        _found_ = True

            if _found_ is False:
                raise Exception("No CPU Usage Information found in output")
            else:
                return True, _return_dict_

        except Exception as _exception_:
            raise Exception("Error: %s: %s" % (type(_exception_), _exception_))
Esempio n. 3
0
    def fetch_vnf_list_from_config(self, device_handle):
        """
        Python function to get a list of VNF names configured on the JDM

        Python Example:
            _vnf_list_ = fetch_vnf_list_from_config(device_handle=_jdm_)

        Robot Example:
            ${vnf_list}  Fetch VNF List From Config   device_handle=${jdm}

        :param str device_handle:
          **REQUIRED** Device Handle of JDM

        :returns:
           List containing the VNF names
        """
        try:

            _return_list_ = []
            t.log("INFO",
                  "Fetching Configured VNF List on device: %s" % device_handle)

            _cmd_ = "show configuration | display set | match virtual-network-functions.*image"
            _output_ = execute_cli_command_on_device(device=device_handle,
                                                     command=_cmd_)

            for _row_ in _output_.split("\n"):
                _match_ = re.match(
                    r"set\s+virtual-network-functions\s+(\S+)\s+.*", _row_)
                if _match_ is not None:
                    _return_list_.append(_match_.group(1))

            return _return_list_

        except Exception as _exception_:
            t.log(
                "ERROR", "Exception in fetch_vnf_list_from_config: %s : %s" %
                (type(_exception_), _exception_))
Esempio n. 4
0
    def get_chassis_fpc_info(self, device, **kwargs):
        """Based on cmd "show chassis fpc pic-status" to get all pic information

        :param BOOL force_get:
            *OPTIONAL* set True will send cmd to get info every time. Or set False to get info from previous. Default: False

        :param INT timeout:
            *OPTIONAL* get info timeout. Default: {}

        :return:
            Return a DICT value have all pic info, or return False
        """.format(self.default["cli_show_timeout"])
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["force_get"] = kwargs.get("force_get", False)
        options["timeout"] = int(kwargs.get("timeout", self.default["cli_show_timeout"]))

        # return immediatelly if have info in previous
        dev_keyword = str(device)
        if dev_keyword in self.info["chassis_fpc_pic_info"] and options["force_get"] is False:
            device.log(message="{} return value:\n{}".format(func_name, self.tool.pprint(self.info["chassis_fpc_pic_info"][dev_keyword])), level="INFO")
            return self.info["chassis_fpc_pic_info"][dev_keyword]

        self.info["chassis_fpc_pic_info"][dev_keyword] = dev.execute_cli_command_on_device(
            device=device,
            command="show chassis fpc pic-status",
            format="xml",
            channel="pyez",
            xml_to_dict=True,
            timeout=options["timeout"],
        )

        device.log(message="{} return value:\n{}".format(func_name, self.tool.pprint(self.info["chassis_fpc_pic_info"][dev_keyword])), level="INFO")
        return self.info["chassis_fpc_pic_info"][dev_keyword]
Esempio n. 5
0
    def _common_get_processing(self, device, cmd_keyword, kwargs):
        """Common processing to handle device xml response

        For "show system security-profile ..." cmds, device response almost have same data structure. This method
        extract common processing to treat these response

        :param STR cmd_keyword:
            **REQUIRED** feature command keyword.

        :param DICT kwargs:
            **REQUIRED** more_options

        :return:
            Return a LIST contain all entries or TEXT response
        """
        options = {}
        options["more_options"] = kwargs.pop('more_options', None)
        options["return_mode"] = str(kwargs.pop("return_mode",
                                                None)).strip().upper()
        options["timeout"] = int(
            kwargs.pop("timeout", self.default["CLI_COMMIT_TIMEOUT"]))

        cmd_element = []
        cmd_element.append(
            "show system security-profile {}".format(cmd_keyword))

        if options["more_options"]:
            cmd_element.append(options["more_options"])

        if options["return_mode"] == "TEXT":
            response_format = "text"
        else:
            response_format = "xml"

        response = dev.execute_cli_command_on_device(
            device=device,
            command=" ".join(cmd_element),
            channel="pyez",
            format=response_format,
            timeout=options["timeout"],
        )

        if options["return_mode"] == "TEXT":
            return response

        response = self.xml.strip_xml_response(
            self.xml.xml_to_pure_dict(response), return_list=True)
        if cmd_keyword == "nat-interface-port-ol":
            cmd_keyword = "nat-interface-po"

        main_path_keyword = "security-profile-{}-information".format(
            cmd_keyword)
        all_entry_list = []
        for item in response:
            info = {}
            for keyword in item:
                if keyword != main_path_keyword:
                    info[self.tool.underscore_and_lowercase_transit(
                        keyword)] = str(item[keyword])

            for entry in self.tool.set_element_list(
                    item[main_path_keyword]["security-profile-information"]):
                for keyword in entry:
                    info_keyword = self.tool.underscore_and_lowercase_transit(
                        keyword)
                    info[info_keyword] = str(entry[keyword])

                all_entry_list.append(copy.deepcopy(info))

        return all_entry_list
Esempio n. 6
0
def change_mek(device_handle, current_pswd, new_pswd, **kwargs):
    """
    :param device_handle:
        **REQUIRED** device object
    :param current_pswd:
        ***REQUIRED*** Current Master Encryption Password
    :param new_pswd:
        ***REQUIRED*** New Master Encryption Password
    :param node:
        ***OPTIONAL*** can be 'node0', 'node1' or 'both' if device is in HA. Default is both.

    :return True if Master Encryption Password is set/changed successfully

    Python Examples:
        change_mek(srx0, current_pswd=ddhhkkslwjcngh!!!, new_pswd=xkjdfkejfns$@!)
        change_mek(srx0, current_pswd=ddhhkkslwjcngh!!!, new_pswd=xkjdfkejfns$@!, node=node0)

    Robot Examples:
        Change Mek    ${srx0}   current_pswd=ddhhkcngh!!!    new_pswd=xkjdfke$@!
        Change Mek    ${srx0}   current_pswd=ddhhkjcngh!!!   new_pswd=xkjdfns$@!   node=node0
    """
    ha_dev = HA()
    result = False
    chassis_cluster = _check_chassis_cluster(device_handle)
    cmd = 'request security tpm master-encryption-password set plain-text-password'
    error_msgs = ["error: Password entered does not match with old password",
                  "error: Passwords do not match",
                  "Recommend at least length 12 and use of 3 character classes"]
    flag = 1 if new_pswd == current_pswd else 0
    if flag:
        raise Exception("error: Password entered is same as old password.")
    if chassis_cluster:
        node = kwargs.get('node', 'both')
        node_list = ['node0', 'node1'] if node == 'both' else [node]
        for node in node_list:
            ha_dev.execute_cli_on_node(device=device_handle, node=node,
                                       command=cmd, pattern="password: "******"password: "******"password: "******"successfully generated", str(response).lower()):
                result = True
            elif str(response) in error_msgs:
                raise Exception(str(response))
            else:
                raise Exception("Master Encryption Password could not be changed")
    else:
        dev.execute_cli_command_on_device(device=device_handle,
                                          command=cmd, pattern="password: "******"password: "******"password: "******"successfully generated", str(response).lower()):
            result = True
        elif str(response) in error_msgs:
            raise Exception(str(response))
        else:
            raise Exception("Master Encryption Password could not be changed")

    return result
Esempio n. 7
0
def set_mek(device_handle, new_pswd, **kwargs):
    """

    :param device_handle:
        **REQUIRED** device object
    :param new_pswd:
        ***REQUIRED*** New Master Encryption Password
    :param node:
        ***OPTIONAL*** can be 'node0', 'node1' or 'both' if device is in HA. Default is both.

    :return True if Master Encryption Password is set/changed successfully

    Python Examples:
        set_mek(srx0, new_pswd=xkjdfkejfns$@!)
        set_mek(srx0, new_pswd=xkjdfkejfns$@!, node=node0)

    Robot Examples:
        Set Mek    ${srx0}    new_pswd=xkjdfkejfns$@!
        Set Mek    ${srx0}    new_pswd=xkjdfkejfns$@!    node=node0
    """
    ha_dev = HA()
    chassis_cluster = _check_chassis_cluster(device_handle)
    cmd = 'request security tpm master-encryption-password set plain-text-password'

    if chassis_cluster:
        node = kwargs.get('node', 'both')
        node_list = ['node0', 'node1'] if node == 'both' else [node]
        for node in node_list:
            ha_dev.execute_cli_on_node(device=device_handle, node=node,
                                       command=cmd, pattern="password: "******"password: "******"successfully", (str(response)).lower()):
                result = True
            elif re.search("error: Passwords do not match", str(response)):
                raise Exception("error: Passwords do not match")
            elif re.search("Recommend at least length 12 and use of 3 character classes",
                           str(response)):
                raise Exception("error: Password does not meet required criteria.")
            else:
                raise Exception("Master Encryption Password could not be set")
    else:
        dev.execute_cli_command_on_device(device=device_handle,
                                          command=cmd, pattern="password: "******"password: "******"successfully", (str(response)).lower()):
            result = True
        elif re.search("error: Passwords do not match", str(response)):
            raise Exception("error: Passwords do not match")
        elif re.search("Recommend at least length 12 and use of 3 character classes",
                       str(response)):
            raise Exception("error: Password does not meet required criteria. "
                            "Recommend at least length 12 and use of 3 character classes")
        else:
            raise Exception("Master Encryption Password could not be set")

    return result
Esempio n. 8
0
    def waiting_for_pic_online(self, device, **kwargs):
        """Waiting a while to make sure wantted pic online

        Based on cmd "show chassis fpc pic-status", this method checking wantted pic whether online. This is useful for device reboot

        :param STR|LIST|TUPLE except_component:
            **OPTIONAL** As default, all device component must online, but you can give one or more component name here to avoid checking.

            For example:

                ```
                Slot 0   Online       SRX5k SPC II
                  PIC 0  Offline      SPU Cp
                  PIC 1  Online       SPU Flow
                  PIC 2  Online       SPU Flow
                  PIC 3  Offline      SPU Flow
                Slot 2   Online       SRX5k IOC II
                  PIC 0  Online       10x 10GE SFP+
                ```

            Above output will create an internal offline list: ["SLOT 0 PIC 0", "SLOT 0 PIC 3", "PIC 0", "PIC 3"], you can list these
            keywords in this option to skip them. This means you can just skip "PIC 0" for all SLOT, or set "SLOT 0 PIC 0" for specific PIC.

            By the way, component keyword is case insensitive, this means keyword "pic 0", "PIC 0", or "Slot 0 Pic 0" all match above output

            For IOC 3, 2 PICs always offline, and this method will skip them automatically.

        :param INT check_counter:
            **OPTIONAL** how many times to checking device status. Default: 10

        :param INT check_interval:
            **OPTIONAL** waiting interval between checking. Default: 30

        :param INT timeout:
            **OPTIONAL** timeout to get device response.

        :return:
            True/False. Or raise ValueError for invalid option

        :example:
            status = self.waiting_for_pic_online(device=r0, except_component=("PIC 0", "Slot 0", "Slot 1 PIC 2"), check_counter=10, check_interval=60)
        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["except_component"] = kwargs.get("except_component", ())
        options["check_counter"] = int(kwargs.get("check_counter", 10))
        options["check_interval"] = int(kwargs.get("check_interval", 30))
        options["timeout"] = int(kwargs.get("timeout", self.default["cli_show_timeout"]))

        if isinstance(options["except_component"], str):
            options["except_component"] = (options["except_component"], )

        checking_result = False
        get_pic_status_cmd = "show chassis fpc pic-status"
        for index in range(1, options["check_counter"] + 1):
            ioc3_component_cnt = 0
            device.log(message="Index {:02d}: FPC PIC status check...".format(index), level="INFO")

            response = dev.execute_cli_command_on_device(
                device=device,
                command=get_pic_status_cmd,
                channel="pyez",
                format="xml",
                xml_to_dict=True,
                timeout=options["timeout"],
            )
            if response is False:
                device.log(
                    message="cannot got FPC PIC status from device, waiting {} secs for next checking...".format(options["check_interval"]),
                    level="INFO",
                )
                time.sleep(options["check_interval"])
                continue

            if "multi-routing-engine-results" in response:
                response = response["multi-routing-engine-results"]["multi-routing-engine-item"]
                if not isinstance(response, (list, tuple)):
                    device.log(
                        message="only one node response occurred, waiting {} secs for next checking...".format(options["check_interval"]),
                        level="INFO",
                    )
                    time.sleep(options["check_interval"])
                    continue

            # SA always a DICT, but HA is a LIST that contain 2 nodes' response
            if not isinstance(response, (list, tuple)):
                response = [response, ]

            offline_component_list = []
            for node_item in response:
                try:
                    fpc_list = node_item["fpc-information"]["fpc"]
                except (TypeError, KeyError):
                    offline_component_list.append("FPC")
                    device.log(message="No FPC status contained.", level="INFO")
                    continue

                if not isinstance(fpc_list, (list, tuple)):
                    fpc_list = [fpc_list, ]

                for fpc in fpc_list:
                    fpc_state = fpc["state"] if "state" in fpc else None
                    fpc_slot = fpc["slot"] if "slot" in fpc else "Unknown"
                    fpc_description = fpc["description"] if "description" in fpc else "Unknown"
                    pic_list = fpc["pic"] if "pic" in fpc else None
                    fpc_name = "SLOT {}".format(fpc_slot)

                    if fpc_state is None or not re.match(r"Online", fpc_state.strip(), re.I):
                        if fpc_name not in offline_component_list:
                            offline_component_list.append(fpc_name)
                        continue

                    if re.search(r"\s+IOC3\s+", fpc_description):
                        device.log(message="'{}' card found on '{}'.".format(fpc_description, fpc_name), level="INFO")
                        ioc3_component_cnt += 1

                    if not pic_list:
                        device.log(message="no PIC infomation for FPC '{}'".format(fpc_description), level="INFO")
                        continue

                    if not isinstance(pic_list, (list, tuple)):
                        pic_list = [pic_list, ]

                    for pic in pic_list:
                        pic_slot = pic["pic-slot"] if "pic-slot" in pic else "Unknown"
                        pic_state = pic["pic-state"] if "pic-state" in pic else None
                        # pic_type = pic["pic-type"] if "pic-type" in pic else "Unknown"
                        pic_name = "{} PIC {}".format(fpc_name, pic_slot)

                        if pic_state is None or not re.match(r"Online", pic_state.strip(), re.I):
                            if pic_name not in offline_component_list:
                                offline_component_list.append(pic_name)

            if offline_component_list:
                device.log(message="OFFLINE component: {}".format(offline_component_list), level="INFO")

                for item in options["except_component"]:
                    item = item.upper()
                    if item in offline_component_list:
                        del offline_component_list[offline_component_list.index(item)]

            # IOC3 card always have 2 offline PIC
            if not offline_component_list or len(offline_component_list) == ioc3_component_cnt * 2:
                checking_result = True
                device.log(message="All FPC and PIC onlined...", level="INFO")
                break

            device.log(message="Waiting '{}' secs for next component checking...".format(options["check_interval"]), level="INFO")
            time.sleep(options["check_interval"])

        device.log(message="{} return value: {}".format(func_name, checking_result), level="INFO")
        return checking_result
Esempio n. 9
0
    def execute_command_on_vnf(self,
                               tag,
                               vnf_name,
                               cmd,
                               console=False,
                               mode="SHELL"):
        """
        Function to execute a command on a VNF that is either of type linux / junos.

        Python Example:
            _cmd_shell_ = "uptime"
            _cmd_cli_ = "show version"
            _cmd_config_ = "show system"
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='centos', cmd=_cmd_shell_, mode='shell', console=False)
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='vsrx', cmd=_cmd_cli_, mode='cli', console=False)
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='vjunos0', cmd=_cmd_config_, mode='config', console=False)
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='centos', cmd=_cmd_shell_, mode='shell', console=True)
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='vsrx', cmd=_cmd_cli_, mode='cli', console=True)
            _response_ = execute_command_on_vnf(tag='r0', vnf_name='vjunos0', cmd=_cmd_config_, mode='config', console=True)

        Robot Example:
            ${cmd_shell}    Set Variable   uptime
            ${cmd_cli}      Set Variable   show version
            ${cmd_config}   Set Variable   show system

            ${response}     Execute Command On VNF   tag=r0  vnf_name=centos   cmd=${cmd_shell}   mode=shell   console=${false}
            ${response}     Execute Command On VNF   tag=r0  vnf_name=vsrx     cmd=${cmd_cli}     mode=cli     console=${false}
            ${response}     Execute Command On VNF   tag=r0  vnf_name=vjunos0  cmd=${cmd_config}  mode=config  console=${false}
            ${response}     Execute Command On VNF   tag=r0  vnf_name=centos   cmd=${cmd_shell}   mode=shell   console=${true}
            ${response}     Execute Command On VNF   tag=r0  vnf_name=vsrx     cmd=${cmd_cli}     mode=cli     console=${true}
            ${response}     Execute Command On VNF   tag=r0  vnf_name=vjunos0  cmd=${cmd_config}  mode=config  console=${true}

        :param str tag:
          **REQUIRED** Name of the resource on which this VNF is hosted

        :param str vnf_name:
          **REQUIRED** Name of the VNF

        :param str cmd:
          **REQUIRED** Command to be executed

        :param bool console:
          **OPTIONAL** Set to True if command is to be executed on console to vnf, else to False for ssh
          Default: False

        :param str mode:
          **OPTIONAL** Mode of execution shell/cli/config. For linux VNFs, only shell is valid value and others apply for junos
                       type VNFs. It is up to the user to invoke this function accordingly
          Default: shell
        """
        try:
            self.__log_info__(
                "Executing Command: %s in Mode: %s on VNF: %s on %s" %
                (cmd, mode, vnf_name, tag))
            _device_handle_ = None
            if console is True:
                _status_, _device_handle_ = self.get_vnf_handle(tag,
                                                                vnf_name,
                                                                mode="console")
            else:
                _status_, _device_handle_ = self.get_vnf_handle(tag,
                                                                vnf_name,
                                                                mode="ssh")
        except Exception as _exception_:
            raise Exception("Exception caught: %s: %s" %
                            (type(_exception_), _exception_))

        mode = mode.lower()
        _expected_modes_ = ["shell", "cli", "config"]
        if mode not in _expected_modes_:
            raise Exception("Unsupported value for mode: %s" % mode)

        try:
            if mode == "shell":
                _resp_ = execute_shell_command_on_device(
                    device=_device_handle_, command=cmd)
            elif mode == "cli":
                _resp_ = execute_cli_command_on_device(device=_device_handle_,
                                                       command=cmd)
            elif mode == "config":
                _resp_ = execute_config_command_on_device(
                    device=_device_handle_, command_list=cmd)

            return True, _resp_

        except Exception as _exception_:
            raise Exception("Exception caught: %s: %s" %
                            (type(_exception_), _exception_))
Esempio n. 10
0
    def fetch_route_instance_entry(self, device, **kwargs):
        """Get route instance entries

        This method use basic command "show route instance". More options will be tailed to basic command.

        HighEnd/LowEnd, SA/HA are supported. According to option "return_mode", method can return a LIST contain all
        flat entries or just plain-text

        :param STR name:
            *OPTIONAL* Instance name. default: None

        :param STR more_options:
            *OPTIONAL* String will tailed to base cmd. Default: None

        :param str return_mode:
            *OPTIONAL* response format that one of "TEXT", "ENTRY_LIST" or "FLAT_DICT. Default: ENTRY_LIST

        :param int timeout:
            *OPTIONAL* timeout to get command response. default: 300

        :return:
            If option "return_mode" is 'TEXT', just return device response without any more process.

            if option 'return_mode' is 'ENTRY_LIST' (default), return a LIST contain all entries. No entry found just
            return empty LIST

        :example:
            [
                {
                    'instance_name': 'master',
                    'instance_type': 'forwarding',
                    'instance_rib': [
                        {
                            'irib_name': 'inet.0',
                            'irib_active_count': '22',
                            'irib_holddown_count': '0',
                            'irib_hidden_count': '0'
                        },
                        {
                            'irib_name': 'inet6.0',
                            'irib_active_count': '7',
                            'irib_holddown_count': '0',
                            'irib_hidden_count': '0'
                        }
                    ]
                }
            ]

            if option 'return_mode' is 'FLAT_DICT', return a LIST contain all entries like below:

        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["name"] = kwargs.pop('name', None)
        options["more_options"] = kwargs.pop('more_options', None)
        options["return_mode"] = str(kwargs.pop("return_mode",
                                                "ENTRY_LIST")).strip().upper()
        options["print_response"] = kwargs.pop("print_response", True)
        options["timeout"] = int(
            kwargs.pop('timeout', self.default['cli_show_timeout']))

        if options["return_mode"] not in ("TEXT", "ENTRY_LIST"):
            raise ValueError(
                "'return_mode' must be 'ENTRY_LIST' or 'TEXT', not '{}'".
                format(options["return_mode"]))

        if options["return_mode"] == "ENTRY_LIST":
            response_format = "xml"
        else:
            response_format = "text"

        # combine options to basic command
        cmd_elements = []
        cmd_elements.append("show route instance")

        if options["name"]:
            cmd_elements.append(options["name"])

        if options["more_options"]:
            cmd_elements.append(options["more_options"])

        # get route instance entries
        response = dev.execute_cli_command_on_device(
            device=device,
            command=" ".join(cmd_elements),
            channel="pyez",
            format=response_format,
            timeout=options["timeout"],
        )

        # if user want get "text" mode response, just return here
        if options["return_mode"] == "TEXT":
            device.log(message="{} return value:\n{}".format(
                func_name, response),
                       level="INFO")
            return response

        if response is False:
            return False

        response = self.xml.strip_xml_response(
            self.xml.xml_to_pure_dict(response), return_list=False)
        instance_core_list = self.tool.set_element_list(
            response["instance-information"]["instance-core"])
        route_instance_entry_list = []
        # HE/LE, SA/HA device all have same structure response
        for instance_core in instance_core_list:
            info = {}
            for keyword in instance_core:
                underscore_keyword = self.tool.underscore_and_lowercase_transit(
                    keyword)

                # instance_rib have another argument list
                if underscore_keyword == "instance_rib":
                    rib_list = []
                    instance_core[keyword] = self.tool.set_element_list(
                        instance_core[keyword])
                    for rib_entry in instance_core[keyword]:
                        rib_info = {}
                        for rib_keyword in rib_entry:
                            rib_underscore_keyword = self.tool.underscore_and_lowercase_transit(
                                rib_keyword)
                            rib_info[rib_underscore_keyword] = str(
                                rib_entry[rib_keyword])
                        rib_list.append(rib_info)

                    info[underscore_keyword] = rib_list
                    continue

                info[underscore_keyword] = str(instance_core[keyword])

            route_instance_entry_list.append(info)

        flat_entry_list = []
        for entry in route_instance_entry_list:
            info = {}
            for keyword in entry:
                if keyword != "instance_rib":
                    info[keyword] = entry[keyword]

            if "instance_rib" in entry:
                for instance_rib_entry in entry["instance_rib"]:
                    for keyword in instance_rib_entry:
                        info["instance_rib_{}".format(
                            keyword)] = instance_rib_entry[keyword]

                    flat_entry_list.append(copy.deepcopy(info))
            else:
                flat_entry_list.append(copy.deepcopy(info))

        if options["print_response"] is True:
            device.log(message="return value:\n{}".format(
                self.tool.pprint(flat_entry_list)),
                       level="INFO")
        return flat_entry_list
Esempio n. 11
0
    def get_ioc_slot_number(self, device, **kwargs):
        """Get IOC slot id

        This method based on command "show chassis fpc pic-status" and return ioc's slot number. This is useful to enable/disable services-offload
        configuration later.

        :param INT|STR|LIST except_slot_number:
            *OPTIONAL* Given slot number(s) will not added to list. Default: None

        :param INT|STR largest_slot_number:
            *OPTIONAL* For HA topology. Ignore slot id greater or equal given slot number. Default: 6

        :param BOOL force_get:
            *OPTIONAL* If set True, will get ioc_slot_number list every time. Set False will return ioc_slot_number from cache.

            **IMPORTANT: If 'force_get' is False, this method will return ioc_slot_number from cache, it means will not remove 'except_slot_number'.**
            **If need except more slot number, pls set 'force_get'=True**

            Default: False

        :return:
            Return a LIST that contain all IOC's slot number
        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["except_slot_number"] = kwargs.pop("except_slot_number", [])
        options["largest_slot_number"] = int(
            kwargs.pop("largest_slot_number", 6))
        options["force_get"] = self.tool.check_boolean(
            kwargs.pop("force_get", False))

        if not isinstance(options["except_slot_number"], (list, tuple)):
            options["except_slot_number"] = (options["except_slot_number"], )

        if len(options["except_slot_number"]) != 0 \
           or func_name not in self.hidden_info \
           or str(device) not in self.hidden_info[func_name]:
            options["force_get"] = True

        if options["force_get"] is False and str(
                device) in self.hidden_info[func_name]:
            return_value = self.hidden_info[func_name][str(device)]
            device.log(message="{} return value: {}".format(
                func_name, return_value),
                       level="INFO")
            return return_value

        ioc_number_sets = set()
        response = dev.execute_cli_command_on_device(
            device=device,
            command="show interface terse",
            channel="text",
            format="text")
        for line in response.splitlines():
            match = re.search(r"xe\-(\d+)\/\d+\/\d+\s+", line)
            if match and int(match.group(1)) <= options["largest_slot_number"]:
                ioc_number_sets.add(int(match.group(1)))

        for except_number in options["except_slot_number"]:
            except_number = int(except_number)
            if except_number in ioc_number_sets:
                ioc_number_sets.remove(except_number)

        return_value = list(ioc_number_sets)
        if func_name not in self.hidden_info:
            self.hidden_info[func_name] = {}
        self.hidden_info[func_name][str(device)] = return_value

        device.log(message="{} return value: {}".format(
            func_name, return_value),
                   level="INFO")
        return return_value
Esempio n. 12
0
    def set_services_offload(self, device, ioc_slot_number, **kwargs):
        """Enable/Disable services offload on FPC

        :param INT|STR|LIST ioc_slot_number:
            *MANDATORY* IOC slot number or number list to enable/disable services-offload.

        :param STR action:
            *OPTIONAL* Enable or Disable services-offload on given ioc slot number(s). Default: Enable

        :param STR reboot_mode:
            *OPTIONAL* One of "None", "Reboot", "Gracefully", "Immediately" or "Soft". Case-insensitive. Default: None

            - None: Do not reboot
            - Reboot: Reboot device by command: "request system reboot"
            - Gracefully: by command: "restart chassis-control gracefully"
            - Immediately: by command: "restart chassis-control immediately"
            - Soft: by command: "restart chassis-control soft"

        :param BOOL waiting_for_pic_online:
            *OPTIONAL* Waiting for all PIC online after device reboot. This option only for option 'reboot_mode' is not None. Default: True

        :param STR|LIST waiting_for_pic_online_except_component:
            *OPTIONAL* Set security.chassis.chassis.waiting_for_pic_online for detail. Default: ()

        :param INT|STR waiting_for_pic_online_check_interval:
            *OPTIONAL* Check interval (sec) during waiting_for_pic_online. Default: 30

        :param INT|STR waiting_for_pic_online_check_counter:
            *OPTIONAL* Check counter (sec) during waiting_for_pic_online. Default: 20

        :return:
            True/False for services-offload enabled/disabled for given ioc_slot_number.
        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["ioc_slot_number"] = ioc_slot_number
        options["action"] = str(kwargs.pop("action", "Enable")).upper()
        options["reboot_mode"] = str(kwargs.pop("reboot_mode", None)).lower()
        options["waiting_for_pic_online"] = self.tool.check_boolean(
            kwargs.pop("waiting_for_pic_online", True))
        options["waiting_for_pic_online_except_component"] = kwargs.pop(
            "waiting_for_pic_online_except_component", ())
        options["waiting_for_pic_online_check_interval"] = int(
            kwargs.pop("waiting_for_pic_online_check_interval", 30))
        options["waiting_for_pic_online_check_counter"] = int(
            kwargs.pop("waiting_for_pic_online_check_counter", 20))

        if not isinstance(options["ioc_slot_number"], (list, tuple)):
            options["ioc_slot_number"] = (options["ioc_slot_number"], )

        if options["action"] not in ("ENABLE", "DISABLE"):
            raise ValueError(
                "{}: option 'action' must be enable or disable but got '{}'".
                format(func_name, options["action"]))

        if options["reboot_mode"] not in ("none", "reboot", "gracefully",
                                          "immediately", "soft"):
            raise ValueError(
                "{}: option 'reboot_mode' must be 'none', 'reboot', 'gracefully', 'immediately' or 'soft'"
                .format(func_name))

        action_str = "set" if options["action"] == "ENABLE" else "delete"
        cmds = []
        for number in options["ioc_slot_number"]:
            cmds.append("{} chassis fpc {} np-cache".format(
                action_str, number))
        status = dev.execute_config_command_on_device(device=device,
                                                      command=cmds,
                                                      commit=True)

        if options["reboot_mode"] == "none":
            device.log(message="{} return value: {}".format(func_name, status),
                       level="INFO")
            return status

        elif options["reboot_mode"] == "reboot":
            if device.is_ha() is True:
                status = dev.reboot_device(device=device,
                                           timeout=1200,
                                           all=True)
            else:
                status = dev.reboot_device(device=device, timeout=1200)

        else:
            status = dev.execute_cli_command_on_device(
                device=device,
                channel="text",
                format="text",
                command="restart chassis-control {}".format(
                    options["reboot_mode"]),
            )

        if options["waiting_for_pic_online"] is False:
            device.log(message="{} return value: {}".format(func_name, status),
                       level="INFO")
            return status

        time.sleep(10)
        status = self.chassis.waiting_for_pic_online(
            device=device,
            except_component=options[
                "waiting_for_pic_online_except_component"],
            check_interval=options["waiting_for_pic_online_check_interval"],
            check_counter=options["waiting_for_pic_online_check_counter"],
        )
        device.log(message="{} return value: {}".format(func_name, status),
                   level="INFO")
        return status
Esempio n. 13
0
def check_vmhost(device, **kwargs):
    """checking vmhost based device for SRX

    There are 2 ways to upgrade or ISSU upgrade device, one is "request system software ..." and the other is
    "request vmhost software ...". This method checking device hardware and tell you keyword of 'system' or 'vmhost'.

    Return:
        'system' or 'vmhost'
    """
    func_name = TOOL.get_current_function_name()
    dev_fingerprint = str(device)

    vmhost_keyword_list = (re.compile(r"RE-2000x6", re.I), )

    options = {}
    options["force"] = TOOL.check_boolean(kwargs.pop("force", False))

    if func_name not in RUNTIME:
        RUNTIME[func_name] = {}

    if dev_fingerprint not in RUNTIME[func_name]:
        RUNTIME[func_name][dev_fingerprint] = None

    if options["force"] is False and RUNTIME[func_name][
            dev_fingerprint] is not None:
        return RUNTIME[func_name][dev_fingerprint]

    cmd = "show chassis hardware"
    if device.is_ha() is True:
        cmd += " node 0"

    component_list = dev.execute_cli_command_on_device(device=device,
                                                       channel="pyez",
                                                       format="xml",
                                                       xml_to_dict=True,
                                                       command=cmd)
    if device.is_ha() is True:
        component_list = component_list["multi-routing-engine-results"][
            "multi-routing-engine-item"]

    # strip root tag then all sub chassis components should be list or tuple
    component_list = component_list["chassis-inventory"]["chassis"][
        "chassis-module"]
    if not isinstance(component_list, (tuple, list)):
        component_list = (component_list, )

    return_value = "system"
    for component in component_list:
        if "name" not in component or not re.match(
                r"Routing Engine",
                str(component["name"]).strip()):
            continue

        for pattern in vmhost_keyword_list:
            if re.search(pattern, component["description"]):
                return_value = "vmhost"
                break

        if return_value == "vmhost":
            break

    RUNTIME[func_name][dev_fingerprint] = return_value

    device.log(message="{} return value: {}".format(func_name, return_value),
               level="INFO")
    return return_value
Esempio n. 14
0
def get_interface_hardware_address(device, interface_name, **kwargs):
    """Get device interface MAC address

    This function get interface MAC address from Linux host or SRX device.

    :param STR platform:
        *OPTIONAL* Device platform string such as 'Linux' or 'srx'. Set None to get platform automatically. default: None

    :param BOOL uppercase:
        *OPTIONAL* Uppercase hardware address and return. default: False

    :return: Return interface MAC address or raise RuntimeException
    """
    func_name = TOOL.get_current_function_name()
    device.log(message=TOOL.print_title(func_name), level="INFO")

    options = {}
    options["platform"] = kwargs.pop("platform", None)
    options["uppercase"] = TOOL.check_boolean(kwargs.pop("uppercase", False))

    if not hasattr(device, "get_model"):
        raise RuntimeError(
            "Device object '{}' do not have 'get_model' method.".format(
                str(device)))

    if options["platform"] is None:
        if str(device.get_model()).upper() in ("LINUX", "CENTOS", "FEDORA"):
            options["platform"] = "LINUX"
        else:
            options["platform"] = "SRX"
    else:
        options["platform"] = options["platform"].upper()

    # interface name maybe set to ge-0/0/1.0 or eth1:1, but only ge-0/0/1 and eth1 needed
    interface_name = re.split(r"[\.\:]", interface_name)[0]

    return_value = None
    if options["platform"] == "LINUX":
        result = dev.execute_shell_command_on_device(
            device=device, command="/sbin/ifconfig {}".format(interface_name))
        match = re.search(r"ether\s+(\S+)\s+", result)
        if match and len(re.split(r":", match.group(1))) == 6:
            return_value = match.group(1)
        else:
            raise RuntimeError(
                "Cannot get interface MAC address from device '{}'\n{}".format(
                    str(device), result))

    else:
        result = dev.execute_cli_command_on_device(
            device=device,
            format="xml",
            channel="xml",
            xml_to_dict=True,
            command="show interface {}".format(interface_name))

        if "physical-interface" not in result["interface-information"]:
            msg = "No interface response from device '{}'".format(str(device))
            if "rpc-error" in result["interface-information"]:
                msg = result["interface-information"]["rpc-error"][
                    "error-message"]

            raise RuntimeError(msg)

        return_value = str(result["interface-information"]
                           ["physical-interface"]["hardware-physical-address"])

    if options["uppercase"] is True:
        return_value = return_value.upper()

    device.log(message="{} return value: {}".format(func_name, return_value),
               level="INFO")
    return return_value
Esempio n. 15
0
    def fetch_cpu_pinning_info(self, device_handle, vnf_name):
        """
        Function to fetch the CPU Pinning Information for VNFs hosted on the NFX

        Python Example:
            _cpu_pin_ = fetch_cpu_pinning_info(device_handle=_dh_, vnf_name='centos-1')

        Robot Example:
            ${cpu_usage}   Fetch CPU Pinning Info   device_handle=${jdm}   vnf_name=centos-1

        :params str device_handle:
          **REQUIRED** Device handle for JDM
        :params str vnf_name:
          **REQUIRED** Name of the VNF hosted on the NFX
        :returns:
          Dictionary of logical cpu as keys and physical cpus list as value
        """
        try:

            t.log("INFO", "Fetching CPU Pinning Info of VNF: %s" % vnf_name)

            _cmd_ = "show system visibility cpu"
            _output_ = execute_cli_command_on_device(device=device_handle,
                                                     command=_cmd_)

            _cpu_pinning_flag_ = False
            _return_dict_ = {}
            _found_ = False
            for _row_ in _output_.split("\n"):

                _match_ = re.match(r".*CPU\s+Pinning.*", _row_)
                if _match_ is not None:
                    _cpu_pinning_flag_ = True
                    continue

                if _cpu_pinning_flag_ is True:
                    _match_ = re.match(r"(\S+)\s+(\d+)\s+(\d+).*", _row_)
                    if _match_ is not None:
                        _vnf_ = _match_.group(1)
                        _vcpu_ = _match_.group(2)
                        _cpu_ = _match_.group(3)
                        t.log(
                            "INFO",
                            "Match: '%s', vnf: '%s', vcpu: '%s', cpu: '%s'" %
                            (_row_, _vnf_, _vcpu_, _cpu_))
                        if _vnf_ != vnf_name:
                            t.log("INFO", " - vnf ignored")
                            continue

                        if _vcpu_ not in _return_dict_.keys():
                            _return_dict_[_vcpu_] = [str(_cpu_)]
                        else:
                            _return_dict_[_vcpu_].append(str(_cpu_))
                        _found_ = True

            if _found_ is False:
                raise Exception(
                    "No CPU Pinning Information found for VNF: %s" % vnf_name)
            else:
                return True, _return_dict_

        except Exception as _exception_:
            raise Exception("Error: %s: %s" % (type(_exception_), _exception_))
Esempio n. 16
0
    def change_multitenancy_mode(self, device, mode="lsys", **kwargs):
        """switch logical-system mode to tradition or logical-domain mode.

        Base on command "set system processes multitenancy mode" to change LSYS mode, and reboot device if needed.

        This method support both SA/HA. For HA setup, will reboot 2 nodes in parallel and waiting for all FPC online

        :param STR mode:
            *OPTIONAL* One of lsys, ld, logical-system or logical-domain (case insensitive). default: lsys

        :param BOOL reboot_if_need:
            *OPTIONAL* If multitenancy mode changed and need reboot, reboot device (SA) or all nodes (HA) in parallel. default: True

        :param INT|STR reboot_timeout:
            *OPTIONAL* reboot device timeout. default: 600

        :param BOOL checking_fpc_online:
            *OPTIONAL* After rebooting, waiting all FPC PIC online by loop checking. default: True

        :param INT|STR fpc_online_check_counter:
            *OPTIONAL* Loop counter to check FPC PIC online. default: 10

        :param INT|STR fpc_online_check_interval:
            *OPTIONAL* Loop interval between each checking. default: 30

        :param STR|LIST|TUPLE fpc_online_except_component:
            *OPTIONAL* As default, all device component must online, but you can give one or more component name here to avoid checking.

            For example:

                ```
                Slot 0   Online       SRX5k SPC II
                  PIC 0  Offline      SPU Cp
                  PIC 1  Online       SPU Flow
                  PIC 2  Online       SPU Flow
                  PIC 3  Offline      SPU Flow
                Slot 2   Online       SRX5k IOC II
                  PIC 0  Online       10x 10GE SFP+
                ```

            Above output will create an internal offline list: ["SLOT 0 PIC 0", "SLOT 0 PIC 3", "PIC 0", "PIC 3"], you can list these
            keywords in this option to skip them. This means you can just skip "PIC 0" for all SLOT, or set "SLOT 0 PIC 0" for specific PIC.

            By the way, component keyword is case insensitive, this means keyword "pic 0", "PIC 0", or "Slot 0 Pic 0" all match above output

            For IOC 3, 2 PICs always offline, and this method will skip them automatically.

        :param INT|STR timeout:
            *OPTIONAL* show and commit timeout. default: 300

        :return:
            If lsys mode change succeed and implemented, and all PIC onlined, return True. Otherwise return False
        """
        func_name = self.tool.get_current_function_name()
        device.log(message=self.tool.print_title(func_name), level="INFO")

        options = {}
        options["mode"] = mode.strip().upper()
        options["reboot_if_need"] = kwargs.get('reboot_if_need', True)
        options["reboot_timeout"] = int(kwargs.get("reboot_timeout", 600))
        options["checking_fpc_online"] = kwargs.get("checking_fpc_online",
                                                    True)
        options["fpc_online_check_counter"] = int(
            kwargs.get("fpc_online_check_counter", 10))
        options["fpc_online_check_interval"] = int(
            kwargs.get("fpc_online_check_interval", 30))
        options["fpc_online_except_component"] = kwargs.get(
            "fpc_online_except_component", ())
        options["timeout"] = int(
            kwargs.get("timeout", self.default["CLI_COMMIT_TIMEOUT"]))

        if options["mode"] in ("LSYS", "LOGICAL-SYSTEM"):
            wanted_mode = "logical-system"
        elif options["mode"] in ("LD", "LOGICAL-DOMAIN"):
            wanted_mode = "logical-domain"
        else:
            raise ValueError(
                "'mode' must be 'LSYS' 'LD', 'Logical-system' or 'Logical-domain' but got '{}'"
                .format(options["mode"]))

        # make sure operate on primary node for HA setup
        status = device.is_ha()
        if status is True:
            if device.node0.is_master() is True:
                primary_device = device.node0
            else:
                primary_device = device.node1
        else:
            primary_device = device

        status = dev.execute_config_command_on_device(
            device=primary_device,
            command="set system processes multitenancy mode {}".format(
                wanted_mode),
            get_response=False,
            commit=True,
            timeout=options["timeout"],
        )
        if status is False:
            device.log(
                message="commit multitenancy mode configuration failed.",
                level="ERROR")
            return status

        show_cmd = "show system processes multitenancy"
        response_dict = dev.execute_cli_command_on_device(
            device=primary_device,
            command=show_cmd,
            channel="pyez",
            format="xml",
            xml_to_dict=True)
        device.log(message="show command response:\n{}".format(
            self.tool.pprint(response_dict)),
                   level="DEBUG")

        if "multi-routing-engine-results" in response_dict:
            response_dict = response_dict["multi-routing-engine-results"][
                "multi-routing-engine-item"]

        dev_configure_mode = response_dict["show-mtenancy"][
            "mtenancy-mode-config"]
        dev_configure_status = ""
        if "mtenancy-mode-config-status" in response_dict["show-mtenancy"]:
            dev_configure_status = response_dict["show-mtenancy"][
                "mtenancy-mode-config-status"]

        dev_running_mode = response_dict["show-mtenancy"][
            "mtenancy-mode-running"]
        dev_configure_status = ""
        if "mtenancy-mode-running-status" in response_dict["show-mtenancy"]:
            dev_configure_status = response_dict["show-mtenancy"][
                "mtenancy-mode-running-status"]

        if dev_configure_mode == dev_running_mode and not re.search(
                r"must reboot", dev_configure_status):
            device.log(
                message=
                "multitenancy is working on '{}' mode and do not need rebooting."
                .format(dev_running_mode),
                level="INFO")
            device.log(message="{} return value: True".format(func_name),
                       level="INFO")
            return True

        dev.reboot_device(device=device, all=True)

        # waiting for all PIC online
        return_value = self.chassis.waiting_for_pic_online(
            device=device,
            except_component=options["fpc_online_except_component"],
            check_counter=options["fpc_online_check_counter"],
            check_interval=options["fpc_online_check_interval"],
        )

        device.log(message="{} return value: {}".format(
            func_name, return_value),
                   level="INFO")
        return return_value