Example #1
0
    def set_status(self, state):

        if self.__in_firmware_collection_mode is True:
            return

        if self.__return_status == state:
            return

        if state not in list(plugin_status_types.keys()):
            raise Exception(
                f"Status '{state}' is invalid, needs to be one of these: %s" %
                list(plugin_status_types.keys()))

        if plugin_status_types[state] > plugin_status_types[
                self.__return_status]:
            self.__return_status = state
Example #2
0
    def __setattr__(self, key, value):

        # add source data without any formatting
        if key == "source_data":
            super().__setattr__(key, value)
            return

        if key not in self.valid_attributes:
            raise AttributeError("'%s' object has no attribute '%s'" %
                                 (self.__class__.__name__, key))

        current_value = getattr(self, key)

        if value is None and current_value is None:
            return

        if isinstance(value, str):
            value = value.strip()

            if len(value) == 0:
                value = None

            def is_int(v):
                return v == '0' or (v if v.find('..') > -1 else v.lstrip(
                    '-+').rstrip('0').rstrip('.')).isdigit()

            def is_float(v):
                try:
                    _ = float(v)
                except Exception:
                    return False
                return True

            # skip formatting of certain attributes
            if value is not None and key not in [
                    "id", "name", "firmware", "serial", "version"
            ]:
                if is_int(value):
                    value = int(float(value))

                elif is_float(value):
                    value = float(value)

                elif value.upper() in plugin_status_types.keys():
                    value = value.upper()

        if isinstance(current_value, list):
            if value is None:
                value = list()
            elif isinstance(value, (str, int, float)):
                value = [value]
            elif not isinstance(value, list):
                value = [f"{value}"]
        else:
            if isinstance(value, (list, dict, set, tuple)):
                value = f"{value}"

        super().__setattr__(key, value)
Example #3
0
    def __init__(self,
                 state="OK",
                 command=None,
                 text=None,
                 location=None,
                 is_summary=False,
                 log_entry=False):

        if state not in list(plugin_status_types.keys()):
            raise Exception(
                f"Status '{state}' is invalid, needs to be one of these: %s" %
                list(plugin_status_types.keys()))

        self.state = state
        self.command = command
        self.text = text
        self.location = location
        self.is_summary = is_summary
        self.log_entry = log_entry
Example #4
0
    def set_status(self, state):

        if self.__return_status == state:
            return

        if state not in list(plugin_status_types.keys()):
            raise Exception(f"Status '{state}' is invalid")

        if plugin_status_types[state] > plugin_status_types[
                self.__return_status]:
            self.__return_status = state
Example #5
0
def get_status_data(status_data=None):
    """
        Some vendors provide incomplete status information
        This function is meant to parse a status structure
        and return a sanitized representation.

        Parameters
        ----------
        status_data: str, dict
            the status structure to parse

        Returns
        -------
        dict
            a unified representation of status data
            as defined in "return_data" var
    """

    return_data = {"Health": None, "HealthRollup": None, "State": None}
    """
        If it's just a string then try to check if it's one of the valid
        status types and add it as "Health" otherwise fill State
    """
    if isinstance(status_data, str):
        if status_data.upper() in plugin_status_types.keys():
            return_data["Health"] = status_data.upper()
        else:
            return_data["State"] = status_data

    # If status data is a dict then try to match the keys case insensitive.
    elif isinstance(status_data, dict):
        for status_key, status_value in status_data.items():
            for key in return_data.keys():
                if status_key.lower() == key.lower():
                    if status_value is not None and \
                            key.lower().startswith("health") and \
                            status_value.upper() in plugin_status_types.keys():
                        status_value = status_value.upper()
                    return_data[key] = status_value

    return return_data
