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..84c5d791 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,144 +23,141 @@ # 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 = { # 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': { 0: ( "", "" ), - 6: ( "LED is active", "LED is inactive" ), - 7: ( "LED is present", "LED is NOT present" ), + 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" ), }, }, @@ -164,37 +166,160 @@ 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 speed' + 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 = "Level %d (%s)" % ( + val, + 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: - 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': - 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") -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)): + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 + else: + 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[lowl]), slot) + else: + l[i][0] = '[{}] {}'.format(str(d[lowl]), 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", + 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_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..01350e10 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 = { @@ -37,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)", @@ -60,37 +56,51 @@ 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 (!!)" } - 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)): + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 + else: + d[lowl] = 1 + + if 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: + 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..57ce762f 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,22 +23,20 @@ # 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 = { 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) @@ -55,11 +58,34 @@ 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)): + lowl = l[i][0].lower() + if lowl in d: + d[lowl] += 1 + else: + d[lowl] = 1 + + if 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: + 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", +) diff --git a/infortrend/infortrend-4.5.mkp b/infortrend/infortrend-4.5.mkp deleted file mode 100644 index 6621215f..00000000 Binary files a/infortrend/infortrend-4.5.mkp and /dev/null differ diff --git a/infortrend/infortrend-5.0.0.mkp b/infortrend/infortrend-5.0.0.mkp new file mode 100644 index 00000000..be9ed2fb Binary files /dev/null and b/infortrend/infortrend-5.0.0.mkp differ