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


# <<<emcvnx_mirrorview:sep(58)>>>
# MirrorView Name:                     Mirror_Lun_306
# MirrorView Description:
# MirrorView UID:                      50:06:01:60:88:60:50:CB:2E:00:00:00:00:00:00:00
# Logical Unit Numbers:                306
# Remote Mirror Status:                Mirrored
# MirrorView State:                    Active
# MirrorView Faulted:                  NO
# MirrorView Transitioning:            NO
# Quiesce Threshold:                   60
# Minimum number of images required:   0
# Image Size:                          1073741824
# Image Count:                         2
# Write Intent Log Used:               YES
# Images:
#     Image UID:                     50:06:01:60:88:60:50:CB
#     Is Image Primary:              YES
#     Logical Unit UID:              60:06:01:60:11:21:3A:00:68:82:C2:16:F9:64:E4:11
#     Image Condition:               Primary Image
#     Preferred SP:                  A
#
#     Image UID:                     50:06:01:60:88:60:4F:13
#     Is Image Primary:              NO
#     Logical Unit UID:              60:06:01:60:18:21:3A:00:EF:4D:0B:A4:03:65:E4:11
#     Image State:                   Consistent
#     Image Condition:               Normal
#     Recovery Policy:               Manual
#     Preferred SP:                  A
#     Synchronization Rate:          Medium
#
# MirrorView Name:                     Mirror_LUN_205
# ...

# parsed = {
#     u'Lun 53': {
#         u'Logical Unit Numbers': u'53',
#         u'Minimum number of images required': u'0',
#         u'MirrorView Description': u'',
#         u'MirrorView Faulted': u'NO',
#         u'MirrorView State': u'Active',
#         u'MirrorView Transitioning': u'NO',
#         u'MirrorView UID': u'50:06:01:60:88:60:50:CB:3D:00:00:00:00:00:00:00',
#         u'Quiesce Threshold': u'60',
#         u'Remote Mirror Status': u'Mirrored',
#         u'Write Intent Log Used': u'YES',
#         u'Image Count': u'2',
#         u'Image Size': u'10485760',
#         'Images': {
#             u'50:06:01:60:88:60:4F:13': {
#                 u'Image Condition': u'Normal',
#                 u'Image State': u'Synchronized',
#                 u'Is Image Primary': u'NO',
#                 u'Logical Unit UID': u'60:06:01:60:18:21:3A:00:77:9A:BF:71:CA:68:E4:11',
#                 u'Preferred SP': u'A',
#                 u'Recovery Policy': u'Manual',
#                 u'Synchronization Rate': u'Medium',
#             },
#             u'50:06:01:60:88:60:50:CB': {
#                 u'Image Condition': u'Primary Image',
#                 u'Is Image Primary': u'YES',
#                 u'Logical Unit UID': u'60:06:01:60:11:21:3A:00:5A:85:A0:F7:F7:64:E4:11',
#                 u'Preferred SP': u'A',
#         }},
#     },
#     ...
# }


def parse_emcvnx_mirrorview(info):
    parsed = {}
    for line in info:
        if line[0] == "Request failed.  Management Server - Sync Mirror Feature software is not installed or unavailable.":
            break

        elif line[0] == "MirrorView Name":
            lun_name = line[1].replace("_", " ").replace("Mirror", "").strip()
            parsed.setdefault(lun_name, {})

        else:
            if "UID" in line[0]:
                lun_value = ":".join(line[1:]).strip()
            else:
                lun_value = " ".join(line[1:]).strip()

            if line[0] == "Images":
                parsed[lun_name].setdefault("Images", {})
            else:
                if "Images" in parsed[lun_name]:
                    if line[0] == "Image UID":
                        image_uid = lun_value
                        parsed[lun_name]["Images"].setdefault(image_uid, {})
                    else:
                        parsed[lun_name]["Images"][image_uid][line[0]] = lun_value
                else:
                    parsed[lun_name][line[0]] = lun_value
    return parsed


def inventory_emcvnx_mirrorview(parsed):
    return [ (lun_name, None) for lun_name, lun_states in parsed.items() \
             if lun_states["MirrorView State"].lower() == "active" ]


def check_emcvnx_mirrorview(item, params, parsed):
    map_state = {
        "no"        : (0, "NO, mirror is running as expected"),
        "yes"       : (2, "YES, mirror broken"),
        "active"    : (0, "normal (all IOs are allowed)"),
        "attention" : (1, "something happened to the mirrored image"),
        "inactive"  : (2, "stopped mirroring"),
    }
    if item in parsed:
        state, state_readable = map_state[parsed[item]["MirrorView State"].lower()]
        yield state, "Status: %s" % state_readable

        state_faulted, state_readable_faulted = map_state[parsed[item]["MirrorView Faulted"].lower()]
        yield state, "Faulted: %s" % state_readable_faulted


check_info['emcvnx_mirrorview'] = {
    'parse_function'            : parse_emcvnx_mirrorview,
    'inventory_function'        : inventory_emcvnx_mirrorview,
    'check_function'            : check_emcvnx_mirrorview,
    'service_description'       : 'Mirror view %s',
}
