Skip to content
Permalink
Browse files

4108 ipmi_sensors: new options available

The special agent ipmi_sensors has now further options:
<ul>
<li>Specify IPMI driver.</li>
<li>Do not output information about cache creation/deletion.</li>
<li>Automatically recreate the sensor data repository (SDR) cache.</li>
<li>Attempt to interpret OEM data.</li>
<li>Output sensor state in output.</li>
<li>Ignore not-available (i.e. N/A) sensors in output.</li>
<li>Specify the driver type to use instead of doing an auto selection.</li>
<li>Output sensor thresholds in output.</li>
<li>Specify the K_g BMC key to use when authenticating with the remote host for IPMI 2.0.</li>
</ul>
  • Loading branch information
si-23 committed Nov 30, 2016
1 parent 3c24b97 commit a4dafd898231d9d762e0fa0f6399742084468570
Showing with 226 additions and 104 deletions.
  1. +20 −0 .werks/4108
  2. +1 −0 ChangeLog
  3. +123 −84 agents/special/agent_ipmi_sensors
  4. +24 −6 checks/agent_ipmi_sensors
  5. +33 −12 checks/ipmi_sensors
  6. +25 −2 web/plugins/wato/datasource_programs.py
@@ -0,0 +1,20 @@
Title: ipmi_sensors: new options available
Level: 1
Component: checks
Compatible: compat
Version: 1.4.0i3
Date: 1480517272
Class: feature

The special agent ipmi_sensors has now further options:
<ul>
<li>Specify IPMI driver.</li>
<li>Do not output information about cache creation/deletion.</li>
<li>Automatically recreate the sensor data repository (SDR) cache.</li>
<li>Attempt to interpret OEM data.</li>
<li>Output sensor state in output.</li>
<li>Ignore not-available (i.e. N/A) sensors in output.</li>
<li>Specify the driver type to use instead of doing an auto selection.</li>
<li>Output sensor thresholds in output.</li>
<li>Specify the K_g BMC key to use when authenticating with the remote host for IPMI 2.0.</li>
</ul>
@@ -16,6 +16,7 @@
* 3995 skype check: updated perfvariable and metric names, making their purpose more clear...
NOTE: Please refer to the migration notes!
* 3996 agent_netapp clustermode: now uses a fallback query to determine the node name if the intial query fails
* 4108 ipmi_sensors: new options available...
* 3987 FIX: Check_MK Agent Access: Windows agent reported incorrect only from value
* 3952 FIX: diskstat: fixed bug if multipath devices having an alias...
* 3939 FIX: f5_bigip_conns: readded performance data and graphs...
@@ -25,89 +25,40 @@
# Boston, MA 02110-1301 USA.


import os, sys, getopt, subprocess
import os
import sys
import getopt
import subprocess


def usage():
sys.stderr.write("""Check_MK IPMI Sensors
def agent_ipmi_sensors_usage():
sys.stderr.write( """Check_MK IPMI Sensors
USAGE: agent_ipmi_sensors [OPTIONS] HOST
agent_ipmi_sensors --help
ARGUMENTS:
HOST Host name or IP address
HOST Host name or IP address
OPTIONS:
--help Show this help message and exit
-u Username
-p Password
-l Privilege level
Possible are 'user', 'operator', 'admin'
--debug Debug output
""")


short_options = 'u:p:l:'
long_options = [ 'help', 'debug' ]


opt_debug = False
hostname = None
username = None
password = None
privilege_lvl = None


try:
opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
except getopt.GetoptError, err:
sys.stderr.write("%s\n" % err)
sys.exit(1)


for o, a in opts:
if o in [ '--help' ]:
usage()
sys.exit(0)
elif o in [ '--debug' ]:
opt_debug = True
elif o in [ '-u' ]:
username = a
elif o in [ '-p' ]:
password = a
elif o in [ '-l' ]:
privilege_lvl = a


if len(args) == 1:
hostname = args[0]
elif not args:
sys.stderr.write("ERROR: No host given.\n")
sys.exit(1)
else:
sys.stderr.write("ERROR: Please specify exactly one host.\n")
sys.exit(1)


if not (username and password and privilege_lvl):
sys.stderr.write("ERROR: Credentials are missing.\n")
sys.exit(1)


for sub_path in [ "sbin", "bin", "local/sbin", "local/bin" ]:
base_cmd = "/usr/%s/ipmi-sensors" % sub_path
ipmi_cmd = [base_cmd, "-h", hostname, "-u", username, "-p", password, "-l", privilege_lvl ]
try:
if opt_debug:
sys.stdout.write("DEBUG: try executing '%s'\n" % base_cmd)
p = subprocess.Popen(ipmi_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sensor_data, err = p.communicate()
break
except Exception, e:
err = e
if opt_debug:
sys.stdout.write("ERROR: '%s': %s\n" % (base_cmd, e))
continue
--help Show this help message and exit.
-u USER Username
-p PASSWD Password
-l LVL Privilege level
Possible are 'user', 'operator', 'admin'
--debug Debug output
-D DRIVER Specify IPMI driver.
--quiet-cache Do not output information about cache creation/deletion.
--sdr-cache-recreate Automatically recreate the sensor data repository (SDR) cache.
--interpret-oem-data Attempt to interpret OEM data.
--output-sensor-state Output sensor state in output.
--ignore-not-available-sensors Ignore not-available (i.e. N/A) sensors in output.
--driver-type TYPE Specify the driver type to use instead of doing an auto selection.
--output-sensor-thresholds Output sensor thresholds in output.
-k KEY Specify the K_g BMC key to use when authenticating
with the remote host for IPMI 2.0.
""" )


