#!/usr/bin/python
##########################################################################
# Copyright (C) 2018  Igor Castro
#
# This program 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, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>
###########################################################################
###########################################################################
# Version = 1.0
# Organisation = IATA
# Author = I.CASTRO
# Description =
# Nagios check in python to fetch by snmpwalk  the Gauge32 value of
# OID 1.3.6.1.4.1.3375.2.6.1.5.3  and trigger alarm based on it.
# F5-BIGIP-APM-MIB 
# 1.3.6.1.4.1.3375.2.6.1.5.3 = apmGlobalConnectivityStatCurConns  
#
##########################################################################
import os, sys, time, argparse
from datetime import date

# Hardcoded parameters to debug
my_command="snmpwalk"
target_OID="1.3.6.1.4.1.3375.2.6.1.5.3"
#warning_arg=int("60")
#critical_arg=int("30")

# exit statuses recognized by Nagios
OK = 0
WARNING = 1
CRITICAL = 2
UNKNOWN = 3

# Create a Parser to get value from command arguments

parser = argparse.ArgumentParser(description='Nagios check to collect by snmp F5 APM concurrent users')

parser.add_argument('-c', default=90, dest='critical', type=int, help='critical threshold for nagios (default: 90) is users')
parser.add_argument('-w', default=75, dest='warning', type=int, help='warning threshold for nagios (default: 75) is users')
parser.add_argument('-H', dest='host', help='target host')
parser.add_argument('-m', default=100, dest='maximum', type=int, help='maximal possible value per apm license (default: 100)')
parser.add_argument('--snmp', dest='snmp', help='snmp argument in form  \"-v 3 -a MD5 -A authpass -l authPriv -u username -x des -X password -r 5 -t 30\"')

args = parser.parse_args()


warning_arg=args.warning
critical_arg=args.critical
my_host=args.host
snmp_parameters=args.snmp
maxusers=args.maximum

# Create the actual snmpwalk command with all parameters
#snmp_command="%s -a %s -A %s -l %s -u %s -x %s -X %s %s %s" % (my_command,snmp3_auth_hash,snmp3_auth_pass,snmp3_mode,snmp3_user,snmp3_enc_cypher,snmp3_enc_pass,my_host,target_OID)

snmp_command="%s %s %s %s" % (my_command,snmp_parameters,my_host,target_OID)

# Print snmpwalk command
#print "snmp_command is %s" % snmp_command
result_snmp=os.popen(snmp_command).readlines()
#print "result is %s" % result_snmp

# Include a avlidation that snmp reply is not empty 
if (len(result_snmp) == 0 ):
	print "UNKNOWN"
	sys.exit(UNKNOWN)

# Detect when data is starting just after last Gauge32: value
result_snmp=result_snmp[0].strip()
value_str=result_snmp.find("Gauge32:")+8


# If snmpwalk failed for any reason date_str=-1 +8
if value_str == 7 :
        print "UNKNOWN"
        sys.exit(UNKNOWN)
else :

        # SNMPWALK Result has a valid value

        # Detect end of string to display only valuable data
        end_str=len(result_snmp)

        # value separated by space
        final_val=result_snmp[value_str:end_str]

        # Cast back to Integer
        final_val=int(final_val)
        
	#Check if value is over possible license
	if final_val > maxusers :
        	print "UNKNOWN"
		sys.exit(UNKNOWN)        
        
	# Check if the CPU level is more  than crtitical threshold
        if final_val > critical_arg :
                print "CRITICAL - High number of users detected: %d which is over critical threshold %d | 'concurrent users'=%d;%d;%d" % (final_val,critical_arg,final_val,warning_arg,critical_arg)
                sys.exit(CRITICAL)

        # Check if the remaining number of days is more than warning threshold
        if final_val > warning_arg :
                print "WARNING - High number of users detected: %d which is over warning threshold %d | 'concurrent users'=%d;%d;%d" % (final_val,warning_arg,final_val,warning_arg,critical_arg)
                sys.exit(WARNING)
        else :
                print "OK - Current number of users is %d | 'concurrent users'=%d;%d;%d" % (final_val,final_val,warning_arg,critical_arg) 
                sys.exit(OK)