#!/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.

# Example output:
# <<<hpux_tunables:sep(58)>>>
# Tunable:        dbc_max_pct
# Usage:          0
# Setting:        1
# Percentage:     0.0
#
# Tunable:        maxdsiz
# Usage:          176676864
# Setting:        1073741824
# Percentage:     16.5

# Example of parsed:
#
# {'dbc_max_pct' : (0, 1),
#  'maxdsiz'     : (176676864, 1073741824),
# }

#.
#   .--general functions---------------------------------------------------.
#   |                                                  _                   |
#   |                   __ _  ___ _ __   ___ _ __ __ _| |                  |
#   |                  / _` |/ _ \ '_ \ / _ \ '__/ _` | |                  |
#   |                 | (_| |  __/ | | |  __/ | | (_| | |                  |
#   |                  \__, |\___|_| |_|\___|_|  \__,_|_|                  |
#   |                  |___/                                               |
#   |              __                  _   _                               |
#   |             / _|_   _ _ __   ___| |_(_) ___  _ __  ___               |
#   |            | |_| | | | '_ \ / __| __| |/ _ \| '_ \/ __|              |
#   |            |  _| |_| | | | | (__| |_| | (_) | | | \__ \              |
#   |            |_|  \__,_|_| |_|\___|\__|_|\___/|_| |_|___/              |
#   |                                                                      |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

# For legacy reasons we need to keep the old format:
hpux_tunables_nproc_default_levels = (90.0, 96.0)
hpux_tunables_nkthread_default_levels = (80.0, 85.0)

def parse_hpux_tunables(info):
    parsed = {}
    for line in info:
        if "Tunable" in line[0] or "Parameter" in line[0]:
            key       = line[1].strip()
        elif "Usage"   in line[0]:
            usage = int(line[1])
        elif "Setting" in line[0]:
            threshold = int(line[1])

            parsed[key] = (usage, threshold)

    return parsed


def inventory_hpux_tunables(info, tunable):
    if tunable in parse_hpux_tunables(info):
        return [ (None, {}) ]

def check_hpux_tunables(info, params, tunable, descr):
    # Since the original author forgot to implement a
    # main check (without dot) we cannot declare parse
    # function in check_info...
    parsed = parse_hpux_tunables(info)

    if tunable in parsed:
        usage, threshold = parsed[tunable]
        perc = float(usage)/float(threshold)*100

        if isinstance(params, tuple):
            params = {
                'levels' : params,
            }
        warn, crit = params["levels"]
        warn_perf = float(warn * threshold / 100)
        crit_perf = float(crit * threshold / 100)

        yield 0, "%.2f%% used (%d/%d %s)" % (perc, usage, threshold, descr), \
            [ (descr, usage, warn_perf, crit_perf, 0, threshold) ]

        if perc > crit:
            state = 2
        elif perc > warn:
            state = 1
        else:
            state = 0

        if state > 0:
            yield state, "(warn/crit at %s/%s)" % (warn, crit)

    else:
       yield 3, "tunable not found in agent output"


#.
#   .--nkthread------------------------------------------------------------.
#   |                    _    _   _                        _               |
#   |              _ __ | | _| |_| |__  _ __ ___  __ _  __| |              |
#   |             | '_ \| |/ / __| '_ \| '__/ _ \/ _` |/ _` |              |
#   |             | | | |   <| |_| | | | | |  __/ (_| | (_| |              |
#   |             |_| |_|_|\_\\__|_| |_|_|  \___|\__,_|\__,_|              |
#   |                                                                      |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_nkthread_default_levels"] = {
            'levels' : (80.0, 85.0),
}

def inventory_hpux_tunables_nkthread(info):
    tunable = "nkthread"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_nkthread(_no_item, params, info):
    tunable = "nkthread"
    descr = "threads"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.nkthread"] = {
    "inventory_function"        : inventory_hpux_tunables_nkthread,
    "check_function"            : check_hpux_tunables_nkthread,
    "service_description"       : "Number of threads",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_nkthread_default_levels",
}

#.
#   .--nproc---------------------------------------------------------------.
#   |                                                                      |
#   |                     _ __  _ __  _ __ ___   ___                       |
#   |                    | '_ \| '_ \| '__/ _ \ / __|                      |
#   |                    | | | | |_) | | | (_) | (__                       |
#   |                    |_| |_| .__/|_|  \___/ \___|                      |
#   |                          |_|                                         |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_nproc_default_levels"] = {
            'levels'    : (90.0, 96.0)
}

