#!/usr/bin/perl -w
# Check NTP status from timedatectl


use strict;
use Monitoring::Plugin;

$ENV{LC_ALL} = 'C';

my $plugin = Monitoring::Plugin->new( usage => '',);

my @ntp_status_text;
my $ntp_status_exit = OK;

if ( open (TDCTLSTATUS, "-|", "timedatectl status") ) {
	my $expected_keys = 2;
	my $found_keys = 0;
	while (<TDCTLSTATUS>) {
		my $line = $_;
		chomp($line);
		$line =~ s/^\s+//;
		$line =~ s/\s+$//;
		my ($key, $value) = split( /\s*:\s*/, $line );
		if ( $key eq 'System clock synchronized' ) {
			$found_keys++;
			if ( $value eq 'yes' ) {
				push @ntp_status_text, 'ntp synchronization enabled';
			} else {
				push @ntp_status_text, 'ntp synchronization disabled';
				$ntp_status_exit = CRITICAL;
			}
		} elsif ( $key eq 'NTP service' ) {
			$found_keys++;
			if ( $value eq 'active' ) {
				push @ntp_status_text, 'ntp service active';
			} else {
				push @ntp_status_text, 'ntp service inactive';
				$ntp_status_exit = CRITICAL;
			}
		}

	}
	unless ( $expected_keys == $found_keys ) {
		push @ntp_status_text, "missing attributes from timedatectl output";
		$ntp_status_exit = CRITICAL;
	}
	close(TDCTLSTATUS);
} else {
	push @ntp_status_text, "unable to get ntp status: $!";
	$ntp_status_exit = CRITICAL;
}

# NTP is enabled, check sync status
if ( $ntp_status_exit == OK ) {
    if ( `systemctl is-active systemd-timesyncd.service 2>&1` =~ m/^active$/ ) {

        if ( open (TDCTLSYNCSTATUS, "-|", "timedatectl timesync-status") ) {
            my $expected_keys = 1;
            my $found_keys = 0;
            while (<TDCTLSYNCSTATUS>) {
                my $line = lc($_);
                chomp($line);
                $line =~ s/^\s+//;
                $line =~ s/\s+$//;
                my ($key, $value) = split( /\s*:\s*/, $line );
                if ( $key eq 'leap' ) {
                    $found_keys++;
                    if ( $value eq 'normal' ) {
                        push @ntp_status_text, 'leap normal';
                    } else {
                        push @ntp_status_text, 'leap failure';
                        $ntp_status_exit = CRITICAL;
                    }
                }

            }
            close(TDCTLSYNCSTATUS);
            unless ( $expected_keys == $found_keys ) {
                push @ntp_status_text, "missing attributes from timedatectl output";
                $ntp_status_exit = CRITICAL;
            }
        } else {
            push @ntp_status_text, "unable to get ntp status: $!";
            $ntp_status_exit = CRITICAL;
        }

    } elsif ( `systemctl is-active chrony.service 2>&1` =~ m/^active$/  ) {
        if ( open (TDCTLSYNCSTATUS, "-|", "chronyc tracking") ) {
            my $expected_keys = 1;
            my $found_keys = 0;
            while (<TDCTLSYNCSTATUS>) {
                my $line = lc($_);
                chomp($line);
                $line =~ s/^\s+//;
                $line =~ s/\s+$//;
                my ($key, $value) = split( /\s*:\s*/, $line );
                if ( $key eq 'leap status' ) {
                    $found_keys++;
                    if ( $value eq 'normal' ) {
                        push @ntp_status_text, 'leap normal';
                    } else {
                        push @ntp_status_text, 'leap failure';
                        $ntp_status_exit = CRITICAL;
                    }
                }

            }
            close(TDCTLSYNCSTATUS);
            unless ( $expected_keys == $found_keys ) {
                push @ntp_status_text, "missing attributes from timedatectl output";
                $ntp_status_exit = CRITICAL;
            }
        } else {
            push @ntp_status_text, "unable to get ntp status: $!";
            $ntp_status_exit = CRITICAL;
        }
    } else {
        push @ntp_status_text, "no ntp client found";
        $ntp_status_exit = CRITICAL;
    }
}

$plugin->nagios_exit($ntp_status_exit, join('/', @ntp_status_text));
