#!/usr/bin/python3

'''
Check for CISCO portchannel.

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

from __future__ import print_function

import sys, os, getopt
from netsnmp import Session, VarList

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.session = Session(DestHost=host, Community=community, Version=2)
  def list(self, oid):
      vars = VarList(oid)
      ret = self.session.walk(vars)
      for row in vars:
        yield row.iid, row.val
  def get(self, oid, id=None):
      if id is not None:
        oid = oid + "." + str(id)
      ret = self.session.get(VarList(oid))
      return int(ret[0])
  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, 4000, 40000, 50000]:
          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|ok=%d failed=%d' % (
    ", ".join(snmp_client.failed),
    len(snmp_client.ok),
    len(snmp_client.failed)
  ))
  sys.exit(2)
else:
  print('OK - %s|ok=%s failed=%d' % (
    ", ".join(snmp_client.ok),
    len(snmp_client.ok),
    len(snmp_client.failed)
  ))
  sys.exit(0)
