WLC AP Up/Down Alerting

Just wanted to thank everyone who contributed to this thread. I was able to piece together your collected knowledge and get a basic alerting system going to send notifications when APs on our network go up and down. This has been a goal of mine for some time now. I owe its accomplishment to all of you.

Thanks!

1 Like

This alert was working great for us for a few weeks and then suddenly stopped working. Now I am having a hard time even getting the default “ap deleted=1” rule to work properly.

Does not appear to be a larger issue with notification settings/transport settings as I am still getting alerts for down devices that I have other rules for.

Might I need to adjust some settings in the database? I’d love to get this rule working again. If anyone has any suggestions, I am all ears!

Let me know if I can provide you with any additional information.

Thanks so much

Just tried setting up the same alert and it is not working. AP Name isn’t being displayed.

You can use this Nagios Plugin as a Service in LibreNMS and it works great for us.

Use the flag “–showerror_only” to see only the APs which are down.

@temporal-lin Are you able to share a screenshot of the service you have working (blank/blur any specific IPs etc) ?

Thanks

1 Like

Here you go! :slight_smile:

Host IP for the WLC IP address and SNMP for SNMP Community string.

P.S: You might have to change the permission on “/var/nagios_plugin_cache/” if there is no file after running the script for the first time. This is where it stores online AP MAC Address and name.

“sudo chmod o=rw -R /var/nagios_plugin_cache/” should do the job.

Hello!

Is it possible to see what AP who is down in the output of the check_snmp cisco wlc script?

Best regards!

I Answer myself: Yes it shows the AP who is down :slight_smile:

I am actually on Cisco 9800 and no AP count can be seen and SSID was also missing. Any one has this problem too? Alerts on AP down is another problem too

Hello!

Yes known limitation, You can read more here: Cisco CL9800 Wireless Controller support

I was able to get a working solution for our Aruba controllers with the help of this thread and figured I would post for anyone wanting to do the same. It works with a custom alert and a perl cron script that runs every day. We have been using this setup for about 2 years and it works great. Also no manual maintenance when changing names, adding aps, removing aps etc.

Librenms Alert:
SELECT distinct mac_addr, deleted, name FROM access_points WHERE (access_points.device_id = ?) && (access_points.deleted = ‘1’ )

Librenms Template:

<b>{{ $alert->title }}<br>
<br>
Ap Information</b>:<br>
@foreach ($alert->faults as $key => $value)
AP Name: {{ $alert->faults[$key]['name'] }} <br>
AP Mac: {{ $alert->faults[$key]['mac_addr'] }} <br>
@if ($alert->state == 0) Down since: {{ $alert->elapsed }} @endif
@endforeach
<br>
<b>Controller information</b>:<br>
Severity: {{ $alert->severity }}<br>
Timestamp: {{ $alert->timestamp }}<br>
Unique-ID: {{ $alert->uid }}<br>
Device ID: {{ $alert->device_id }}<br>
Hostname of the Device: {{ $alert->hostname }}<br>
sysName of the Device: {{ $alert->sysName }}<br>
sysDescr of the Device: {{ $alert->sysDescr }}<br>
sysContact of the Device: {{ $alert->sysContact }}<br>

This perl script runs every day and maintains the access_points database.
crontab: 0 12 * * * /root/sync_aruba_aps_to_librenms.pl >> /root/sync_aruba_aps_to_librenms.pl.cron.log 2>&1

Script ( Add host,password and controller prompt ):

#!/usr/bin/perl

use strict;
use warnings;

use Net::SSH::Expect;
use DBD::mysql;

print localtime . " Sync started.\n";

my $expected_low_ap_count = 175; # If there are lower than n AP's that get pulled from the controller the script will die. 

my $ssh = Net::SSH::Expect->new (
    host => '', 
    password=> '', 
    user => 'admin', 
    raw_pty => 1,
);

my $Prompt = qr/\(EXPECTED_PROMPT\) \*#/;

my $login_output = $ssh->login();
if ($login_output !~ $Prompt) {
    die localtime .  " Login has failed. Login output was $login_output";    
}

$ssh->send("no paging");
$ssh->waitfor($Prompt, 2) or die localtime .  " Failed to set no paging";
$ssh->send("show ap database long");

print localtime . " Logged into controller, requesting ap database.\n";

my $active_aps;
while ( defined (my $line = $ssh->read_line()) ) {
	
	 # If there is a mac on the line I assume its an AP listing
	 if ($line !~ /([0-9A-Fa-f]{2}[:]?){5}([0-9A-Fa-f]{2})/ ) { next }

 	my @data = split('\s+',$line);
 	if ($data[4] ne 'Up') { 
		splice @data, 5,0,undef;
 	}
 	if ($data[6] ne 'S') {
 		splice @data, 6,0,undef;
 	}

 	if (! $data[9]) { die localtime .  " Could not get mac address"; }
 	if (! $data[0]) { die localtime .  " Could not get name"; }

 	my $h = {
 		mac => $data[9],
 		name  => $data[0],
 		master_ip => $data[7],
 		standby_ip => $data[8],
 		status => $data[4]
 	};
 	push @{$active_aps}, $h;
}

if ( !$active_aps ) {
	die localtime .  " Unable to grab aps from the controller. Bad output, cannot parse.\n";
}

if ( scalar @{$active_aps} < $expected_low_ap_count ) { 
	die localtime .  " " . scalar @{$active_aps} . " were pulled from the controller, a low of $expected_low_ap_count is set.\n";
}

print localtime . " Pulled " . scalar @{$active_aps} . " AP's from the controller to sync.\n";

my $sql_not_in_mac_str = '(' . join(',',map{ "'" . $_->{mac} . "'"} @{$active_aps} ) . ')';
my $sql_not_in_name_str = '(' . join(',',map{ "'" . $_->{name} . "'"} @{$active_aps} ) . ')';

my @deletes;
foreach my $ap (@{$active_aps}) {

	if ($ap->{status} eq 'Up') {
		push @deletes, " ( name = '" . $ap->{name} . "' and deleted = '1' )"
	}

}
my $sql_not_in_name_cont_str = join(' or ', @deletes );

my $dbh = DBI->connect("DBI:mysql:database=librenms;host=localhost",undef, undef, {'RaiseError' => 1});

# these two are for removing old access points
my $sth = $dbh->prepare("delete from access_points where mac_addr not in $sql_not_in_mac_str");
$sth->execute() or die localtime .  " cannot execute not in mac query";

$sth = $dbh->prepare("delete from access_points where name not in $sql_not_in_name_str");
$sth->execute() or die localtime .  " cannot execute not in name sql";

# deletes aps that are set to down in database but up in controller, this can happen with an ap swapped controllers or an ssid is gone.
$sth = $dbh->prepare("delete from access_points where $sql_not_in_name_cont_str");
$sth->execute() or die localtime .  " cannot execute not in name sql";

print localtime . " Database queries successful.\n";

Did anyone get check_snmp_cisco_wlc working with SNMPv3 or are you bums still using v2c?