def get_system_nics(plugin_object, redfish_url): def get_network_port(port_data=None, network_function_id=None, return_data=False): # could be # * a string # * a dict with just the link # * a dict with full data port_response = None redfish_path = None if isinstance(port_data, dict): if port_data.get("Id") is not None: port_response = port_data else: redfish_path = port_data.get("@odata.id") elif isinstance(port_data, str): redfish_path = port_data # query data if port_response is None and redfish_path is not None: port_response = plugin_object.rf.get_view(f"{redfish_path}{plugin_object.rf.vendor_data.expand_string}") if port_response is None: return NetworkPort() # get health status status_data = get_status_data(port_response.get("Status")) # get Link speed current_speed = \ port_response.get("CurrentLinkSpeedMbps") or \ grab(port_response, "SupportedLinkCapabilities.0.LinkSpeedMbps") or \ grab(port_response, "SupportedLinkCapabilities.LinkSpeedMbps") if isinstance(current_speed, str): current_speed = current_speed.replace("Gbps", "000") if str(current_speed) == "-": current_speed = None # get port number if port_response.get("PhysicalPortNumber"): nic_port_name = "Port " + port_response.get("PhysicalPortNumber") else: nic_port_name = port_response.get("Name") if plugin_object.rf.vendor == "Cisco" and network_function_id is not None: port_id = f"{network_function_id}.{port_response.get('Id')}" else: port_id = port_response.get('Id') if plugin_object.rf.vendor != "Dell": port_id = f"{adapter_id}.{port_id}" # check if port has already be added if port_id in [p.id for p in plugin_object.inventory.get(NetworkPort)]: print(f"ALREADY in INVENTORY: {port_id}") return network_port_inventory = NetworkPort( id=port_id, name=port_response.get("Name"), port_name=nic_port_name, health_status=status_data.get("Health"), operation_status=status_data.get("State"), addresses=format_interface_addresses(grab(port_response, "AssociatedNetworkAddresses")), link_type=port_response.get("ActiveLinkTechnology"), autoneg=grab(port_response, "SupportedLinkCapabilities.0.AutoSpeedNegotiation"), current_speed=current_speed, capable_speed=grab(port_response, "SupportedLinkCapabilities.0.CapableLinkSpeedMbps.0"), link_status=f"{port_response.get('LinkStatus') or ''}".replace("Link", ""), system_ids=system_id ) network_port_inventory.add_relation(plugin_object.rf.get_system_properties(), port_response.get("Links")) network_port_inventory.add_relation(plugin_object.rf.get_system_properties(), port_response.get("RelatedItem")) plugin_object.inventory.add(network_port_inventory) if plugin_object.cli_args.verbose: network_port_inventory.source_data = {"port": port_response} if return_data is True: return network_port_inventory return def get_network_function(function_data=None): # could be # * a string # * a dict with just the link # * a dict with full data function_response = None redfish_path = None if isinstance(function_data, dict): if function_data.get("Id") is not None: function_response = function_data else: redfish_path = function_data.get("@odata.id") elif isinstance(function_data, str): redfish_path = function_data # query data if function_response is None and redfish_path is not None: function_response = plugin_object.rf.get_view(f"{redfish_path}{plugin_object.rf.vendor_data.expand_string}") port_inventory = None if function_response is not None: physical_port_path = grab(function_response, "Links.PhysicalPortAssignment") or \ grab(function_response, "PhysicalPortAssignment") if physical_port_path is None: return network_function_id = function_response.get("Id") port_inventory = get_network_port(physical_port_path, network_function_id, True) if plugin_object.cli_args.verbose: source_data = getattr(port_inventory, "source_data") source_data["function"] = function_response port_inventory.update("source_data", source_data) port_inventory.add_relation(plugin_object.rf.get_system_properties(), function_response.get("Links")) port_inventory.add_relation(plugin_object.rf.get_system_properties(), function_response.get("RelatedItem")) # get health status status_data = get_status_data(function_response.get("Status")) if port_inventory.health_status is None: port_inventory.health_status = status_data.get("Health") if port_inventory.operation_status is None: port_inventory.operation_status = status_data.get("State") # get and sanitize MAC and WWPN addresses port_inventory.update("addresses", format_interface_addresses(grab(function_response, "Ethernet.PermanentMACAddress")) + format_interface_addresses(grab(function_response, "Ethernet.MACAddress")) + format_interface_addresses(grab(function_response, "FibreChannel.PermanentWWPN")) + format_interface_addresses(grab(function_response, "FibreChannel.WWPN")), append=True) # set VLAN settings port_inventory.vlan_id = grab(function_response, "Ethernet.VLAN.VLANId") port_inventory.vlan_enabled = grab(function_response, "Ethernet.VLAN.VLANEnable") # get IP addresses vendor_data = grab(function_response, f"Oem.{plugin_object.rf.vendor_dict_key}") if vendor_data is not None: port_inventory.ipv4_addresses = get_interface_ip_addresses(vendor_data, "IPv4Addresses") port_inventory.ipv6_addresses = get_interface_ip_addresses(vendor_data, "IPv6Addresses") # set link type port_inventory.update("link_type", function_response.get("NetDevFuncType")) if plugin_object.rf.vendor == "Cisco": port_inventory.update("os_name", function_response.get("Name")) if plugin_object.rf.vendor == "Dell": duplex_setting = \ grab(function_response, f"Oem.{plugin_object.rf.vendor_dict_key}.DellNIC.LinkDuplex") or "" if "full" in duplex_setting.lower(): port_inventory.update("full_duplex", True) elif "half" in duplex_setting.lower(): port_inventory.update("full_duplex", False) port_inventory.update("name", grab(function_response, f"Oem.{plugin_object.rf.vendor_dict_key}.DellNIC.DeviceDescription")) return port_inventory plugin_object.set_current_command("NICs") system_id = redfish_url.rstrip("/").split("/")[-1] if plugin_object.rf.vendor == "HPE": system_response = plugin_object.rf.get(redfish_url) ethernet_interfaces_path = grab(system_response, f"Oem/{plugin_object.rf.vendor_dict_key}/Links/EthernetInterfaces/@odata.id", separator="/") network_adapter_path = grab(system_response, f"Oem/{plugin_object.rf.vendor_dict_key}/Links/NetworkAdapters/@odata.id", separator="/") else: ethernet_interfaces_path = f"{redfish_url}/EthernetInterfaces" network_adapter_path = f"{redfish_url}/NetworkInterfaces" network_adapter_response = \ plugin_object.rf.get_view(f"{network_adapter_path}{plugin_object.rf.vendor_data.expand_string}") # HPE specific if network_adapter_response.get("NetworkAdapters") is not None: network_adapter_members = network_adapter_response.get("NetworkAdapters") else: network_adapter_members = network_adapter_response.get("Members") if network_adapter_members and len(network_adapter_members) > 0: for adapter in network_adapter_members: if adapter.get("Id") is not None: nic_member = adapter else: nic_member = plugin_object.rf.get(adapter.get("@odata.id")) adapter_path = grab(nic_member, "Links/NetworkAdapter/@odata.id", separator="/") or \ grab(nic_member, "Links.NetworkAdapter.0") # HPE systems num_ports = 0 network_ports = None network_functions = None if adapter_path is None: status_data = get_status_data(nic_member.get("Status")) adapter_id = nic_member.get("Id") manufacturer = None name = nic_member.get("Name") model = nic_member.get("Model") part_number = nic_member.get("PartNumber") serial = nic_member.get("SerialNumber") firmware = grab(nic_member, "Firmware.Current.VersionString") source_data = nic_member num_ports = len(nic_member.get("PhysicalPorts") or list()) else: adapter_response = plugin_object.rf.get(adapter_path) source_data = adapter_response status_data = get_status_data(adapter_response.get("Status")) adapter_id = adapter_response.get("Id") manufacturer = adapter_response.get("Manufacturer") name = adapter_response.get("Name") model = adapter_response.get("Model") part_number = adapter_response.get("PartNumber") serial = adapter_response.get("SerialNumber") firmware = grab(adapter_response, "Firmware.Current.VersionString") adapter_controllers = adapter_response.get("Controllers") or list() if isinstance(adapter_controllers, dict): adapter_controllers = [adapter_controllers] for controller in adapter_controllers: firmware = grab(controller, "FirmwarePackageVersion") network_ports = grab(controller, "Links.NetworkPorts") or \ grab(controller, "Link.NetworkPorts") network_functions = grab(controller, "Links.NetworkDeviceFunctions") or \ grab(controller, "Link.NetworkDeviceFunctions") num_ports = len(network_ports) adapter_inventory = NetworkAdapter( id=adapter_id, name=name, health_status=status_data.get("Health"), operation_status=status_data.get("State"), model=model, manufacturer=manufacturer, num_ports=num_ports, firmware=firmware, part_number=part_number, serial=serial, system_ids=system_id ) discovered_network_ports = 0 for network_function in network_functions or list(): port_inventory_data = get_network_function(network_function) if port_inventory_data is not None: adapter_inventory.update("port_ids", port_inventory_data.id, True) port_inventory_data.update("adapter_id", adapter_inventory.id) discovered_network_ports += 1 if discovered_network_ports == 0: for network_port in network_ports or list(): port_inventory_data = get_network_port(network_port, return_data=True) if port_inventory_data is not None: adapter_inventory.update("port_ids", port_inventory_data.id, True) port_inventory_data.update("adapter_id", adapter_inventory.id) # special case for HPE if plugin_object.rf.vendor == "HPE" and len(nic_member.get("PhysicalPorts") or list()) > 0: num_port = 0 for network_port in nic_member.get("PhysicalPorts") or list(): num_port += 1 port_id = f"{adapter_inventory.id}.{num_port}" status_data = get_status_data(network_port.get("Status")) network_port_inventory = NetworkPort( id=port_id, adapter_id=adapter_inventory.id, os_name=network_port.get("Name"), port_name=num_port, health_status=status_data.get("Health"), operation_status=status_data.get("State"), addresses=format_interface_addresses(grab(network_port, "MacAddress")), ipv4_addresses=get_interface_ip_addresses(network_port, "IPv4Addresses"), ipv6_addresses=get_interface_ip_addresses(network_port, "IPv6Addresses"), full_duplex=grab(network_port, "FullDuplex"), current_speed=grab(network_port, "SpeedMbps"), link_status=f"{network_port.get('LinkStatus') or ''}".replace("Link", ""), system_ids=system_id ) adapter_inventory.update("port_ids", port_id, True) plugin_object.inventory.add(network_port_inventory) if plugin_object.cli_args.verbose: network_port_inventory.source_data = {"port": network_port} if plugin_object.cli_args.verbose: adapter_inventory.source_data = source_data plugin_object.inventory.add(adapter_inventory) if len(plugin_object.inventory.get(NetworkPort)) == 0: ethernet_interface_response = \ plugin_object.rf.get_view(f"{ethernet_interfaces_path}{plugin_object.rf.vendor_data.expand_string}") # HPE specific if ethernet_interface_response.get("EthernetInterfaces") is not None: ethernet_interface_members = ethernet_interface_response.get("EthernetInterfaces") else: ethernet_interface_members = ethernet_interface_response.get("Members") if ethernet_interface_members and len(ethernet_interface_members) > 0: for interface in ethernet_interface_members: if interface.get("Id") is not None: interface_member = interface else: interface_member = plugin_object.rf.get(interface.get("@odata.id")) if interface_member.get("Id"): # get health status status_data = get_status_data(interface_member.get("Status")) addresses = interface_member.get("PermanentMACAddress") or interface_member.get("MACAddress") port_inventory = NetworkPort( id=interface_member.get("Id"), name=interface_member.get("Name"), health_status=status_data.get("Health"), operation_status=status_data.get("State"), link_status=interface_member.get("LinkStatus"), addresses=format_interface_addresses(addresses), current_speed=interface_member.get("SpeedMbps"), system_ids=system_id ) if plugin_object.cli_args.verbose: port_inventory.source_data = interface_member # add relations port_inventory.add_relation(plugin_object.rf.get_system_properties(), interface_member.get("Links")) port_inventory.add_relation(plugin_object.rf.get_system_properties(), interface_member.get("RelatedItem")) plugin_object.inventory.add(port_inventory) def add_port_status(port_inventory_item): plugin_status = port_status = port_inventory_item.health_status if port_status is None: port_status = port_inventory_item.operation_status if plugin_status is None and port_status == "Enabled": plugin_status = "OK" if plugin_status is None: plugin_status = "OK" ip_addresses_string = None ip_addresses = [*port_inventory_item.ipv4_addresses, *port_inventory_item.ipv6_addresses] if len(ip_addresses) > 0: ip_addresses_string = "/".join(ip_addresses) duplex = autoneg = None if port_inventory_item.full_duplex is not None: duplex = "full" if port_inventory_item.full_duplex is True else "half" if port_inventory_item.autoneg is not None: autoneg = "on" if port_inventory_item.autoneg is True else "off" status_text = f"Port {port_inventory_item.id} " if port_inventory_item.os_name is not None: status_text += f"(OS name: {port_inventory_item.os_name}) " if ip_addresses_string is not None: status_text += f"(IPs: {ip_addresses_string}) " status_text += f"(type: {port_inventory_item.link_type}, " \ f"speed: {port_inventory_item.current_speed}, " \ f"autoneg: {autoneg}, duplex: {duplex}) " if port_status is not None: status_text += f"status: {port_status}, " status_text += f"link: {port_inventory_item.link_status}" plugin_object.add_output_data("CRITICAL" if plugin_status not in ["OK", "WARNING"] else plugin_status, status_text) adapter_inventory = plugin_object.inventory.get(NetworkAdapter) port_inventory = plugin_object.inventory.get(NetworkPort) num_adapters = len(adapter_inventory) num_ports = len(port_inventory) for network_adapter in adapter_inventory: plugin_status = adapter_status = network_adapter.health_status if adapter_status is None: adapter_status = network_adapter.operation_status if plugin_status is None and adapter_status == "Enabled": plugin_status = "OK" if plugin_status is None: plugin_status = "OK" adapter_name = network_adapter.model \ if len(network_adapter.model or '') > len(network_adapter.name or '') else network_adapter.name if plugin_object.rf.vendor in ["Huawei", "Cisco", "Dell"] and \ not all(v is None for v in [network_adapter.model, network_adapter.manufacturer]): adapter_name = f"{network_adapter.manufacturer} {network_adapter.model}" status_text = f"Adapter {adapter_name} (FW: {network_adapter.firmware}) status: {adapter_status}" plugin_object.add_output_data("CRITICAL" if plugin_status not in ["OK", "WARNING"] else plugin_status, status_text) for network_port in port_inventory: if str(network_port.adapter_id) == str(network_adapter.id): add_port_status(network_port) for network_port in port_inventory: if network_port.adapter_id is None: add_port_status(network_port) if num_ports == 0: plugin_object.add_output_data("UNKNOWN", f"No network adapter or interface data " f"returned for API URL '{network_adapter_path}'") plugin_object.add_output_data("OK", f"All network adapter ({num_adapters}) and " f"ports ({num_ports}) are in good condition", summary=True) return
def get_network_port(port_data=None, network_function_id=None, return_data=False): # could be # * a string # * a dict with just the link # * a dict with full data port_response = None redfish_path = None if isinstance(port_data, dict): if port_data.get("Id") is not None: port_response = port_data else: redfish_path = port_data.get("@odata.id") elif isinstance(port_data, str): redfish_path = port_data # query data if port_response is None and redfish_path is not None: port_response = plugin_object.rf.get_view(f"{redfish_path}{plugin_object.rf.vendor_data.expand_string}") if port_response is None: return NetworkPort() # get health status status_data = get_status_data(port_response.get("Status")) # get Link speed current_speed = \ port_response.get("CurrentLinkSpeedMbps") or \ grab(port_response, "SupportedLinkCapabilities.0.LinkSpeedMbps") or \ grab(port_response, "SupportedLinkCapabilities.LinkSpeedMbps") if isinstance(current_speed, str): current_speed = current_speed.replace("Gbps", "000") if str(current_speed) == "-": current_speed = None # get port number if port_response.get("PhysicalPortNumber"): nic_port_name = "Port " + port_response.get("PhysicalPortNumber") else: nic_port_name = port_response.get("Name") if plugin_object.rf.vendor == "Cisco" and network_function_id is not None: port_id = f"{network_function_id}.{port_response.get('Id')}" else: port_id = port_response.get('Id') if plugin_object.rf.vendor != "Dell": port_id = f"{adapter_id}.{port_id}" # check if port has already be added if port_id in [p.id for p in plugin_object.inventory.get(NetworkPort)]: print(f"ALREADY in INVENTORY: {port_id}") return network_port_inventory = NetworkPort( id=port_id, name=port_response.get("Name"), port_name=nic_port_name, health_status=status_data.get("Health"), operation_status=status_data.get("State"), addresses=format_interface_addresses(grab(port_response, "AssociatedNetworkAddresses")), link_type=port_response.get("ActiveLinkTechnology"), autoneg=grab(port_response, "SupportedLinkCapabilities.0.AutoSpeedNegotiation"), current_speed=current_speed, capable_speed=grab(port_response, "SupportedLinkCapabilities.0.CapableLinkSpeedMbps.0"), link_status=f"{port_response.get('LinkStatus') or ''}".replace("Link", ""), system_ids=system_id ) network_port_inventory.add_relation(plugin_object.rf.get_system_properties(), port_response.get("Links")) network_port_inventory.add_relation(plugin_object.rf.get_system_properties(), port_response.get("RelatedItem")) plugin_object.inventory.add(network_port_inventory) if plugin_object.cli_args.verbose: network_port_inventory.source_data = {"port": port_response} if return_data is True: return network_port_inventory return
def get_bmc_info_generic(plugin_object, redfish_url): """ Possible Info to add * NTP Status * NTP servers configured * BMC accounts * BIOS settings (maybe, varies a lot between vendors) """ view_response = plugin_object.rf.get_view(f"{redfish_url}{plugin_object.rf.vendor_data.expand_string}") if view_response.get("error"): plugin_object.add_data_retrieval_error(Manager, view_response, redfish_url) return # HPE iLO 5 view if view_response.get("ILO"): manager_response = view_response.get("ILO")[0] else: manager_response = view_response # get model bmc_model = manager_response.get("Model") bmc_fw_version = manager_response.get("FirmwareVersion") if plugin_object.rf.vendor == "HPE": bmc_model = " ".join(bmc_fw_version.split(" ")[0:2]) if plugin_object.rf.vendor == "Dell": if bmc_model == "13G Monolithic": bmc_model = "iDRAC 8" if bmc_model in ["14G Monolithic", "15G Monolithic"]: bmc_model = "iDRAC 9" # some Cisco Systems have a second manager with no attributes which needs to be skipped if plugin_object.rf.vendor == "Cisco": if manager_response.get("Status") is None: return status_text = f"BMC: {bmc_model} (Firmware: {bmc_fw_version})" # get status data status_data = get_status_data(manager_response.get("Status")) manager_inventory = Manager( id=manager_response.get("Id"), type=manager_response.get("ManagerType"), name=manager_response.get("Name"), health_status=status_data.get("Health"), operation_status=status_data.get("State"), model=bmc_model, firmware=bmc_fw_version ) if plugin_object.cli_args.verbose: manager_inventory.source_data = manager_response # add relations manager_inventory.add_relation(plugin_object.rf.get_system_properties(), manager_response.get("Links")) plugin_object.inventory.add(manager_inventory) # workaround for older ILO versions if manager_inventory.health_status is not None: bmc_status = manager_inventory.health_status elif manager_inventory.operation_status == "Enabled": bmc_status = "OK" else: bmc_status = "UNKNOWN" # BMC Network interfaces manager_nic_response = None manager_nic_member = None if plugin_object.rf.vendor == "HPE" and view_response.get("ILOInterfaces") is not None: manager_nic_response = {"Members": view_response.get("ILOInterfaces")} else: manager_nics_link = grab(manager_response, "EthernetInterfaces/@odata.id", separator="/") if manager_nics_link is not None: redfish_url = f"{manager_nics_link}{plugin_object.rf.vendor_data.expand_string}" manager_nic_response = plugin_object.rf.get(redfish_url) if manager_nic_response.get("error"): plugin_object.add_data_retrieval_error(NetworkPort, manager_nic_response, redfish_url) if manager_nic_response is not None: if manager_nic_response.get("Members") is None or len(manager_nic_response.get("Members")) == 0: status_text = f"{status_text} but no information about the BMC network interfaces found" plugin_object.inventory.add_issue(NetworkPort, "No information about the BMC network interfaces found") else: # if args.detailed is False: status_text = f"{status_text} and all nics are in 'OK' state." for manager_nic_member in manager_nic_response.get("Members"): if manager_nic_member.get("@odata.context"): manager_nic = manager_nic_member else: manager_nic = plugin_object.rf.get(manager_nic_member.get("@odata.id")) if manager_nic.get("error"): plugin_object.add_data_retrieval_error(NetworkPort, manager_nic, manager_nic_member.get("@odata.id")) continue status_data = get_status_data(manager_nic.get("Status")) if plugin_object.rf.vendor == "Dell": interface_id = manager_nic.get("Id") else: interface_id = "{}:{}".format(manager_inventory.id, manager_nic.get("Id")) vlan_id = grab(manager_nic, "VLAN.VLANId") if vlan_id is None: vlan_id = grab(manager_nic, "VLANId") vlan_enabled = grab(manager_nic, "VLAN.VLANEnable") if vlan_enabled is None: vlan_enabled = grab(manager_nic, "VLANEnable") network_inventory = NetworkPort( id=interface_id, name=manager_nic.get("Name"), health_status=status_data.get("Health"), operation_status=status_data.get("State"), current_speed=manager_nic.get("SpeedMbps"), autoneg=manager_nic.get("AutoNeg"), full_duplex=manager_nic.get("FullDuplex"), hostname=manager_nic.get("HostName"), addresses=format_interface_addresses(manager_nic.get("PermanentMACAddress")), manager_ids=manager_inventory.id, system_ids=manager_inventory.system_ids, chassi_ids=manager_inventory.chassi_ids, ipv4_addresses=get_interface_ip_addresses(manager_nic, "IPv4Addresses"), ipv6_addresses=get_interface_ip_addresses(manager_nic, "IPv6Addresses"), link_type="Ethernet", link_status=f"{manager_nic.get('LinkStatus') or ''}".replace("Link", ""), vlan_id=vlan_id, vlan_enabled=vlan_enabled, ) if plugin_object.cli_args.verbose: network_inventory.source_data = manager_nic plugin_object.inventory.add(network_inventory) # if we are connected wie via interface IP address then we can assume the link is up if network_inventory.link_status is None: for address in network_inventory.ipv4_addresses + network_inventory.ipv6_addresses: if address in plugin_object.cli_args.host: network_inventory.link_status = "Up" if plugin_object.rf.vendor == "Cisco" and manager_nic.get("InterfaceEnabled") is True: network_inventory.operation_status = "Enabled" # Huawei is completely missing any status information if plugin_object.rf.vendor == "Huawei" and network_inventory.operation_status is None: network_inventory.operation_status = "Enabled" if network_inventory.health_status: nic_status = network_inventory.health_status elif network_inventory.operation_status == "Enabled": nic_status = "OK" else: nic_status = "UNKNOWN" if network_inventory.operation_status in ["Disabled", None]: continue host_name = network_inventory.hostname or "no hostname set" ip_addresses_string = None ip_addresses = [*network_inventory.ipv4_addresses, *network_inventory.ipv6_addresses] if len(ip_addresses) > 0: ip_addresses_string = "/".join(ip_addresses) duplex = autoneg = None if network_inventory.full_duplex is not None: duplex = "full" if network_inventory.full_duplex is True else "half" if nic_status == "OK" and duplex == "half" and network_inventory.current_speed is not None: nic_status = "WARNING" duplex += f" ({nic_status})" if network_inventory.autoneg is not None: autoneg = "on" if network_inventory.autoneg is True else "off" nic_status_text = f"NIC {network_inventory.id} '{host_name}' (IPs: {ip_addresses_string}) " nic_status_text += f"(speed: {network_inventory.current_speed}, " \ f"autoneg: {autoneg}, duplex: {duplex}) status: {nic_status}" plugin_object.add_output_data("CRITICAL" if nic_status not in ["OK", "WARNING"] else nic_status, nic_status_text, location=f"Manager {manager_inventory.id}") # get vendor information vendor_data = grab(manager_response, f"Oem.{plugin_object.rf.vendor_dict_key}") # get license information bmc_licenses = list() if plugin_object.rf.vendor == "HPE": ilo_license_string = grab(vendor_data, "License.LicenseString") ilo_license_key = grab(vendor_data, "License.LicenseKey") bmc_licenses.append(f"{ilo_license_string} ({ilo_license_key})") elif plugin_object.rf.vendor == "Lenovo": fod_link = grab(vendor_data, "FoD/@odata.id", separator="/") if fod_link is not None: fod_url = f"{fod_link}/Keys{plugin_object.rf.vendor_data.expand_string}" fod_data = plugin_object.rf.get(fod_url) if fod_data.get("error"): plugin_object.add_data_retrieval_error(Manager, fod_data, fod_url) for fod_member in fod_data.get("Members", list()): if manager_nic_member is not None and manager_nic_member.get("@odata.context"): licenses_data = fod_member else: licenses_data = plugin_object.rf.get(fod_member.get("@odata.id")) lic_status = licenses_data.get("Status") # valid lic_expire_date = licenses_data.get("Expires") # NO CONSTRAINTS lic_description = licenses_data.get("Description") license_string = f"{lic_description}" if lic_expire_date != "NO CONSTRAINTS": license_string += " (expires: {lic_expire_date}" license_string += f" Status: {lic_status}" bmc_licenses.append(license_string) elif plugin_object.rf.vendor == "Fujitsu": # get configuration irmc_configuration_link = grab(vendor_data, f"iRMCConfiguration/@odata.id", separator="/") irmc_configuration = None if irmc_configuration_link is not None: irmc_configuration = plugin_object.rf.get(irmc_configuration_link) if irmc_configuration.get("error"): plugin_object.add_data_retrieval_error(Manager, irmc_configuration, irmc_configuration_link) license_information = None license_information_link = grab(irmc_configuration, f"Licenses/@odata.id", separator="/") if license_information_link is not None: license_information = plugin_object.rf.get(license_information_link) if license_information.get("error"): plugin_object.add_data_retrieval_error(Manager, license_information, license_information_link) if license_information is not None and license_information.get("*****@*****.**") > 0: for bmc_license in license_information.get("Keys"): bmc_licenses.append("%s (%s)" % (bmc_license.get("Name"), bmc_license.get("Type"))) elif plugin_object.rf.vendor == "Huawei": ibmc_license_link = vendor_data.get("LicenseService") if ibmc_license_link is not None and len(ibmc_license_link) > 0: ibmc_lic = plugin_object.rf.get(ibmc_license_link.get("@odata.id")) if ibmc_lic.get("error"): plugin_object.add_data_retrieval_error(Manager, ibmc_lic, ibmc_license_link.get("@odata.id")) bmc_licenses.append("%s (%s)" % (ibmc_lic.get("InstalledStatus"), ibmc_lic.get("LicenseClass"))) manager_inventory.licenses = bmc_licenses for bmc_license in bmc_licenses: plugin_object.add_output_data("OK", f"BMC License: {bmc_license}", location=f"Manager {manager_inventory.id}") # HP ILO specific stuff if plugin_object.rf.vendor == "HPE": # iLO Self Test for self_test in vendor_data.get("iLOSelfTestResults"): self_test_status = self_test.get("Status") if self_test_status in ["Informational", None]: continue self_test_status = self_test_status.upper() self_test_name = self_test.get("SelfTestName") self_test_notes = self_test.get("Notes") if self_test_notes is not None and len(self_test_notes) != 0: self_test_notes = self_test_notes.strip() self_test_status_text = f"BMC SelfTest {self_test_name} ({self_test_notes}) status: {self_test_status}" else: self_test_status_text = f"BMC SelfTest {self_test_name} status: {self_test_status}" plugin_object.add_output_data("CRITICAL" if self_test_status not in ["OK", "WARNING"] else self_test_status, self_test_status_text, location=f"Manager {manager_inventory.id}") # Lenovo specific stuff if plugin_object.rf.vendor == "Lenovo": redfish_chassi_url = grab(manager_response, "Links/ManagerForChassis/0/@odata.id", separator="/") chassi_response = None if redfish_chassi_url is not None: chassi_response = plugin_object.rf.get(redfish_chassi_url) if chassi_response.get("error"): plugin_object.add_data_retrieval_error(Manager, chassi_response, redfish_chassi_url) located_data = grab(chassi_response, f"Oem.{plugin_object.rf.vendor_dict_key}.LocatedIn") if located_data is not None: descriptive_name = located_data.get("DescriptiveName") rack = located_data.get("Rack") system_name_string = f"System name: {descriptive_name} ({rack})" if plugin_object.cli_args.detailed: plugin_object.add_output_data("OK", f"BMC {system_name_string}", location=f"Manager {manager_inventory.id}") else: status_text += f" {system_name_string}" # get running firmware information from Fujitsu server if plugin_object.rf.vendor == "Fujitsu": for bmc_firmware in get_firmware_info_fujitsu(plugin_object, redfish_url, True): plugin_object.add_output_data("OK", "BMC Firmware: %s: %s" % (bmc_firmware.get("name"), bmc_firmware.get("version")), location=f"Manager {manager_inventory.id}") # get Huawei Server location data if plugin_object.rf.vendor == "Huawei": ibmc_location = vendor_data.get("DeviceLocation") if ibmc_location is not None and len(ibmc_location) > 0: location_string = f"Location: {ibmc_location}" if plugin_object.cli_args.detailed: plugin_object.add_output_data("OK", f"BMC {location_string}", location=f"Manager {manager_inventory.id}") else: status_text += f" {location_string}" plugin_object.add_output_data("CRITICAL" if bmc_status not in ["OK", "WARNING"] else bmc_status, status_text, summary=True, location=f"Manager {manager_inventory.id}") return