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
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)
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
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
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
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