diff --git a/src/selenio_mcp/baseinfo.ini b/src/selenio_mcp/baseinfo.ini new file mode 100644 index 0000000..0393611 --- /dev/null +++ b/src/selenio_mcp/baseinfo.ini @@ -0,0 +1,7 @@ +[info] +title = Selenio MCP SNMP Checks +author = Markus Birth +description = SNMP based checks for the Selenio MCP frame controller. +version = 2016.06.01.1 +version.min_required = 1.2.8p2 +download_url = https://github.com/mbirth/check_mk-plugins diff --git a/src/selenio_mcp/checks/selenio_mcp_ctrls b/src/selenio_mcp/checks/selenio_mcp_ctrls new file mode 100644 index 0000000..97c3810 --- /dev/null +++ b/src/selenio_mcp/checks/selenio_mcp_ctrls @@ -0,0 +1,64 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def inventory_selenio_mcp_ctrls(info): + inventory = [] + if len(info[0]) > 0: + inventory.append( ("Controllers", None) ) + return inventory + +def check_selenio_mcp_ctrls(item, _no_params, info): + E59enum = [ "Booting", "Fault", "In Service", "None", "not present", "Shutdown", "Wrong Type" ] + E66enum = [ "Active", "Standby", "Synchronizing", "not present" ] + + if len(info[0]) < 3: + return 3, "%s not found in SNMP data." % item + + # remove OID part from array + info[0].pop(0) + + ctrlStatus = [ E59enum[int(info[0][0])], E59enum[int(info[0][1])] ] + ctrlStatus2 = [ E66enum[int(info[0][2])], E66enum[int(info[0][3])] ] + + status = 0 + message = "" + + for i in range(0, len(ctrlStatus)): + c = ctrlStatus[i] + d = ctrlStatus2[i] + if i>0: + message += ", " + message += " Controller %i: %s (%s)" % ((i+1), c, d) + if c not in ["In Service", "not present"]: + if c in ["Booting", "Shutdown"]: + message += "(!)" + if status < 1: + status = 1 + else: + message += "(!!)" + if status < 2: + status = 2 + + return status, message + +check_info["selenio_mcp_ctrls"] = { + "check_function" : check_selenio_mcp_ctrls, + "inventory_function" : inventory_selenio_mcp_ctrls, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.290.9.3.3.21", ["1.1", "25.1"], + [ OID_END, # "1.1.1.1.0" (MCP3) or "25.1.1.1.0" (MCP1) + 1176, # ctrl1Status (E59enum) + 1190, # ctrl2Status + 393, # ctrl1Status (E66enum) + 228, # ctrl2Status + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.290.9.3.3.21"), + "has_perfdata" : False +} diff --git a/src/selenio_mcp/checks/selenio_mcp_fans b/src/selenio_mcp/checks/selenio_mcp_fans new file mode 100644 index 0000000..264d845 --- /dev/null +++ b/src/selenio_mcp/checks/selenio_mcp_fans @@ -0,0 +1,78 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def inventory_selenio_mcp_fans(info): + inventory = [] + if len(info[0]) > 0 and info[0][1] > 0: + inventory.append( ("Fans", None) ) + return inventory + +def check_selenio_mcp_fans(item, _no_params, info): + E18enum = [ "degraded", "faulty", "not present", "OK", "N/A" ] + E46enum = [ "degraded", "faulty", "OK" ] + + if len(info[0]) < 3: + return 3, "%s not found in SNMP data." % item + + # remove OID part from array + info[0].pop(0) + + # get frontpanelstatus + fpStatus = int(info[0].pop(0)) + frontPanel = E18enum[fpStatus] + + status = 0 + message = "" + details = "\\nFrontpanel: %s" % frontPanel + + if frontPanel != "OK" and frontPanel != "N/A": + status = 1 + message += "Frontpanel is %s (!)" % frontPanel + + # if frontPanel == "not present", fans 1..4 will report faults + + for i in range(0, len(info[0])): + fan_state = E46enum[int(info[0][i])] + details += "\\nFan %i: %s" % ((i+1), fan_state) + if fan_state == "degraded": + if status < 1: + status = 1 + message += " Fan %i is %s." % ((i+1), fan_state) + elif fan_state == "faulty": + if (frontPanel != "not present" or i>=4): + # only handle if fan failure is not due to open front panel + if status < 2: + status = 2 + message += " Fan %i is %s. (!!)" % ((i+1), fan_state) + + if message == "": + message = "All ok." + + message += details + + return status, message + +check_info["selenio_mcp_fans"] = { + "check_function" : check_selenio_mcp_fans, + "inventory_function" : inventory_selenio_mcp_fans, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.290.9.3.3.21", ["1.1", "25.1"], + [ OID_END, # "1.1.1.1.0" (MCP3) or "25.1.1.1.0" (MCP1) + 392, # frontPanelStatus (E18enum) + 386, # fan1Value (E46enum) + 387, # fan2Value + 388, # fan3Value + 389, # fan4Value + 1394, # fan5Value + 1395, # fan6Value + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.290.9.3.3.21"), + "has_perfdata" : False +} diff --git a/src/selenio_mcp/checks/selenio_mcp_leds b/src/selenio_mcp/checks/selenio_mcp_leds new file mode 100644 index 0000000..4715c6b --- /dev/null +++ b/src/selenio_mcp/checks/selenio_mcp_leds @@ -0,0 +1,76 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def inventory_selenio_mcp_leds(info): + inventory = [] + if len(info[0]) > 0 and info[0][1] > 0: + inventory.append( ("Frontpanel", None) ) + return inventory + +def check_selenio_mcp_leds(item, _no_params, info): + LEDs = [ "System", "Module", "Input", "Alarm", "Ctrl", "Ref", "CA Ref" ] + E18enum = [ "degraded", "faulty", "not present", "OK", "N/A" ] + E62enum = [ "Off", "Red", "Green", "Amber" ] + + + if len(info[0]) < 3: + return 3, "%s not found in SNMP data." % item + + # remove OID part from array + info[0].pop(0) + + # get frontpanelstatus + fpStatus = int(info[0].pop(0)) + frontPanel = E18enum[fpStatus] + + status = 0 + message = "Frontpanel: %s" % frontPanel + details = "\\nFrontpanel: %s" % frontPanel + + if frontPanel != "OK" and frontPanel != "N/A": + status = 1 + + for i in range(0, len(info[0])): + led_name = LEDs[i] + led_code = int(info[0][i]) + led_color = E62enum[led_code] + details += "\\n%s LED: %s" % (led_name, led_color) + + if led_color == "Amber": + if status < 1: + status = 1 + message += " %s LED is %s" % (led_name, led_color) + elif led_color == "Red": + if status < 2: + status = 2 + message += " %s LED is %s" % (led_name, led_color) + + message += details + + return status, message + +check_info["selenio_mcp_leds"] = { + "check_function" : check_selenio_mcp_leds, + "inventory_function" : inventory_selenio_mcp_leds, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.290.9.3.3.21", ["1.1", "25.1"], + [ OID_END, # "1.1.1.1.0" (MCP3) or "25.1.1.1.0" (MCP1) + 392, # frontPanelStatus (E18enum) + 229, # systemLEDValue (E62enum) + 230, # moduleLEDValue + 231, # inputLEDValue + 232, # alarmLEDValue + 1159, # controllerLEDValue + 1405, # refLEDValue ("Ref") + 1406, # carefLEDValue ("CA Ref") + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.290.9.3.3.21"), + "has_perfdata" : False +} diff --git a/src/selenio_mcp/checks/selenio_mcp_power b/src/selenio_mcp/checks/selenio_mcp_power new file mode 100644 index 0000000..3056b80 --- /dev/null +++ b/src/selenio_mcp/checks/selenio_mcp_power @@ -0,0 +1,111 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def inventory_selenio_mcp_power(info): + inventory = [] + if len(info[0]) > 0 and info[0][1] > 0: + inventory.append( ("Power", None) ) + return inventory + +def check_selenio_mcp_power(item, _no_params, info): + E12enum = [ "Yes", "No" ] + E13enum = [ "not present", "unknown", "AC", "DC" ] + E18enum = [ "degraded", "faulty", "not present", "OK", "N/A" ] + E46enum = [ "degraded", "faulty", "OK" ] + E66enum = [ "Active", "Standby", "Synchronizing", "not present" ] + E71enum = [ "PS1 (left)", "PS2 (right)", "Both (load sharing)" ] + + if len(info[0]) < 3: + return 3, "%s not found in SNMP data." % item + + # remove OID part from array + info[0].pop(0) + + systemVoltStatus = E46enum[int(info[0][0])] + psuStatus = [ E18enum[int(info[0][1])], E18enum[int(info[0][2])] ] + psuExpected = [ E12enum[int(info[0][3])], E12enum[int(info[0][4])] ] + ctrlVoltStatus = [ E18enum[int(info[0][5])], E18enum[int(info[0][6])] ] + psuType = [ E13enum[int(info[0][7])], E13enum[int(info[0][8])] ] + activePSU = E71enum[int(info[0][9])] + ctrlStatus = [ E66enum[int(info[0][10])], E66enum[int(info[0][11])] ] + + status = 0 + message = "Active PSU: %s." % activePSU + details = "\\nActive Power Supply: %s" % activePSU + details += "\\nPSU1: %s (Expected: %s) - %s" % (psuStatus[0], psuExpected[0], psuType[0]) + details += "\\nPSU2: %s (Expected: %s) - %s" % (psuStatus[1], psuExpected[1], psuType[1]) + details += "\\nSystem Voltage Status: %s" % systemVoltStatus + details += "\\nController 1 Status: %s" % ctrlStatus[0] + details += "\\nController 1 Voltage Status: %s" % ctrlVoltStatus[0] + details += "\\nController 2 Status: %s" % ctrlStatus[1] + details += "\\nController 2 Voltage Status: %s" % ctrlVoltStatus[1] + + if systemVoltStatus != "OK": + message += " System voltage is %s." % systemVoltStatus + if systemVoltStatus == "degraded": + message += " (!)" + if status < 1: + status = 1 + elif systemVoltStatus == "faulty": + message += " (!!)" + if status < 2: + status = 2 + + for i in range(0, 2): + if psuExpected[i] == "Yes" and psuStatus[i] != "OK": + message += " PSU%i is %s" % ((i+1), psuStatus[i]) + if psuStatus[i] in [ "degraded", "N/A" ]: + if status < 1: + status = 1 + else: + if status < 2: + status = 2 + + # if a controller is in Standby, the corresponding PSU will be "degraded" + if ctrlVoltStatus[i] not in [ "OK", "N/A" ] and not ( ctrlVoltStatus[i] == "degraded" and ctrlStatus[i] == "Standby" ): + message += " Ctrl%i voltage is %s." % ((i+1), ctrlVoltStatus[i]) + if ctrlVoltStatus[i] in [ "degraded", "not present" ]: + message += " (!)" + if status < 1: + status = 1 + else: + message += " (!!)" + if status < 2: + status = 2 + + if status == 0: + message += " All ok." + + message += details + + return status, message + +check_info["selenio_mcp_power"] = { + "check_function" : check_selenio_mcp_power, + "inventory_function" : inventory_selenio_mcp_power, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.290.9.3.3.21", ["1.1", "25.1"], + [ OID_END, # "1.1.1.1.0" (MCP3) or "25.1.1.1.0" (MCP1) + 385, # 0 systemVoltStatus (E46enum) + 390, # 1 primaryPSUStatus (E18enum) + 391, # 2 secondaryPSUStatus + 473, # 3 PSU1 expected (E12enum) + 474, # 4 PSU2 expected + 1173, # 5 Ctrl1VoltageStatus (E18enum) + 1186, # 6 Ctrl2VoltageStatus + 1375, # 7 PSU1Type (E13enum) + 1376, # 8 PSU2Type (E13enum) + 1404, # 9 activePSU (E71enum) + 393, # 10 Ctrl1Status (E66enum) + 228, # 11 Ctrl2Status + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.290.9.3.3.21"), + "has_perfdata" : False +} diff --git a/src/selenio_mcp/checks/selenio_mcp_temp b/src/selenio_mcp/checks/selenio_mcp_temp new file mode 100644 index 0000000..4abe530 --- /dev/null +++ b/src/selenio_mcp/checks/selenio_mcp_temp @@ -0,0 +1,97 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def inventory_selenio_mcp_temp(info): + inventory = [] + if len(info[0]) > 0 and info[0][1] > 0: + inventory.append( ("Temperatures", None) ) + return inventory + +def check_selenio_mcp_temp(item, _no_params, info): + E18enum = [ "degraded", "faulty", "not present", "OK", "N/A" ] + E65enum = [ "N/A", "OK", "hot", "overheated" ] + if len(info[0]) < 3: + return 3, "%s not found in SNMP data." % item + + # remove OID part from array + info[0].pop(0) + + status = 0 + ambTemp = info[0][0] + message = u"Ambient Temperature is %s℃." % (ambTemp) + details = "" + + psuOk = True + for i in range(0, 2): + msg = "PSU %i is %s." % ((i+1), E18enum[int(info[0][1+i])]) + details += "\\n" + msg + if int(info[0][1+i]) not in [2, 3, 4]: + message += " " + msg + status = 2 + psuOk = False + if psuOk: + message += " PSUs: OK." + + slotOk = True + for i in range(0, 14): + msg = "Slot %i is %s." % ((i+1), E65enum[int(info[0][3+i])]) + details += "\\n" + msg + if int(info[0][3+i]) not in [0, 1]: + message += " " + msg + status = 2 + slotOk = False + if slotOk: + message += " Slots: OK." + + ctrlOk = True + for i in range(0, 2): + msg = "Ctrl %i is %s." % ((i+1), E65enum[int(info[0][17+i])]) + details += "\\n" + msg + if int(info[0][17+i]) not in [0, 1]: + message += " " + msg + status = 2 + ctrlOk = False + if ctrlOk: + message += " Ctrls: OK." + + message += details + + perfdata = [ ("Ambient_Temp", int(ambTemp), None, None, 0, 50) ] + return status, message, perfdata + +check_info["selenio_mcp_temp"] = { + "check_function" : check_selenio_mcp_temp, + "inventory_function" : inventory_selenio_mcp_temp, + "service_description" : "%s", + "snmp_info" : (".1.3.6.1.4.1.290.9.3.3.21", ["1.1", "25.1"], + [ OID_END, # "1.1.1.1.0" (MCP3) or "25.1.1.1.0" (MCP1) + 377, # 0 ambientTemperature (int/degC) + 378, # 1 primaryPSUtempOK (E18enum) + 379, # 2 secondaryPSUtempOK (E18enum) + 567, # 3 slot1tempOK (E65enum) + 593, # 4 slot2tempOK + 619, # 5 slot3tempOK + 644, # 6 slot4tempOK + 670, # 7 slot5tempOK + 696, # 8 slot6tempOK + 722, # 9 slot7tempOK + 748, # 10 slot8tempOK + 774, # 11 slot9tempOK + 800, # 12 slot10tempOK + 826, # 13 slot11tempOK + 852, # 14 slot12tempOK + 878, # 15 slot13tempOK + 904, # 16 slot14tempOK + 1208, # 17 primaryCtrlTempOK (E65enum) + 1185, # 18 secondaryCtrlTempOK (E65enum) + ]), + "snmp_scan_function" : lambda oid: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.290.9.3.3.21"), + "has_perfdata" : True +} diff --git a/src/selenio_mcp/web/plugins/perfometer/selenio_mcp_temp.py b/src/selenio_mcp/web/plugins/perfometer/selenio_mcp_temp.py new file mode 100644 index 0000000..f593312 --- /dev/null +++ b/src/selenio_mcp/web/plugins/perfometer/selenio_mcp_temp.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +# -*- coding: utf-8; py-indent-offset: 4 -*- +# _______ __ _ ____ __ +# | | \ | |___ \ / / +# | | \| | __) | / /-,_ +# | | |\ |/ __/ /__ _| +# |_______|_| \__|_____| |_| +# +# @author Markus Birth + +def perfometer_selenio_mcp_temp(row, check_command, perfdata): + if len(perfdata) < 1: + return "", "" + + tcur = int(perfdata[0][1]) + tmax = int(perfdata[0][6]) + + return "%i℃" % tcur, perfometer_linear(tcur*100/tmax, "#f82") + +perfometers["check_mk-selenio_mcp_temp"] = perfometer_selenio_mcp_temp