NTP Monitor

Problem this snippet solves:

Version 9 (tested on v9.2.4)

Based on F5's example monitor, with the NTP check added. We make sure that the node gives us an NTP response and that the node hasn't become stratum 16 (ie, it's lost it's source). We use the CPAN Net::NTP module to make things easy.

Just use it like a normal external monitor, it only uses the default IP and port.

Code :

#!/usr/bin/perl -w
###############################################################################
#                                                                             #
# F5 Networks and BIG/ip(c) Copyright                                         #
#                                                                             #
# No part of the software may be reproduced or transmitted in any form or by  #
# any means, electronic or mechanical, for any purpose, without express       #
# written permission of F5 Networks, Inc. It is against the law to copy the   #
# software. No part of this program may be reproduced or transmitted in any   #
# form or by any means, electronic or mechanical, including photocopying,     #
# recording, or information storage and retrieval systems, for any purpose    #
# other than the purchasers personal use, without the express written         #
# permission of F5 Networks, Inc. Copyright (c) 1996-2005 BIG/ip Software. All     #
# rights reserved. Our services are only available for legal users of the     #
# program for instance in case we extend our services by offering updating of #
# files through Internet.                                                     #
#                                                                             #
###############################################################################
#
#
# As for any external monitor program, the first two command
# line arguments are the node ip address and the node port.
# After that its whatever is supplied via the monitor template.
#
# Caveat: This does assume that you're using IPv4.
#

use lib "/shared/lib/perl5";
use strict;
use Net::NTP;
require 5.005;

# Derive and untaint programname.
my $programname = '/' . $0;
$programname =~ m/^.*\/([^\/]+)$/;
$programname = $1;

if ($programname eq '') {
    die "Bad data in program name\n"
}

# Process ID and file where it's to be stored.  The format
# is significant.

my $node = $ARGV[0];
$node =~ s/^::ffff://;
my $port = $ARGV[1];

my $pidfile = "/var/run/$programname.$node..$port.pid";
my $pid = "$$";

# Maintenence.  Clean up any existing EAV.

if (-f $pidfile ) {
    open(PID, "<$pidfile"); 
    my $pid = ; 
    close(PID);
    if ( $pid ) {
        chomp $pid; $pid =~ m/^(\d+)$/; $pid = $1;
        if ( $pid ) {
            kill 9, $pid;
        }
    }
    unlink($pidfile);
}

# Create a new maintenence file.

open(PID, ">$pidfile");
print PID $pid, "\n";
close(PID);

########################################3
##

if (try_ntp_test($node,$port)) {
        print "OK\n";
}

unlink($pidfile);
exit(0);

########


sub try_ntp_test {
        # we just make sure we get a response
        # and that the server isn't a stratum
        # 16 server (ie, it's lost it's time source).

        my ($node,$port) = @_;
        my %response;

        eval {
                %response = get_ntp_response($node,$port);
        };
        if ($@) {
                return 0;
        } else {
                if ($response{'Stratum'} =~ /\d+/) {
                        # if the stratum is a number
                        if ($response{'Stratum'} == 16) {
                                return 0;
                        } else {
                                # and it isn't 16
                                return 1;
                        }
                } else {
                        return 0;
                }
        }

}

Tested this on version:

11.0
Published Mar 12, 2015
Version 1.0

Was this article helpful?

23 Comments