#!/usr/bin/perl -w
# Check local nagios/icinga instance using livestatus and report any alert back
# Filter on-call hosts/services only

use strict;
use Getopt::Long;
use Monitoring::Livestatus;
use Monitoring::Plugin qw(%ERRORS %STATUS_TEXT);


my %opts = (
    socket => '/var/lib/icinga/rw/live',
    'service-group' => 'on-call',
    'host-group' => 'on-call',
    'skip-downtime' => 1,
    'use-timeperiod' => 1,
);

sub usage {
    print "Usage: check_nagios_hosts [OPTIONS]\n";
    print "\n";
    print "    Check local nagios/icinga instance using livestatus and report any alert back\n";
    print "\n";
    print "--socket=PATH         Livestatus socket path (default: $opts{socket})\n";
    print "--service-group=GROUP Service group name used to filter (default: $opts{'service-group'})\n";
    print "--host-group=GROUP    Host group name used to filter (default: $opts{'host-group'})\n";
    print "--skip-downtime=0|1   Skip if host/service is in scheduled downtime period (default: $opts{'skip-downtime'})\n";
    print "--use-timeperiod=0|1  Skip if host/service is not in notification period (default: $opts{'use-timeperiod'})\n";
    print "--help                Show this helpful description\n";
    print "\n\n";
}

GetOptions(\%opts,
    'socket=s',
    'service-group=s',
    'host-group=s',
    'skip-downtime=i',
    'use-timeperiod=i',
    'help|h',
);

if ( $opts{help} ) {
    usage;
    exit($ERRORS{UNKNOWN});
}

my $np = Monitoring::Plugin->new;

my $ml = Monitoring::Livestatus->new(
    socket => $opts{socket},
);

my $hosts = $ml->selectall_arrayref("GET hosts\nColumns: name state acknowledged groups in_notification_period scheduled_downtime_depth\n", { Slice => {} } );

my $status = 0;
my $status_msg = '';
my $hosts_count = 0;
foreach my $host (@$hosts) {
    next if ( $opts{'host-group'} && ! grep { $_ eq $opts{'host-group'} } @{$host->{groups}} );
    next if ( $opts{'use-timeperiod'} && ! $host->{in_notification_period} );
    next if ( $opts{'skip-downtime'} && $host->{scheduled_downtime_depth} && $host->{scheduled_downtime_depth} > 0 );
    $hosts_count++;
    my $host_name = $host->{name};
    $status = $host->{state} if ( $host->{state} > $status && ! $host->{acknowledged} );
    if ( $host->{state} != $ERRORS{OK} && ! $host->{acknowledged} ) {
        $status_msg .= ', ' if ( $status_msg && $status_msg ne '' );
        $status_msg .= $host_name.": ".$STATUS_TEXT{$host->{state}};
    }

    my $services = $ml->selectall_arrayref("GET services\nFilter: host_name = $host_name\nFilter: state != 0\nFilter: acknowledged != 1\nColumns: state plugin_output description groups in_notification_period scheduled_downtime_depth", { Slice => {} } );
    foreach my $service (@$services) {
        next if ( $opts{'service-group'} && ! grep { $_ eq $opts{'service-group'} } @{$service->{groups}} );
        next if ( $opts{'use-timeperiod'} && ! $service->{in_notification_period} );
        next if ( $opts{'skip-downtime'} && $service->{scheduled_downtime_depth} && $service->{scheduled_downtime_depth} > 0 );
        $status = $service->{state} if ( $service->{state} > $status );
        if ( $service->{state} != $ERRORS{OK} ) {
            $status_msg .= ', ' if ( $status_msg && $status_msg ne '' );
            $status_msg .= $host_name."(".$service->{description}."): ".$service->{plugin_output};
        }
    }
}

$status_msg = "$hosts_count host(s) checked" if ( $status_msg eq '' );

my $status_text = $STATUS_TEXT{$status};
print "$status_text: $status_msg\n";

exit($status);
