#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2013             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-
# ails.  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.

# Author: Lars Michelsen <lm@mathias-kettner.de>

# Example outputs from agent:
#
# <<<win_dhcp_pools>>>
#
# MIB-Anzahl:
#     Entdeckungen = 0.
#     Angebote = 0.
#     Anforderungen = 0.
#     Acks = 0.
#     Naks = 0.
#     Abweisungen = 0.
#     Freigaben = 0.
#     ServerStartTime = Dienstag, 29. Juni 2010 19:08:55
#     Bereiche = 1.
#     Subnetz = 192.168.123.0.
#         Anzahl der verwendeten Adressen = 0.
#         Anzahl der freien Adressen = 239.
#         Anzahl der anstehenden Angebote = 0.
#
# MIBCounts:
#         Discovers = 0.
#         Offers = 0.
#         Requests = 0.
#         Acks = 1.
#         Naks = 0.
#         Declines = 0.
#         Releases = 0.
#         ServerStartTime = Sunday, May 25, 2008 12:38:06 PM
#         Scopes = 1.
#         Subnet = 172.16.11.0.
#                 No. of Addresses in use = 1.
#                 No. of free Addresses = 23.
#                 No. of pending offers = 0.

win_dhcp_pools_default_levels = (10, 5)
win_dhcp_pools_inventorize_empty = False

win_dhcp_pools_stats_translate = {
    'Entdeckungen': 'Discovers',
    'Angebote': 'Offers',
    'Anforderungen': 'Requests',
    'Acks': 'Acks',
    'Naks': 'Nacks',
    'Abweisungen': 'Declines',
    'Freigaben': 'Releases',
    'Subnetz': 'Subnet',
    'Bereiche': 'Scopes',
    'Anzahl der verwendeten Adressen': 'No. of Addresses in use',
    'Anzahl der freien Adressen': 'No. of free Addresses',
    'Anzahl der anstehenden Angebote': 'No. of pending offers',
}

def parse_win_dhcp_pools(info):
    return [ ' '.join(line).rstrip('.').split(' = ') for line in info ]

def inventory_win_dhcp_pools(info):
    inventory = []
    in_block = False
    last_pool = ""
    pool_stats = []
    for line in parse_win_dhcp_pools(info):
        if win_dhcp_pools_stats_translate.get(line[0], line[0]) == 'Subnet':
            in_block = True
            pool_stats = []
            last_pool = line[1]
            continue
        if in_block:
            pool_stats.append(saveint(line[1]))
        if len(pool_stats) == 3:
            in_block = False
            used, free, pending = pool_stats
            size = used + free + pending
            if size > 0 or win_dhcp_pools_inventorize_empty:
                inventory.append((last_pool, 'win_dhcp_pools_default_levels'))
    return inventory

def check_win_dhcp_pools(item, params, info):
    in_block = False
    pool_stats = []
    status = 0
    for line in parse_win_dhcp_pools(info):
        if win_dhcp_pools_stats_translate.get(line[0], line[0]) == 'Subnet' and line[1] == item:
            in_block = True
            continue
        if in_block:
            pool_stats.append(saveint(line[1]))
        if len(pool_stats) == 3:
            break

    if len(pool_stats) == 3:
        used, free, pending = pool_stats
        size = used + free + pending

        # Catch unused pools
        if size == 0:
            return (3, "UNKNOWN - DHCP Pool contains no IP addresses / is deactivated")

        if free > 0:
            perc_free = 100 * size / free
        else:
            perc_free = 0

        if perc_free < params[1]:
            status = 2
        elif perc_free < params[0]:
            status = 1

        perfdata = [ ('free', free, params[0], params[1], 0, size),
                     ('used', used, None, None, 0, size),
                     ('pending', pending, None, None, 0, size) ]

        return (status, '%s - Addresses Free: %d, Used: %d, Pending: %d' %
                              (nagios_state_names[status], free, used, pending), perfdata)
    else:
        return (3, 'UNKNOWN - Pool information not found')

def inventory_win_dhcp_pools_stats(info):
    return [ (None, None) for line in info if line[0] != '' ]

def check_win_dhcp_pools_stats(item, params, info):
    output = ''
    perfdata = []
    this_time = int(time.time())
    timedif = 0

    for line in parse_win_dhcp_pools(info):
        if len(line) > 0:
            key = win_dhcp_pools_stats_translate.get(line[0], line[0])
            if key in [ 'Discovers', 'Offers', 'Requests', 'Acks',
                        'Nacks', 'Declines', 'Releases', 'Scopes' ]:
                value = saveint(line[1])
                try:
                    timedif, per_sec = get_counter("win_dhcp_stats.%s" % key, this_time, value)
                except MKCounterWrapped:
                    per_sec = 0
                    pass
                output += '%s: %.0f/s, ' % (key, per_sec)
                perfdata.append((key, per_sec))

    if output == '':
        return (3, "UNKNOWN - Information not available")
    else:
        if timedif != 0:
            output = 'In last %d secs: %s' % (timedif, output)
        return (0, "OK - %s" % (output.rstrip(', ')), perfdata)

check_info['win_dhcp_pools'] = (check_win_dhcp_pools, "DHCP Pool %s",  1, inventory_win_dhcp_pools)
check_info['win_dhcp_pools.stats'] = (check_win_dhcp_pools_stats, "DHCP Stats",  1, inventory_win_dhcp_pools_stats)
checkgroup_of['win_dhcp_pools'] = "win_dhcp_pools"
