#!/usr/bin/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.
  --debug                           Debug output
  -u USER                           Username
  -p PASSWORD                       Password
  -l LEVEL                          Privilege level
                                    Possible are 'user', 'operator', 'admin'

  -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 DRIVER-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" % o, "%s" % a]
        elif o in ['--driver-type']:
            additional_opts += ["%s=%s" % (o, a)]
        elif o in ['-k']:
            additional_opts += ["%s" % o, "%s" % 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:])
