#!/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 from agent:
# <<<hyperv_vms>>>
# DMZ-DC1                         Running 4.21:44:58          Operating normally
# DMZ-DC2                         Running 4.21:44:47          Operating normally

# Another example, here with a snapshow with spaces in the name:
# <<<hyperv_vms>>>
# windows-hyperv2-z4058044                              Running 21:33:08   Operating normally
# windows-hyperv2-z4058044_snap (23.05.2014 - 09:29:29) Running 18:20:34   Operating normally
# windows-hyperv2-z4065002                              Running 11:04:50   Operating normally
# windows-hyperv2-z4065084                              Running 1.10:42:33 Operating normally
# windows-hyperv2-z4133235                              Running 1.03:52:18 Operating normally

# A broken version of the agent outputted this:
# <<<hyperv_vms>>>
# z4058044                        Running 21:19:14            Operating normally
# z4058044_snap (2...             Running 18:06:39            Operating normally
# z4065002                        Running 10:50:55            Operating normally
# z4065084                        Running 1.10:28:39          Operating normally
# z4133235                        Running 1.03:38:23          Operating normally

# A Version with a plugin that uses tab as seperator and quotes the strings:
# <<<hyperv_vms:sep(9)>>>
# "Name"  "State" "Uptime"        "Status"
# "z4058013"      "Running"       "06:05:16"      "Operating normally"
# "z4058020"      "Running"       "01:01:57"      "Operating normally"
# "z4058021"      "Running"       "01:02:11"      "Operating normally"
# "z4065012"      "Running"       "01:02:04"      "Operating normally"
# "z4065013"      "Running"       "07:47:27"      "Operating normally"
# "z4065020"      "Running"       "01:02:09"      "Operating normally"
# "z4065025"      "Running"       "01:02:05"      "Operating normally"
# "z4133199"      "Running"       "00:57:23"      "Operating normally"

# result:
# {
#   "windows-hyperv2-z4058044_snap (23.05.2014 - 09:29:29)" : {
#        "vm_state" : "Running",
#        "uptime" : "1.10:42:33",
#        "state_msg" : "Operating normally",
#    }
# }

def parse_hyperv_vms(info):
    parsed = {}
    for line in info:
        # Remove quotes
        line = [ x.strip('"') for x in line ]
        if line[1].endswith("..."): # broken output
            vm_name = line[0]
            line = line[2:]
        elif line[1].startswith("("):
            idx = 2
            while idx < len(line):
                if line[idx].endswith(")"):
                    vm_name = " ".join(line[:idx+1])
                    break
                idx += 1
            line = line[idx+1:]
        else:
            vm_name = line[0]
            line = line[1:]

        if ':' in line[1]: # skip heading line
            parsed[vm_name] = {
                "state"  : line[0],
                "uptime" : line[1],
                "state_msg" : " ".join(line[2:]),
            }
    return parsed


def inventory_hyperv_vms(parsed):
    return [ (vm_name, {'state': vm["state"] })
             for (vm_name, vm)
             in parsed.items() ]


def check_hyperv_vms(item, params, parsed):
    if item in parsed:
        vm = parsed[item]
        if vm["state"] == params['state']:
            state = 0
            message = "State is %s (%s)" % (vm["state"], vm["state_msg"])
        else:
            message = "State has changed from %s to %s (%s)" % (
                params['state'],\
                vm["state"],
                vm["state_msg"])
            state = 2
        return state, message


check_info["hyperv_vms"] = {
    "parse_function"        : parse_hyperv_vms,
    "check_function"        : check_hyperv_vms,
    "inventory_function"    : inventory_hyperv_vms,
    "service_description"   : "VM %s",
}