def inventory_hpux_tunables_nproc(info):
    tunable = "nproc"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_nproc(_no_item, params, info):
    tunable = "nproc"
    descr = "processes"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.nproc"] = {
    "inventory_function"        : inventory_hpux_tunables_nproc,
    "check_function"            : check_hpux_tunables_nproc,
    "service_description"       : "Number of processes",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_nproc_default_levels",
}

#.
#   .--maxfiles_lim--------------------------------------------------------.
#   |                            __ _ _               _ _                  |
#   |      _ __ ___   __ ___  __/ _(_) | ___  ___    | (_)_ __ ___         |
#   |     | '_ ` _ \ / _` \ \/ / |_| | |/ _ \/ __|   | | | '_ ` _ \        |
#   |     | | | | | | (_| |>  <|  _| | |  __/\__ \   | | | | | | | |       |
#   |     |_| |_| |_|\__,_/_/\_\_| |_|_|\___||___/___|_|_|_| |_| |_|       |
#   |                                           |_____|                    |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_maxfiles_lim_default_levels"] = {
            'levels'    : (85.0, 90.0)
}

def inventory_hpux_tunables_maxfiles_lim(info):
    tunable = "maxfiles_lim"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_maxfiles_lim(_no_item, params, info):
    tunable = "maxfiles_lim"
    descr = "files"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.maxfiles_lim"] = {
    "inventory_function"        : inventory_hpux_tunables_maxfiles_lim,
    "check_function"            : check_hpux_tunables_maxfiles_lim,
    "service_description"       : "Number of open files",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_maxfiles_lim_default_levels",
}

#.
#   .--semmni--------------------------------------------------------------.
#   |                                                   _                  |
#   |                ___  ___ _ __ ___  _ __ ___  _ __ (_)                 |
#   |               / __|/ _ \ '_ ` _ \| '_ ` _ \| '_ \| |                 |
#   |               \__ \  __/ | | | | | | | | | | | | | |                 |
#   |               |___/\___|_| |_| |_|_| |_| |_|_| |_|_|                 |
#   |                                                                      |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_semmni_default_levels"] = {
            'levels'    : (85.0, 90.0)
}

def inventory_hpux_tunables_semmni(info):
    tunable = "semmni"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_semmni(_no_item, params, info):
    tunable = "semmni"
    descr = "semaphore_ids"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.semmni"] = {
    "inventory_function"        : inventory_hpux_tunables_semmni,
    "check_function"            : check_hpux_tunables_semmni,
    "service_description"       : "Number of IPC Semaphore IDs",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_semmni_default_levels",
}

#.
#   .--shmseg--------------------------------------------------------------.
#   |                     _                                                |
#   |                 ___| |__  _ __ ___  ___  ___  __ _                   |
#   |                / __| '_ \| '_ ` _ \/ __|/ _ \/ _` |                  |
#   |                \__ \ | | | | | | | \__ \  __/ (_| |                  |
#   |                |___/_| |_|_| |_| |_|___/\___|\__, |                  |
#   |                                              |___/                   |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_shmseg_default_levels"] = {
            'levels'    : (85.0, 90.0)
}

def inventory_hpux_tunables_shmseg(info):
    tunable = "shmseg"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_shmseg(_no_item, params, info):
    tunable = "shmseg"
    descr = "segments"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.shmseg"] = {
    "inventory_function"        : inventory_hpux_tunables_shmseg,
    "check_function"            : check_hpux_tunables_shmseg,
    "service_description"       : "Number of shared memory segments",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_shmseg_default_levels",
}

#.
#   .--semmns--------------------------------------------------------------.
#   |                                                                      |
#   |               ___  ___ _ __ ___  _ __ ___  _ __  ___                 |
#   |              / __|/ _ \ '_ ` _ \| '_ ` _ \| '_ \/ __|                |
#   |              \__ \  __/ | | | | | | | | | | | | \__ \                |
#   |              |___/\___|_| |_| |_|_| |_| |_|_| |_|___/                |
#   |                                                                      |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings["hpux_tunables_semmns_default_levels"] = {
            'levels'    : (85.0, 90.0)
}

def inventory_hpux_tunables_semmns(info):
    tunable = "semmns"
    return inventory_hpux_tunables(info, tunable)

def check_hpux_tunables_semmns(_no_item, params, info):
    tunable = "semmns"
    descr = "entries"
    return check_hpux_tunables(info, params, tunable, descr)

check_info["hpux_tunables.semmns"] = {
    "inventory_function"        : inventory_hpux_tunables_semmns,
    "check_function"            : check_hpux_tunables_semmns,
    "service_description"       : "Number of IPC Semaphores",
    "has_perfdata"              : True,
    "default_levels_variable"   : "hpux_tunables_semmns_default_levels",
}


