#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |          _           _           _       _   __   _______        |
# |       __| |_  ___ __| |__  _ __ | |__   / | /  \ |__ / _ \       |
# |      / _| ' \/ -_) _| / / | '  \| / /   | || () | |_ \_, /       |
# |      \__|_||_\___\__|_\_\_|_|_|_|_\_\   |_(_)__(_)___//_/        |
# |                                            check_mk 1.0.39       |
# |                                                                  |
# | Copyright Mathias Kettner 2009                mk@mathias-kettner |
# +------------------------------------------------------------------+
# 
# This file is part of check_mk 1.0.39.
# 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.


def check_df(mountpoint, params, df_lines):
    # df outputs seven columns:
    # DEVICE FS-TYPE SIZE(KB) USED(KB) AVAIL(KB) USED(%) MOUNTPOINT

    used_list = [ l for l in df_lines if l[6].replace('\\','/') == mountpoint ]

    if len(used_list) == 0:
	return (3, "UNKNOWN - %s missing or not a partition" % mountpoint )
    used = used_list[0] # might be listed twice. We take the first occurance

    if len(used) != 7 or used[5][-1] != '%':
	return (3, "UNKNOWN - Invalid ouput from agent (%s)" % (' '.join(used),))

    # Beware: the 6th column of df ("used perc") may includes 5% which are reserved
    # for the superuser, whereas the 4th colum ("used MB") does *not* include that.
    # Beware(2): the column used_mb does not account for the reserved space for
    # superusers. So we rather use the column 'avail' and subtract that from total
    # to compute the used space.
    
    size_mb   = int(used[2]) / 1024.0
    if size_mb == 0:
        return (1, "WARN - size of filesystem is 0 MB")
        
    avail_mb   = int(used[4]) / 1024.0
    used_mb = size_mb - avail_mb
    
    used_perc = 100.0 * (used_mb / size_mb)
    size_gb   = size_mb / 1024.0
    
    # Get warning and critical levels already with 'magic factor' applied
    warn_mb, crit_mb, levelstext = get_filesystem_levels(g_hostname, mountpoint, size_gb, params)

    # Take into account magic scaling factor (third optional argument
    # in check params). A factor of 1.0 changes nothing. Factor should
    # be > 0 and <= 1. A smaller factor raises levels for big file systems
    # bigger than 100 GB and lowers it for file systems smaller than 100 GB.
    # Please run df_magic_factor.py to understand how it works.

    perfdata = [(mountpoint, str(used_mb) + 'MB', warn_mb, crit_mb, 0, size_mb)]
    infotext = "%.1f%% used (%.1f of %.1f GB), %s" % \
                (used_perc, used_mb / 1024.0, size_gb, levelstext)

    if used_mb >= crit_mb:
	return (2, "CRIT - %s" % infotext, perfdata)
    elif used_mb >= warn_mb:
	return (1, "WARN - %s" % infotext, perfdata)
    else:
	return (0, "OK - %s" % infotext, perfdata)
	


def inventory_df(checkname, info):
    inventory = []
    for line in info:
        try:
            fs_type    = line[1]
            size_kb = int(line[2])
            if size_kb == 0 or line[5] == '-':
                continue # exclude filesystems without size
            mountpoint = line[6].replace('\\', '/') # Windows \ is replaced with /

            # exclude some filesystem types and some mountpoints
            if fs_type not in inventory_df_exclude_fs and mountpoint not in inventory_df_exclude_mountpoints:
                inventory.append((mountpoint, None, inventory_df_check_params))
        except ValueError,e:
            sys.stderr.write("Invalid plugin output '%s'\n" % (line,))
            pass # ignore e.g. entries for /proc, etc. if plugin sends any
            
    return inventory

check_info['df']        = (check_df, "fs_%s", 1, inventory_df)
precompile_params['df'] = precompile_filesystem_levels

