From b418181dfe80dd75169b6e8a619ac1932155dea2 Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Mon, 20 Jan 2014 00:54:34 +0100 Subject: renamed module into Monitoring::Plugin since the complete monitoring team has been renamed, we also rename this module. Signed-off-by: Sven Nierlein --- lib/Nagios/Plugin.pm | 697 ------------------------------- lib/Nagios/Plugin/Config.pm | 174 -------- lib/Nagios/Plugin/ExitResult.pm | 67 --- lib/Nagios/Plugin/Functions.pm | 446 -------------------- lib/Nagios/Plugin/Getopt.pm | 873 --------------------------------------- lib/Nagios/Plugin/Performance.pm | 294 ------------- lib/Nagios/Plugin/Range.pm | 169 -------- lib/Nagios/Plugin/Threshold.pm | 134 ------ 8 files changed, 2854 deletions(-) delete mode 100644 lib/Nagios/Plugin.pm delete mode 100644 lib/Nagios/Plugin/Config.pm delete mode 100644 lib/Nagios/Plugin/ExitResult.pm delete mode 100644 lib/Nagios/Plugin/Functions.pm delete mode 100644 lib/Nagios/Plugin/Getopt.pm delete mode 100644 lib/Nagios/Plugin/Performance.pm delete mode 100644 lib/Nagios/Plugin/Range.pm delete mode 100644 lib/Nagios/Plugin/Threshold.pm (limited to 'lib/Nagios') diff --git a/lib/Nagios/Plugin.pm b/lib/Nagios/Plugin.pm deleted file mode 100644 index d85d35a..0000000 --- a/lib/Nagios/Plugin.pm +++ /dev/null @@ -1,697 +0,0 @@ - -package Nagios::Plugin; - -use Nagios::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT @STATUS_CODES); -use Params::Validate qw(:all); - -use strict; -use warnings; - -use Carp; -use base qw(Class::Accessor::Fast); - -Nagios::Plugin->mk_accessors(qw( - shortname - perfdata - messages - opts - threshold - )); - -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = (@STATUS_CODES); -our @EXPORT_OK = qw(%ERRORS %STATUS_TEXT); - -# CPAN stupidly won't index this module without a literal $VERSION here, -# so we're forced to duplicate it explicitly -# Make sure you update $Nagios::Plugin::Functions::VERSION too -our $VERSION = "0.36"; - -sub new { - my $class = shift; -# my %args = @_; - - my %args = validate( @_, - { - shortname => 0, - usage => 0, - version => 0, - url => 0, - plugin => 0, - blurb => 0, - extra => 0, - license => 0, - timeout => 0 - }, - ); - - my $shortname = Nagios::Plugin::Functions::get_shortname(\%args); - delete $args{shortname} if (exists $args{shortname}); - my $self = { - shortname => $shortname, - perfdata => [], # to be added later - messages => { - warning => [], - critical => [], - ok => [] - }, - opts => undef, # see below - threshold => undef, # defined later - }; - bless $self, $class; - if (exists $args{usage}) { - require Nagios::Plugin::Getopt; - $self->opts( new Nagios::Plugin::Getopt(%args) ); - } - return $self; -} - -sub add_perfdata { - my ($self, %args) = @_; - require Nagios::Plugin::Performance; - my $perf = Nagios::Plugin::Performance->new(%args); - push @{$self->perfdata}, $perf; -} -sub all_perfoutput { - my $self = shift; - return join(" ", map {$_->perfoutput} (@{$self->perfdata})); -} - -sub set_thresholds { - my $self = shift; - require Nagios::Plugin::Threshold; - return $self->threshold( Nagios::Plugin::Threshold->set_thresholds(@_)); -} - -# NP::Functions wrappers -sub nagios_exit { - my $self = shift; - Nagios::Plugin::Functions::nagios_exit(@_, { plugin => $self }); -} -sub nagios_die { - my $self = shift; - Nagios::Plugin::Functions::nagios_die(@_, { plugin => $self }); -} -sub die { - my $self = shift; - Nagios::Plugin::Functions::nagios_die(@_, { plugin => $self }); -} -sub max_state { - Nagios::Plugin::Functions::max_state(@_); -} -sub max_state_alt { - Nagios::Plugin::Functions::max_state_alt(@_); -} - -# top level interface to Nagios::Plugin::Threshold -sub check_threshold { - my $self = shift; - - my %args; - - if ( $#_ == 0 && (! ref $_[0] || ref $_[0] eq "ARRAY" )) { # one positional param - %args = (check => shift); - } - else { - %args = validate ( @_, { # named params - check => 1, - warning => 0, - critical => 0, - } ); - } - - # in order of preference, get warning and critical from - # 1. explicit arguments to check_threshold - # 2. previously explicitly set threshold object - # 3. implicit options from Getopts object - if ( exists $args{warning} || exists $args{critical} ) { - $self->set_thresholds( - warning => $args{warning}, - critical => $args{critical}, - ); - } - elsif ( defined $self->threshold ) { - # noop - } - elsif ( defined $self->opts ) { - $self->set_thresholds( - warning => $self->opts->warning, - critical => $self->opts->critical, - ); - } - else { - return UNKNOWN; - } - - return $self->threshold->get_status($args{check}); -} - -# top level interface to my Nagios::Plugin::Getopt object -sub add_arg { - my $self = shift; - $self->opts->arg(@_) if $self->_check_for_opts; -} -sub getopts { - my $self = shift; - $self->opts->getopts(@_) if $self->_check_for_opts; -} - -sub _check_for_opts { - my $self = shift; - croak - "You have to supply a 'usage' param to Nagios::Plugin::new() if you want to use Getopts from your Nagios::Plugin object." - unless ref $self->opts() eq 'Nagios::Plugin::Getopt'; - return $self; -} - - - -# ------------------------------------------------------------------------- -# NP::Functions::check_messages helpers and wrappers - -sub add_message { - my $self = shift; - my ($code, @messages) = @_; - - croak "Invalid error code '$code'" - unless defined($ERRORS{uc $code}) || defined($STATUS_TEXT{$code}); - - # Store messages using strings rather than numeric codes - $code = $STATUS_TEXT{$code} if $STATUS_TEXT{$code}; - $code = lc $code; - 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; -} - -sub check_messages { - my $self = shift; - my %args = @_; - - # Add object messages to any passed in as args - for my $code (qw(critical warning ok)) { - my $messages = $self->messages->{$code} || []; - if ($args{$code}) { - unless (ref $args{$code} eq 'ARRAY') { - if ($code eq 'ok') { - $args{$code} = [ $args{$code} ]; - } else { - croak "Invalid argument '$code'" - } - } - push @{$args{$code}}, @$messages; - } - else { - $args{$code} = $messages; - } - } - - Nagios::Plugin::Functions::check_messages(%args); -} - -# ------------------------------------------------------------------------- - -1; - -#vim:et:sw=4 - -__END__ - -=head1 NAME - -Nagios::Plugin - A family of perl modules to streamline writing Nagios -plugins - -=head1 SYNOPSIS - - # Constants OK, WARNING, CRITICAL, and UNKNOWN are exported by default - # See also Nagios::Plugin::Functions for a functional interface - use Nagios::Plugin; - - # Constructor - $np = Nagios::Plugin->new; # OR - $np = Nagios::Plugin->new( shortname => "PAGESIZE" ); # OR - - - # use Nagios::Plugin::Getopt to process the @ARGV command line options: - # --verbose, --help, --usage, --timeout and --host are defined automatically. - $np = Nagios::Plugin->new( - usage => "Usage: %s [ -v|--verbose ] [-H ] [-t ] " - . "[ -c|--critical= ] [ -w|--warning= ]", - ); - - # add valid command line options and build them into your usage/help documentation. - $np->add_arg( - spec => 'warning|w=s', - help => '-w, --warning=INTEGER:INTEGER . See ' - . 'http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT ' - . 'for the threshold format. ', - ); - - # Parse @ARGV and process standard arguments (e.g. usage, help, version) - $np->getopts; - - - # Exit/return value methods - nagios_exit( CODE, MESSAGE ), - # nagios_die( MESSAGE, [CODE]) - $page = retrieve_page($page1) - or $np->nagios_exit( UNKNOWN, "Could not retrieve page" ); - # Return code: 3; - # output: PAGESIZE UNKNOWN - Could not retrieve page - test_page($page) - or $np->nagios_exit( CRITICAL, "Bad page found" ); - - # nagios_die() is just like nagios_exit(), but return code defaults - # to UNKNOWN - $page = retrieve_page($page2) - or $np->nagios_die( "Could not retrieve page" ); - # Return code: 3; - # output: PAGESIZE UNKNOWN - Could not retrieve page - - # Threshold methods - $code = $np->check_threshold( - check => $value, - warning => $warning_threshold, - critical => $critical_threshold, - ); - $np->nagios_exit( $code, "Threshold check failed" ) if $code != OK; - - - # Message methods (EXPERIMENTAL AND SUBJECT TO CHANGE) - - # add_message( CODE, $message ); check_messages() - for (@collection) { - if (m/Error/) { - $np->add_message( CRITICAL, $_ ); - } else { - $np->add_message( OK, $_ ); - } - } - ($code, $message) = $np->check_messages(); - nagios_exit( $code, $message ); - # If any items in collection matched m/Error/, returns CRITICAL and - # the joined set of Error messages; otherwise returns OK and the - # joined set of ok messages - - - # Perfdata methods - $np->add_perfdata( - label => "size", - value => $value, - uom => "kB", - threshold => $threshold, - ); - $np->add_perfdata( label => "time", ... ); - $np->nagios_exit( OK, "page size at http://... was ${value}kB" ); - # Return code: 0; - # output: PAGESIZE OK - page size at http://... was 36kB \ - # | size=36kB;10:25;25: time=... - - -=head1 DESCRIPTION - -Nagios::Plugin and its associated Nagios::Plugin::* modules are a -family of perl modules to streamline writing Nagios plugins. The main -end user modules are Nagios::Plugin, providing an object-oriented -interface to the entire Nagios::Plugin::* collection, and -Nagios::Plugin::Functions, providing a simpler functional interface to -a useful subset of the available functionality. - -The purpose of the collection is to make it as simple as possible for -developers to create plugins that conform the Nagios Plugin guidelines -(http://nagiosplug.sourceforge.net/developer-guidelines.html). - - -=head2 EXPORTS - -Nagios status code constants are exported by default: - - OK - WARNING - CRITICAL - UNKNOWN - DEPENDENT - -The following variables are also exported on request: - -=over 4 - -=item %ERRORS - -A hash mapping error strings ("CRITICAL", "UNKNOWN", etc.) to the -corresponding status code. - -=item %STATUS_TEXT - -A hash mapping status code constants (OK, WARNING, CRITICAL, etc.) to the -corresponding error string ("OK", "WARNING, "CRITICAL", etc.) i.e. the -reverse of %ERRORS. - -=back - - -=head2 CONSTRUCTOR - - Nagios::Plugin->new; - - Nagios::Plugin->new( shortname => 'PAGESIZE' ); - - Nagios::Plugin->new( - usage => "Usage: %s [ -v|--verbose ] [-H ] [-t ] - [ -c|--critical= ] [ -w|--warning= ] ", - version => $VERSION, - blurb => $blurb, - extra => $extra, - url => $url, - license => $license, - plugin => basename $0, - timeout => 15, - ); - -Instantiates a new Nagios::Plugin object. Accepts the following named -arguments: - -=over 4 - -=item shortname - -The 'shortname' for this plugin, used as the first token in the plugin -output by the various exit methods. Default: uc basename $0. - -=item usage ("Usage: %s --foo --bar") - -Passing a value for the usage() argument makes Nagios::Plugin -instantiate its own C object so you can start -doing command line argument processing. See -L for more about "usage" and the -following options: - -=item version - -=item url - -=item blurb - -=item license - -=item extra - -=item plugin - -=item timeout - -=back - -=head2 OPTION HANDLING METHODS - -C provides these methods for accessing the functionality in C. - -=over 4 - -=item add_arg - -Examples: - - # Define --hello argument (named parameters) - $plugin->add_arg( - spec => 'hello=s', - help => "--hello\n Hello string", - required => 1, - ); - - # Define --hello argument (positional parameters) - # Parameter order is 'spec', 'help', 'default', 'required?' - $plugin->add_arg('hello=s', "--hello\n Hello string", undef, 1); - -See L for more details. - -=item getopts() - -Parses and processes the command line options you've defined, -automatically doing the right thing with help/usage/version arguments. - -See L for more details. - -=item opts() - -Assuming you've instantiated it by passing 'usage' to new(), opts() -returns the Nagios::Plugin object's C object, -with which you can do lots of great things. - -E.g. - - if ( $plugin->opts->verbose ) { - print "yah yah YAH YAH YAH!!!"; - } - - # start counting down to timeout - alarm $plugin->opts->timeout; - your_long_check_step_that_might_time_out(); - - # access any of your custom command line options, - # assuming you've done these steps above: - # $plugin->add_arg('my_argument=s', '--my_argument [STRING]'); - # $plugin->getopts; - print $plugin->opts->my_argument; - -Again, see L. - -=back - -=head2 EXIT METHODS - -=over 4 - -=item nagios_exit( , $message ) - -Exit with return code CODE, and a standard nagios message of the -form "SHORTNAME CODE - $message". - -=item nagios_die( $message, [] ) - -Same as nagios_exit(), except that CODE is optional, defaulting -to UNKNOWN. NOTE: exceptions are not raised by default to calling code. -Set C<$_use_die> flag if this functionality is required (see test code). - -=item die( $message, [] ) - -Alias for nagios_die(). Deprecated. - -=item max_state, max_state_alt - -These are wrapper function for Nagios::Plugin::Functions::max_state and -Nagios::Plugin::Functions::max_state_alt. - -=back - -=head2 THRESHOLD METHODS - -These provide a top level interface to the -C module; for more details, see -L and L. - -=over 4 - -=item check_threshold( $value ) - -=item check_threshold( check => $value, warning => $warn, critical => $crit ) - -Evaluates $value against the thresholds and returns OK, CRITICAL, or -WARNING constant. The thresholds may be: - -1. explicitly set by passing 'warning' and/or 'critical' parameters to - C, or, - -2. explicitly set by calling C before C, or, - -3. implicitly set by command-line parameters -w, -c, --critical or - --warning, if you have run C<< $plugin->getopts() >>. - -You can specify $value as an array of values and each will be checked against -the thresholds. - -The return value is ready to pass to C , e . g ., - - $p->nagios_exit( - return_code => $p->check_threshold($result), - message => " sample result was $result" - ); - - -=item set_thresholds(warning => "10:25", critical => "~:25") - -Sets the acceptable ranges and creates the plugin's -Nagios::Plugins::Threshold object. See -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT -for details and examples of the threshold format. - -=item threshold() - -Returns the object's C object, if it has -been defined by calling set_thresholds(). You can pass a new -Threshold object to it to replace the old one too, but you shouldn't -need to do that from a plugin script. - -=back - -=head2 MESSAGE METHODS - -EXPERIMENTAL AND SUBJECT TO CHANGE - -add_messages and check_messages are higher-level convenience methods to add -and then check a set of messages, returning an appropriate return code -and/or result message. They are equivalent to maintaining a set of @critical, -@warning, and and @ok message arrays (add_message), and then doing a final -if test (check_messages) like this: - - if (@critical) { - nagios_exit( CRITICAL, join(' ', @critical) ); - } - elsif (@warning) { - nagios_exit( WARNING, join(' ', @warning) ); - } - else { - nagios_exit( OK, join(' ', @ok) ); - } - -=over 4 - -=item add_message( , $message ) - -Add a message with CODE status to the object. May be called multiple times. -The messages added are checked by check_messages, following. - -Only CRITICAL, WARNING, and OK are accepted as valid codes. - - -=item check_messages() - -Check the current set of messages and return an appropriate nagios return -code and/or a result message. In scalar context, returns only a return -code; in list context returns both a return code and an output message, -suitable for passing directly to nagios_exit() e.g. - - $code = $np->check_messages; - ($code, $message) = $np->check_messages; - -check_messages returns CRITICAL if any critical messages are found, WARNING -if any warning messages are found, and OK otherwise. The message returned -in list context defaults to the joined set of error messages; this may be -customised using the arguments below. - -check_messages accepts the following named arguments (none are required): - -=over 4 - -=item join => SCALAR - -A string used to join the relevant array to generate the message -string returned in list context i.e. if the 'critical' array @crit -is non-empty, check_messages would return: - - join( $join, @crit ) - -as the result message. Default: ' ' (space). - -=item join_all => SCALAR - -By default, only one set of messages are joined and returned in the -result message i.e. if the result is CRITICAL, only the 'critical' -messages are included in the result; if WARNING, only the 'warning' -messages are included; if OK, the 'ok' messages are included (if -supplied) i.e. the default is to return an 'errors-only' type -message. - -If join_all is supplied, however, it will be used as a string to -join the resultant critical, warning, and ok messages together i.e. -all messages are joined and returned. - -=item critical => ARRAYREF - -Additional critical messages to supplement any passed in via add_message(). - -=item warning => ARRAYREF - -Additional warning messages to supplement any passed in via add_message(). - -=item ok => ARRAYREF | SCALAR - -Additional ok messages to supplement any passed in via add_message(). - -=back - -=back - - -=head2 PERFORMANCE DATA METHODS - -=over 4 - -=item add_perfdata( label => "size", value => $value, uom => "kB", threshold => $threshold ) - -Add a set of performance data to the object. May be called multiple times. -The performance data is included in the standard plugin output messages by -the various exit methods. - -See the Nagios::Plugin::Performance documentation for more information on -performance data and the various field definitions, as well as the relevant -section of the Nagios Plugin guidelines -(http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN202). - -=back - - -=head1 EXAMPLES - -"Enough talk! Show me some examples!" - -See the file 'check_stuff.pl' in the 't' directory included with the -Nagios::Plugin distribution for a complete working example of a plugin -script. - - -=head1 VERSIONING - -The Nagios::Plugin::* modules are currently experimental and so the -interfaces may change up until Nagios::Plugin hits version 1.0, although -every attempt will be made to keep them as backwards compatible as -possible. - - -=head1 SEE ALSO - -See L for a simple functional interface to a subset -of the available Nagios::Plugin functionality. - -See also L, L, -L, L, and -L. - -The Nagios Plugin project page is at http://nagiosplug.sourceforge.net. - - -=head1 BUGS - -Please report bugs in these modules to the Nagios Plugin development team: -nagiosplug-devel@lists.sourceforge.net. - - -=head1 AUTHOR - -Maintained by the Nagios Plugin development team - -http://nagiosplug.sourceforge.net. - -Originally by Ton Voon, Eton.voon@altinity.comE. - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2006 by Nagios Plugin Development Team - -This library is free software; you can redistribute it and/or modify it -under the same terms as Perl itself, either Perl version 5.8.4 or, at your -option, any later version of Perl 5 you may have available. - -=cut - diff --git a/lib/Nagios/Plugin/Config.pm b/lib/Nagios/Plugin/Config.pm deleted file mode 100644 index dd270e9..0000000 --- a/lib/Nagios/Plugin/Config.pm +++ /dev/null @@ -1,174 +0,0 @@ -package Nagios::Plugin::Config; - -use strict; -use Carp; -use File::Spec; -use base qw(Config::Tiny); - -my $FILENAME1 = 'plugins.ini'; -my $FILENAME2 = 'nagios-plugins.ini'; -my $CURRENT_FILE = undef; - -# Config paths ending in nagios (search for $FILENAME1) -my @NAGIOS_CONFIG_PATH = qw(/etc/nagios /usr/local/nagios/etc /usr/local/etc/nagios /etc/opt/nagios); -# Config paths not ending in nagios (search for $FILENAME2) -my @CONFIG_PATH = qw(/etc /usr/local/etc /etc/opt); - -# Override Config::Tiny::read to default the filename, if not given -sub read -{ - my $class = shift; - - unless ($_[0]) { - SEARCH: { - if ($ENV{NAGIOS_CONFIG_PATH}) { - for (split /:/, $ENV{NAGIOS_CONFIG_PATH}) { - my $file = File::Spec->catfile($_, $FILENAME1); - unshift(@_, $file), last SEARCH if -f $file; - $file = File::Spec->catfile($_, $FILENAME2); - unshift(@_, $file), last SEARCH if -f $file; - } - } - for (@NAGIOS_CONFIG_PATH) { - my $file = File::Spec->catfile($_, $FILENAME1); - unshift(@_, $file), last SEARCH if -f $file; - } - for (@CONFIG_PATH) { - my $file = File::Spec->catfile($_, $FILENAME2); - unshift(@_, $file), last SEARCH if -f $file; - } - } - - # Use die instead of croak, so we can pass a clean message downstream - die "Cannot find '$FILENAME1' or '$FILENAME2' in any standard location.\n" unless $_[0]; - } - - $CURRENT_FILE = $_[0]; - $class->SUPER::read( @_ ); -} - -# Straight from Config::Tiny - only changes are repeated property key support -# Would be nice if we could just override the per-line handling ... -sub read_string -{ - my $class = ref $_[0] ? ref shift : shift; - my $self = bless {}, $class; - return undef unless defined $_[0]; - - # Parse the file - my $ns = '_'; - my $counter = 0; - foreach ( split /(?:\015{1,2}\012|\015|\012)/, shift ) { - $counter++; - - # Skip comments and empty lines - next if /^\s*(?:\#|\;|$)/; - - # Handle section headers - if ( /^\s*\[\s*(.+?)\s*\]\s*$/ ) { - # Create the sub-hash if it doesn't exist. - # Without this sections without keys will not - # appear at all in the completed struct. - $self->{$ns = $1} ||= {}; - next; - } - - # Handle properties - if ( /^\s*([^=]+?)\s*=\s*(.*?)\s*$/ ) { - push @{$self->{$ns}->{$1}}, $2; - next; - } - - return $self->_error( "Syntax error at line $counter: '$_'" ); - } - - $self; -} - -sub write { croak "Write access not permitted" } - -# Return last file used by read(); -sub np_getfile { return $CURRENT_FILE; } - -1; - -=head1 NAME - -Nagios::Plugin::Config - read nagios plugin .ini style config files - -=head1 SYNOPSIS - - # Read given nagios plugin config file - $Config = Nagios::Plugin::Config->read( '/etc/nagios/plugins.ini' ); - - # Search for and read default nagios plugin config file - $Config = Nagios::Plugin::Config->read(); - - # Access sections and properties (returns scalars or arrayrefs) - $rootproperty = $Config->{_}->{rootproperty}; - $one = $Config->{section}->{one}; - $Foo = $Config->{section}->{Foo}; - -=head1 DESCRIPTION - -Nagios::Plugin::Config is a subclass of the excellent Config::Tiny, -with the following changes: - -=over 4 - -=item - -Repeated keys are allowed within sections, returning lists instead of scalars - -=item - -Write functionality has been removed i.e. access is read only - -=item - -Nagios::Plugin::Config searches for a default nagios plugins file if no explicit -filename is given to C. The current standard locations checked are: - -=over 4 - -=item /etc/nagios/plugins.ini - -=item /usr/local/nagios/etc/plugins.ini - -=item /usr/local/etc/nagios /etc/opt/nagios/plugins.ini - -=item /etc/nagios-plugins.ini - -=item /usr/local/etc/nagios-plugins.ini - -=item /etc/opt/nagios-plugins.ini - -=back - -To use a custom location, set a C environment variable -to the set of directories that should be checked. The first C or -C file found will be used. - -=back - - -=head1 SEE ALSO - -L, L - - -=head1 AUTHORS - -This code is maintained by the Nagios Plugin Development Team: -L. - - -=head1 COPYRIGHT and LICENCE - -Copyright (C) 2006-2007 by Nagios Plugin Development Team - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. - -=cut - diff --git a/lib/Nagios/Plugin/ExitResult.pm b/lib/Nagios/Plugin/ExitResult.pm deleted file mode 100644 index b161e9e..0000000 --- a/lib/Nagios/Plugin/ExitResult.pm +++ /dev/null @@ -1,67 +0,0 @@ -# Tiny helper class to return both output and return_code when testing - -package Nagios::Plugin::ExitResult; - -use strict; - -# Stringify to message -use overload '""' => sub { shift->{message} }; - -# Constructor -sub new { - my $class = shift; - return bless { return_code => $_[0], message => $_[1] }, $class; -} - -# Accessors -sub message { shift->{message} } -sub return_code { shift->{return_code} } -sub code { shift->{return_code} } - -1; - -__END__ - -=head1 NAME - -Nagios::Plugin::ExitResult - Helper class for returning both output and -return codes when testing. - -=head1 SYNOPSIS - - use Test::More; - use Nagios::Plugin::Functions; - - # In a test file somewhere - Nagios::Plugin::Functions::_fake_exit(1); - - # Later ... - $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!'); - - - -=head1 DESCRIPTION - -Nagios::Plugin::ExitResult is a tiny helper class intended for use -when testing other Nagios::Plugin modules. A Nagios::Plugin::ExitResult -object is returned by nagios_exit() and friends when -Nagios::Plugin::Functions::_fake_exit has been set, instead of doing a -conventional print + exit. - -=head1 AUTHOR - -Gavin Carr , Egavin@openfusion.com.auE - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2006 by Nagios Plugin Development Team - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. - -=cut diff --git a/lib/Nagios/Plugin/Functions.pm b/lib/Nagios/Plugin/Functions.pm deleted file mode 100644 index 14fe661..0000000 --- a/lib/Nagios/Plugin/Functions.pm +++ /dev/null @@ -1,446 +0,0 @@ -# Functional interface to basic Nagios::Plugin constants, exports, -# and functions - -package Nagios::Plugin::Functions; - -use 5.006; - -use strict; -use warnings; -use File::Basename; -use Params::Validate qw(:types validate); -use Math::Calc::Units; - -# Remember to update Nagios::Plugins as well -our $VERSION = "0.36"; - -our @STATUS_CODES = qw(OK WARNING CRITICAL UNKNOWN DEPENDENT); - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT = (@STATUS_CODES, qw(nagios_exit nagios_die check_messages)); -our @EXPORT_OK = qw(%ERRORS %STATUS_TEXT @STATUS_CODES get_shortname max_state max_state_alt convert $value_re); -our %EXPORT_TAGS = ( - all => [ @EXPORT, @EXPORT_OK ], - codes => [ @STATUS_CODES ], - functions => [ qw(nagios_exit nagios_die check_messages max_state max_state_alt convert) ], -); - -use constant OK => 0; -use constant WARNING => 1; -use constant CRITICAL => 2; -use constant UNKNOWN => 3; -use constant DEPENDENT => 4; - -our %ERRORS = ( - 'OK' => OK, - 'WARNING' => WARNING, - 'CRITICAL' => CRITICAL, - 'UNKNOWN' => UNKNOWN, - 'DEPENDENT' => DEPENDENT, -); - -our %STATUS_TEXT = reverse %ERRORS; - -my $value = qr/[-+]?[\d\.]+/; -our $value_re = qr/$value(?:e$value)?/; - -# _fake_exit flag and accessor/mutator, for testing -my $_fake_exit = 0; -sub _fake_exit { @_ ? $_fake_exit = shift : $_fake_exit }; - -# _use_die flag and accessor/mutator, so exceptions can be raised correctly -my $_use_die = 0; -sub _use_die { @_ ? $_use_die = shift : $_use_die }; - -sub get_shortname { - my $arg = shift; - - my $shortname = undef; - - return $arg->{shortname} if (defined($arg->{shortname})); - $shortname = $arg->{plugin} if (defined( $arg->{plugin})); - - $shortname = uc basename($shortname || $ENV{NAGIOS_PLUGIN} || $0); - $shortname =~ s/^CHECK_(?:BY_)?//; # Remove any leading CHECK_[BY_] - $shortname =~ s/\..*$//; # Remove any trailing suffix - return $shortname; -} - -sub max_state { - return CRITICAL if grep { $_ == CRITICAL } @_; - return WARNING if grep { $_ == WARNING } @_; - return OK if grep { $_ == OK } @_; - return UNKNOWN if grep { $_ == UNKNOWN } @_; - return DEPENDENT if grep { $_ == DEPENDENT } @_; - return UNKNOWN; -} - -sub max_state_alt { - return CRITICAL if grep { $_ == CRITICAL } @_; - return WARNING if grep { $_ == WARNING } @_; - return UNKNOWN if grep { $_ == UNKNOWN } @_; - return DEPENDENT if grep { $_ == DEPENDENT } @_; - return OK if grep { $_ == OK } @_; - return UNKNOWN; -} - -# nagios_exit( $code, $message ) -sub nagios_exit { - my ($code, $message, $arg) = @_; - - # Handle named parameters - if (defined $code && ($code eq 'return_code' || $code eq 'message')) { - # Remove last argument if odd no and last is ref - if (int(@_ / 2) != @_ / 2 && ref $_[$#_]) { - $arg = pop @_; - } else { - undef $arg; - } - my %arg = @_; - $code = $arg{return_code}; - $message = $arg{message}; - } - $arg ||= {}; - - # Handle string codes - $code = $ERRORS{$code} if defined $code && exists $ERRORS{$code}; - - # Set defaults - $code = UNKNOWN unless defined $code && exists $STATUS_TEXT{$code}; - $message = '' unless defined $message; - if (ref $message && ref $message eq 'ARRAY') { - $message = join(' ', map { chomp; $_ } @$message); - } - else { - chomp $message; - } - - # Setup output - my $output = "$STATUS_TEXT{$code}"; - $output .= " - $message" if defined $message && $message ne ''; - my $shortname = ($arg->{plugin} ? $arg->{plugin}->shortname : undef); - $shortname ||= get_shortname(); # Should happen only if funnctions are called directly - $output = "$shortname $output" if $shortname; - if ($arg->{plugin}) { - my $plugin = $arg->{plugin}; - $output .= " | ". $plugin->all_perfoutput - if $plugin->perfdata && $plugin->all_perfoutput; - } - $output .= "\n"; - - # Don't actually exit if _fake_exit set - if ($_fake_exit) { - require Nagios::Plugin::ExitResult; - return Nagios::Plugin::ExitResult->new($code, $output); - } - - _nagios_exit($code, $output); -} - -sub _nagios_exit { - my ($code, $output) = @_; - # Print output and exit; die if flag set and called via a die in stack backtrace - if ($_use_die) { - for (my $i = 0;; $i++) { - @_ = caller($i); - last unless @_; - if ($_[3] =~ m/die/) { - $! = $code; - die($output); - } - } - } - print $output; - exit $code; -} - -# nagios_die( $message, [ $code ]) OR nagios_die( $code, $message ) -# Default $code: UNKNOWN -sub nagios_die { - my ($arg1, $arg2, $rest) = @_; - - # Named parameters - if (defined $arg1 && ($arg1 eq 'return_code' || $arg1 eq 'message')) { - return nagios_exit(@_); - } - - # ($code, $message) - elsif (defined $arg1 && (exists $ERRORS{$arg1} || exists $STATUS_TEXT{$arg1})) { - return nagios_exit(@_); - } - - # ($message, $code) - elsif (defined $arg2 && (exists $ERRORS{$arg2} || exists $STATUS_TEXT{$arg2})) { - return nagios_exit($arg2, $arg1, $rest); - } - - # Else just assume $arg1 is the message and hope for the best - else { - return nagios_exit( UNKNOWN, $arg1, $arg2 ); - } -} - -# For backwards compatibility -sub die { nagios_die(@_); } - - -# ------------------------------------------------------------------------ -# Utility functions - -# Simple wrapper around Math::Calc::Units::convert -sub convert -{ - my ($value, $from, $to) = @_; - my ($newval) = Math::Calc::Units::convert("$value $from", $to, 'exact'); - return $newval; -} - -# ------------------------------------------------------------------------ -# check_messages - return a status and/or message based on a set of -# message arrays. -# Returns a nagios status code in scalar context. -# Returns a code and a message in list context. -# The message is join($join, @array) for the relevant array for the code, -# or join($join_all, $message) for all arrays if $join_all is set. -sub check_messages { - my %arg = validate( @_, { - critical => { type => ARRAYREF }, - warning => { type => ARRAYREF }, - ok => { type => ARRAYREF | SCALAR, optional => 1 }, - 'join' => { default => ' ' }, - join_all => 0, - }); - $arg{join} = ' ' unless defined $arg{join}; - - # Decide $code - my $code = OK; - $code ||= CRITICAL if @{$arg{critical}}; - $code ||= WARNING if @{$arg{warning}}; - return $code unless wantarray; - - # Compose message - my $message = ''; - if ($arg{join_all}) { - $message = join( $arg{join_all}, - map { @$_ ? join( $arg{'join'}, @$_) : () } - $arg{critical}, - $arg{warning}, - $arg{ok} ? (ref $arg{ok} ? $arg{ok} : [ $arg{ok} ]) : [] - ); - } - - else { - $message ||= join( $arg{'join'}, @{$arg{critical}} ) - if $code == CRITICAL; - $message ||= join( $arg{'join'}, @{$arg{warning}} ) - if $code == WARNING; - $message ||= ref $arg{ok} ? join( $arg{'join'}, @{$arg{ok}} ) : $arg{ok} - if $arg{ok}; - } - - return ($code, $message); -} - -# ------------------------------------------------------------------------ - -1; - -# vim:sw=4:sm:et - -__END__ - -=head1 NAME - -Nagios::Plugin::Functions - functions to simplify the creation of -Nagios plugins - -=head1 SYNOPSIS - - # Constants OK, WARNING, CRITICAL, and UNKNOWN exported by default - use Nagios::Plugin::Functions; - - # nagios_exit( CODE, $message ) - exit with error code CODE, - # and message "PLUGIN CODE - $message" - nagios_exit( CRITICAL, $critical_error ) if $critical_error; - nagios_exit( WARNING, $warning_error ) if $warning_error; - nagios_exit( OK, $result ); - - # nagios_die( $message, [$CODE] ) - just like nagios_exit(), - # but CODE is optional, defaulting to UNKNOWN - do_something() - or nagios_die("do_something() failed horribly"); - do_something_critical() - or nagios_die("do_something_critical() failed", CRITICAL); - - # check_messages - check a set of message arrays, returning a - # CODE and/or a result message - $code = check_messages(critical => \@crit, warning => \@warn); - ($code, $message) = check_messages( - critical => \@crit, warning => \@warn, - ok => \@ok ); - - # get_shortname - return the default short name for this plugin - # (as used by nagios_exit/die; not exported by default) - $shortname = get_shortname(); - - -=head1 DESCRIPTION - -This module is part of the Nagios::Plugin family, a set of modules -for simplifying the creation of Nagios plugins. This module exports -convenience functions for the class methods provided by -Nagios::Plugin. It is intended for those who prefer a simpler -functional interface, and who do not need the additional -functionality of Nagios::Plugin. - -=head2 EXPORTS - -Nagios status code constants are exported by default: - - OK - WARNING - CRITICAL - UNKNOWN - DEPENDENT - -as are the following functions: - - nagios_exit - nagios_die - check_messages - -The following variables and functions are exported only on request: - - %ERRORS - %STATUS_TEXT - get_shortname - max_state - max_state_alt - - -=head2 FUNCTIONS - -The following functions are supported: - -=over 4 - -=item nagios_exit( , $message ) - -Exit with return code CODE, and a standard nagios message of the -form "PLUGIN CODE - $message". - -=item nagios_die( $message, [CODE] ) - -Same as nagios_exit(), except that CODE is optional, defaulting -to UNKNOWN. NOTE: exceptions are not raised by default to calling code. -Set C<$_use_die> flag if this functionality is required (see test code). - -=item check_messages( critical => \@crit, warning => \@warn ) - -Convenience function to check a set of message arrays and return -an appropriate nagios return code and/or a result message. Returns -only a return code in scalar context; returns a return code and an -error message in list context i.e. - - # Scalar context - $code = check_messages(critical => \@crit, warning => \@warn); - # List context - ($code, $msg) = check_messages(critical => \@crit, warning => \@warn); - -check_messages() accepts the following named arguments: - -=over 4 - -=item critical => ARRAYREF - -An arrayref of critical error messages - check_messages() returns -CRITICAL if this arrayref is non-empty. Mandatory. - -=item warning => ARRAYREF - -An arrayref of warning error messages - check_messages() returns -WARNING if this arrayref is non-empty ('critical' is checked -first). Mandatory. - -=item ok => ARRAYREF | SCALAR - -An arrayref of informational messages (or a single scalar message), -used in list context if both the 'critical' and 'warning' arrayrefs -are empty. Optional. - -=item join => SCALAR - -A string used to join the relevant array to generate the message -string returned in list context i.e. if the 'critical' array @crit -is non-empty, check_messages would return: - - join( $join, @crit ) - -as the result message. Optional; default: ' ' (space). - -=item join_all => SCALAR - -By default, only one set of messages are joined and returned in the -result message i.e. if the result is CRITICAL, only the 'critical' -messages are included in the result; if WARNING, only the 'warning' -messages are included; if OK, the 'ok' messages are included (if -supplied) i.e. the default is to return an 'errors-only' type -message. - -If join_all is supplied, however, it will be used as a string to -join the resultant critical, warning, and ok messages together i.e. -all messages are joined and returned. - -=back - -=item get_shortname - -Return the default shortname used for this plugin i.e. the first -token reported by nagios_exit/nagios_die. The default is basically - - uc basename( $ENV{NAGIOS_PLUGIN} || $0 ) - -with any leading 'CHECK_' and trailing file suffixes removed. - -get_shortname is not exported by default, so must be explicitly -imported. - -=item max_state(@a) - -Returns the worst state in the array. Order is: CRITICAL, WARNING, OK, UNKNOWN, -DEPENDENT - -The typical usage of max_state is to initialise the state as UNKNOWN and use -it on the result of various test. If no test were performed successfully the -state will still be UNKNOWN. - -=item max_state_alt(@a) - -Returns the worst state in the array. Order is: CRITICAL, WARNING, UNKNOWN, -DEPENDENT, OK - -This is a true definition of a max state (OK last) and should be used if the -internal tests performed can return UNKNOWN. - -=back - -=head1 SEE ALSO - -Nagios::Plugin; the nagios plugin developer guidelines at -http://nagiosplug.sourceforge.net/developer-guidelines.html. - - -=head1 AUTHORS - -This code is maintained by the Nagios Plugin Development Team: http://nagiosplug.sourceforge.net - - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2006 by Nagios Plugin Development Team - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. - -=cut diff --git a/lib/Nagios/Plugin/Getopt.pm b/lib/Nagios/Plugin/Getopt.pm deleted file mode 100644 index 22ff642..0000000 --- a/lib/Nagios/Plugin/Getopt.pm +++ /dev/null @@ -1,873 +0,0 @@ -# -# Nagios::Plugin::Getopt - OO perl module providing standardised argument -# processing for nagios plugins -# - -package Nagios::Plugin::Getopt; - -use strict; -use File::Basename; -use Getopt::Long qw(:config no_ignore_case bundling); -use Carp; -use Params::Validate qw(:all); -use base qw(Class::Accessor); - -use Nagios::Plugin::Functions; -use Nagios::Plugin::Config; -use vars qw($VERSION); -$VERSION = $Nagios::Plugin::Functions::VERSION; - -# Standard defaults -my %DEFAULT = ( - timeout => 15, - verbose => 0, - license => -"This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY. -It may be used, redistributed and/or modified under the terms of the GNU -General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt).", -); -# Standard arguments -my @ARGS = ({ - spec => 'usage|?', - help => "-?, --usage\n Print usage information", - }, { - spec => 'help|h', - help => "-h, --help\n Print detailed help screen", - }, { - spec => 'version|V', - help => "-V, --version\n Print version information", - }, { - spec => 'extra-opts:s@', - help => "--extra-opts=[section][\@file]\n Read options from an ini file. See http://nagiosplugins.org/extra-opts\n for usage and examples.", - }, { - spec => 'timeout|t=i', - help => "-t, --timeout=INTEGER\n Seconds before plugin times out (default: %s)", - default => $DEFAULT{timeout}, - }, { - spec => 'verbose|v+', - help => "-v, --verbose\n Show details for command-line debugging (can repeat up to 3 times)", - default => $DEFAULT{verbose}, - }, -); -# Standard arguments we traditionally display last in the help output -my %DEFER_ARGS = map { $_ => 1 } qw(timeout verbose); - -# ------------------------------------------------------------------------- -# Private methods - -sub _die -{ - my $self = shift; - my ($msg) = @_; - $msg .= "\n" unless substr($msg, -1) eq "\n"; - Nagios::Plugin::Functions::_nagios_exit(3, $msg); -} - -# Return the given attribute, if set, including a final newline -sub _attr -{ - my $self = shift; - my ($item, $extra) = @_; - $extra = '' unless defined $extra; - return '' unless $self->{_attr}->{$item}; - $self->{_attr}->{$item} . "\n" . $extra; -} - -# Turn argument spec into help-style output -sub _spec_to_help -{ - my ($self, $spec, $label) = @_; - - my ($opts, $type) = split /=/, $spec, 2; - my (@short, @long); - for (split /\|/, $opts) { - if (length $_ == 1) { - push @short, "-$_"; - } else { - push @long, "--$_"; - } - } - - my $help = join(', ', @short, @long); - if ($type) { - if ($label) { - $help .= '=' . $label; - } - else { - $help .= $type eq 'i' ? '=INTEGER' : '=STRING'; - } - } - elsif ($label) { - carp "Label specified, but there's no type in spec '$spec'"; - } - $help .= "\n "; - return $help; -} - -# Options output for plugin -h -sub _options -{ - my $self = shift; - - my @args = (); - my @defer = (); - for (@{$self->{_args}}) { - if (exists $DEFER_ARGS{$_->{name}}) { - push @defer, $_; - } else { - push @args, $_; - } - } - - my @options = (); - for my $arg (@args, @defer) { - my $help_array = ref $arg->{help} && ref $arg->{help} eq 'ARRAY' ? $arg->{help} : [ $arg->{help} ]; - my $label_array = $arg->{label} && ref $arg->{label} && ref $arg->{label} eq 'ARRAY' ? $arg->{label} : [ $arg->{label} ]; - my $help_string = ''; - for (my $i = 0; $i <= $#$help_array; $i++) { - my $help = $help_array->[$i]; - # Add spec arguments to help if not already there - if ($help =~ m/^\s*-/) { - $help_string .= $help; - } - else { - $help_string .= $self->_spec_to_help($arg->{spec}, $label_array->[$i]) . $help; - $help_string .= "\n " if $i < $#$help_array; - } - } - - # Add help_string to @options - if ($help_string =~ m/%s/) { - my $default = defined $arg->{default} ? $arg->{default} : ''; - # We only handle '%s' formats here, so escape everything else - $help_string =~ s/%(?!s)/%%/g; - push @options, sprintf($help_string, $default, $default, $default, $default); - } else { - push @options, $help_string; - } - } - - return ' ' . join("\n ", @options); -} - -# Output for plugin -? (or missing/invalid args) -sub _usage -{ - my $self = shift; - sprintf $self->_attr('usage'), $self->{_attr}->{plugin}; -} - -# Output for plugin -V -sub _revision -{ - my $self = shift; - my $revision = sprintf "%s %s", $self->{_attr}->{plugin}, $self->{_attr}->{version}; - $revision .= sprintf " [%s]", $self->{_attr}->{url} if $self->{_attr}->{url}; - $revision .= "\n"; - $revision; -} - -# Output for plugin -h -sub _help -{ - my $self = shift; - my $help = ''; - $help .= $self->_revision . "\n"; - $help .= $self->_attr('license', "\n"); - $help .= $self->_attr('blurb', "\n"); - $help .= $self->_usage ? $self->_usage . "\n" : ''; - $help .= $self->_options ? $self->_options . "\n" : ''; - $help .= $self->_attr('extra', "\n"); - return $help; -} - -# Return a Getopt::Long-compatible option array from the current set of specs -sub _process_specs_getopt_long -{ - my $self = shift; - - my @opts = (); - for my $arg (@{$self->{_args}}) { - push @opts, $arg->{spec}; - # Setup names and defaults - my $spec = $arg->{spec}; - # Use first arg as name (like Getopt::Long does) - $spec =~ s/[=:].*$//; - my $name = (split /\s*\|\s*/, $spec)[0]; - $arg->{name} = $name; - if (defined $self->{$name}) { - $arg->{default} = $self->{$name}; - } else { - $self->{$name} = $arg->{default}; - } - } - - return @opts; -} - -# Check for existence of required arguments -sub _check_required_opts -{ - my $self = shift; - - my @missing = (); - for my $arg (@{$self->{_args}}) { - if ($arg->{required} && ! defined $self->{$arg->{name}}) { - push @missing, $arg->{name}; - } - } - if (@missing) { - $self->_die($self->_usage . "\n" . - join("\n", map { sprintf "Missing argument: %s", $_ } @missing) . "\n"); - } -} - -# Process and handle any immediate options -sub _process_opts -{ - my $self = shift; - - # Print message and exit for usage, version, help - $self->_die($self->_usage) if $self->{usage}; - $self->_die($self->_revision) if $self->{version}; - $self->_die($self->_help) if $self->{help}; -} - -# ------------------------------------------------------------------------- -# Default opts methods - -sub _load_config_section -{ - my $self = shift; - my ($section, $file, $flags) = @_; - $section ||= $self->{_attr}->{plugin}; - - my $Config; - eval { $Config = Nagios::Plugin::Config->read($file); }; - $self->_die($@) if ($@); #TODO: add test? - - # TODO: is this check sane? Does --extra-opts=foo require a [foo] section? - ## Nevertheless, if we die as UNKNOWN here we should do the same on default - ## file *added eval/_die above*. - $file ||= $Config->np_getfile(); - $self->_die("Invalid section '$section' in config file '$file'") - unless exists $Config->{$section}; - - return $Config->{$section}; -} - -# Helper method to setup a hash of spec definitions for _cmdline -sub _setup_spec_index -{ - my $self = shift; - return if defined $self->{_spec}; - $self->{_spec} = { map { $_->{name} => $_->{spec} } @{$self->{_args}} }; -} - -# Quote values that require it -sub _cmdline_value -{ - my $self = shift; - local $_ = shift; - if (m/\s/ && (m/^[^"']/ || m/[^"']$/)) { - return qq("$_"); - } - elsif ($_ eq '') { - return q(""); - } - else { - return $_; - } -} - -# Helper method to format key/values in $hash in a quasi-commandline format -sub _cmdline -{ - my $self = shift; - my ($hash) = @_; - $hash ||= $self; - - $self->_setup_spec_index; - - my @args = (); - for my $key (sort keys %$hash) { - # Skip internal keys - next if $key =~ m/^_/; - - # Skip defaults and internals - next if exists $DEFAULT{$key} && $hash->{$key} eq $DEFAULT{$key}; - next if grep { $key eq $_ } qw(help usage version extra-opts); - next unless defined $hash->{$key}; - - # Render arg - my $spec = $self->{_spec}->{$key} || ''; - if ($spec =~ m/[=:].+$/) { - # Arg takes value - may be a scalar or an arrayref - for my $value (ref $hash->{$key} eq 'ARRAY' ? @{$hash->{$key}} : ( $hash->{$key} )) { - $value = $self->_cmdline_value($value); - if (length($key) > 1) { - push @args, sprintf "--%s=%s", $key, $value; - } - else { - push @args, "-$key", $value; - } - } - } - - else { - # Flag - render long or short based on option length - push @args, (length($key) > 1 ? '--' : '-') . $key; - } - } - - return wantarray ? @args : join(' ', @args); -} - -# Process and load extra-opts sections -sub _process_extra_opts -{ - my $self = shift; - my ($args) = @_; - - my $extopts_list = $args->{'extra-opts'}; - - my @sargs = (); - for my $extopts (@$extopts_list) { - $extopts ||= $self->{_attr}->{plugin}; - my $section = $extopts; - my $file = ''; - - # Parse section@file - if ($extopts =~ m/^([^@]*)@(.*?)\s*$/) { - $section = $1; - $file = $2; - } - - # Load section args - my $shash = $self->_load_config_section($section, $file); - - # Turn $shash into a series of commandline-like arguments - push @sargs, $self->_cmdline($shash); - } - - # Reset ARGV to extra-opts + original - @ARGV = ( @sargs, @{$self->{_attr}->{argv}} ); - - printf "[extra-opts] %s %s\n", $self->{_attr}->{plugin}, join(' ', @ARGV) - if $args->{verbose} && $args->{verbose} >= 3; -} - -# ------------------------------------------------------------------------- -# Public methods - -# Define plugin argument -sub arg -{ - my $self = shift; - my %args; - - # Named args - if ($_[0] =~ m/^(spec|help|required|default)$/ && scalar(@_) % 2 == 0) { - %args = validate( @_, { - spec => 1, - help => 1, - default => 0, - required => 0, - label => 0, - }); - } - - # Positional args - else { - my @args = validate_pos(@_, 1, 1, 0, 0, 0); - %args = ( - spec => $args[0], - help => $args[1], - default => $args[2], - required => $args[3], - label => $args[4], - ); - } - - # Add to private args arrayref - push @{$self->{_args}}, \%args; -} - -# Process the @ARGV array using the current _args list (possibly exiting) -sub getopts -{ - my $self = shift; - - # Collate spec arguments for Getopt::Long - my @opt_array = $self->_process_specs_getopt_long; - - # Capture original @ARGV (for extra-opts games) - $self->{_attr}->{argv} = [ @ARGV ]; - - # Call GetOptions using @opt_array - my $args1 = {}; - my $ok = GetOptions($args1, @opt_array); - # Invalid options - give usage message and exit - $self->_die($self->_usage) unless $ok; - - # Process extra-opts - $self->_process_extra_opts($args1); - - # Call GetOptions again, this time including extra-opts - $ok = GetOptions($self, @opt_array); - # Invalid options - give usage message and exit - $self->_die($self->_usage) unless $ok; - - # Process immediate options (possibly exiting) - $self->_process_opts; - - # Required options (possibly exiting) - $self->_check_required_opts; - - # Setup accessors for options - $self->mk_ro_accessors(grep ! /^_/, keys %$self); - - # Setup default alarm handler for alarm($ng->timeout) in plugin - $SIG{ALRM} = sub { - my $plugin = uc $self->{_attr}->{plugin}; - $plugin =~ s/^check_//; - $self->_die( - sprintf("%s UNKNOWN - plugin timed out (timeout %ss)", - $plugin, $self->timeout)); - }; -} - -# ------------------------------------------------------------------------- -# Constructor - -sub _init -{ - my $self = shift; - - # Check params - my $plugin = basename($ENV{NAGIOS_PLUGIN} || $0); - my %attr = validate( @_, { - usage => 1, - version => 0, - url => 0, - plugin => { default => $plugin }, - blurb => 0, - extra => 0, - 'extra-opts' => 0, - license => { default => $DEFAULT{license} }, - timeout => { default => $DEFAULT{timeout} }, - }); - - # Add attr to private _attr hash (except timeout) - $self->{timeout} = delete $attr{timeout}; - $self->{_attr} = { %attr }; - # Chomp _attr values - chomp foreach values %{$self->{_attr}}; - - # Setup initial args list - $self->{_args} = [ @ARGS ]; - - $self -} - -sub new -{ - my $class = shift; - my $self = bless {}, $class; - $self->_init(@_); -} - -# ------------------------------------------------------------------------- - -1; - -__END__ - -=head1 NAME - -Nagios::Plugin::Getopt - OO perl module providing standardised argument -processing for Nagios plugins - - -=head1 SYNOPSIS - - use Nagios::Plugin::Getopt; - - # Instantiate object (usage is mandatory) - $ng = Nagios::Plugin::Getopt->new( - usage => "Usage: %s -H -w -c ", - version => '0.1', - url => 'http://www.openfusion.com.au/labs/nagios/', - blurb => 'This plugin tests various stuff.', - ); - - # Add argument - named parameters (spec and help are mandatory) - $ng->arg( - spec => 'critical|c=i', - help => q(Exit with CRITICAL status if fewer than INTEGER foobars are free), - required => 1, - default => 10, - ); - - # Add argument - positional parameters - arg spec, help text, - # default value, required? (first two mandatory) - $ng->arg( - 'warning|w=i', - q(Exit with WARNING status if fewer than INTEGER foobars are free), - 5, - 1); - - # Parse arguments and process standard ones (e.g. usage, help, version) - $ng->getopts; - - # Access arguments using named accessors or or via the generic get() - print $ng->warning; - print $ng->get('critical'); - - - -=head1 DESCRIPTION - -Nagios::Plugin::Getopt is an OO perl module providing standardised and -simplified argument processing for Nagios plugins. It implements -a number of standard arguments itself (--help, --version, ---usage, --timeout, --verbose, and their short form counterparts), -produces standardised nagios plugin help output, and allows -additional arguments to be easily defined. - - -=head2 CONSTRUCTOR - - # Instantiate object (usage is mandatory) - $ng = Nagios::Plugin::Getopt->new( - usage => 'Usage: %s --hello', - version => '0.01', - ); - -The Nagios::Plugin::Getopt constructor accepts the following named -arguments: - -=over 4 - -=item usage (required) - -Short usage message used with --usage/-? and with missing required -arguments, and included in the longer --help output. Can include -a '%s' sprintf placeholder which will be replaced with the plugin -name e.g. - - usage => qq(Usage: %s -H -p [-v]), - -might be displayed as: - - $ ./check_tcp_range --usage - Usage: check_tcp_range -H -p [-v] - -=item version (required) - -Plugin version number, included in the --version/-V output, and in -the longer --help output. e.g. - - $ ./check_tcp_range --version - check_tcp_range 0.2 [http://www.openfusion.com.au/labs/nagios/] - -=item url - -URL for info about this plugin, included in the --version/-V output, -and in the longer --help output (see preceding 'version' example). - -=item blurb - -Short plugin description, included in the longer --help output -(see below for an example). - -=item license - -License text, included in the longer --help output (see below for an -example). By default, this is set to the standard nagios plugins -GPL license text: - - This nagios plugin is free software, and comes with ABSOLUTELY - NO WARRANTY. It may be used, redistributed and/or modified under - the terms of the GNU General Public Licence (see - http://www.fsf.org/licensing/licenses/gpl.txt). - -Provide your own to replace this text in the help output. - -=item extra - -Extra text to be appended at the end of the longer --help output. - -=item plugin - -Plugin name. This defaults to the basename of your plugin, which is -usually correct, but you can set it explicitly if not. - -=item timeout - -Timeout period in seconds, overriding the standard timeout default -(15 seconds). - -=back - -The full --help output has the following form: - - version string - - license string - - blurb - - usage string - - options list - - extra text - -The 'blurb' and 'extra text' sections are omitted if not supplied. For -example: - - $ ./check_tcp_range -h - check_tcp_range 0.2 [http://www.openfusion.com.au/labs/nagios/] - - This nagios plugin is free software, and comes with ABSOLUTELY NO WARRANTY. - It may be used, redistributed and/or modified under the terms of the GNU - General Public Licence (see http://www.fsf.org/licensing/licenses/gpl.txt). - - This plugin tests arbitrary ranges/sets of tcp ports for a host. - - Usage: check_tcp_range -H -p [-v] - - Options: - -h, --help - Print detailed help screen - -V, --version - Print version information - -H, --hostname=ADDRESS - Host name or IP address - -p, --ports=STRING - Port numbers to check. Format: comma-separated, colons for ranges, - no spaces e.g. 8700:8705,8710:8715,8760 - -t, --timeout=INTEGER - Seconds before plugin times out (default: 15) - -v, --verbose - Show details for command-line debugging (can repeat up to 3 times) - - -=head2 ARGUMENTS - -You can define arguments for your plugin using the arg() method, which -supports both named and positional arguments. In both cases -the C and C arguments are required, while the C