[Nagiosplug-checkins] Nagios-Plugin/lib/Nagios/Plugin Getopt.pm, 1.7, 1.8

Gavin Carr gonzai at users.sourceforge.net
Thu Feb 8 06:16:17 CET 2007


Update of /cvsroot/nagiosplug/Nagios-Plugin/lib/Nagios/Plugin
In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv13151/lib/Nagios/Plugin

Modified Files:
	Getopt.pm 
Log Message:
Add initial --default-opts implementation to Nagios::Plugin::Getopt.

Index: Getopt.pm
===================================================================
RCS file: /cvsroot/nagiosplug/Nagios-Plugin/lib/Nagios/Plugin/Getopt.pm,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Getopt.pm	10 Nov 2006 01:26:16 -0000	1.7
+++ Getopt.pm	8 Feb 2007 05:16:15 -0000	1.8
@@ -10,12 +10,15 @@
 use Getopt::Long qw(:config no_ignore_case bundling);
 use Carp;
 use Params::Validate qw(:all);
+use Config::Tiny;
 use base qw(Class::Accessor);
 
 use Nagios::Plugin::Functions;
-use vars qw($VERSION);
+use vars qw($VERSION $DEFAULT_CONFIG_FILE);
 $VERSION = $Nagios::Plugin::Functions::VERSION;
 
+$DEFAULT_CONFIG_FILE = '/etc/nagios/plugins.cfg';
+
 # Standard defaults
 my %DEFAULT = (
   timeout => 15,
@@ -36,6 +39,9 @@
     spec => 'version|V',
     help => "-V, --version\n   Print version information",
   }, {
+    spec => 'default-opts:s@',
+    help => "--default-opts=[<section>[@<config_file>]]\n   Section and/or config_file from which to load default options (may repeat)",
+  }, {
     spec => 'timeout|t=i',
     help => "-t, --timeout=INTEGER\n   Seconds before plugin times out (default: %s)",
     default => $DEFAULT{timeout},
@@ -140,7 +146,7 @@
     # Setup names and defaults
     my $spec = $arg->{spec};
     # Use first arg as name (like Getopt::Long does)
-    $spec =~ s/=\w+$//;
+    $spec =~ s/[=:].*$//;
     my $name = (split /\s*\|\s*/, $spec)[0];
     $arg->{name} = $name;
     if (defined $self->{$name}) {
@@ -182,6 +188,135 @@
 }
 
 # -------------------------------------------------------------------------
+# Default opts methods
+
+sub _load_config_section
+{
+  my $self = shift;
+  my ($section, $file, $flags) = @_;
+  $section ||= $self->{_attr}->{plugin};
+  $file ||= $DEFAULT_CONFIG_FILE;
+
+  $self->_die("Cannot find config file '$file'") if $flags->{fatal} && ! -f $file;
+
+  my $Config = Config::Tiny->read($file);
+  $self->_die("Cannot read config file '$file'") unless defined $Config;
+
+  $self->_die("Invalid section '$section' in config file '$file'")
+    if $flags->{fatal} && ! 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 default-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 default-opts sections
+sub _process_default_opts
+{
+  my $self = shift;
+  my ($args) = @_;
+
+  my $defopts_list = $args->{'default-opts'};
+  my $defopts_explicit = 1;
+
+  # If no default_opts defined, force one implicitly
+  if (! $defopts_list) {
+    $defopts_list = [ '' ];
+    $defopts_explicit = 0;
+  }
+
+  my @sargs = ();
+  for my $defopts (@$defopts_list) {
+    $defopts ||= $self->{_attr}->{plugin};
+    my $section = $defopts;
+    my $file = '';
+
+    # Parse section at file
+    if ($defopts =~ m/^(\w*)@(.*?)\s*$/) {
+      $section = $1;
+      $file = $2;
+    }
+
+    # Load section args
+    my $shash = $self->_load_config_section($section, $file, { fatal => $defopts_explicit });
+
+    # Turn $shash into a series of commandline-like arguments
+    push @sargs, $self->_cmdline($shash);
+  }
+
+  # Reset ARGV to default-opts + original
+  @ARGV = ( @sargs, @{$self->{_attr}->{argv}} );
+
+  printf "[default-opts] %s %s\n", $self->{_attr}->{plugin}, join(' ', @ARGV)
+    if $args->{verbose} && $args->{verbose} >= 3;
+}
+
+# -------------------------------------------------------------------------
 # Public methods
 
 # Define plugin argument
@@ -223,10 +358,21 @@
   # Collate spec arguments for Getopt::Long
   my @opt_array = $self->_process_specs_getopt_long;
 
+  # Capture original @ARGV (for default-opts games)
+  $self->{_attr}->{argv} = [ @ARGV ];
+
   # Call GetOptions using @opt_array
-  my $ok = GetOptions($self, @opt_array);
+  my $args1 = {};
+  my $ok = GetOptions($args1, @opt_array);
+  # Invalid options - give usage message and exit
+  $self->_die($self->_usage) unless $ok;
 
-  # Invalid options - given usage message and exit
+  # Process default-opts
+  $self->_process_default_opts($args1);
+
+  # Call GetOptions again, this time including default-opts
+  $ok = GetOptions($self, @opt_array);
+  # Invalid options - give usage message and exit
   $self->_die($self->_usage) unless $ok;
 
   # Process immediate options (possibly exiting)
@@ -264,6 +410,7 @@
     plugin => { default => $plugin },
     blurb => 0,
     extra => 0,
+    'default-opts' => 0,
     license => { default => $DEFAULT{license} },
     timeout => { default => $DEFAULT{timeout} },
   });
@@ -295,11 +442,8 @@
 
 =head1 NAME
 
-Nagios::Plugin::Getopt - OO perl module providing standardised argument processing for Nagios plugins
-
-=head1 VERSION
-
-This documentation applies to version 0.01 of Nagios::Plugin::Getopt.
+Nagios::Plugin::Getopt - OO perl module providing standardised argument 
+processing for Nagios plugins
 
 
 =head1 SYNOPSIS





More information about the Commits mailing list