# output
@@ -117,18 +68,106 @@ for sub_path in [ "sbin", "bin", "local/sbin", "local/bin" ]:
# 607 | P1-DIMMC2 TEMP | Temperature | N/A | C | N/A


def parse_ipmi_sensor_data(ipmi_sensor_data):
def agent_ipmi_sensors_parse_data( ipmi_sensor_data ):
for line in ipmi_sensor_data:
if line.startswith("ID"):
if line.startswith( "ID" ):
continue
else:
sys.stdout.write("%s\n" % line)
sys.stdout.write( "%s\n" % line )


def agent_ipmi_sensors_main( cmdline_args ):
short_options = 'u:p:l:' + 'D:k:'
long_options = [ 'help', 'debug' ] + \
[ 'quiet-cache', 'sdr-cache-recreate', 'interpret-oem-data',
'output-sensor-state', 'ignore-not-available-sensors',
'driver-type=', 'output-sensor-thresholds' ]

opt_debug = False
hostname = None
username = None
password = None
privilege_lvl = None

try:
opts, args = getopt.getopt( cmdline_args, short_options, long_options )
except getopt.GetoptError, err:
sys.stderr.write( "%s\n" % err )
sys.exit(1)

additional_opts = []
for o, a in opts:
if o in [ '--help' ]:
agent_ipmi_sensors_usage()
sys.exit(0)
elif o in [ '--debug' ]:
opt_debug = True
elif o in [ '-u' ]:
username = a
elif o in [ '-p' ]:
password = a
elif o in [ '-l' ]:
privilege_lvl = a
elif o in [ '-D' ]:
additional_opts += [ "%s %s" % (o, a) ]
elif o in [ '--driver-type' ]:
additional_opts += [ "%s=%s" % (o, a) ]
elif o in [ '-k' ]:
additional_opts += [ "%s %s" % (o, a) ]
elif o in [ '--quiet-cache' ]:
additional_opts.append( o )
elif o in [ '--sdr-cache-recreate' ]:
additional_opts.append( o )
elif o in [ '--interpret-oem-data' ]:
additional_opts.append( o )
elif o in [ '--output-sensor-state' ]:
additional_opts.append( o )
elif o in [ '--ignore-not-available-sensors' ]:
additional_opts.append( o )
elif o in [ '--output-sensor-thresholds' ]:
additional_opts.append( o )

if opt_debug:
sys.stderr.write( "DEBUG: opts are '%s'.\n" % opts + \
"DEBUG: args are '%s'.\n" % args )

if len(args) == 1:
hostname = args[0]
else:
sys.stderr.write( "ERROR: Please specify exactly one host.\n" )
sys.exit(1)

if not (username and password and privilege_lvl):
sys.stderr.write( "ERROR: Credentials are missing.\n" )
sys.exit(1)

for sub_path in [ "sbin", "bin", "local/sbin", "local/bin" ]:
ipmi_cmd = [ "/usr/%s/ipmi-sensors" % sub_path,
"-h", hostname, "-u", username,
"-p", password, "-l", privilege_lvl ] + \
additional_opts

if opt_debug:
sys.stderr.write( "DEBUG: try executing '%s'.\n" % " ".join( ipmi_cmd ) )

