From 73cc9e0200b3b8ac53bce53f675941c413de2bbc Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Fri, 31 May 2024 07:48:41 +0200 Subject: [PATCH 1/4] rework to use LegacyCheckDefinition to be compatible with current checkmk versions again. --- infortrend/checks/infortrend_chassis | 28 ++++++++---- infortrend/checks/infortrend_chassis1 | 64 +++++++++++++++++++------- infortrend/checks/infortrend_disks | 28 ++++++++---- infortrend/checks/infortrend_disks1 | 65 +++++++++++++++------------ infortrend/checks/infortrend_ldrives | 28 ++++++++---- infortrend/checks/infortrend_ldrives1 | 47 ++++++++++++++----- 6 files changed, 180 insertions(+), 80 deletions(-) diff --git a/infortrend/checks/infortrend_chassis b/infortrend/checks/infortrend_chassis index 7c880801..e63ef2e3 100644 --- a/infortrend/checks/infortrend_chassis +++ b/infortrend/checks/infortrend_chassis @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -137,11 +142,18 @@ def check_infortrend_chassis(item, params, info): adtl_status = status_info[type]['adtl_func'](status) yield status_info[type]['adtl_info'][adtl_status][0], status_info[type]['adtl_info'][adtl_status][1] -check_info["infortrend_chassis"] = { - 'check_function' : check_infortrend_chassis, - 'service_description' : "IFT %s", - 'has_perfdata' : False, - 'inventory_function' : inventory_infortrend_chassis, - 'snmp_scan_function' : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1714.1.2"), - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.1.9.1", [ "8", "13", "6", "9", "10", "12" ] ), -} +def parse_infortrend_chassis(string_table: StringTable) -> StringTable | None: + return string_table or None + +check_info["infortrend_chassis"] = LegacyCheckDefinition( + detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1714.1.2"), + parse_function=parse_infortrend_chassis, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.1.9.1", + oids=["8", "13", "6", "9", "10", "12"], + ), + service_name="IFT %s", + discovery_function=inventory_infortrend_chassis, + check_function=check_infortrend_chassis, + check_ruleset_name="infortend_chassis", +) diff --git a/infortrend/checks/infortrend_chassis1 b/infortrend/checks/infortrend_chassis1 index 98c18e4d..21eaf408 100644 --- a/infortrend/checks/infortrend_chassis1 +++ b/infortrend/checks/infortrend_chassis1 @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -18,15 +23,12 @@ # Boston, MA 02110-1301 USA. def inventory_infortrend_chassis1(info): - # Debug: lets see how the data we get looks like - inventory = [] for name, status, devtype, value, unit in info: - if devtype == '15' and not name: + if not name: continue if devtype == '14' and status == '128': continue - inventory.append( (name, status) ) - return inventory + yield name, {} def check_infortrend_chassis1(item, params, info): status_info = { @@ -121,8 +123,7 @@ def check_infortrend_chassis1(item, params, info): 'adtl_func': lambda status: status >> 2 & 3, }, # LED - "12": { 'bits': { 0: ( "", "" ), - 6: ( "LED is active", "LED is inactive" ), + "12": { 'bits': { 6: ( "LED is active", "LED is inactive" ), 7: ( "LED is present", "LED is NOT present" ), }, }, @@ -171,7 +172,7 @@ def check_infortrend_chassis1(item, params, info): output = [] for bit in status_info[devtype]['bits'].keys(): bit_set = ( status & 1 << bit ) >> bit - if bit_set: + if bit_set and status_info[devtype]['bits'][bit][bit_set] != "LED is inactive": output.append("%s (!)" % status_info[devtype]['bits'][bit][bit_set]) else: output.append(status_info[devtype]['bits'][bit][bit_set]) @@ -183,18 +184,47 @@ def check_infortrend_chassis1(item, params, info): output.append(status_info[devtype]['adtl_info'][adtl_status]) if status == 64: if devtype == '12': - return (0, ", ".join(output)) + if any("(!)" in s for s in output): + return (1, ", ".join(output)) + else: + return (0, ", ".join(output)) else: return (1, "%d %s" % ( status, ", ".join(output))) else: return (2, "%d %s" % ( status, ", ".join(output))) return (3, "not yet implemented") -check_info["infortrend_chassis1"] = { - 'check_function' : check_infortrend_chassis1, - 'service_description' : "IFT %s", - 'has_perfdata' : False, - 'inventory_function' : inventory_infortrend_chassis1, - 'snmp_scan_function' : lambda oid: "infortrend" in oid(".1.3.6.1.2.1.1.1.0").lower() and oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1714.1.1"), - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.1.9.1", [ "8", "13", "6", "9", "10" ] ), -} +def rename_dups(l): + d = {} + for i in range(len(l)): + if l[i][0] in d: + d[l[i][0]] += 1 + else: + d[l[i][0]] = 1 + + if l[i][0]: + if "Device Slot" in l[i][0]: + slot = int(l[i][0][-1]) + l[i][0] = '[{}] Device Slot {:02d}'.format(str(d[l[i][0]]), slot) + else: + l[i][0] = '[{}] {}'.format(str(d[l[i][0]]), l[i][0]) + return l + +def parse_infortrend_chassis1(string_table: StringTable) -> StringTable | None: + return rename_dups(string_table) or None + +check_info["infortrend_chassis1"] = LegacyCheckDefinition( + detect=all_of( + contains(".1.3.6.1.2.1.1.1.0", "Infortrend"), + startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1714.1.1"), + ), + parse_function=parse_infortrend_chassis1, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.1.9.1", + oids=["8", "13", "6", "9", "10"], + ), + service_name="IFT %s", + discovery_function=inventory_infortrend_chassis1, + check_function=check_infortrend_chassis1, + check_ruleset_name="infortend_chassis1", +) diff --git a/infortrend/checks/infortrend_disks b/infortrend/checks/infortrend_disks index 644de631..ccd6eaa8 100644 --- a/infortrend/checks/infortrend_disks +++ b/infortrend/checks/infortrend_disks @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, exists, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -69,11 +74,18 @@ def check_infortrend_disks(item, params, info): return (2, info + status_info[status]) return (1, info + status_info[status]) -check_info["infortrend_disks"] = { - 'check_function' : check_infortrend_disks, - 'service_description' : "IFT Disk Slot %s", - 'has_perfdata' : False, - 'inventory_function' : inventory_infortrend_disks, - 'snmp_scan_function' : lambda oid: oid(".1.3.6.1.4.1.1714.1.1.1.1.0"), - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.6.1", [ "13", "11", "15", "16", "17", "7", "8" ] ), -} +def parse_infortrend_disks(string_table: StringTable) -> StringTable | None: + return string_table or None + +check_info["infortrend_disks"] = LegacyCheckDefinition( + detect=exists(".1.3.6.1.4.1.1714.1.1.1.1.0"), + parse_function=parse_infortrend_disks, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.6.1", + oids=["13", "11", "15", "16", "17", "7", "8"], + ), + service_name="IFT Disk Slot %s", + discovery_function=inventory_infortrend_disks, + check_function=check_infortrend_disks, + check_ruleset_name="infortend_disks", +) diff --git a/infortrend/checks/infortrend_disks1 b/infortrend/checks/infortrend_disks1 index 69145b71..77e9ce7e 100644 --- a/infortrend/checks/infortrend_disks1 +++ b/infortrend/checks/infortrend_disks1 @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -18,17 +23,8 @@ # Boston, MA 02110-1301 USA. def inventory_infortrend_disks1(info): - # Debug: lets see how the data we get looks like - inventory = [] - disknumber = 0 for slot, status in info: - if int(slot) != 0: - if int(slot) > int(disknumber): - disknumber = int(slot) - else: - disknumber = int(disknumber) + 1 - inventory.append( (str(disknumber), int(status)) ) - return inventory + yield slot, {} def check_infortrend_disks1(item, params, info): status_info = { @@ -65,32 +61,45 @@ def check_infortrend_disks1(item, params, info): 254 : "Missing Drive", 255 : "Failed Drive" } - disknumber = 0 - new_info = [] for slot, status in info: - if int(slot) != 0: - if int(slot) > int(disknumber): - disknumber = int(slot) - else: - disknumber = int(disknumber) + 1 - new_info.append([str(disknumber), str(status)]) - for slot, status in new_info: status = int(status) if slot == item: if status not in status_info.keys(): return (3, "Status is %d" % status) - if status == 1 or status == 3 or status == 9 or status == 63: + if status == 1 or status == 3 or status == 9 or status == 63 or status == 141: return (0, status_info[status]) if status > 63: return (2, status_info[status]) return (1, status_info[status]) return (3, "not yet implemented") -check_info["infortrend_disks1"] = { - 'check_function' : check_infortrend_disks1, - 'inventory_function' : inventory_infortrend_disks1, - 'service_description' : 'IFT Disk Slot %s', - 'has_perfdata' : False, - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.1.6.1", [ "13", "11" ] ), - 'snmp_scan_function' : lambda oid: "infortrend" in oid(".1.3.6.1.2.1.1.1.0").lower() and oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1714.1.1"), -} +def rename_dups(l): + d = {} + for i in range(len(l)): + if l[i][0] in d: + d[l[i][0]] += 1 + else: + d[l[i][0]] = 1 + + if l[i][0]: + l[i][0] = '[{}] Disk Slot {:02d}'.format(str(d[l[i][0]]), int(l[i][0])) + return l + +def parse_infortrend_disks1(string_table: StringTable) -> StringTable | None: + return rename_dups(string_table) or None + +check_info["infortrend_disks1"] = LegacyCheckDefinition( + detect=all_of( + contains(".1.3.6.1.2.1.1.1.0", "Infortrend"), + startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1714.1.1"), + ), + parse_function=parse_infortrend_disks1, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.1.6.1", + oids=["13", "11"], + ), + service_name="IFT %s", + discovery_function=inventory_infortrend_disks1, + check_function=check_infortrend_disks1, + check_ruleset_name="infortend_disks1", +) diff --git a/infortrend/checks/infortrend_ldrives b/infortrend/checks/infortrend_ldrives index 478088f2..1f6ceff7 100644 --- a/infortrend/checks/infortrend_ldrives +++ b/infortrend/checks/infortrend_ldrives @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, exists, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -54,11 +59,18 @@ def check_infortrend_ldrives(item, params, info): return (rc, ", ".join(output)) return (3, "not yet implemented") -check_info["infortrend_ldrives"] = { - 'check_function' : check_infortrend_ldrives, - 'service_description' : "IFT Logical Drive %s", - 'has_perfdata' : False, - 'inventory_function' : inventory_infortrend_ldrives, - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.2.1", [ "2", "6" ] ), - 'snmp_scan_function' : lambda oid: oid(".1.3.6.1.4.1.1714.1.1.1.1.0"), -} +def parse_infortrend_ldrives(string_table: StringTable) -> StringTable | None: + return string_table or None + +check_info["infortrend_ldrives"] = LegacyCheckDefinition( + detect=exists(".1.3.6.1.4.1.1714.1.1.1.1.0"), + parse_function=parse_infortrend_ldrives, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.2.1", + oids=["2", "6"], + ), + service_name="IFT Logical Drive %s", + discovery_function=inventory_infortrend_ldrives, + check_function=check_infortrend_ldrives, + check_ruleset_name="infortend_ldrives", +) diff --git a/infortrend/checks/infortrend_ldrives1 b/infortrend/checks/infortrend_ldrives1 index 4ecbda36..435b7dd1 100644 --- a/infortrend/checks/infortrend_ldrives1 +++ b/infortrend/checks/infortrend_ldrives1 @@ -4,8 +4,13 @@ # # (c) 2013 Heinlein Support GmbH # Robert Sander +# (c) 2024 Jens Maus # +from cmk.base.check_api import LegacyCheckDefinition, saveint +from cmk.base.config import check_info +from cmk.agent_based.v2 import all_of, contains, startswith, exists, SNMPTree, StringTable + # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. This file is distributed @@ -18,10 +23,8 @@ # Boston, MA 02110-1301 USA. def inventory_infortrend_ldrives1(info): - inventory = [] for id, status in info: - inventory.append( (id, int(status)) ) - return inventory + yield id, {} def check_infortrend_ldrives1(item, params, info): status_info = { @@ -55,11 +58,33 @@ def check_infortrend_ldrives1(item, params, info): return (rc, ", ".join(output)) return (3, "not yet implemented") -check_info["infortrend_ldrives1"] = { - 'check_function' : check_infortrend_ldrives1, - 'inventory_function' : inventory_infortrend_ldrives1, - 'service_description' : 'IFT Logical Drive %s', - 'has_perfdata' : False, - 'snmp_info' : ( ".1.3.6.1.4.1.1714.1.1.2.1", [ "2", "6" ] ), - 'snmp_scan_function' : lambda oid: "infortrend" in oid(".1.3.6.1.2.1.1.1.0").lower() and oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1714.1.1"), -} +def rename_dups(l): + d = {} + for i in range(len(l)): + if l[i][0] in d: + d[l[i][0]] += 1 + else: + d[l[i][0]] = 1 + + if l[i][0]: + l[i][0] = '[{}] Logical Drive [{}]'.format(str(d[l[i][0]]), l[i][0]) + return l + +def parse_infortrend_ldrives1(string_table: StringTable) -> StringTable | None: + return rename_dups(string_table) or None + +check_info["infortrend_ldrives1"] = LegacyCheckDefinition( + detect=all_of( + contains(".1.3.6.1.2.1.1.1.0", "Infortrend"), + startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.1714.1.1"), + ), + parse_function=parse_infortrend_ldrives1, + fetch=SNMPTree( + base=".1.3.6.1.4.1.1714.1.1.2.1", + oids=["2", "6"], + ), + service_name="IFT %s", + discovery_function=inventory_infortrend_ldrives1, + check_function=check_infortrend_ldrives1, + check_ruleset_name="infortend_ldrives1", +) From 7f2fd376e5dd74f815f6192bb5ab87622fbb5fec Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Fri, 31 May 2024 13:53:38 +0200 Subject: [PATCH 2/4] rework to add performance data in chassis1 and add warn/crit tags where appropriate. --- infortrend/checks/infortrend_chassis1 | 242 ++++++++++++++++++-------- infortrend/checks/infortrend_disks1 | 21 +-- infortrend/checks/infortrend_ldrives1 | 25 +-- 3 files changed, 192 insertions(+), 96 deletions(-) diff --git a/infortrend/checks/infortrend_chassis1 b/infortrend/checks/infortrend_chassis1 index 21eaf408..85cfce60 100644 --- a/infortrend/checks/infortrend_chassis1 +++ b/infortrend/checks/infortrend_chassis1 @@ -33,130 +33,131 @@ def inventory_infortrend_chassis1(info): def check_infortrend_chassis1(item, params, info): status_info = { # Power supply - "1": { 'bits': { 0: ( "Power supply functioning normally", "Power supply malfunctioning" ), - 6: ( "Power supply is ON", "Power supply is OFF" ), - 7: ( "Power supply IS present", "Power supply is NOT present" ), + "1": { 'bits': { 0: ( "Power supply functioning normally", "Power supply malfunctioning (!!)" ), + 6: ( "Power supply is ON", "Power supply is OFF (!)" ), + 7: ( "Power supply IS present", "Power supply is NOT present (!)" ), }, }, # Fan - "2": { 'bits': { 0: ( "Fan functioning normally", "Fan malfunctioning" ), - 6: ( "Fan is ON", "Fan is OFF" ), - 7: ( "Fan IS present", "Fan is NOT present" ), + "2": { 'bits': { 0: ( "Fan functioning normally", "Fan malfunctioning (!!)" ), + 6: ( "Fan is ON", "Fan is OFF (!!)" ), + 7: ( "Fan IS present", "Fan is NOT present (!)" ), }, }, # Temperature sensor - "3": { 'bits': { 0: ( "Temp. sensor functioning normally", "Temp. sensor malfunctioning" ), - 6: ( "Temp. Sensor is Activated", "Temp. Sensor is NOT Activated" ), - 7: ( "Temperature sensor IS present", "Temperature sensor is NOT present" ), + "3": { 'bits': { 0: ( "Temp. sensor functioning normally", "Temp. sensor malfunctioning (!!)" ), + 6: ( "Temp. Sensor is Activated", "Temp. Sensor is NOT Activated (!)" ), + 7: ( "Temperature sensor IS present", "Temperature sensor is NOT present (!)" ), }, 'adtl_info': { 0: "Temp. within safe range", - 2: "Cold Temp. Warning", - 3: "Hot Temp. Warning", - 4: "Cold Temp. Limit Exceeded", - 5: "Hot Temp. Limit Exceeded", + 2: "Cold Temp. Warning (!)", + 3: "Hot Temp. Warning (!)", + 4: "Cold Temp. Limit Exceeded (!!)", + 5: "Hot Temp. Limit Exceeded (!!)", }, 'adtl_func': lambda status: status >> 1 & 7, }, # UPS - "4": { 'bits': { 0: ( "Unit functioning normally", "Unit malfunctioning" ), - 1: ( "AC Power present", "AC Power NOT present" ), - 6: ( "UPS is ON", "UPS is OFF" ), + "4": { 'bits': { 0: ( "Unit functioning normally", "Unit malfunctioning (!!)" ), + 1: ( "AC Power present", "AC Power NOT present (!)" ), + 6: ( "UPS is ON", "UPS is OFF (!)" ), 7: ( "UPS IS present", "UPS is NOT present" ), }, 'adtl_info': { 0: "battery fully charged", 1: "battery not fully charged", - 2: "battery charge critically low", - 3: "battery completely drained", + 2: "battery charge critically low (!!)", + 3: "battery completely drained (!!)", }, 'adtl_func': lambda status: status >> 2 & 3, }, # Voltage sensors - "5": { 'bits': { 0: ( "Voltage sensor functioning normally", "Voltage sensor malfunctioning" ), - 6: ( "Voltage Sensor is Activated", "Voltage Sensor is NOT Activated" ), - 7: ( "Voltage sensor IS present", "Voltage sensor is NOT present" ), + "5": { 'bits': { 0: ( "Voltage sensor functioning normally", "Voltage sensor malfunctioning (!!)" ), + 6: ( "Voltage Sensor is Activated", "Voltage Sensor is NOT Activated (!)" ), + 7: ( "Voltage sensor IS present", "Voltage sensor is NOT present (!)" ), }, 'adtl_info': { 0: "Voltage within acceptable range", - 2: "Low Voltage Warning", - 3: "High Voltage Warning", - 4: "Low Voltage Limit Exceeded", - 5: "High Voltage Limit Exceeded", + 2: "Low Voltage Warning (!)", + 3: "High Voltage Warning (!)", + 4: "Low Voltage Limit Exceeded (!!)", + 5: "High Voltage Limit Exceeded (!!)", }, 'adtl_func': lambda status: status >> 1 & 7, }, # Current sensors - "6": { 'bits': { 0: ( "Current sensor functioning normally", "Current sensor malfunctioning" ), - 6: ( "Current Sensor is Activated", "Current Sensor is NOT Activated" ), - 7: ( "Current sensor IS present", "Current sensor is NOT present" ), + "6": { 'bits': { 0: ( "Current sensor functioning normally", "Current sensor malfunctioning (!!)" ), + 6: ( "Current Sensor is Activated", "Current Sensor is NOT Activated (!)" ), + 7: ( "Current sensor IS present", "Current sensor is NOT present (!)" ), }, 'adtl_info': { 0: "Current within acceptable range", - 3: "Over Current Warning", - 5: "Over Current Limit Exceeded", + 3: "Over Current Warning (!)", + 5: "Over Current Limit Exceeded (!!)", }, 'adtl_func': lambda status: status >> 1 & 7, }, # Temperature Out-of-Range Flags "8": { }, # Door - "9": { 'bits': { 0: ( "Door OK", "Door, door lock, or door sensor malfunctioning" ), - 1: ( "Door is shut", "Door is open" ), - 6: ( "Door lock engaged", "Door lock NOT engaged" ), + "9": { 'bits': { 0: ( "Door OK", "Door, door lock, or door sensor malfunctioning (!!)" ), + 1: ( "Door is shut", "Door is open (!)" ), + 6: ( "Door lock engaged", "Door lock NOT engaged (!)" ), 7: ( "Door IS present", "Door is NOT present" ), }, }, # Speaker - "10": { 'bits': { 0: ("Speaker functioning normally", "Speaker malfunctioning" ), - 6: ("Speaker is ON", "Speaker is OFF" ), + "10": { 'bits': { 0: ("Speaker functioning normally", "Speaker malfunctioning (!!)" ), + 6: ("Speaker is ON", "Speaker is OFF (!)" ), 7: ("Speaker IS present", "Speaker is NOT present" ), }, }, # Battery-backup battery - "11": { 'bits': { 0: ( "Battery functioning normally", "Battery malfunctioning" ), - 1: ( "Battery charging OFF (or trickle)", "Battery charging ON" ), - 6: ( "Battery-backup is enabled", "Battery-backup is disabled" ), - 7: ( "Battery IS present", "Battery is NOT present" ), + "11": { 'bits': { 0: ( "Battery functioning normally", "Battery malfunctioning (!!)" ), + 1: ( "Battery charging OFF (or trickle)", "Battery charging ON (!)" ), + 6: ( "Battery-backup is enabled", "Battery-backup is disabled (!)" ), + 7: ( "Battery IS present", "Battery is NOT present (!)" ), }, 'adtl_info': { 0: "battery fully charged", - 1: "battery not fully charged", - 2: "battery charge critically low", - 3: "battery completely drained", + 1: "battery not fully charged (!)", + 2: "battery charge critically low (!!)", + 3: "battery completely drained (!!)", }, 'adtl_func': lambda status: status >> 2 & 3, }, # LED - "12": { 'bits': { 6: ( "LED is active", "LED is inactive" ), - 7: ( "LED is present", "LED is NOT present" ), + "12": { 'bits': { 0: ( "", "" ), + 6: ( "LED is active (!)", "LED is inactive" ), + 7: ( "LED is present", "LED is NOT present (!)" ), }, }, # Cache-Data-Backup Flash Device - "13": { 'bits': { 0: ( "Flash Device functioning normally", "Flash Device malfunctioning" ), - 6: ( "Flash Device is enabled", "Flash Device is disabled" ), + "13": { 'bits': { 0: ( "Flash Device functioning normally", "Flash Device malfunctioning (!!)" ), + 6: ( "Flash Device is enabled", "Flash Device is disabled (!)" ), 7: ( "Flash Device is present", "Flash Device is NOT present" ), }, }, # Host Board "14": { 'bits': { 0: ( "Host Board IS present", "" ), - 7: ( "Host Board IS present", "Host Board is NOT present" ) + 7: ( "Host Board IS present", "Host Board is NOT present (!!)" ) }, }, # Midplane/Backplane "15": { 'bits': { 0: ( "Midplane/Backplane", "" ) } }, # Slot states - "17": { 'bits': { 0: ( "Slot sense circuitry functioning normally", "Slot sense circuitry malfunctioning" ), - 1: ( "Device in slot has not been marked 'needing replacement' or a replacement drive has been inserted", "Device in slot has been marked BAD and is awaiting replacement" ), - 2: ( "Slot is activated so that drive can be accessed", "Slot NOT activated" ), + "17": { 'bits': { 0: ( "Slot sense circuitry functioning normally", "Slot sense circuitry malfunctioning (!!)" ), + 1: ( "Device in slot has not been marked 'needing replacement' or a replacement drive has been inserted", "Device in slot has been marked BAD and is awaiting replacement (!)" ), + 2: ( "Slot is activated so that drive can be accessed", "Slot NOT activated (!)" ), 6: ( "Slot is NOT ready for insertion/removal", "Slot is ready for insertion/removal" ), 7: ( "Device inserted in slot", "Slot is empty" ), }, }, # Enclosure drawer - "18": { 'bits': { 0: ( "Enclosure Drawer functioning normally", "Enclosure Drawer malfunctioning" ), - 6: ( "Enclosure Drawer is closed", "Enclosure Drawer is opened" ), + "18": { 'bits': { 0: ( "Enclosure Drawer functioning normally", "Enclosure Drawer malfunctioning (!!)" ), + 6: ( "Enclosure Drawer is closed", "Enclosure Drawer is opened (!)" ), 7: ( "Enclosure Drawer is present", "Enclosure Drawer is NOT present" ), }, }, # Enclosure Management Services Controller - "31": { 'bits': { 0: ( "Enclosure Management Services Controller functioning normally", "Enclosure Management Services Controller malfunctioning" ), - 6: ( "Enclosure Management Services Controller is closed", "Enclosure Management Services Controller is opened" ), + "31": { 'bits': { 0: ( "Enclosure Management Services Controller functioning normally", "Enclosure Management Services Controller malfunctioning (!!)" ), + 6: ( "Enclosure Management Services Controller is closed", "Enclosure Management Services Controller is opened (!)" ), 7: ( "Enclosure Management Services Controller is present", "Enclosure Management Services Controller is NOT present" ), }, }, @@ -165,49 +166,136 @@ def check_infortrend_chassis1(item, params, info): for name, status, devtype, value, unit in info: status = int(status) if name == item: - if status == 0: - return (0, status_info[devtype]['bits'][0][0]) if status == 255: return (3, "Status unknown") + output = [] + perfdata = [] + text = None + warn = None + crit = None + # collect perfdata for temp/volate/fan sensors + if devtype == '3': # temp sensor + unit_symbol = " °C" + val = (float(value) * float(unit) / 1000.0) - 273.0 + warn, crit = params.get('temp') + perfdata = [(name.replace(' ', '-'), val, warn, crit)] + text = "%.1f%s (warn/crit at %.1f%s/%.1f%s)" % ( + val, + unit_symbol, + warn, + unit_symbol, + crit, + unit_symbol, + ) + elif devtype == '5': # voltage sensor + unit_symbol = " V" + val = (float(value) * float(unit) / 1000.0) + if "12V" in name: + warn, crit = params.get('voltage12') + else: + warn, crit = params.get('voltage5') + perfdata = [(name.replace(' ', '-'), val, warn, crit)] + text = "%.1f%s (warn/crit at %.1f%s/%.1f%s)" % ( + val, + unit_symbol, + warn, + unit_symbol, + crit, + unit_symbol, + ) + elif devtype == '2': # fan + if int(unit) == 0: + speed = 'Unknown (!)' + val = int(value) + if val == 0: + speed = 'Normal' + elif val == 1: + speed = 'Lowest speed' + elif val == 2: + speed = 'Second lowest speed' + elif val == 3: + speed = 'Third lowest speed' + elif val == 4: + speed = 'Intermediate speed' + elif val == 5: + speed = 'Third highest speed' + elif val == 6: + speed = 'Second highest speed' + elif val == 7: + speed = 'Highest speed' + + perfdata = [(name.replace(' ', '-'), val)] + text = "Status: %s" % ( + speed, + ) + + else: + unit_symbol = " rpm" + val = int(value) + warn, crit = params.get('fan') + perfdata = [(name.replace(' ', '-'), val, warn, crit)] + text = "%d%s (warn/crit at %d%s/%d%s)" % ( + val, + unit_symbol, + warn, + unit_symbol, + crit, + unit_symbol, + ) + + if text: + if crit and warn: + if val >= crit: + text += "(!!)" + elif val >= warn: + text += "(!)" + + output.append(text) + for bit in status_info[devtype]['bits'].keys(): bit_set = ( status & 1 << bit ) >> bit - if bit_set and status_info[devtype]['bits'][bit][bit_set] != "LED is inactive": - output.append("%s (!)" % status_info[devtype]['bits'][bit][bit_set]) - else: - output.append(status_info[devtype]['bits'][bit][bit_set]) + if status_info[devtype]['bits'][bit][bit_set]: + output.append(status_info[devtype]['bits'][bit][bit_set]) + if 'adtl_info' in status_info[devtype]: adtl_status = status_info[devtype]['adtl_func'](status) - if adtl_status > 0: - output.append("%s (!)" % status_info[devtype]['adtl_info'][adtl_status]) - else: + if status_info[devtype]['adtl_info'][adtl_status]: output.append(status_info[devtype]['adtl_info'][adtl_status]) + + outstr = ", ".join(output) + state = 0 + if "(!)" in outstr: + state = 1 # warn + elif "(!!)" in outstr: + state = 2 # crit + if status == 64: if devtype == '12': - if any("(!)" in s for s in output): - return (1, ", ".join(output)) - else: - return (0, ", ".join(output)) + return (state, outstr, perfdata) else: - return (1, "%d %s" % ( status, ", ".join(output))) + return (state, "%d %s" % ( status, outstr), perfdata) + elif status == 0: + return (state, outstr, perfdata) else: - return (2, "%d %s" % ( status, ", ".join(output))) + return (state, "%d %s" % ( status, outstr), perfdata) return (3, "not yet implemented") def rename_dups(l): d = {} for i in range(len(l)): - if l[i][0] in d: - d[l[i][0]] += 1 + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 else: - d[l[i][0]] = 1 + d[lowl] = 1 if l[i][0]: if "Device Slot" in l[i][0]: slot = int(l[i][0][-1]) - l[i][0] = '[{}] Device Slot {:02d}'.format(str(d[l[i][0]]), slot) + l[i][0] = '[{}] Device Slot {:02d}'.format(str(d[lowl]), slot) else: - l[i][0] = '[{}] {}'.format(str(d[l[i][0]]), l[i][0]) + l[i][0] = '[{}] {}'.format(str(d[lowl]), l[i][0]) return l def parse_infortrend_chassis1(string_table: StringTable) -> StringTable | None: @@ -227,4 +315,10 @@ check_info["infortrend_chassis1"] = LegacyCheckDefinition( discovery_function=inventory_infortrend_chassis1, check_function=check_infortrend_chassis1, check_ruleset_name="infortend_chassis1", + check_default_parameters={ + "temp": (65.0, 75.0), + "voltage12": (12.5, 13.0), + "voltage5": (5.5, 6.0), + "fan": (0.0, 1.0), + }, ) diff --git a/infortrend/checks/infortrend_disks1 b/infortrend/checks/infortrend_disks1 index 77e9ce7e..01350e10 100644 --- a/infortrend/checks/infortrend_disks1 +++ b/infortrend/checks/infortrend_disks1 @@ -33,13 +33,13 @@ def check_infortrend_disks1(item, params, info): 2 : "Used Drive", 3 : "Spare Drive", 4 : "Drive Initialization in Progress", - 5 : "Drive Rebuild in Progress", + 5 : "Drive Rebuild in Progress (!)", 6 : "Add Drive to Logical Drive in Progress", 9 : "Global Spare Drive", 17 : "Drive is in process of Cloning another Drive", 18 : "Drive is a valid Clone of another Drive", 19 : "Drive is in process of Copying from another Drive (for Copy/Replace LD Expansion function)", - 63 : "Drive Absent", + 63 : "Drive Absent (!)", 128 : "SCSI Device (Type 0)", 129 : "SCSI Device (Type 1)", 130 : "SCSI Device (Type 2)", @@ -56,10 +56,10 @@ def check_infortrend_disks1(item, params, info): 141 : "SCSI Device (Type 13)", 142 : "SCSI Device (Type 14)", 143 : "SCSI Device (Type 15)", - 252 : "Missing Global Spare Drive", - 253 : "Missing Spare Drive", - 254 : "Missing Drive", - 255 : "Failed Drive" + 252 : "Missing Global Spare Drive (!)", + 253 : "Missing Spare Drive (!)", + 254 : "Missing Drive (!)", + 255 : "Failed Drive (!!)" } for slot, status in info: status = int(status) @@ -76,13 +76,14 @@ def check_infortrend_disks1(item, params, info): def rename_dups(l): d = {} for i in range(len(l)): - if l[i][0] in d: - d[l[i][0]] += 1 + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 else: - d[l[i][0]] = 1 + d[lowl] = 1 if l[i][0]: - l[i][0] = '[{}] Disk Slot {:02d}'.format(str(d[l[i][0]]), int(l[i][0])) + l[i][0] = '[{}] Disk Slot {:02d}'.format(str(d[lowl]), int(l[i][0])) return l def parse_infortrend_disks1(string_table: StringTable) -> StringTable | None: diff --git a/infortrend/checks/infortrend_ldrives1 b/infortrend/checks/infortrend_ldrives1 index 435b7dd1..57ce762f 100644 --- a/infortrend/checks/infortrend_ldrives1 +++ b/infortrend/checks/infortrend_ldrives1 @@ -29,14 +29,14 @@ def inventory_infortrend_ldrives1(info): def check_infortrend_ldrives1(item, params, info): status_info = { 0 : "Good", - 1 : "Rebuilding", - 2 : "Initializing", - 3 : "Degraded", - 4 : "Dead", - 5 : "Invalid", - 6 : "Incomplete", - 7 : "Drive Missing", - 64 : "Good" + 1 : "Rebuilding (!)", + 2 : "Initializing (!)", + 3 : "Degraded (!)", + 4 : "Dead (!!)", + 5 : "Invalid (!!)", + 6 : "Incomplete (!!)", + 7 : "Drive Missing (!!)", + 64 : "Good" } for slot, status in info: status = int(status) @@ -61,13 +61,14 @@ def check_infortrend_ldrives1(item, params, info): def rename_dups(l): d = {} for i in range(len(l)): - if l[i][0] in d: - d[l[i][0]] += 1 + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 else: - d[l[i][0]] = 1 + d[lowl] = 1 if l[i][0]: - l[i][0] = '[{}] Logical Drive [{}]'.format(str(d[l[i][0]]), l[i][0]) + l[i][0] = '[{}] Logical Drive [{}]'.format(str(d[lowl]), l[i][0]) return l def parse_infortrend_ldrives1(string_table: StringTable) -> StringTable | None: From 6358168a0ed0616f26cc207c435aaca3e8bac7ff Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Fri, 31 May 2024 14:02:11 +0200 Subject: [PATCH 3/4] add value and rename Status to Level to make clear that we only real fan levels. --- infortrend/checks/infortrend_chassis1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/infortrend/checks/infortrend_chassis1 b/infortrend/checks/infortrend_chassis1 index 85cfce60..84c5d791 100644 --- a/infortrend/checks/infortrend_chassis1 +++ b/infortrend/checks/infortrend_chassis1 @@ -209,7 +209,7 @@ def check_infortrend_chassis1(item, params, info): speed = 'Unknown (!)' val = int(value) if val == 0: - speed = 'Normal' + speed = 'Normal speed' elif val == 1: speed = 'Lowest speed' elif val == 2: @@ -226,7 +226,8 @@ def check_infortrend_chassis1(item, params, info): speed = 'Highest speed' perfdata = [(name.replace(' ', '-'), val)] - text = "Status: %s" % ( + text = "Level %d (%s)" % ( + val, speed, ) From cfcad290e2648bc391b6d783fa3d21fd02d2889e Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Sun, 2 Jun 2024 22:14:00 +0200 Subject: [PATCH 4/4] add new package version --- infortrend/infortrend-4.5.mkp | Bin 27785 -> 0 bytes infortrend/infortrend-5.0.0.mkp | Bin 0 -> 29042 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 infortrend/infortrend-4.5.mkp create mode 100644 infortrend/infortrend-5.0.0.mkp diff --git a/infortrend/infortrend-4.5.mkp b/infortrend/infortrend-4.5.mkp deleted file mode 100644 index 6621215fbef17dee22d041d3db359d5c19aff9d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27785 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