Back to Home Back to Archive

Nagios Plugin to monitor WLC AP's

I wrote this plugin to monitor the currently associated Access Points on a Cisco Wireless Lan Controller in Nagios.  It throws an 'Critical' alert if an AP is not found, and e-mails you the name of the AP (or AP's) that were not found associated to the WLC. If it finds an AP that was on the WLC that it was not expecting to find, it throws a 'warning'.
An example showing the 'warning' state: 

And an example showing the 'critical' state:


 It's customizable, but I chose this method, since what typically happens when there is a WLC problem is AP's begin roaming around to various WLC's that are all part of the same mobility group. This can yield a lot of alerts, if you specify 'Critical' for both AP's missing AND AP's found unexpectedly.

I wrote it in Python. The usage is fairly simple, just populate a file in your conf.d directory called "wlc-<#>-aps_expected. Note, this relies on netsnmp and the correct mibs to be installed. This is currently for AirOS WLC's only.
usage: check_wlc_ap.py -H -f  

Below are some sample config modifications needed to make this work.


 /etc/nagios3/commands.cfg: define command{ command_name check_wlc_ap command_line /usr/lib/nagios/plugins/check_wlc_ap.py -H $HOSTADDRESS$ -f $ARG1$ }
In order for me to get the correct email output you need to modify the "service macro" to include "long" output...meaning, instead of a single line in the result email it will include all the lines that are put to stdout (in my case all the ap's that are missing) vi /etc/nagios3/commands.cfg: under 'notify-service-by-email' I added "LONGSERVICEOUTPUT" directly after " "SERVICEOUTPUT". Resulting command is as follows:
# 'notify-service-by-email' command definition define command{ command_name notify-service-by-email command_line /usr/bin/printf "%b" "***** Nagios *****nnNotification Type: $NOTIFICATIONTYPE$nnService: $SERVICEDESC$nHost: $HOSTALIAS$nAddress: $HOSTADDRESS$nState: $SERVICESTATE$nnDate/Time: $LONGDATETIME$nnAdditional Info:n$SERVICEOUTPUT$n$LONGSERVICEOUTPUT$" | /usr/bin/mail -s "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$ }


The plugin:
Note, be sure to put in your WLC RO snmp string (and leave the space after it) and also tell the script the path/name of your aps_expected file (the file containing only ap names w/ out carriage return at the end)

#!/usr/bin/python

#######
# this is a script to check the currently joined Access Points to a Cisco Wireless Lan Controller.
# It relies on a file, passed as an argument, which contains the access points that "should" exist on said WLC.
# It will report a Critical error if ap's are not there, and a Warning error if an ap is there, but it shouldn't be
# (ie ap there but not in the list)
# edited July 23 2013 by Mike Albano
########

import commands, sys, re, os, syslog
from sets import Set

#make sure arguments are passed to script
if len(sys.argv) < 4:
    sys.exit("usage: check_wlc_ap.py -H <wlc_ip_address> -f <aps_expected file>")

#create list from snmpget, and regex out just the AP's
get_aps = commands.getoutput('snmpwalk -v2c -c <community_string_here> ' + sys.argv[2] + ' 1.3.6.1.4.1.14179.2.2.1.1.3')
search_aps = re.findall(r'\"(\w.+)\"', get_aps)

#print the differences between the 2 sets, created below, using message passed to function
def list_aps(apset, message):
    if len(apset) == 0:
        return
    print message
    for item in sorted(apset):
        print item
        #log the messages to syslog
        syslog.syslog('%s - %s' % (message, item))

def main():
    #create 2 empty sets
    configuredaps = Set()
    activeaps = Set()

    #add to configuredaps Set by looping over sys.argv[4]
    apfile = open(sys.argv[4], 'rU')
    for line in apfile:
        configuredaps.add(line.strip())

    #add to activeaps Set by looping over regex result (search_aps)
    for item in search_aps:
        activeaps.add(item)

    list_aps(configuredaps - activeaps, "The following APs are down: ")
    list_aps(activeaps - configuredaps, "The following APs were found but dont belong here: ")

    #exit with Critical if aps are down, Warning if don't belong on WLC
    if configuredaps - activeaps:
        sys.exit(2)
    if activeaps - configuredaps:
        sys.exit(1)

main()