From d84da4e2ec8569b8ff15356b6881df307c7333ca Mon Sep 17 00:00:00 2001 From: Nathan Vonnahme Date: Fri, 10 Nov 2006 01:26:16 +0000 Subject: * exposed Getopt and Threshold functionality from top level Nagios::Plugin * exchanged Class::Struct for Class::Accessor * POD is not updated yet. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/Nagios-Plugin/trunk@1536 f882894a-f735-0410-b71e-b25c423dba1c diff --git a/MANIFEST b/MANIFEST index f46acd9..7fe300f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -7,6 +7,7 @@ t/check_stuff.t t/Nagios-Plugin-01.t t/Nagios-Plugin-02.t t/Nagios-Plugin-03.t +t/Nagios-Plugin-04.t t/Nagios-Plugin-Functions-01.t t/Nagios-Plugin-Functions-02.t t/Nagios-Plugin-Getopt-01.t diff --git a/lib/Nagios/Plugin.pm b/lib/Nagios/Plugin.pm index 71d12ed..1fcd28a 100644 --- a/lib/Nagios/Plugin.pm +++ b/lib/Nagios/Plugin.pm @@ -1,30 +1,67 @@ -# This is only because Class::Struct doesn't allow subclasses -# Trick stolen from Class::DBI -###package Nagios::__::Plugin; - -use Class::Struct; -struct "Nagios::__::Plugin" => { - perfdata => '@', - shortname => '$', - messages => '%', - }; package Nagios::Plugin; use Nagios::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT @STATUS_CODES); +use Nagios::Plugin::Getopt; +use Nagios::Plugin::Threshold; +use Params::Validate qw(:all); use strict; use warnings; use Carp; +use base qw(Class::Accessor::Fast); + +# do we need all of these to be accessible? +Nagios::Plugin->mk_accessors(qw( + perfdata + messages + opts + threshold + )); use Exporter; -our @ISA = qw(Exporter Nagios::__::Plugin); +our @ISA = qw(Exporter); our @EXPORT = (@STATUS_CODES); our @EXPORT_OK = qw(%ERRORS); # Remember to update Nagios::Plugin::Functions as well! -our $VERSION = "0.14"; +our $VERSION = "0.15"; + +sub new { + my $class = shift; +# my %args = @_; + + my %args = validate( @_, { + shortname => 0, + usage => 1, + version => 0, + url => 0, + plugin => 0, + blurb => 0, + extra => 0, + license => 0, + timeout => 0 }, + ); + my $shortname = undef; + if (exists $args{shortname}) { + $shortname = $args{shortname}; + delete $args{shortname}; + } + my $self = { + shortname => $shortname, + perfdata => [], # to be added later + messages => { + warning => [], + critical => [], + ok => [] + }, + opts => new Nagios::Plugin::Getopt(%args), + threshold => undef, # defined later + }; + bless $self, $class; + return $self; +} sub add_perfdata { my ($self, %args) = @_; @@ -38,9 +75,9 @@ sub all_perfoutput { } sub set_thresholds { - shift; + my $self = shift; require Nagios::Plugin::Threshold; - Nagios::Plugin::Threshold->set_thresholds(@_); + return $self->threshold( Nagios::Plugin::Threshold->set_thresholds(@_)); } # NP::Functions wrappers @@ -56,14 +93,54 @@ sub die { my $self = shift; Nagios::Plugin::Functions::nagios_die(@_, { plugin => $self }); } + # Override default shortname accessor to add default sub shortname { my $self = shift; - $self->{'Nagios::__::Plugin::shortname'} = shift if @_; - return $self->{'Nagios::__::Plugin::shortname'} || + $self->{shortname} = shift if @_; + return $self->{shortname} || Nagios::Plugin::Functions::get_shortname(); } +# top level interface to Nagios::Plugin::Threshold +sub check_threshold { + my $self = shift; + + my %args; + + if ( $#_ == 0 && ! ref $_[0]) { # one positional param + %args = (check => shift); + } + else { + %args = validate ( @_, { # named params + check => 1, + warning => 0, + critical => 0, + } ); + } + + if (! $self->threshold || exists $args{warning} || exists $args{critical}) { + $self->set_thresholds( + warning => $args{warning} || $self->opts->warning , + critical => $args{critical} || $self->opts->critical , + ); + } + + + return $self->threshold->get_status($args{check}); +} + +# top level interface to my Nagios::Plugin::Getopt object +sub arg { + my $self = shift; + $self->opts->arg(@_); +} +sub getopts { + my $self = shift; + $self->opts->getopts(@_); +} + + # ------------------------------------------------------------------------- # NP::Functions::check_messages helpers and wrappers @@ -80,8 +157,8 @@ sub add_message { croak "Error code '$code' not supported by add_message" if $code eq 'unknown' || $code eq 'dependent'; - $self->messages($code, []) unless $self->messages($code); - push @{$self->messages($code)}, @messages; + $self->messages($code, []) unless $self->messages->{$code}; + push @{$self->messages->{$code}}, @messages; } sub check_messages { @@ -90,7 +167,7 @@ sub check_messages { # Add object messages to any passed in as args for my $code (qw(critical warning ok)) { - my $messages = $self->messages($code) || []; + my $messages = $self->messages->{$code} || []; if ($args{$code}) { unless (ref $args{$code} eq 'ARRAY') { if ($code eq 'ok') { @@ -123,9 +200,10 @@ __END__ Nagios::Plugin - a family of perl modules to streamline writing Nagios plugins - =head1 SYNOPSIS + # TODO NJV -- make this more like check_stuff. + # Constants OK, WARNING, CRITICAL, and UNKNOWN are exported by default # See also Nagios::Plugin::Functions for a functional interface use Nagios::Plugin; @@ -188,9 +266,7 @@ plugins # | size=36kB;10:25;25: time=... # Option handling methods (NOT YET IMPLEMENTED - use - # Nagios::Plugin::Getopt for now) - - + # Nagios::Plugin::Getopt for =head1 DESCRIPTION @@ -280,6 +356,7 @@ NOT YET IMPLEMENTED - use Nagios::Plugin::Threshold directly for now. =over 4 +=item check_threshold( $value ) =item check_threshold( check => $value, warning => $warn, critical => $crit ) =back @@ -382,6 +459,8 @@ section of the Nagios Plugin guidelines =head2 OPTION HANDLING METHODS +TODO + NOT YET IMPLEMENTED - use Nagios::Plugin::Getopt directly for now. @@ -426,9 +505,6 @@ http://nagiosplug.sourceforge.net. Originally by Ton Voon, Eton.voon@altinity.comE. -Nathan Vonnahme added extra tests and subsequent fixes. - - =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by Nagios Plugin Development Team diff --git a/lib/Nagios/Plugin/ExitResult.pm b/lib/Nagios/Plugin/ExitResult.pm index 191c92a..b161e9e 100644 --- a/lib/Nagios/Plugin/ExitResult.pm +++ b/lib/Nagios/Plugin/ExitResult.pm @@ -39,7 +39,7 @@ return codes when testing. $e = nagios_exit( CRITICAL, 'aiiii ...' ); print $e->message; print $e->return_code; - + # NP::ExitResult also stringifies to the message output like(nagios_exit( WARNING, 'foobar'), qr/^foo/, 'matches!'); diff --git a/lib/Nagios/Plugin/Functions.pm b/lib/Nagios/Plugin/Functions.pm index 5772c97..41ec27a 100644 --- a/lib/Nagios/Plugin/Functions.pm +++ b/lib/Nagios/Plugin/Functions.pm @@ -11,7 +11,7 @@ use File::Basename; use Params::Validate qw(validate :types); # Remember to update Nagios::Plugins as well -our $VERSION = "0.14"; +our $VERSION = "0.15"; our @STATUS_CODES = qw(OK WARNING CRITICAL UNKNOWN DEPENDENT); diff --git a/lib/Nagios/Plugin/Getopt.pm b/lib/Nagios/Plugin/Getopt.pm index 8a9fc1c..bbf1fc9 100644 --- a/lib/Nagios/Plugin/Getopt.pm +++ b/lib/Nagios/Plugin/Getopt.pm @@ -306,7 +306,7 @@ This documentation applies to version 0.01 of Nagios::Plugin::Getopt. use Nagios::Plugin::Getopt; - # Instantiate object (usage and version are mandatory) + # Instantiate object (usage is mandatory) $ng = Nagios::Plugin::Getopt->new( usage => "Usage: %s -H -w -c ", @@ -352,7 +352,7 @@ additional arguments to be easily defined. =head2 CONSTRUCTOR - # Instantiate object (usage and version are mandatory) + # Instantiate object (usage is mandatory) $ng = Nagios::Plugin::Getopt->new( usage => 'Usage: %s --hello', version => '0.01', diff --git a/t/Nagios-Plugin-01.t b/t/Nagios-Plugin-01.t index 9de5009..a73fce4 100644 --- a/t/Nagios-Plugin-01.t +++ b/t/Nagios-Plugin-01.t @@ -11,21 +11,26 @@ Nagios::Plugin::Functions::_fake_exit(1); diag "\nusing Nagios::Plugin revision ". $Nagios::Plugin::VERSION . "\n" if $ENV{TEST_VERBOSE}; -my $p = Nagios::Plugin->new; +my $p = Nagios::Plugin->new (usage => "dummy usage"); isa_ok( $p, "Nagios::Plugin"); $p->shortname("PAGESIZE"); -is($p->shortname, "PAGESIZE", "shortname set correctly"); +is($p->shortname, "PAGESIZE", "shortname explicitly set correctly"); -$p = Nagios::Plugin->new; +$p = Nagios::Plugin->new (usage => "dummy usage"); is($p->shortname, "NAGIOS-PLUGIN-01", "shortname should default on new"); -$p = Nagios::Plugin->new( shortname => "SIZE" ); +$p = Nagios::Plugin->new( shortname => "SIZE", usage => "dummy usage" ); is($p->shortname, "SIZE", "shortname set correctly on new"); diag "warn if < 10, critical if > 25 " if $ENV{TEST_VERBOSE}; my $t = $p->set_thresholds( warning => "10:25", critical => "~:25" ); +use Data::Dumper; +#diag "dumping p: ". Dumper $p; +#diag "dumping perfdata: ". Dumper $p->perfdata; + + $p->add_perfdata( label => "size", value => 1, @@ -34,6 +39,7 @@ $p->add_perfdata( ); cmp_ok( $p->all_perfoutput, 'eq', "size=1kB;10:25;~:25", "Perfdata correct"); +#diag "dumping perfdata: ". Dumper ($p->perfdata); my $expected = {qw( -1 WARNING diff --git a/t/Nagios-Plugin-02.t b/t/Nagios-Plugin-02.t index 360e180..15ae3d6 100644 --- a/t/Nagios-Plugin-02.t +++ b/t/Nagios-Plugin-02.t @@ -16,7 +16,7 @@ is(UNKNOWN, $ERRORS{UNKNOWN}, "UNKNOWN => $ERRORS{UNKNOWN}"); is(DEPENDENT, $ERRORS{DEPENDENT}, "DEPENDENT => $ERRORS{DEPENDENT}"); my $plugin = 'TEST_PLUGIN'; -my $np = Nagios::Plugin->new( shortname => $plugin ); +my $np = Nagios::Plugin->new( shortname => $plugin, usage => "dummy usage" ); is($np->shortname, $plugin, "shortname() is $plugin"); # Test nagios_exit( CONSTANT, $msg ), nagios_exit( $string, $msg ) @@ -151,7 +151,7 @@ for (@ok) { # shortname testing SKIP: { skip "requires File::Basename", 2 unless eval { require File::Basename }; - $np = Nagios::Plugin->new; + $np = Nagios::Plugin->new (usage => "dummy usage", version => "1"); $plugin = uc File::Basename::basename($0); $plugin =~ s/\..*$//; is($np->shortname, $plugin, "shortname() is '$plugin'"); diff --git a/t/Nagios-Plugin-03.t b/t/Nagios-Plugin-03.t index 0366156..0b7b8af 100644 --- a/t/Nagios-Plugin-03.t +++ b/t/Nagios-Plugin-03.t @@ -10,7 +10,7 @@ BEGIN { Nagios::Plugin::Functions::_fake_exit(1); my $plugin = 'NP_CHECK_MESSAGES_03'; -my $np = Nagios::Plugin->new( shortname => $plugin ); +my $np = Nagios::Plugin->new( shortname => $plugin, usage => "dummy usage" ); is($np->shortname, $plugin, "shortname() is $plugin"); my ($code, $message); @@ -172,33 +172,33 @@ is($message, 'D E F', "join_all '$join_all' (critical, warning) message is $mess # add_messages # Constant codes -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( CRITICAL, "A B C" ); $np->add_message( WARNING, "D E F" ); ($code, $message) = $np->check_messages(); is($code, CRITICAL, "(CRITICAL, WARNING) code is $STATUS_TEXT{$code}"); is($message, $messages{critical}, "(CRITICAL, WARNING) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( CRITICAL, "A B C" ); ($code, $message) = $np->check_messages(); is($code, CRITICAL, "(CRITICAL) code is $STATUS_TEXT{$code}"); is($message, $messages{critical}, "(CRITICAL) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( WARNING, "D E F" ); ($code, $message) = $np->check_messages(); is($code, WARNING, "(WARNING) code is $STATUS_TEXT{$code}"); is($message, $messages{warning}, "(WARNING) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( WARNING, "D E F" ); $np->add_message( OK, "G H I" ); ($code, $message) = $np->check_messages(); is($code, WARNING, "(WARNING, OK) code is $STATUS_TEXT{$code}"); is($message, $messages{warning}, "(WARNING, OK) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( OK, "G H I" ); ($code, $message) = $np->check_messages(); is($code, OK, "(OK) code is $STATUS_TEXT{$code}"); @@ -206,33 +206,33 @@ is($message, $messages{ok}, "(OK) message is $message"); # String codes -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( critical => "A B C" ); $np->add_message( warning => "D E F" ); ($code, $message) = $np->check_messages(); is($code, CRITICAL, "(critical, warning) code is $STATUS_TEXT{$code}"); is($message, $messages{critical}, "(critical, warning) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( critical => "A B C" ); ($code, $message) = $np->check_messages(); is($code, CRITICAL, "(critical) code is $STATUS_TEXT{$code}"); is($message, $messages{critical}, "(critical) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( warning => "D E F" ); ($code, $message) = $np->check_messages(); is($code, WARNING, "(warning) code is $STATUS_TEXT{$code}"); is($message, $messages{warning}, "(warning) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( warning => "D E F" ); $np->add_message( ok => "G H I" ); ($code, $message) = $np->check_messages(); is($code, WARNING, "(warning, ok) code is $STATUS_TEXT{$code}"); is($message, $messages{warning}, "(warning, ok) message is $message"); -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); $np->add_message( ok => "G H I" ); ($code, $message) = $np->check_messages(); is($code, OK, "(ok) code is $STATUS_TEXT{$code}"); @@ -240,7 +240,7 @@ is($message, $messages{ok}, "(ok) message is $message"); # No add_message -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); ($code, $message) = $np->check_messages(); is($code, OK, "() code is $STATUS_TEXT{$code}"); is($message, '', "() message is ''"); @@ -250,7 +250,7 @@ is($message, '', "() message is ''"); # Error conditions # add_message errors -$np = Nagios::Plugin->new; +$np = Nagios::Plugin->new (usage => "dummy usage"); ok(! defined eval { $np->add_message( foobar => 'hi mum' ) }, 'add_message dies on invalid code'); ok(! defined eval { $np->add_message( OKAY => 'hi mum' ) }, diff --git a/t/check_stuff.pl b/t/check_stuff.pl index 51f551f..889e484 100755 --- a/t/check_stuff.pl +++ b/t/check_stuff.pl @@ -18,32 +18,25 @@ use strict; use warnings; -use Nagios::Plugin qw(%ERRORS); - -use Nagios::Plugin::Getopt; - +use Nagios::Plugin ; use vars qw($VERSION $PROGNAME $verbose $warn $critical $timeout $result); '$Revision$' =~ /^.*(\d+.\d+) \$$/; # Use The Revision from RCS/CVS/Subversion $VERSION = $1; -$0 =~ m!^.*/([^/]+)$!; -$PROGNAME = $1; -# shortname is the identifier this script will give to Nagios. -# it's set here to the uppercase program name with file extension removed, -# e.g. check_stuff.pl -> CHECK_STUFF -my $short_name = uc $PROGNAME; -$short_name =~ s/\.\w+$//; +# get the base name of this script for use in the examples +use File::Basename; +$PROGNAME = basename($0); ############################################################################## # define and get the command line options. # see the command line option guidelines at -# +# http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOPTIONS -# Instantiate Nagios::Plugin::Getopt object (usage and version are mandatory) -my $nagopts = Nagios::Plugin::Getopt->new( +# Instantiate Nagios::Plugin object (the 'usage' parameter is mandatory) +my $p = Nagios::Plugin->new( usage => "Usage: %s [ -v|--verbose ] [-H ] [-t ] [ -c|--critical= ] [ -w|--warning= ] @@ -51,7 +44,7 @@ my $nagopts = Nagios::Plugin::Getopt->new( version => $VERSION, blurb => 'This plugin is an example of a Nagios plugin written in Perl using the Nagios::Plugin modules. It will generate a random integer between 1 and 20 (though you can specify the number with the -n option for testing), and will output OK, WARNING or CRITICAL if the resulting number is outside the specified thresholds.', - extra => qq{ + extra => " THRESHOLDs for -w and -c are specified 'min:max' or 'min:' or ':max' (or 'max'). If specified '\@min:max', a warning status will be generated @@ -70,16 +63,14 @@ Examples: Returns a warning if the resulting number is less than 10, or a critical error if it is less than 4. - -} - +" ); # Define and document the valid command line options # usage, help, version, timeout and verbose are defined by default. -$nagopts->arg( +$p->arg( spec => 'warning|w=s', help => @@ -91,17 +82,15 @@ qq{-w, --warning=INTEGER:INTEGER # default => 10, ); -$nagopts->arg( +$p->arg( spec => 'critical|c=s', help => qq{-c, --critical=INTEGER:INTEGER Minimum and maximum number of the generated result, outside of - which a critical will be generated. If omitted, a critical is - generated if no processes are running.}, - + which a critical will be generated. }, ); -$nagopts->arg( +$p->arg( spec => 'result|r=f', help => qq{-r, --result=INTEGER @@ -110,59 +99,41 @@ qq{-r, --result=INTEGER ); # Parse arguments and process standard ones (e.g. usage, help, version) -$nagopts->getopts; - +$p->getopts; -my $p = Nagios::Plugin->new; -$p->shortname($short_name); - - -# sanity checking on command line options -if ( (defined $nagopts->result) && ($nagopts->result < 0 || $nagopts->result > 20) ) { - $p->die( - return_code => $ERRORS{UNKNOWN}, - message => 'invalid number supplied for the -r option' - ); +# perform sanity checking on command line options +if ( (defined $p->opts->result) && ($p->opts->result < 0 || $p->opts->result > 20) ) { + $p->nagios_die( "invalid number supplied for the -r option" ); } -unless ( defined $nagopts->warning || defined $nagopts->critical ) { - $p->die( - return_code => $ERRORS{UNKNOWN}, - message => "you didn't supply a threshold argument" - ); +unless ( defined $p->opts->warning || defined $p->opts->critical ) { + $p->nagios_die( "you didn't supply a threshold argument" ); } -############################################################################## -# define a Nagios::Threshold object based on the command line options -my $t = $p->set_thresholds( warning => $nagopts->warning, critical => $nagopts->critical ); ############################################################################## # check stuff. # THIS is where you'd do your actual checking to get a real value for $result -# don't forget to timeout after $nagopts->timeout seconds, if applicable. +# don't forget to timeout after $p->opts->timeout seconds, if applicable. my $result; -if (defined $nagopts->result) { - $result = $nagopts->result; - print "using supplied result $result from command line\n" if $nagopts->verbose; +if (defined $p->opts->result) { # you got a 'result' option from the command line options + $result = $p->opts->result; + print "using supplied result $result from command line\n" if $p->opts->verbose; } else { $result = int rand(20)+1; - print "generated random result $result\n" if $nagopts->verbose; + print "generated random result $result\n" if $p->opts->verbose; } -print "status of result ($result) is ", $t->get_status($result), "\n" - if $nagopts->verbose; - - - ############################################################################## +# check the result against the defined warning and critical thresholds, # output the result and exit -$p->die( - return_code => $t->get_status($result), +$p->nagios_exit( + return_code => $p->check_threshold($result), message => "sample result was $result" ); diff --git a/t/check_stuff.t b/t/check_stuff.t index a748605..2d2ce38 100755 --- a/t/check_stuff.t +++ b/t/check_stuff.t @@ -8,7 +8,7 @@ my ($r,$args); my $s = 't/check_stuff.pl'; $s = 'perl -Ilib '.$s; -my $n = 'CHECK_STUFF'; +my $n = 'STUFF'; # Nagios status strings and exit codes my %e = qw( -- cgit v0.10-9-g596f