#!/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-
# 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.

# Example SNMP walk (extract)
# All names OIDs are prefixed with CISCO-VIRTUAL-SWITCH-MIB::
# All numeric OIDs are prefixed with .1.3.6.1.4.1.9.9.388

# cvsDomain.0                            .1.1.1.0 10
# cvsSwitchID.0                          .1.1.2.0 1
# cvsSwitchCapability.0                  .1.1.3.0 "C0 "
# cvsSwitchMode.0                        .1.1.4.0 2
# cvsSwitchConvertingStatus.0            .1.1.5.0 2
# cvsVSLChangeNotifEnable.0              .1.1.6.0 2
# cvsCoreSwitchPriority.1                .1.2.1.1.2.1 100
# cvsCoreSwitchPriority.2                .1.2.1.1.2.2 100
# cvsCoreSwitchPreempt.1                 .1.2.1.1.3.1 2
# cvsCoreSwitchPreempt.2                 .1.2.1.1.3.2 2
# cvsCoreSwitchLocation.1                .1.2.1.1.4.1
# cvsCoreSwitchLocation.2                .1.2.1.1.4.2
# cvsChassisSwitchID.2                   .1.2.2.1.1.2 1
# cvsChassisSwitchID.500                 .1.2.2.1.1.500 2
# cvsChassisRole.2                       .1.2.2.1.2.2 2
# cvsChassisRole.500                     .1.2.2.1.2.500 3
# cvsChassisUpTime.2                     .1.2.2.1.3.2 184371004
# cvsChassisUpTime.500                   .1.2.2.1.3.500 184371004
# cvsVSLCoreSwitchID.41                  .1.3.1.1.2.41 1
# cvsVSLCoreSwitchID.42                  .1.3.1.1.2.42 2
# cvsVSLConnectOperStatus.41             .1.3.1.1.3.41 1
# cvsVSLConnectOperStatus.42             .1.3.1.1.3.42 1
# cvsVSLLastConnectionStateChange.41     .1.3.1.1.4.41 "07 DE 07 18 01 12 22 00 "
# cvsVSLLastConnectionStateChange.42     .1.3.1.1.4.42 "07 DE 07 18 01 12 22 00 "
# cvsVSLConfiguredPortCount.41           .1.3.1.1.5.41 2
# cvsVSLConfiguredPortCount.42           .1.3.1.1.5.42 2
# cvsVSLOperationalPortCount.41          .1.3.1.1.6.41 2
# cvsVSLOperationalPortCount.42          .1.3.1.1.6.42 2
# cvsVSLConnectionRowStatus.41           .1.3.1.1.7.41 1
# cvsVSLConnectionRowStatus.42           .1.3.1.1.7.42 1
# cvsModuleVSSupported.1000              .1.4.1.1.1.1000 1
# cvsModuleVSSupported.11000             .1.4.1.1.1.11000 1
# cvsModuleVSLCapable.1000               .1.4.1.1.2.1000 1
# cvsModuleVSLCapable.11000              .1.4.1.1.2.11000 1
# cvsModuleSlotNumber.1000               .1.4.1.1.3.1000 1
# cvsModuleSlotNumber.11000              .1.4.1.1.3.11000 11
# cvsModuleRprWarm.1000                  .1.4.1.1.4.1000 1
# cvsModuleRprWarm.11000                 .1.4.1.1.4.11000 1
# cvsDualActiveDetectionNotifEnable.0    .1.5.1.0 2

cisco_vss_role_names = {
    '1' : 'standalone',
    '2' : 'active',
    '3' : 'standby',
}

cisco_vss_operstatus_names = {
    '1' : 'up',
    '2' : 'down',
}

def inventory_cisco_vss(info):
    for switch_id, chassis_role in info[0]:
        if chassis_role in [ '2', '3' ]: # active, standby
            return [ (None, None) ]

def check_cisco_vss(item, params, info):
    chassis, ports = info
    for switch_id, chassis_role in chassis:
        if chassis_role == '1':
            state = 2
        else:
            state = 0
        yield state, "chassis %s: %s" % (switch_id, cisco_vss_role_names[chassis_role])

    yield 0, "%d VSL connections configured" % len(ports)

    for core_switch_id, operstatus, conf_portcount, op_portcount in ports:
        if operstatus == '1':
            state = 0
        else:
            state = 2
        yield state, "core switch %s: VSL %s" % (core_switch_id, cisco_vss_operstatus_names[operstatus])

        if conf_portcount == op_portcount:
            state = 0
        else:
            state = 2
        yield state, "%s/%s ports operational" % (op_portcount, conf_portcount)


check_info["cisco_vss"]  = {
    "check_function"     : check_cisco_vss,
    "inventory_function" : inventory_cisco_vss,
    "service_description": "VSS Status",
    "snmp_scan_function" : lambda oid: (
                             "Catalyst 45" in oid(".1.3.6.1.2.1.1.1.0") or
                             "Catalyst 65" in oid(".1.3.6.1.2.1.1.1.0")) and \
                             oid(".1.3.6.1.4.1.9.9.388.1.1.1.0"),
    "snmp_info"          : [
        ( ".1.3.6.1.4.1.9.9.388.1.2.2.1",
              [
                 1,       # cvsChassisSwitchID
                 2,       # cvsChassisRole: standalone(1), active(2), standby(3)
              ]
        ),
        ( ".1.3.6.1.4.1.9.9.388.1.3.1.1",
              [
                 2,       # cvsVSLCoreSwitchID
                 3,       # cvsVSLConnectOperStatus: up(1), down(2)
                 5,       # cvsVSLConfiguredPortCount
                 6,       # cvsVSLOperationalPortCount
              ]
        ),
      ],
}
