Hello,
I’ve made SNMP Storage Checks for Fujitsu Primergy Servers. They check physical and logical drives.
I release them under the GNU General Public License v3.0. I’m not a software developer, so I can’t fix any specific bugs or give in depth support. Please regard this plugin as the work of a CheckMK hobbyist, with no support or any liability.
I tested it with Checkmk 2.1.0p24 and 2.2.0p4.
#!/usr/bin/python3
# Creates a Check for each Logical Drive on a Fujitsu Primergy Server. 2 is operational, all other results are critical.
# GNU General Public License v3.0
# copy into ./local/lib/check_mk/base/agent_based/primergy_logical_drives.py
from .agent_based_api.v1 import *
def discover_primergy_logical_drives(section):
for _logical_drive_name, _status in section:
yield Service(item=_logical_drive_name)
def check_primergy_logical_drives(item, section):
# Dictionary for SNMP Check
_dict_svrLogicalDriveStatusEx = dict([
(1, 'unknown'),
(2, 'operational - drive is OK, all disks working properly'),
(3, 'partiallyDegraded - one disk in this array failed, reduced redundancy still available'),
(4, 'degraded - one disk in this array failed, redundancy lost'),
(5, 'failed - too many disks in this array failed, drive no longer available'),
(6, 'rebuilding - drive is currently rebuilding'),
(7, 'checking - drive is currently executing a consistency check'),
(8, 'mdcing - drive is currently executing a consistency check and fixes inconsistencies'),
(9, 'initializing - drive is currently being initialized'),
(10, 'backgroundInitializing - drive is currently being initialized in background'),
(11, 'migrating - drive is currently being modified (online RAID extension)'),
(12, 'copying - drive is currently executing a copyback or redundant copy operation'),
(13, 'offline - drive is temporarily not operational'),
(14, 'spareInUse - drive is using a hot spare'),
(15, 'erasing - drive is being erased'),
])
for _logical_drive_name, _status in section:
if _logical_drive_name == item:
if _status == "":
_status = "1"
_status = int(_status)
_status_verbose = _dict_svrLogicalDriveStatusEx[_status]
if _status == 2 or 7 or 9 or 10:
s = State.OK
elif _status == 1 or 3 or 6 or 8 or 11 or 12 or 14:
s = State.WARN
else:
s = State.CRIT
yield Result(
state=s,
summary=f"Raid {_logical_drive_name} is {_status_verbose}"
)
return
register.check_plugin(
name="primergy_logical_drives",
service_name="LD %s",
discovery_function=discover_primergy_logical_drives,
check_function=check_primergy_logical_drives,
)
register.snmp_section(
name="primergy_logical_drives",
detect=startswith(".1.3.6.1.2.1.1.1.0", "Primergy"),
fetch=SNMPTree(
base=".1.3.6.1.4.1.231.2.49.1.6.2.1",
oids=[
"11.0", # _logical_drive_name
"19.0", # _status
],
),
)
#!/usr/bin/python3
# Creates a Check for each Physical Drive on a Fujitsu Primergy Server.
# GNU General Public License v3.0
# copy into ./local/lib/check_mk/base/agent_based/primergy_physical_drives.py
from .agent_based_api.v1 import *
def discover_primergy_physical_drives(section):
for _svrPhysicalDeviceIdx, _svrPhysicalDeviceInfo, _svrPhysicalDeviceVendorName, _svrPhysicalDeviceSmartStatus, _svrPhysicalDeviceStatus, _svrPhysicalDeviceSerialNumber in section:
yield Service(item=_svrPhysicalDeviceIdx.zfill(3) + " " + _svrPhysicalDeviceVendorName + " " + _svrPhysicalDeviceInfo)
def check_primergy_physical_drives(item, section):
# Dictionary for SNMP Check
_dict_svrPhysicalDeviceStatus = dict([
(1, 'unknown'),
(2, 'noDisk - device is not a hard disk'),
(3, 'online - device is available and working properly'),
(4, 'ready - device can be used for new configuration'),
(5, 'failed - device is available but no longer working'),
(6, 'rebuilding - device is restoring fault tolerance'),
(7, 'hotspareGlobal - device is a hot spare device for use in any array'),
(8, 'hotspareDedicated - device is a hot spare device for use in a dedicated array'),
(9, 'offline - device is set to non-working state'),
(10, 'unconfiguredFailed - device is not configured but a failure has occurred'),
(11, 'formatting - device is currently being formatted'),
(12, 'dead - device is not available or not responding'),
])
_dict_svrPhysicalDeviceSmartStatus = dict([
(1, 'ok'),
(2, 'failurePredicted'),
(3, 'smartNotAvailable'),
(4, 'smartMonitoringDisabled'),
])
for _svrPhysicalDeviceIdx, _svrPhysicalDeviceInfo, _svrPhysicalDeviceVendorName, _svrPhysicalDeviceSmartStatus, _svrPhysicalDeviceStatus, _svrPhysicalDeviceSerialNumber in section:
if _svrPhysicalDeviceIdx.zfill(3) + " " + _svrPhysicalDeviceVendorName + " " + _svrPhysicalDeviceInfo == item:
if _svrPhysicalDeviceSmartStatus == "":
_svrPhysicalDeviceSmartStatus = "3"
_svrPhysicalDeviceSmartStatus = int(_svrPhysicalDeviceSmartStatus)
_svrPhysicalDeviceSmartStatus_verbose = _dict_svrPhysicalDeviceSmartStatus[_svrPhysicalDeviceSmartStatus]
if _svrPhysicalDeviceStatus == "":
_svrPhysicalDeviceStatus = "1"
_svrPhysicalDeviceStatus = int(_svrPhysicalDeviceStatus)
_svrPhysicalDeviceStatus_verbose = _dict_svrPhysicalDeviceStatus[_svrPhysicalDeviceStatus]
if _svrPhysicalDeviceSmartStatus == 1 or 3 or 4 and _svrPhysicalDeviceStatus == 2 or 3 or 7 or 8:
s = State.OK
elif _svrPhysicalDeviceStatus == 1 or 4 or 6 or 9 or 11:
s = State.WARN
else:
s = State.CRIT
yield Result(
state=s,
summary=f"SerialNumber: {_svrPhysicalDeviceSerialNumber} - SMART status is {_svrPhysicalDeviceSmartStatus_verbose} - Device status is {_svrPhysicalDeviceStatus_verbose}"
)
return
register.check_plugin(
name="primergy_physical_drives",
service_name="PD %s",
discovery_function=discover_primergy_physical_drives,
check_function=check_primergy_physical_drives,
)
register.snmp_section(
name="primergy_physical_drives",
detect=startswith(".1.3.6.1.2.1.1.1.0", "Primergy"),
fetch=SNMPTree(
base=".1.3.6.1.4.1.231.2.49.1.5.2.1",
oids=[
"19", # svrPhysicalDeviceIdx
"5", # svrPhysicalDeviceInfo
"6", # svrPhysicalDeviceVendorName
"14", # svrPhysicalDeviceSmartStatus
"15", # svrPhysicalDeviceStatus
"17", # svrPhysicalDeviceSerialNumber
],
),
)