#!/usr/bin/python

'''
Check for CISCO portchannel.

Usage:
  check_papouch -H hostname -C community
'''

from __future__ import print_function

import sys, os, urllib2, getopt
from pysnmp.entity.rfc3413.oneliner import cmdgen

VERBOSE = False

class check_snmp:
  int_entry = ".1.3.6.1.2.1.2.2.1"
  int_name = ".1.3.6.1.2.1.31.1.1.1.1"
  int_descr = int_entry + ".2"
  int_oper_status = int_entry + ".8"
  int_speed = ".1.3.6.1.2.1.31.1.1.1.15"
  def __init__(self, host, community):
      self.gen = cmdgen.CommandGenerator()
      self.community = cmdgen.CommunityData(community)
      self.transport = cmdgen.UdpTransportTarget((host, 161))
  def list(self, oid):
      errorIndication, errorStatus, errorIndex, varBindTable = \
        self.gen.nextCmd(
          self.community,
          self.transport,
          oid
        )
      for row in varBindTable:
        id = row[0][0][-1]
        value = row[0][1].asOctets()
        yield id, value
  def get(self, oid, id=None):
      if id is not None:
        oid = oid + "." + str(id)
      errorIndication, errorStatus, errorIndex, varBinds = \
        self.gen.getCmd(
          self.community,
          self.transport,
          oid
        )
      #import IPython;IPython.embed();sys.exit()
      return int(varBinds[0][1])
  def check(self):
      self.failed = []
      self.ok = []
      interfaces = self.list(self.int_name)
      pos = [x for x in interfaces if x[1].startswith("Po")]
      for int_id, po_name in pos:
        po_id = int(po_name.lower().lstrip("port-channel"))
        if po_id>=500:
          # ignore special interfaces
          continue
        speed = self.get(self.int_speed, int_id)
        status = self.get(self.int_oper_status, int_id)
        if VERBOSE:
          print(int_id, po_id, po_name, status, speed)
        if status!=1:
          self.failed.append(po_name)
          continue
        if speed not in [2000, 20000]:
          self.failed.append(po_name)
          continue
        self.ok.append(po_name)
      return len(self.failed)>0

opts,files = getopt.gnu_getopt(sys.argv[1:], 'H:C:v', [])
community = "public"
for key, value in opts:
  if key=="-H":
    host = value
  elif key=="-C":
    community = value
  elif key=="-v":
    VERBOSE = True

snmp_client = check_snmp(host, community)
if snmp_client.check():
  print('CRITICAL - Failed: %s' % (", ".join(snmp_client.failed)))
  sys.exit(2)
else:
  print('OK - %s' % (", ".join(snmp_client.ok)))
  sys.exit(0)
