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


# targetstate is 1 (used) or 0 (unused)
# info columns: INDEX PHYSTATE OPSTATE TXWORDS RXWORDS
brocade_pystate_names = ['', 'noCard', 'noTransceiver', 'laserFault', 'noLight', 'noSync', 'inSync', 'portFault', 'diagFault', 'lockRef']
brocade_opstate_names = [ 'unknown', 'online', 'offline', 'testing', 'faulty']
brocade_perfdata_errors = False
brocade_default_params = (0.1, 0.01)

def inventory_brocade_port(checkname, info):
   inventory = []
   for index, phystate, opstate, txwords, rxwords, crcerrors, c3discards in info:
      state = (int(phystate), int(opstate))
      if state == (4,2):
         used = 0
         used_txt = "unused"
      elif phystate == "1" or phystate == "2":
         used = 0
         used_txt = "no card or no transceiver"
      else:
         used = 1
         used_txt = "used"
      # index  is e.g. '3'. But port number printed on switch
      # and in management software of switch counts from 0, so subtract
      # one. Also make it 2-digits => '03'
      if used:
          index = "%02d" % (int(index) - 1)
          inventory.append( (index, used_txt, "brocade_default_params") )
   return inventory


def check_brocade_port(portno, params, info):
   try:
       warning, critical = params
   except:
       warning, critical = (0.1, 0.01) # percent error rate

   # SNMP counts ports from 1, but management console and hardware from 0
   portinfo = [ line[1:] for line in info if int(line[0]) == int(portno) + 1 ]
   if len(portinfo) < 1:
      return (3, "UNKNOWN - No port number %d present" % int(portno))
   phystate, opstate, txwords, rxwords, crcerrors, c3discards = map(int, portinfo[0])
   perfdata = [
       ( "txwords", "%dc" % txwords ),
       ( "rxwords", "%dc" % rxwords ) ]
   if brocade_perfdata_errors:
       perfdata += [
           ( "crcerrors", "%dc" % crcerrors ),
           ( "c3discards", "%dc" % c3discards ) ]


   state = phystate,opstate
   if state == (6,1):
      return (0, "OK - physical and logical link UP", perfdata)
   else:
      return (2, "CRIT - physical state %s, opstate %s" % (brocade_pystate_names[phystate],
                                                           brocade_opstate_names[opstate]), perfdata)


check_info['fc_brocade_port'] = (check_brocade_port, "PORT %s", 1,  inventory_brocade_port)
snmp_info['fc_brocade_port'] = ( "enterprises.1588.2.1.1.1.6.2.1", [ 1, 3, 4, 11, 12, 22, 28 ] )
# 1: swFCPortIndex, 3: swFCPortOpStatus, 4:swFCPortAdmStatus,
# 11: swFCPortTxWords, 12: swFCPortRxWords
# 22: swFCPortRxCrcs, 28: swFCPortC3Discards
check_config_variables.append("brocade_perfdata_errors")
