-
Notifications
You must be signed in to change notification settings - Fork 474
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes: #776 Change-Id: I7f7b1bc5d4a16494fc5f9ec18a89348448019b33 Co-Authored-by: Moritz Kiemer <[email protected]>
- Loading branch information
1 parent
984e057
commit 00c8b51
Showing
40 changed files
with
4,402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
cmk/plugins/redfish/agent_based/inv_redfish_firmware.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 | ||
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and | ||
# conditions defined in the file COPYING, which is part of this source code package. | ||
'''Redfish firmware inventory for HPE devices''' | ||
|
||
from cmk.agent_based.v2 import ( | ||
AgentSection, | ||
CheckPlugin, | ||
CheckResult, | ||
DiscoveryResult, | ||
InventoryPlugin, | ||
InventoryResult, | ||
Result, | ||
Service, | ||
State, | ||
TableRow, | ||
) | ||
from cmk_addons.plugins.redfish.lib import ( | ||
RedfishAPIData, | ||
parse_redfish_multiple, | ||
redfish_health_state, | ||
) | ||
|
||
agent_section_redfish_firmware = AgentSection( | ||
name="redfish_firmwareinventory", | ||
parse_function=parse_redfish_multiple, | ||
parsed_section_name="redfish_firmware", | ||
) | ||
|
||
|
||
def _item_name(item_data, padding): | ||
"""build item name for inventory entry""" | ||
if not item_data.get('Id'): | ||
if item_data.get('Name'): | ||
item_name = item_data.get('Name') | ||
else: | ||
return None | ||
elif item_data.get('Id').isdigit(): | ||
item_name = f"{item_data.get('Id').zfill(padding)}-{item_data.get('Name')}" | ||
elif item_data.get('Id') == item_data.get('Name'): | ||
item_name = item_data.get('Name') | ||
elif item_data.get('Description') == "Represents Firmware Inventory": | ||
prefix = item_data.get('Id').split("-")[0] | ||
item_name = f"{prefix}-{item_data.get('Name')}" | ||
else: | ||
item_name = f"{item_data.get('Id')}-{item_data.get('Name')}" | ||
return item_name | ||
|
||
|
||
def inventory_redfish_firmware(section: RedfishAPIData) -> InventoryResult: | ||
"""create inventory table for firmware""" | ||
path = ["hardware", "firmware", "redfish"] | ||
if section.get("FirmwareInventory", {}).get("Current"): | ||
data = section.get("FirmwareInventory", {}).get("Current") | ||
padding = len(str(len(data))) | ||
for index, entry_id in enumerate(data): | ||
entry = data.get(entry_id) | ||
component_name = f"{str(index).zfill(padding)}-{entry[0].get('Name')}" | ||
yield TableRow( | ||
path=path, | ||
key_columns={ | ||
"component": component_name, | ||
}, | ||
inventory_columns={ | ||
"version": entry[0].get("VersionString"), | ||
"location": entry[0].get("Location"), | ||
}, | ||
) | ||
else: | ||
padding = len(str(len(section))) | ||
for _key, entry in section.items(): | ||
item_name = _item_name(entry, padding) | ||
if not item_name: | ||
continue | ||
if entry.get('Description') == "Represents Firmware Inventory": | ||
description = entry.get('Id') | ||
else: | ||
description = entry.get('Description') | ||
yield TableRow( | ||
path=path, | ||
key_columns={ | ||
"component": item_name, | ||
}, | ||
inventory_columns={ | ||
"version": entry.get("Version"), | ||
"description": description, | ||
"updateable": entry.get("Updateable"), | ||
}, | ||
) | ||
|
||
|
||
inventory_plugin_redfish_firmware = InventoryPlugin( | ||
name="redfish_firmware", | ||
inventory_function=inventory_redfish_firmware, | ||
) | ||
|
||
|
||
def discovery_redfish_firmware(section: RedfishAPIData) -> DiscoveryResult: | ||
"""discover service if data exists""" | ||
if section: | ||
yield Service() | ||
|
||
|
||
def check_redfish_firmware(section: RedfishAPIData) -> CheckResult: | ||
"""check the health state of the firmware""" | ||
|
||
padding = len(str(len(section))) | ||
overall_state = 0 | ||
msg_text = "" | ||
info_text = "" | ||
info_list = [] | ||
for _key, entry in section.items(): | ||
if not entry.get("Status"): | ||
continue | ||
component_name = _item_name(entry, padding) | ||
comp_state, comp_msg = redfish_health_state(entry.get("Status", {})) | ||
if entry.get("Status", {}).get("State", "UNKNOWN") == "StandbyOffline": | ||
comp_state = 0 | ||
overall_state = max(overall_state, comp_state) | ||
if comp_state != 0: | ||
msg_text += f"{component_name} - {comp_msg} - " | ||
info_list.append( | ||
[component_name, comp_msg, entry.get("Version"), entry.get("Updateable")] | ||
) | ||
|
||
if not msg_text: | ||
msg_text = "All firmware in optimal state" | ||
|
||
line_bracket = "<tr>%s</tr>" | ||
cell_bracket = "<td>%s</td>" | ||
cell_seperator = "" | ||
headers = ("Component", "Status", "Version", "Updateable") | ||
info_text = f'<table style="border-collapse: separate; border-spacing: 10px 0;">{( | ||
"<tr><th>" | ||
+ "</th><th>".join(headers) | ||
+ "</th></tr>" | ||
+ "".join( | ||
[ | ||
line_bracket | ||
% cell_seperator.join([cell_bracket % value for value in info_entry]) | ||
for info_entry in info_list | ||
] | ||
) | ||
)}</table>' | ||
|
||
yield Result(state=State(overall_state), summary=msg_text, details=info_text) | ||
|
||
|
||
check_plugin_redfish_firmware = CheckPlugin( | ||
name="redfish_firmware", | ||
service_name="Firmware health", | ||
sections=["redfish_firmware"], | ||
discovery_function=discovery_redfish_firmware, | ||
check_function=check_redfish_firmware, | ||
) |
48 changes: 48 additions & 0 deletions
48
cmk/plugins/redfish/agent_based/inv_redfish_firmware_hpe_ilo4.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 | ||
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and | ||
# conditions defined in the file COPYING, which is part of this source code package. | ||
"""Redfish firmware inventory for HPE devices""" | ||
|
||
from cmk.agent_based.v2 import ( | ||
AgentSection, | ||
InventoryPlugin, | ||
InventoryResult, | ||
TableRow, | ||
) | ||
from cmk_addons.plugins.redfish.lib import ( | ||
RedfishAPIData, | ||
parse_redfish, | ||
) | ||
|
||
|
||
agent_section_redfish_firmware_hpe_ilo4 = AgentSection( | ||
name="redfish_firmware_hpe_ilo4", | ||
parse_function=parse_redfish, | ||
parsed_section_name="redfish_firmware_hpe_ilo4", | ||
) | ||
|
||
|
||
def inventory_redfish_firmware_hpe_ilo4(section: RedfishAPIData) -> InventoryResult: | ||
"""create inventory table for firmware""" | ||
path = ["hardware", "firmware", "redfish"] | ||
padding = len(str(len(section))) | ||
for index, entry_id in enumerate(section): | ||
entry = section.get(entry_id) | ||
component_name = f"{str(index).zfill(padding)}-{entry[0].get('Name')}" | ||
yield TableRow( | ||
path=path, | ||
key_columns={ | ||
"component": component_name, | ||
}, | ||
inventory_columns={ | ||
"version": entry[0].get("VersionString"), | ||
"location": entry[0].get("Location"), | ||
}, | ||
) | ||
|
||
|
||
inventory_plugin_redfish_firmware_hpe_ilo4 = InventoryPlugin( | ||
name="redfish_firmware_hpe_ilo4", | ||
inventory_function=inventory_redfish_firmware_hpe_ilo4, | ||
) |
13 changes: 13 additions & 0 deletions
13
cmk/plugins/redfish/agent_based/redfish_arraycontrollers.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 | ||
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and | ||
# conditions defined in the file COPYING, which is part of this source code package. | ||
|
||
from cmk.agent_based.v2 import AgentSection | ||
from cmk_addons.plugins.redfish.lib import parse_redfish_multiple | ||
|
||
agent_section_redfish_arraycontrollers = AgentSection( | ||
name="redfish_arraycontrollers", | ||
parse_function=parse_redfish_multiple, | ||
parsed_section_name="redfish_arraycontrollers", | ||
) |
59 changes: 59 additions & 0 deletions
59
cmk/plugins/redfish/agent_based/redfish_arraycontrollers_generic.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 | ||
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and | ||
# conditions defined in the file COPYING, which is part of this source code package. | ||
|
||
from cmk.agent_based.v2 import ( | ||
CheckPlugin, | ||
CheckResult, | ||
DiscoveryResult, | ||
Result, | ||
Service, | ||
State, | ||
) | ||
from cmk_addons.plugins.redfish.lib import ( | ||
RedfishAPIData, | ||
redfish_health_state, | ||
) | ||
|
||
|
||
def discovery_redfish_arraycontrollers_generic( | ||
section: RedfishAPIData, | ||
) -> DiscoveryResult: | ||
for key in section.keys(): | ||
if section[key].get("Oem"): | ||
if section[key]["Oem"].get("Dell"): | ||
yield Service(item=section[key]["Id"]) | ||
|
||
|
||
def check_redfish_arraycontrollers_generic( | ||
item: str, section: RedfishAPIData | ||
) -> CheckResult: | ||
data = section.get(item, None) | ||
if data is None: | ||
return | ||
|
||
if data.get("[email protected]") == 1: | ||
ctrl_data = data.get("StorageControllers")[0] | ||
|
||
storage_msg = ( | ||
f"Type: {ctrl_data.get('Model')}, " | ||
f"RaidLevels: {','.join(ctrl_data.get('SupportedRAIDTypes', []))}, " | ||
f"DeviceProtocols: {','.join(ctrl_data.get('SupportedDeviceProtocols', []))}" | ||
) | ||
yield Result(state=State(0), summary=storage_msg) | ||
|
||
dev_state, dev_msg = redfish_health_state(data.get("Status", {})) | ||
status = dev_state | ||
message = dev_msg | ||
|
||
yield Result(state=State(status), notice=message) | ||
|
||
|
||
check_plugin_redfish_arraycontrollers_generic = CheckPlugin( | ||
name="redfish_arraycontrollers_generic", | ||
service_name="Storage Controller %s", | ||
sections=["redfish_arraycontrollers"], | ||
discovery_function=discovery_redfish_arraycontrollers_generic, | ||
check_function=check_redfish_arraycontrollers_generic, | ||
) |
52 changes: 52 additions & 0 deletions
52
cmk/plugins/redfish/agent_based/redfish_arraycontrollers_hpe.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2 | ||
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and | ||
# conditions defined in the file COPYING, which is part of this source code package. | ||
|
||
from cmk.agent_based.v2 import ( | ||
CheckPlugin, | ||
CheckResult, | ||
DiscoveryResult, | ||
Result, | ||
Service, | ||
State, | ||
) | ||
from cmk_addons.plugins.redfish.lib import ( | ||
RedfishAPIData, | ||
redfish_health_state, | ||
) | ||
|
||
|
||
def discovery_redfish_arraycontrollers_hpe(section: RedfishAPIData) -> DiscoveryResult: | ||
for key in section.keys(): | ||
if "SmartStorageArrayController" in section[key]["@odata.type"]: | ||
yield Service(item=section[key]["Id"]) | ||
|
||
|
||
def check_redfish_arraycontrollers_hpe( | ||
item: str, section: RedfishAPIData | ||
) -> CheckResult: | ||
data = section.get(item, None) | ||
if data is None: | ||
return | ||
|
||
dev_type = data.get("Model") | ||
dev_ser = data.get("SerialNumber") | ||
|
||
storage_msg = f"Type: {dev_type}, Serial: {dev_ser}" | ||
yield Result(state=State(0), summary=storage_msg) | ||
|
||
dev_state, dev_msg = redfish_health_state(data.get("Status", {})) | ||
status = dev_state | ||
message = dev_msg | ||
|
||
yield Result(state=State(status), notice=message) | ||
|
||
|
||
check_plugin_redfish_arraycontrollers_hpe = CheckPlugin( | ||
name="redfish_arraycontrollers_hpe", | ||
service_name="Storage Controller %s", | ||
sections=["redfish_arraycontrollers"], | ||
discovery_function=discovery_redfish_arraycontrollers_hpe, | ||
check_function=check_redfish_arraycontrollers_hpe, | ||
) |
Oops, something went wrong.