Example #6
0
def get_event_log_huawei(plugin_object, event_type, system_manager_id):

    num_entry = 0
    data_now = datetime.datetime.now()
    date_warning = None
    date_critical = None
    log_entries = list()

    if event_type == "System":
        redfish_url = f"{system_manager_id}/LogServices/Log1/Entries"

        log_entries = plugin_object.rf.get(redfish_url).get("Members")
    else:

        manager_data = plugin_object.rf.get(system_manager_id)

        if manager_data.get("LogServices") is None or len(manager_data.get("LogServices")) == 0:
            plugin_object.add_output_data("UNKNOWN", f"No 'LogServices' found for redfish URL '{system_manager_id}'",
                                          summary=not plugin_object.cli_args.detailed)
            return

        log_services_data = plugin_object.rf.get(grab(manager_data, "LogServices/@odata.id", separator="/")) or dict()

        # this should loop over following LogServices
        # https://device_ip/redfish/v1/Managers/1/LogServices/OperateLog/Entries
        # https://device_ip/redfish/v1/Managers/1/LogServices/RunLog/Entries
        # https://device_ip/redfish/v1/Managers/1/LogServices/SecurityLog/Entries

        for manager_log_service in log_services_data.get("Members") or list():
            log_entries.extend(plugin_object.rf.get(manager_log_service.get("@odata.id") + "/Entries").get("Members"))

    if plugin_object.cli_args.warning:
        date_warning = data_now - datetime.timedelta(days=int(plugin_object.cli_args.warning))
    if plugin_object.cli_args.critical:
        date_critical = data_now - datetime.timedelta(days=int(plugin_object.cli_args.critical))

    if event_type == "Manager":
        log_entries = sorted(log_entries, key=lambda i: i['Created'], reverse=True)

    for log_entry in log_entries:

        if log_entry.get("Id") is None:
            event_entry = plugin_object.rf.get(log_entry.get("@odata.id"))
        else:
            event_entry = log_entry

        num_entry += 1

        """
        It is not really clear what a "Asserted" and a "Deasserted" event looks like.
        We could assume that an "Asserted" event contains a "MessageId" and a
        "Deasserted" event doesn't. And the Only relation between these events is the
        exact same "Message" text. The "EventID" isn't really helpful either.
        And a clearing (Deasserted) of an alarm doesn't seem to work reliably either.
        It is also not possible to mark an event as "repaired" in iBMC.

        Due to all the above stated issues we implement a simple critical and warnings
        days logic as with HP Manager event logs. Otherwise uncleared events will alarm
        forever.
        """

        severity = event_entry.get("Severity")
        message = event_entry.get("Message")
        date = event_entry.get("Created")
        entry_date = get_log_entry_time(date)
        log_name = event_entry.get("Name")
        source = ""
        status = "OK"

        if severity is not None:
            severity = severity.upper()
        else:
            severity = "OK"

        # get log source information
        if event_type == "System":
            log_name = "%s/%s" % (event_entry.get("EntryType"), event_entry.get("EventType"))
            source = "[%s]" % grab(event_entry, f"Oem.{plugin_object.rf.vendor_dict_key}.Level")
        elif log_name == "Operate Log":
            oem_data = grab(event_entry, f"Oem.{plugin_object.rf.vendor_dict_key}")
            if oem_data is not None:
                source = "[%s/%s/%s]" % \
                         (oem_data.get("Interface"), oem_data.get("User"), oem_data.get("Address"))

        elif log_name == "Run Log":
            alert_level = grab(event_entry, f"Oem.{plugin_object.rf.vendor_dict_key}.Level")
            source = f"[{alert_level}]"
            if alert_level == "WARN":
                severity = "WARNING"
            if alert_level == "CRIT":
                severity = "CRITICAL"

        elif log_name == "Security Log":
            oem_data = grab(event_entry, f"Oem.{plugin_object.rf.vendor_dict_key}")
            if oem_data is not None:
                source = "%s/%s" % (oem_data.get("Host"), oem_data.get("Interface"))

        # check for WARNING and CRITICAL
        if date_critical is not None:
            if entry_date > date_critical.astimezone(entry_date.tzinfo) and severity != "OK":
                status = "CRITICAL" if severity not in list(plugin_status_types.keys()) else severity
        if date_warning is not None:
            if entry_date > date_warning.astimezone(entry_date.tzinfo) and status != "CRITICAL" and severity != "OK":
                status = "WARNING" if severity not in list(plugin_status_types.keys()) else severity

        plugin_object.add_log_output_data(status, f"{date}: {log_name}: {source}: {message}")

        # obey max results returned
        if plugin_object.cli_args.max is not None and num_entry >= plugin_object.cli_args.max:
            return

    return