try:
p = subprocess.Popen( ipmi_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
sensor_data, err = p.communicate()
break
except Exception, e:
err = e
if opt_debug:
sys.stderr.write( "ERROR: '%s': %s.\n" % (ipmi_cmd_str, e) )
continue

if err:
sys.stderr.write( "ERROR: '%s'.\n" % err )
sys.exit(1)
else:
sys.stdout.write( "<<<ipmi_sensors:sep(124)>>>\n" )
agent_ipmi_sensors_parse_data( sensor_data.splitlines() )
sys.exit(0)


if err:
sys.stderr.write("ERROR: '%s'\n" % err[:-1])
sys.exit(1)
else:
sys.stdout.write("<<<ipmi_sensors:sep(124)>>>\n")
parse_ipmi_sensor_data(sensor_data.splitlines())
sys.exit(0)
if __name__ == "__main__":
agent_ipmi_sensors_main( sys.argv[1:] )
@@ -24,14 +24,32 @@
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.


def agent_ipmi_sensors_arguments(params, hostname, ipaddress):
args = ''
args = []

args += [ "-u", quote_shell_string(params["username"]) ]
args += [ "-p", quote_shell_string(params["password"]) ]
args += [ "-l", quote_shell_string(params["privilege_lvl"]) ]

for opt, what in [
("-D", "ipmi_driver"),
("-k", "BMC_key"),
("--driver-type", "driver_type"),
('--quiet-cache', "quiet_cache"),
("--sdr-cache-recreate", "sdr_cache_recreate"),
('--interpret-oem-data', "interpret_oem_data"),
('--output-sensor-state', "output_sensor_state"),
('--ignore-not-available-sensors', "output_sensor_thresholds"),
('--output-sensor-thresholds', "ignore_not_available_sensors"), ]:
this_param = params.get(what)
if this_param:
args.append( opt )
if not isinstance(this_param, bool):
args.append( quote_shell_string(this_param) )

args += " -u " + quote_shell_string(params["username"])
args += " -p " + quote_shell_string(params["password"])
args += " -l " + quote_shell_string(params["privilege_lvl"])
args.append( quote_shell_string(ipaddress) )
return " ".join( args )

args += " " + quote_shell_string(ipaddress)
return args

special_agent_info['ipmi_sensors'] = agent_ipmi_sensors_arguments
@@ -92,10 +92,30 @@
# 71 | System Temp | Temperature | 28.00 | C | 'OK'
# 607 | P1-DIMMC2 TEMP | Temperature | N/A | C | N/A

# unr: Upper Non-Recoverable
# ucr: Upper Critical
# unc: Upper Non-Critical
# lnc: Lower Non-Critical
# lcr: Lower Critical
# lnr: Lower Non-Recoverable
# <<<ipmi_sensors:sep(124)>>>
# ID | Name | Type | State | Reading | Units | Lower NR | Lower C | Lower NC | Upper NC | Upper C | Upper NR | Event
# 0 | UID Light | OEM Reserved | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | 'OK'
# 1 | Sys. Health LED | OEM Reserved | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | 'OK'
# 2 | Power Supply 1 | Power Supply | Nominal | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | 'Presence detected'
# 3 | Power Supply 2 | Power Supply | Nominal | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | 'Presence detected'
# 4 | Power Supplies | Power Supply | Nominal | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | 'Fully Redundant'


#.


def parse_freeipmi(info):
def add_valid_values(values):
for key, value, ty in values:
if value not in [ "NA", "N/A" ]:
parsed[sensorname][key] = ty(value)

parsed = {}
for line in info:
stripped_line = map(lambda x: x.strip(), line)
@@ -124,24 +144,25 @@ def parse_freeipmi(info):

if len(stripped_line) == 4:
current, levels = stripped_line[2].split("(")

cparts = current.split("_")
if cparts[0] not in [ "NA", "N/A" ]:
parsed[sensorname]["value"] = float(cparts[0])
if len(cparts) > 1:
parsed[sensorname]["unit"] = cparts[1]
unit = "NA"
if len(cparts) > 1:
unit = cparts[1]

lower, upper = levels[:-1].split("/")
for key, what in [ ("crit_low", lower), ( "crit_high", upper) ]:
if what not in [ "NA", "N/A" ]:
parsed[sensorname][key] = float(what)
add_valid_values([ ("value", cparts[0], float), ("unit", unit, str),
("crit_low", lower, float), ( "crit_high", upper, float) ] )

elif len(stripped_line) == 6:
sid, name, sensortype, reading_str, unit = stripped_line[:-1]
if reading_str not in [ "NA", "N/A" ]:
parsed[sensorname]["value"] = float(reading_str)
if unit not in [ "NA", "N/A" ]:
parsed[sensorname]["unit"] = unit
add_valid_values( [ ("value", reading_str, float), ("unit", unit, str) ] )

elif len(stripped_line) == 13:
sid, name, stype, sstate, reading_str, unit, lower_nr, lower_c, \
lower_nc, upper_nc, upper_c, upper_nr = stripped_line[:-1]
add_valid_values( [ ("value", reading_str, float), ("unit", unit, str),
("crit_low", lower_c, float), ("warn_low", lower_nc, float),
("warn_high", upper_nw, float), ("crit_high", upper_c, float) ] )

return parsed

0 comments on commit a4dafd8

Please sign in to comment.
You can’t perform that action at this time.