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


def parse_f5_bigip_snat(info):
    snats = {}
    for line in info:
        name = line[0]
        snats.setdefault(name, {})
        snats[name].setdefault("if_in_pkts", []).append(int(line[1]))
        snats[name].setdefault("if_out_pkts", []).append(int(line[2]))
        snats[name].setdefault("if_in_octets", []).append(int(line[3]))
        snats[name].setdefault("if_out_octets", []).append(int(line[4]))
        snats[name].setdefault("connections_rate", []).append(int(line[5]))
        snats[name].setdefault("connections", []).append(int(line[6]))
    return snats


def inventory_f5_bigip_snat(parsed):
    for name in parsed.iterkeys():
        yield name, {}


def check_f5_bigip_snat(item, params, parsed):
    if item in parsed:
        snat = parsed[item]

        summed_values = {}
        now = time.time()
        # Calculate counters
        for what in [
                "if_in_pkts",
                "if_out_pkts",
                "if_in_octets",
                "if_out_octets",
                "connections_rate",
        ]:
            summed_values.setdefault(what, 0)
            for idx, entry in enumerate(snat[what]):
                rate = get_rate("%s.%s" % (what, idx), now, entry)
                summed_values[what] += rate

        # Calculate sum value
        for what, function in [("connections", sum)]:
            summed_values[what] = function(snat[what])

        perfdata = summed_values.items()

        # Current number of connections
        yield 0, "Client connections: %d" % summed_values["connections"], perfdata

        # New connections per time
        yield 0, "Rate: %.2f/sec" % summed_values["connections_rate"]

        # Check configured limits
        map_paramvar_to_text = {
            "if_in_octets": "Incoming Bytes",
            "if_out_octets": "Outgoing Bytes",
            "if_total_octets": "Total Bytes",
            "if_in_pkts": "Incoming Packets",
            "if_out_pkts": "Outgoing Packets",
            "if_total_pkts": "Total Packets",
        }
        summed_values[
            "if_total_octets"] = summed_values["if_in_octets"] + summed_values["if_out_octets"]
        summed_values["if_total_pkts"] = summed_values["if_in_pkts"] + summed_values["if_out_pkts"]
        for param_var, levels in params.items():
            if param_var.endswith("_lower") and isinstance(levels, tuple):
                levels = (None, None) + levels
            value = summed_values[param_var.rstrip("_lower")]
            state, infotext, _extra_perfdata = check_levels(
                value,
                param_var,
                levels,
                human_readable_func=lambda x, p=param_var: get_bytes_human_readable(x, base=1000.0)
                if "octets" in p else str(x),
                infoname=map_paramvar_to_text[param_var.rstrip("_lower")])
            if state:
                yield state, infotext


check_info["f5_bigip_snat"] = {
    "parse_function"          : parse_f5_bigip_snat,
    "check_function"          : check_f5_bigip_snat,
    "inventory_function"      : inventory_f5_bigip_snat,
    "group"                   : "f5_bigip_snat",
    "service_description"     : "Source NAT %s",
    "has_perfdata"            : True,
    "snmp_info"               : (".1.3.6.1.4.1.3375.2.2.9.2.3.1", [
                                     "1", #ltmSnatStatName
                                     "2", #ltmSnatStatClientPktsIn
                                     "3", #ltmSnatStatClientBytesIn
                                     "4", #ltmSnatStatClientPktsOut
                                     "5", #ltmSnatStatClientBytesOut
                                     "7", #ltmSnatStatClientTotConns
                                     "8", #ltmSnatStatClientCurConns
                               ]),
    "snmp_scan_function"      : lambda oid: ".1.3.6.1.4.1.3375.2" in oid(".1.3.6.1.2.1.1.2.0") \
                                      and "big-ip" in oid(".1.3.6.1.4.1.3375.2.1.4.1.0").lower(),
}
