#!/usr/local/bin/perl -T # # cancel_downtime_matching.cgi # # wui to remove scheduled downtime # # by Doke Scott, doke at udel dot edu, 2014.8.14 # # $Header: /opt/home/doke/work/nagios/RCS/cancel_downtime_matching.cgi,v 1.1 2014/08/14 23:08:22 doke Exp $ # use strict; use warnings; use CGI qw/:standard -nosticky/; use Text::Glob qw( glob_to_regex ); use Date::Parse; use POSIX qw( strftime ); use vars qw( $statusfile $cmdfile $verbose $help $cgi $author %hosts %services_by_host ); $statusfile = "/usr/local/nagios/var/status.dat"; $cmdfile = "/usr/local/nagios/var/rw/nagios.cmd"; $verbose = 0; $help = 0; $author = $ENV{REMOTE_USER}; # get author's username from http basic auth $cgi = new CGI; $help = $cgi->param( 'help' ); print $cgi->header(), $cgi->start_html( -title => "nagios cancel downtime matching" ), "
\n
This program cancels scheduled downtime for all nagios hosts and services that match a pattern. During scheduled downtime, nagios will not send out alerts about this host or service.
The pattern is compared with each hostname, each service name, and with "hostname/servicename". So if switch sw-ne37-110-1 has a ping service, the pattern will compared with 'sw-ne37-110-1', then 'ping', then 'sw-ne37-110-1/ping'.
The pattern uses standard unix glob wildcard syntax, except that it ignores case.
? | matches any single character |
* | matches any number of any character, including zero characters |
[abc] | matches any of the characters in the brackets |
[a-n] | matches the range of characters in the brackets |
Examples:
ups-* | any host beginning with 'ups-', ie 'ups-ne37-117-1', 'ups-ne37-117-1/ping', or 'ups-ne37-117-1/liebert' |
*ne37* | anything with 'ne37' in the hostname or service, ie 'sw-ne37-110-1' or 'sw-ne37-110-1/ping' |
*ping | anything with 'ping' at the end of the hostname or service, ie 'sw-ne37-110-1/ping' |
The "preview" button will show you which host and service downtime the pattern would match, without actually doing anything. It's a very good idea to do this first.
The "really cancel downtime" button actually tells nagios to cancel the scheduled downtime.
After canceling downtime, it will about 2 minutes for the change to show in nagios. It may take longer, expecially if nagios is busy, or you cancel downtime for a lot of things at once. }; } sub main_form { my( $progurl, $pattern, $pattern_re, $comment, $start, $start_esec, $duration, $end_esec, $preview, $really ); $progurl = "https://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}"; $pattern = $cgi->param( 'pattern' ); if ( ! defined $pattern ) { $pattern = ''; } print qq{
}; $preview = $cgi->param( 'preview' ); $preview = ( defined $preview && $preview eq 'preview' ) ? 1 : 0; $really = $cgi->param( 'really cancel downtime' ); $really = ( defined $really && $really =~ m/really/i ) ? 1 : 0; if ( $preview || $really ) { print "
\n
\n"; if ( ! defined $pattern || length( $pattern ) == 0 ) { print "you must enter a pattern\n"; return; } if ( $really ) { printf "really canceling downtime\n
\n"; } else { print "preview mode, not actually canceling downtime\n
\n";
}
$Text::Glob::strict_wildcard_slash = 0;
$pattern_re = glob_to_regex( lc $pattern );
$pattern_re =~ s/\?-xism/?i-xsm/;
$verbose && print "pattern_re '$pattern_re' hosts: services:
\n";
read_statusfile( $pattern_re );
cancel_downtime_hosts( $really );
cancel_downtime_services( $really );
}
}
sub read_statusfile {
my( $pattern ) = @_;
my( $in_hostdowntime, $in_servicedowntime, $host, $service, $downtime_id, $current_state,
$entry_time, $start_time, $end_time, $author, $comment );
open( fH, $statusfile ) || die "can't read-open $statusfile: $!\n";
$in_hostdowntime = 0;
$in_servicedowntime = 0;
$host = '';
$service = '';
$downtime_id = 0;
$current_state = 0;
$entry_time = 0;
$start_time = 0;
$end_time = 0;
$author = '';
$comment = '';
while (
\n";
if ( scalar( keys %hosts ) < 1 ) {
print "no host downtime to cancel
\n";
return;
}
# append results to nagios command file
if ( $really ) {
if ( ! open( cH, ">$cmdfile" ) ) {
print "error: can't write-open cmdfile $cmdfile: $!\n";
return;
}
}
$now = time;
print "\n";
foreach $host ( sort keys %hosts ) {
printf "
\n";
close cH;
}
sub cancel_downtime_services {
my( $really ) = @_;
my( $now, $host, $service, $nagios_cmd, $downtime_id );
print " \n",
$host,
scalar( localtime( $hosts{ $host }{ 'start_time' } ) ),
scalar( localtime( $hosts{ $host }{ 'end_time' } ) ),
$hosts{ $host }{ 'author' },
$hosts{ $host }{ 'comment' };
$downtime_id = $hosts{ $host }{ 'downtime_id' };
$nagios_cmd = sprintf "[%lu] DEL_HOST_DOWNTIME;%u\n",
$now, $downtime_id;
$verbose && print "nagios_cmd = $nagios_cmd";
if ( $really ) {
print cH $nagios_cmd;
}
}
print "%s %s %s %s %s
\n";
if ( scalar( keys %services_by_host ) < 1 ) {
print "no service downtime to cancel
\n";
return;
}
# append results to nagios command file
if ( $really ) {
if ( ! open( cH, ">$cmdfile" ) ) {
print "error: can't write-open cmdfile $cmdfile: $!\n";
return;
}
}
$now = time;
print "\n";
foreach $host ( sort keys %services_by_host ) {
foreach $service ( sort keys %{$services_by_host{ $host }} ) {
printf "
\n";
close cH;
}
\n",
$host, $service,
scalar( localtime( $services_by_host{ $host }{ $service }{ 'start_time' } ) ),
scalar( localtime( $services_by_host{ $host }{ $service }{ 'end_time' } ) ),
$services_by_host{ $host }{ $service }{ 'author' },
$services_by_host{ $host }{ $service }{ 'comment' };
$downtime_id = $services_by_host{ $host }{ $service }{ 'downtime_id' };
$nagios_cmd = sprintf "[%lu] DEL_SVC_DOWNTIME;%u\n",
$now, $downtime_id;
$verbose && print "nagios_cmd = $nagios_cmd";
if ( $really ) {
print cH $nagios_cmd;
}
}
}
print "%s/%s %s %s %s %s