#!/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:
# <<<emcvnx_info>>>
#
#
# Server IP Address:       10.1.36.13
# Agent Rev:           7.32.25 (1.56)
#
#
# Agent/Host Information
# -----------------------
#
#
#
# Agent Rev:           7.32.25 (1.56)
# Name:                K10
# Desc:
# Node:                A-CKM00114701225
# Physical Node:       K10
# Signature:           3195192
# Peer Signature:      3187006
# Revision:            05.32.000.5.201
# SCSI Id:             0
# Model:               VNX5300
# Model Type:          Rackmount
# Prom Rev:            7.00.00
# SP Memory:           8192
# Serial No:           CKM00114701225
# SP Identifier:       A
# Cabinet:             DPE7
#
# Name of the software package:        -Compression
# Revision of the software package:    -
# Commit Required:                     NO
# Revert Possible:                     NO
# Active State:                        YES
# Is installation completed:           YES
# Is this System Software:             NO
#
# [... more software packages follow ...]


def parse_emcvnx_info(info):
    parsed = {
        'info':     [],
        'storage':  [],
        'link':     [],
        'config':   [],
        'io': [],
    }
    key_to_subcheck = {
        'System Fault LED':         'info',
        'Server IP Address':        'info',
        'System Date':              'info',
        'System Time':              'info',
        'Serial Number For The SP': 'info',
        'Storage Processor':                 'storage',
        'Storage Processor Network Name':    'storage',
        'Storage Processor IP Address':      'storage',
        'Storage Processor Subnet Mask':     'storage',
        'Storage Processor Gateway Address': 'storage',
        'Storage Processor IPv6 Mode':       'storage',
        'Link Status':     'link',
        'Current Speed':   'link',
        'Requested Speed': 'link',
        'Auto-Negotiate':  'link',
        'Capable Speeds':  'link',
        'Statistics Logging':   'config',
        'SP Read Cache State':  'config',
        'SP Write Cache State': 'config',
        'Hw_flush_on':          'config',
        'Idle_flush_on':        'config',
        'Lw_flush_off':         'config',
        'Max Requests':                  'io',
        'Average Requests':              'io',
        'Hard errors':                   'io',
        'Total Reads':                   'io',
        'Total Writes':                  'io',
        'Read_requests':                 'io',
        'Write_requests':                'io',
        'Blocks_read':                   'io',
        'Blocks_written':                'io',
        'Sum_queue_lengths_by_arrivals': 'io',
        'Arrivals_to_non_zero_queue':    'io',
        'Write_cache_flushes':           'io',
        'Write_cache_blocks_flushed':    'io',
    }

    preparsed, errors = preparse_emcvnx_info(info)

    for key, value in preparsed:
        subcheck = key_to_subcheck.get(key)
        if subcheck:
            parsed[subcheck].append(
                (key, value)
            )
    return parsed, errors


def inventory_emcvnx_info(parsed, subcheck):
    output, errors = parsed
    if output[subcheck]:
        return [(None, None)]


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


def check_emcvnx_info(item, _no_params, parsed):
    output, errors = parsed

    if errors:
        yield 2, ('Error(s) while parsing the output. This may effect the '
                  'discovery of other emcvnx services. Please check your naviseccli '
                  'configuration. Errors are: %s' % (' '.join(errors)))

    for key, value in output['info']:
        status = 0
        if key == 'System Fault LED' and value != 'OFF':
            status = 2
        yield status, "%s: %s" % (key, value)


check_info['emcvnx_info'] = {
    "parse_function"          : parse_emcvnx_info,
    "inventory_function"      : lambda x: inventory_emcvnx_info(x, 'info'),
    "check_function"          : check_emcvnx_info,
    "service_description"     : "EMC VNX Info",
    "includes"                : ["emcvnx.include"],
}


#   .--Storage-------------------------------------------------------------.
#   |                 ____  _                                              |
#   |                / ___|| |_ ___  _ __ __ _  __ _  ___                  |
#   |                \___ \| __/ _ \| '__/ _` |/ _` |/ _ \                 |
#   |                 ___) | || (_) | | | (_| | (_| |  __/                 |
#   |                |____/ \__\___/|_|  \__,_|\__, |\___|                 |
#   |                                          |___/                       |
#   '----------------------------------------------------------------------'


def check_emcvnx_storage(item, params, parsed):
    output, _ = parsed
    for key, value in output['storage']:
        yield 0, '%s: %s' % (key, value)


check_info['emcvnx_info.storage'] = {
    "inventory_function"      : lambda x: inventory_emcvnx_info(x, 'storage'),
    "check_function"          : check_emcvnx_storage,
    "service_description"     : "EMC VNX Storage Processor"
}


#   .--Link----------------------------------------------------------------.
#   |                         _     _       _                              |
#   |                        | |   (_)_ __ | | __                          |
#   |                        | |   | | '_ \| |/ /                          |
#   |                        | |___| | | | |   <                           |
#   |                        |_____|_|_| |_|_|\_\                          |
#   |                                                                      |
#   '----------------------------------------------------------------------'


def check_emcvnx_link(item, params, parsed):
    output, _ = parsed
    for key, value in output['link']:
        status = 0
        if key == u'Link Status' and value != u'Link-Up':
            status = 2
        yield status, '%s: %s' % (key, value)


check_info['emcvnx_info.link'] = {
    "inventory_function"      : lambda x: inventory_emcvnx_info(x, 'link'),
    "check_function"          : check_emcvnx_link,
    "service_description"     : "EMC VNX Link"
}


#   .--Config--------------------------------------------------------------.
#   |                     ____             __ _                            |
#   |                    / ___|___  _ __  / _(_) __ _                      |
#   |                   | |   / _ \| '_ \| |_| |/ _` |                     |
#   |                   | |__| (_) | | | |  _| | (_| |                     |
#   |                    \____\___/|_| |_|_| |_|\__, |                     |
#   |                                           |___/                      |
#   '----------------------------------------------------------------------'


def check_emcvnx_config(item, params, parsed):
    output, _ = parsed
    for key, value in output['config']:
        yield 0, '%s: %s' % (key, value)


check_info['emcvnx_info.config'] = {
    "inventory_function"      : lambda x: inventory_emcvnx_info(x, 'config'),
    "check_function"          : check_emcvnx_config,
    "service_description"     : "EMC VNX Config"
}


#   .--IO------------------------------------------------------------------.
#   |                              ___ ___                                 |
#   |                             |_ _/ _ \                                |
#   |                              | | | | |                               |
#   |                              | | |_| |                               |
#   |                             |___\___/                                |
#   |                                                                      |
#   '----------------------------------------------------------------------'


def check_emcvnx_io(item, params, parsed):
    output, _ = parsed
    for key, value in output['io']:
        status = 0
        if key == 'Hard errors' and value != 'N/A':
            status = 2
        yield status, '%s: %s' % (key, value)


check_info['emcvnx_info.io'] = {
    "inventory_function"      : lambda x: inventory_emcvnx_info(x, 'io'),
    "check_function"          : check_emcvnx_io,
    "service_description"     : "EMC VNX IO"
}
