#!/usr/bin/env python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk 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.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.


import os
import errno
import sys
import getopt
import subprocess


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

OPTIONS:
  --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.
""" )

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 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)

    os.environ["PATH"] = "/usr/local/sbin:/usr/sbin:/sbin:" + os.environ["PATH"]

    ipmi_cmd = [ "ipmi-sensors",
                 "-h", hostname, "-u", username,
                 "-p", password, "-l", privilege_lvl ] + \
                 additional_opts
    ipmi_cmd_str = subprocess.list2cmdline(ipmi_cmd)

    if opt_debug:
        sys.stderr.write("Executing: '%s'\n" % ipmi_cmd_str)

    try:
        try:
            p = subprocess.Popen(ipmi_cmd, shell=False, close_fds=True,
                                 stdin=open(os.devnull),
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except OSError, e:
            if e.errno == errno.ENOENT: # No such file or directory
                raise Exception("Could not find 'ipmi-sensors' command (PATH: %s)" %
                                                            os.environ.get("PATH"))
            else:
                raise

        stdout, stderr = p.communicate()
    except Exception, e:
        sys.stderr.write("ERROR: %s\n" % (e))
        sys.exit(1)

    if stderr:
        sys.stderr.write("ERROR: '%s'.\n" % stderr)
        sys.exit(1)

    # output
    # ID   | Name            | Type              | Reading    | Units | Event
    # 4    | CPU Temp        | Temperature       | 28.00      | C     | 'OK'
    # 71   | System Temp     | Temperature       | 28.00      | C     | 'OK'
    # 607  | P1-DIMMC2 TEMP  | Temperature       | N/A        | C     | N/A
    sys.stdout.write( "<<<ipmi_sensors:sep(124)>>>\n" )
    for line in stdout.splitlines():
        if line.startswith("ID"):
            continue

        sys.stdout.write( "%s\n" % line )

    sys.exit(0)


if __name__ == "__main__":
    agent_ipmi_sensors_main(sys.argv[1:])
