From 6b146c728f178f0668dff12a52616abdc97e89ff Mon Sep 17 00:00:00 2001 From: Sven Velt Date: Thu, 2 Jun 2016 21:05:53 +0200 Subject: [PATCH] Remove old PERL plugins I'm not able to support them --- check_junos.pl | 602 ---------------------- check_junos_bgp.pl | 581 --------------------- check_junos_vc.pl | 836 ------------------------------- check_naf_exports.pl | 262 ---------- perl/lib/Nagios/Plugin/JUNOS.pm | 540 -------------------- perl/lib/Nagios/Plugin/NetApp.pm | 453 ----------------- plugin_wrapper.pl | 79 --- tools/junos_dump.pl | 239 --------- 8 files changed, 3592 deletions(-) delete mode 100755 check_junos.pl delete mode 100755 check_junos_bgp.pl delete mode 100755 check_junos_vc.pl delete mode 100755 check_naf_exports.pl delete mode 100644 perl/lib/Nagios/Plugin/JUNOS.pm delete mode 100644 perl/lib/Nagios/Plugin/NetApp.pm delete mode 100755 plugin_wrapper.pl delete mode 100755 tools/junos_dump.pl diff --git a/check_junos.pl b/check_junos.pl deleted file mode 100755 index 633c6de..0000000 --- a/check_junos.pl +++ /dev/null @@ -1,602 +0,0 @@ -#!/usr/bin/perl - -############################################################################# -# (c) 2001, 2003 Juniper Networks, Inc. # -# (c) 2011-2012 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -use strict; -use warnings; - -use utf8; - -use JUNOS::Device; -use JUNOS::Trace; - -use FindBin qw( $Bin ); -use lib "$Bin/perl/lib"; -use Nagios::Plugin::JUNOS; - -binmode STDOUT, ":utf8"; - -# TODO: -# * chassis_routing_engine: show chassis routing-engine (-> number and status) - -my $plugin = Nagios::Plugin::JUNOS->new( - plugin => 'check_junos', - shortname => 'check_junos', - version => '0.1', - url => 'http://oss.teamix.org/projects/monitoringplugins', - blurb => 'Monitor Juniper™ Switches.', - usage => -"Usage: %s [-v|--verbose] [-H ] [-p ] [-t ] [-P -"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 3-Clause -BSD License (see http://opensource.org/licenses/BSD-3-Clause).", - extra => " -This plugin connects to a Juniper™ Switch device and checks various of its -components. - -A check-tuple consists of the name of the check and, optionally, a \"target\" -which more closely specifies which characteristics should be checked, and -warning and critical thresholds: -checkname[,target[,warning[,critical]]] - -The following checks are available: - * interfaces: Status of interfaces. If a target is specified, only the - specified interface(s) will be taken into account. The special target - '\@with_description' selects all interfaces with a non-empty description. - - If an aggregated interface is encountered, the physical interfaces will - be checked as well. - - * interface_forwarding: Check the forwarding state of interfaces as provided - by 'show ethernet-switching interfaces'. Storm control, MAC limit and - BPDUs will be considered CRITICAL states. If a target is specified, only - the specified interface(s) will be taken into account. Targets may be - specified as : in which case a CRITICAL - state is assumed if the specified interface is not in the specified state. - - * chassis_environment: Check the status of verious system components - (as provided by 'show chassis environment'). If a target is specified, - only the specified component(s) will be taken into account. If specified, - the thresholds will be checked against the temperature of the components. - - * system_storage: Check the amount of used space of system filesystems. If a - target is specified, only the specified filesystem(s) will be taken into - account (specified either by filesystem name or mount point). The - threshold will be checked against the amount (percent) of used space. - -Warning and critical thresholds may be specified in the format documented at -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT.", -); - -my %checks = ( - interfaces => \&check_interfaces, - interface_forwarding => \&check_interface_forwarding, - chassis_environment => \&check_chassis_environment, - system_storage => \&check_system_storage, -); - -my $junos = undef; - -my $cache = {}; - -$plugin->add_common_args(); -$plugin->add_arg({ - spec => 'caching|C', - usage => '-C, --caching', - desc => 'Enabling caching of API results', - default => 0, - }); - -foreach my $check (keys %checks) { - $plugin->add_check_impl($check, $checks{$check}); -} - -$plugin->set_default_check('chassis_environment'); - -# configure removes any options from @ARGV -$plugin->configure(); - -if ($plugin->{'conf'}->{'verbose'} > 3) { - JUNOS::Trace::init(1); -} - -$plugin->set_checks(@ARGV); -$junos = $plugin->connect(); - -$plugin->run_checks(); - -my ($code, $msg) = $plugin->check_messages(join => ', '); - -$plugin->nagios_exit($code, $msg); - -sub check_interface -{ - my $plugin = shift; - my $iface = shift; - my $opts = shift || {}; - my @targets = @_; - - my $name = $plugin->get_query_object_value($iface, 'name'); - my $admin_status = $plugin->get_query_object_value($iface, 'admin-status'); - - if ($admin_status !~ m/^up$/) { - if ((grep { $name =~ m/^$_$/; } @targets) - || ($opts->{'with_description'} && - $plugin->get_query_object_value($iface, 'description'))) { - $plugin->add_message(CRITICAL, - "$name is not enabled"); - return -1; - } - return 1; - } - - if ($plugin->get_query_object_value($iface, 'oper-status') !~ m/^up$/i) { - return 0; - } - - $plugin->add_perfdata( - label => "'$name-input-bytes'", - value => $plugin->get_query_object_value($iface, - ['traffic-statistics', 'input-bytes']), - min => 0, - max => undef, - uom => 'B', - threshold => undef, - ); - $plugin->add_perfdata( - label => "'$name-output-bytes'", - value => $plugin->get_query_object_value($iface, - ['traffic-statistics', 'output-bytes']), - min => 0, - max => undef, - uom => 'B', - threshold => undef, - ); - return 1; -} - -sub get_interfaces -{ - my $plugin = shift; - my $opts = shift || {}; - my @targets = @_; - - my @ifaces = (); - my @ret = (); - - if (defined($cache->{'interfaces'})) { - @ifaces = @{$cache->{'interfaces'}}; - } - else { - my $cmd = 'get_interface_information'; - my $res; - - my $args = { detail => 1 }; - - if ((scalar(@targets) == 1) && (! $opts->{'with_description'}) - && (! $plugin->{'conf'}->{'caching'})) { - $args->{'interface_name'} = $targets[0]; - } - $res = $plugin->send_query($cmd, $args); - - if (! ref $res) { - $plugin->die($res); - } - - @ifaces = $res->getElementsByTagName('physical-interface'); - } - - if ($plugin->{'conf'}->{'caching'}) { - $cache->{'interfaces'} = \@ifaces; - } - - @targets = map { s/\*/\.\*/g; s/\?/\./g; $_; } @targets; - - if (scalar(@targets)) { - @ret = grep { - my $i = $_; - grep { $plugin->get_query_object_value($i, 'name') =~ m/^$_$/ } @targets; - } @ifaces; - } - elsif (! $opts->{'with_description'}) { - @ret = @ifaces; - } - - if ($opts->{'with_description'}) { - foreach my $iface (@ifaces) { - my $name = $plugin->get_query_object_value($iface, 'name'); - if ($plugin->get_query_object_value($iface, 'description') - && (! grep { m/^$name$/; } @targets)) { - push @ret, $iface; - } - } - } - - { - my @i = map { $plugin->get_query_object_value($_, 'name'). " => " - . $plugin->get_query_object_value($_, 'oper-status') } @ret; - $plugin->verbose(3, "Interfaces: " . join(", ", @i)); - } - return @ret; -} - -sub check_interfaces -{ - my $plugin = shift; - my $junos = shift; - my $targets = shift || []; - my $exclude = shift || []; - - my $opts = { - with_description => 0, - }; - - if (grep { m/^\@with_description$/; } @$targets) { - $opts->{'with_description'} = 1; - - @$targets = grep { ! m/^\@with_description$/; } @$targets; - } - - my @interfaces = get_interfaces($plugin, $opts, @$targets);; - - my $down_count = 0; - my @down_ifaces = (); - - my $phys_down_count = 0; - my @phys_down_ifaces = (); - - my $have_lag_ifaces = 0; - - foreach my $iface (@interfaces) { - my $name = $plugin->get_query_object_value($iface, 'name'); - my $desc = $plugin->get_query_object_value($iface, 'description'); - my $status; - - if (grep { m/^$name$/ } @$exclude) { - next; - } - - $status = check_interface($plugin, $iface, $opts, @$targets); - - my $tmp; - - if ($status == 0) { - ++$down_count; - $tmp = $name . ($desc ? " ($desc)" : ""); - push @down_ifaces, $tmp; - } - - if ($status <= 0) { - # disabled or down - next; - } - - if ($name !~ m/^ae/) { - next; - } - - $have_lag_ifaces = 1; - - my @markers = $plugin->get_query_object($iface, - ['logical-interface', 'lag-traffic-statistics', 'lag-marker']); - - if (! @markers) { - print STDERR "Cannot get marker for non-LACP interfaces yet!\n"; - next; - } - - foreach my $marker (@markers) { - my $phy_name = $plugin->get_query_object_value($marker, 'name'); - $phy_name =~ s/\.\d+$//; - - $plugin->verbose(3, "Quering physical interface '$phy_name' " - . "for $name."); - - my @phy_interfaces = get_interfaces($plugin, {}, $phy_name); - foreach my $phy_iface (@phy_interfaces) { - if (check_interface($plugin, $phy_iface, {}, $phy_name) == 0) { - ++$phys_down_count; - $tmp = $name . ($desc ? " ($desc)" : ""); - push @phys_down_ifaces, "$tmp -> $phy_name"; - } - } - } - } - - if ($down_count > 0) { - $plugin->add_message(CRITICAL, $down_count . " interface" - . ($down_count == 1 ? "" : "s") - . " down (" . join(", ", @down_ifaces) . ")"); - } - - if ($phys_down_count > 0) { - $plugin->add_message(WARNING, $phys_down_count - . " LAG member interface" - . ($phys_down_count == 1 ? "" : "s") - . " down (" - . join(", ", @phys_down_ifaces) . ")"); - } - - if ((! $down_count) && (! $phys_down_count)) { - if ((! scalar(@$targets)) || $opts->{'with_description'}) { - $plugin->add_message(OK, "all interfaces up" - . ($have_lag_ifaces - ? " (including all LAG member interfaces)" : "")); - } - else { - $plugin->add_message(OK, "interface" - . (scalar(@$targets) == 1 ? " " : "s ") - . join(", ", @$targets) . " up" - . ($have_lag_ifaces - ? " (including all LAG member interfaces)" : "")); - } - } -} - -sub check_interface_forwarding -{ - my $plugin = shift; - my $junos = shift; - my $targets = shift || []; - my $exclude = shift || []; - - my $res = $plugin->send_query('show ethernet-switching interfaces brief'); - - my %critical_map = ( - 'Disabled by bpdu-control' => 1, - 'MAC limit exceeded' => 1, - 'MAC move limit exceeded' => 1, - 'Storm control in effect' => 1, - ); - - my %targets = map { my @t = split(':', $_); $t[0] => $t[1]; } @$targets; - - my @failed = (); - - { - my @i = map { - $plugin->get_query_object_value($_, 'interface-name') - . " => { " . - join(", ", map { - $plugin->get_query_object_value($_, 'blocking-status') - } $plugin->get_query_object($_, - ['interface-vlan-member-list', 'interface-vlan-member'])) - . " }" - } $plugin->get_query_object($res, 'interface'); - $plugin->verbose(3, "Interfaces: " . join(", ", @i)); - } - - foreach my $iface ($plugin->get_query_object($res, 'interface')) { - my $name = $plugin->get_query_object_value($iface, 'interface-name'); - my $failed_status = undef; - - if (scalar(@$targets) && (! exists($targets{$name}))) { - next; - } - - if (grep { m/^$name$/ } @$exclude) { - next; - } - - foreach my $vlan_member ($plugin->get_query_object($iface, - ['interface-vlan-member-list', 'interface-vlan-member'])) { - my $status = $plugin->get_query_object_value($vlan_member, - 'blocking-status'); - - if (defined($targets{$name})) { - if ($status ne $targets{$name}) { - $failed_status = "$status (should: $targets{$name})"; - last; - } - } - elsif (defined $critical_map{$status}) { - $failed_status = $status; - last; - } - } - - if ($failed_status) { - push @failed, { name => $name, status => $failed_status }; - } - } - - if (scalar(@failed)) { - $plugin->add_message(CRITICAL, scalar(@failed) . " interface" - . (scalar(@failed) == 1 ? "" : "s") - . " blocked: " - . join(", ", map { "$_->{'name'}: $_->{'status'}" } @failed)); - } - else { - $plugin->add_message(OK, "forwarding state of all interfaces OK"); - } -} - -sub check_chassis_environment -{ - my $plugin = shift; - my $junos = shift; - my $targets = shift || []; - my $exclude = shift || []; - - my $res = $plugin->send_query('get_environment_information'); - - my %status_map = ( - OK => OK, - Testing => UNKNOWN, - Check => UNKNOWN, - Failed => CRITICAL, - Absent => CRITICAL, - ); - - my $items_count = 0; - my $items_ok = 0; - - my $class = ""; - foreach my $item ($plugin->get_query_object($res, 'environment-item')) { - my $name = $plugin->get_query_object_value($item, 'name'); - - if (scalar(@$targets) && (! grep { m/^$name$/ } @$targets)) { - next; - } - - if (grep { m/^$name$/ } @$exclude) { - next; - } - - if ($plugin->get_query_object_value($item, 'class')) { - $class = $plugin->get_query_object_value($item, 'class'); - } - - my $status = $plugin->get_query_object_value($item, 'status'); - - if ($status eq "Absent") { - if (! scalar(@$targets)) { - next; - } - # else: check this component - } - - my $state = UNKNOWN; - if (defined $status_map{$status}) { - $state = $status_map{$status}; - } - - ++$items_count; - - if ($state == OK) { - ++$items_ok; - } - else { - $plugin->add_message($state, $class . " $name: status " . - $status); - } - - my $temp = $plugin->get_query_object_value($item, 'temperature'); - if (! $temp) { - next; - } - - ($temp) = $temp =~ m/(\d+) degrees C/; - if (! defined($temp)) { - next; - } - - $state = $plugin->check_threshold($temp); - if ($state != OK) { - $plugin->add_message($state, $class - . " $name: ${temp} degrees C"); - } - - my $label = "$name-temp"; - $label =~ s/ /_/g; - $plugin->add_perfdata( - label => "'$label'", - value => $temp, - min => undef, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - } - - if (! $items_count) { - $plugin->add_message(WARNING, "no components found"); - } - elsif ($items_count == $items_ok) { - $plugin->add_message(OK, "$items_ok component" - . ($items_ok == 1 ? "" : "s") - . " OK"); - } - else { - $plugin->add_message(WARNING, - "$items_ok / $items_count components OK"); - } -} - -sub check_system_storage -{ - my $plugin = shift; - my $junos = shift; - my $targets = shift || []; - my $exclude = shift || []; - - my $res = $plugin->send_query('get_system_storage'); - - my $all_ok = 1; - - foreach my $re ($plugin->get_query_object($res, - 'multi-routing-engine-item')) { - my $re_name = $plugin->get_query_object_value($re, 're-name'); - - foreach my $fs ($plugin->get_query_object($re, - ['system-storage-information', 'filesystem'])) { - my $name = $plugin->get_query_object_value($fs, 'filesystem-name'); - my $mnt_pt = $plugin->get_query_object_value($fs, 'mounted-on'); - - if (scalar(@$targets) && (! grep { m/^$name$/ } @$targets) - && (! grep { m/^$mnt_pt$/ } @$targets)) { - next; - } - - if (grep { m/^$mnt_pt$/ } @$exclude) { - next; - } - - my $used = $plugin->get_query_object_value($fs, 'used-percent') + 0; - - my $state = $plugin->check_threshold($used); - if ($state != OK) { - $all_ok = 0; - $plugin->add_message($state, "$re_name $mnt_pt: " - . "$used\% used"); - } - $plugin->add_perfdata( - label => "'$re_name-$mnt_pt'", - value => $used, - min => 0, - max => 100, - uom => '%', - threshold => $plugin->threshold(), - ); - } - } - - if ($all_ok) { - $plugin->add_message(OK, "all filesystems within thresholds"); - } -} - diff --git a/check_junos_bgp.pl b/check_junos_bgp.pl deleted file mode 100755 index e0f259d..0000000 --- a/check_junos_bgp.pl +++ /dev/null @@ -1,581 +0,0 @@ -#!/usr/bin/perl - -############################################################################# -# (c) 2001, 2003 Juniper Networks, Inc. # -# (c) 2011 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -use strict; -use warnings; - -use utf8; - -use Data::Dumper; - -use POSIX qw( :termios_h ); -use Nagios::Plugin; - -use Regexp::Common; -use Regexp::IPv6 qw( $IPv6_re ); - -use JUNOS::Device; - -binmode STDOUT, ":utf8"; - -my $valid_checks = "peers_count|prefix_count"; - -my $plugin = Nagios::Plugin->new( - plugin => 'check_junos_bgp', - shortname => 'check_junos_bgp', - version => '0.1', - url => 'http://oss.teamix.org/projects/monitoringplugins', - blurb => 'Monitor Juniper™ Router\'s BGP tables.', - usage => -"Usage: %s [-v|--verbose] [-t ] [-p ] [-U ] [-P ] [-I ] check-tuple [...] ", - 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 3-Clause -BSD License (see http://opensource.org/licenses/BSD-3-Clause).", - extra => " -This plugin connects to a Juniper™ Router device and requests BGP table -information using the 'show bgp neighbor' command. It then checks the -specified thresholds depending on the specified checks. - -A check-tuple consists of the name of the check and, optionally, a \"target\" -(e.g., peer address), and warning and critical thresholds: -checkname[,target[,warning[,critical]]] - -The following checks are available: - * peers_count: Total number of peers. If a target is specified, only peers - matching that target are taken into account. - - * prefix_count: Number of active prefixes for a single peer. If multiple - peers match the specified target, each of those is checked against the - specified thresholds. - -Targets are either specified as IPv4/IPv6 addresses or regular expressions / -strings. In the former case, the target is compared against the peer's -address, else against the peer's description. When specifying regular -expressions, they have to be enclosed in '/'. Else, the pattern is treated as -verbatim string that has to be matched. - -Warning and critical thresholds may be specified in the format documented at -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT.", -); - -# Predefined arguments (by Nagios::Plugin) -my @predefined_args = qw( - usage - help - version - extra-opts - timeout - verbose -); - -my @args = ( - { - spec => 'host|H=s', - usage => '-H, --host=HOSTNAME', - desc => 'Hostname/IP of Juniper box to connect to', - default => 'localhost', - }, - { - spec => 'port|p=i', - usage => '-p, --port=PORT', - desc => 'Port to connect to', - default => 22, - }, - { - spec => 'user|U=s', - usage => '-U, --user=USERNAME', - desc => 'Username to log into box as', - default => 'root', - }, - { - spec => 'password|P=s', - usage => '-P, --password=PASSWORD', - desc => 'Password for login username', - default => '', - }, - { - spec => 'logical-router|L=s', - usage => '-L, --logical-router=ROUTER', - desc => 'Logical Router', - default => '', - }, - { - spec => 'instance|I=s', - usage => '-I, --instance=INSTANCE', - desc => 'Instance', - default => '', - }, - -); - -my %conf = (); -my $junos = undef; - -my $neigh_info = undef; -my @peers = (); - -foreach my $arg (@args) { - add_arg($plugin, $arg); -} - -$plugin->getopts; -# Initialize this first, so it may be used right away. -$conf{'verbose'} = $plugin->opts->verbose; - -foreach my $arg (@args) { - my @c = get_conf($plugin, $arg); - $conf{$c[0]} = $c[1]; -} - -foreach my $arg (@predefined_args) { - $conf{$arg} = $plugin->opts->$arg; -} - -add_checks(\%conf, @ARGV); - -if (! $plugin->opts->password) { - my $term = POSIX::Termios->new(); - my $lflag; - - print "Password: "; - - $term->getattr(fileno(STDIN)); - $lflag = $term->getlflag; - $term->setlflag($lflag & ~POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSANOW); - - $conf{'password'} = ; - chomp($conf{'password'}); - - $term->setlflag($lflag | POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSAFLUSH); - print "\n"; -} - -verbose(1, "Connecting to host $conf{'host'} as user $conf{'user'}."); -$junos = JUNOS::Device->new( - hostname => $conf{'host'}, - login => $conf{'user'}, - password => $conf{'password'}, - access => 'ssh', - 'ssh-compress' => 0); - -if (! ref $junos) { - $plugin->die("ERROR: failed to connect to " . $conf{'host'} . "!"); -} - -verbose(1, "Querying BGP neighbor information."); -$neigh_info = get_neighbor_information($junos); -if (! ref $neigh_info) { - $plugin->die($neigh_info); -} - -@peers = $neigh_info->getElementsByTagName('bgp-peer'); -if ($conf{'verbose'} >= 3) { - my @p = map { (get_peer_address($_) // "") - . " => " . (get_peer_description($_) // "") } @peers; - verbose(3, "Peers: " . join(", ", @p)); -} - -foreach my $check (@{$conf{'checks'}}) { - my $code; - my $value; - - my @relevant_peers = get_relevant_peers($check, @peers); - if ($conf{'verbose'} >= 2) { - my @p = map { (get_peer_address($_) // "") - . " => " . (get_peer_description($_) // "") } @relevant_peers; - verbose(2, "Relevant peers: " . join(", ", @p)); - } - - $plugin->set_thresholds( - warning => $check->{'warning'}, - critical => $check->{'critical'}, - ); - - if ($check->{'name'} eq 'peers_count') { - $value = scalar(@relevant_peers); - $code = $plugin->check_threshold($value); - - $plugin->add_message($code, "$value peer" . (($value == 1) ? "" : "s")); - $plugin->add_perfdata( - label => 'peers_count', - value => $value, - min => 0, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - } - elsif ($check->{'name'} eq 'prefix_count') { - foreach my $peer (@relevant_peers) { - my $peer_addr = get_peer_address($peer); - - if (! defined($peer_addr)) { - $peer_addr = ""; - } - - $value = get_peer_element($peer, 'peer-state'); - - if (! defined($value)) { - $value = ""; - } - - verbose(2, "Peer $peer_addr: peer-state = $value."); - - if ($value eq 'Established') { - $value = $peer->getElementsByTagName('bgp-rib'); - $value = get_peer_element($value->[0], 'active-prefix-count'); - if (! $value) { - $value = 0; - } - $code = $plugin->check_threshold($value); - $plugin->add_message($code, "peer $peer_addr: $value prefix" - . (($value == 1) ? "" : "es")); - - verbose(2, "Peer $peer_addr: active-prefix-count = $value."); - } - else { - $value = ""; - $code = CRITICAL; - $plugin->add_message($code, - "peer $peer_addr: no established connection"); - } - - $plugin->add_perfdata( - label => '\'prefix_count[' . $peer_addr . ']\'', - value => $value, - min => 0, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - } - } -} - -my ($code, $msg) = $plugin->check_messages(join => ', '); - -$junos->disconnect(); - -$plugin->nagios_exit($code, $msg); - -sub send_query -{ - my $device = shift; - my $query = shift; - my $queryargs = shift; - - my $res; - my $err; - - verbose(3, "Sending query '$query' to router."); - - if (ref $queryargs) { - $res = $device->$query(%$queryargs); - } else { - $res = $device->$query(); - } - - verbose(5, "Got response: " . Dumper(\$res)); - - if (! ref $res) { - return "ERROR: Failed to execute query '$query'"; - } - - $err = $res->getFirstError(); - if ($err) { - return "ERROR: " . $err->{message}; - } - return $res; -} - -sub get_neighbor_information -{ - my $device = shift; - my @table; - - my $query = "get_bgp_summary_information"; - - my $res; - my %args; - - if (($conf{'logical-router'} ne '') || ($conf{'instance'} ne '')) { - if ($conf{'logical-router'} ne '') { - $args{'logical-router'} = $conf{'logical-router'}; - } - if ($conf{'instance'} ne '') { - $args{'instance'} = $conf{'instance'}; - } - - $res = send_query($device, $query, \%args); - } else { - $res = send_query($device, $query); - } - my $err; - - if (! ref $res) { - return $res; - } - - $err = $res->getFirstError(); - if ($err) { - return "ERROR: " . $err->{message}; - } - return $res; -} - -sub add_arg -{ - my $plugin = shift; - my $arg = shift; - - my $spec = $arg->{'spec'}; - my $help = $arg->{'usage'}; - - if (defined $arg->{'desc'}) { - my @desc; - - if (ref($arg->{'desc'})) { - @desc = @{$arg->{'desc'}}; - } - else { - @desc = ( $arg->{'desc'} ); - } - - foreach my $d (@desc) { - $help .= "\n $d"; - } - - if (defined $arg->{'default'}) { - $help .= " (default: $arg->{'default'})"; - } - } - elsif (defined $arg->{'default'}) { - $help .= "\n (default: $arg->{'default'})"; - } - - $plugin->add_arg( - spec => $spec, - help => $help, - ); -} - -sub get_conf -{ - my $plugin = shift; - my $arg = shift; - - my ($name, undef) = split(m/\|/, $arg->{'spec'}); - my $value = $plugin->opts->$name || $arg->{'default'}; - - if ($name eq 'password') { - verbose(3, "conf: password => " - . (($value eq '') ? '' : '')); - } - else { - verbose(3, "conf: $name => $value"); - } - return ($name => $value); -} - -sub add_single_check -{ - my $conf = shift; - my @check = split(m/,/, shift); - - my %c = (); - - if ($check[0] !~ m/\b(?:$valid_checks)\b/) { - return "ERROR: invalid check '$check[0]'"; - } - - $c{'name'} = $check[0]; - - if ((! defined($check[1])) || ($check[1] eq "")) { - $c{'target'} = qr//, - $c{'ttype'} = 'address', - } - elsif ($check[1] =~ m/^(?:$RE{'net'}{'IPv4'}|$IPv6_re)$/) { - $c{'target'} = $check[1]; - $c{'ttype'} = 'address'; - } - elsif ($check[1] =~ m/^\/(.*)\/$/) { - $c{'target'} = qr/$1/; - $c{'ttype'} = 'description'; - } - else { - $c{'target'} = $check[1]; - $c{'ttype'} = 'description'; - } - - $c{'warning'} = $check[2]; - $c{'critical'} = $check[3]; - - # check for valid thresholds - # set_threshold() will die if any threshold is not valid - $plugin->set_thresholds( - warning => $c{'warning'}, - critical => $c{'critical'}, - ) || $plugin->die("ERROR: Invalid thresholds: " - . "warning => $c{'warning'}, critical => $c{'critical'}"); - - push @{$conf->{'checks'}}, \%c; -} - -sub add_checks -{ - my $conf = shift; - my @checks = @_; - - my $err_str = "ERROR:"; - - if (scalar(@checks) == 0) { - $conf->{'checks'}[0] = { - name => 'peers_count', - target => qr//, - ttype => 'address', - warning => undef, - critical => undef, - }; - return 1; - } - - $conf->{'checks'} = []; - - foreach my $check (@checks) { - my $e; - - $e = add_single_check($conf, $check); - if ($e =~ m/^ERROR: (.*)$/) { - $err_str .= " $1,"; - } - } - - if ($err_str ne "ERROR:") { - $err_str =~ s/,$//; - $plugin->die($err_str); - } -} - -sub get_relevant_peers -{ - my $check = shift; - my @peers = @_; - - my @rpeers = (); - - my $cmp = sub { - my ($a, $b, undef) = @_; - if (ref $b) { - my $r = $a =~ $b; - verbose(3, "Checking peer '$a' against regex '$b' -> " - . ($r ? "true" : "false") . "."); - return $r; - } - else { - my $r = $a eq $b; - verbose(3, "Comparing peer '$a' with string '$b' -> " - . ($r ? "true" : "false") . "."); - return $r; - } - }; - - my $get_peer_elem; - - if ($check->{'ttype'} eq 'description') { - $get_peer_elem = \&get_peer_description; - } - else { - $get_peer_elem = \&get_peer_address; - } - - @rpeers = grep { $cmp->($get_peer_elem->($_), $check->{'target'}) } @peers; - return @rpeers; -} - -sub get_peer_element -{ - my $peer = shift; - my $elem = shift; - - my $e; - - if (! $peer) { - print STDERR "Cannot retrieve element '$elem' " - . "from undefined value.\n"; - return; - } - - $e = $peer->getElementsByTagName($elem); - if ((! $e) || (! $e->item(0))) { - print STDERR "Attribute '$elem' not found for peer.\n"; - verbose(4, "Peer was: " . Dumper($peer)); - return; - } - - return $e->item(0)->getFirstChild->getNodeValue; -} - -sub get_peer_description -{ - my $peer = shift; - return get_peer_element($peer, 'description'); -} - -sub get_peer_address -{ - my $peer = shift; - return get_peer_element($peer, 'peer-address'); -} - -sub verbose -{ - my $level = shift; - my @msgs = @_; - - if ($level > $conf{'verbose'}) { - return; - } - - foreach my $msg (@msgs) { - print "V$level: $msg\n"; - } -} - diff --git a/check_junos_vc.pl b/check_junos_vc.pl deleted file mode 100755 index d90bcbb..0000000 --- a/check_junos_vc.pl +++ /dev/null @@ -1,836 +0,0 @@ -#!/usr/bin/perl - -############################################################################# -# (c) 2001, 2003 Juniper Networks, Inc. # -# (c) 2011 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -use strict; -use warnings; - -use utf8; - -use Data::Dumper; - -use POSIX qw( :termios_h ); -use Nagios::Plugin; - -use JUNOS::Device; - -binmode STDOUT, ":utf8"; - -my $valid_checks = "members_count|master|backup|interfaces|version"; - -# TODO: -# (on newer JUNOS (10.4r5.5)) -# request chassis routing-engine master switch check -# -> graceful switchover status - -my $plugin = Nagios::Plugin->new( - plugin => 'check_junos_vc', - shortname => 'check_junos_vc', - version => '0.1', - url => 'http://oss.teamix.org/projects/monitoringplugins', - blurb => 'Monitor Juniper™ Switch Virtual Chassis.', - usage => -"Usage: %s [-v|--verbose] [-H ] [-p ] [-t ] [-P -"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 3-Clause -BSD License (see http://opensource.org/licenses/BSD-3-Clause).", - extra => " -This plugin connects to a Juniper™ Switch device and and checks Virtual -Chassis information. - -A check-tuple consists of the name of the check and, optionally, a \"target\" -which more closely specifies which characteristics should be checked, and -warning and critical thresholds: -checkname[,target[,warning[,critical]]] - -The following checks are available: - * members_count: Total number of members in the Virtual Chassis. If a target - is specified, only peers whose status (NotPrsnt, Prsnt) matches one of the - specified targets are taken into account. - - * master, backup: Check the number or assignment of master resp. backup - members. If a target is specified, check that those members whose serial - number matches the specified target have the requested role (master, - backup) assigned to them. Else, check the number of master resp. backup - members against the specified thresholds. - - * interfaces: Check that all VCP interfaces are up. If warning or critical - thresholds have been specified, also check the number of VCP interfaces - against the thresholds. - - * version: Check the version of all physically connected members. - -Warning and critical thresholds may be specified in the format documented at -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT.", -); - -# Predefined arguments (by Nagios::Plugin) -my @predefined_args = qw( - usage - help - version - extra-opts - timeout - verbose -); - -my @args = ( - { - spec => 'host|H=s', - usage => '-H, --host=HOSTNAME', - desc => 'Hostname/IP of Juniper box to connect to', - default => 'localhost', - }, - { - spec => 'port|p=i', - usage => '-p, --port=PORT', - desc => 'Port to connect to', - default => 22, - }, - { - spec => 'user|U=s', - usage => '-U, --user=USERNAME', - desc => 'Username to log into box as', - default => 'root', - }, - { - spec => 'password|P=s', - usage => '-P, --password=PASSWORD', - desc => 'Password for login username', - default => '', - }, -); - -my %conf = (); -my $junos = undef; - -foreach my $arg (@args) { - add_arg($plugin, $arg); -} - -$plugin->getopts; -# Initialize this first, so it may be used right away. -$conf{'verbose'} = $plugin->opts->verbose; - -foreach my $arg (@args) { - my @c = get_conf($plugin, $arg); - $conf{$c[0]} = $c[1]; -} - -foreach my $arg (@predefined_args) { - $conf{$arg} = $plugin->opts->$arg; -} - -add_checks(\%conf, @ARGV); - -if (! $plugin->opts->password) { - my $term = POSIX::Termios->new(); - my $lflag; - - print "Password: "; - - $term->getattr(fileno(STDIN)); - $lflag = $term->getlflag; - $term->setlflag($lflag & ~POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSANOW); - - $conf{'password'} = ; - chomp($conf{'password'}); - - $term->setlflag($lflag | POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSAFLUSH); - print "\n"; -} - -verbose(1, "Connecting to host $conf{'host'} as user $conf{'user'}."); -$junos = JUNOS::Device->new( - hostname => $conf{'host'}, - login => $conf{'user'}, - password => $conf{'password'}, - access => 'ssh', - 'ssh-compress' => 0); - -if (! ref $junos) { - $plugin->die("ERROR: failed to connect to " . $conf{'host'} . "!"); -} - -my $vc = undef; -my @vc_members = (); -my $have_vc_members = 0; - -foreach my $check (@{$conf{'checks'}}) { - my $code; - my $value; - - my @targets = (); - - if (defined $check->{'target'}) { - @targets = @{$check->{'target'}}; - } - - $plugin->set_thresholds( - warning => $check->{'warning'}, - critical => $check->{'critical'}, - ); - - if ($check->{'name'} eq 'members_count') { - my @relevant_members = (); - my $value = 0; - my $code; - - @vc_members = get_vc_members($junos); - - if (scalar(@targets)) { - foreach my $member (@vc_members) { - my $role = get_member_status($member); - if (scalar(grep { $role eq $_ } @targets)) { - push @relevant_members, $member; - $value++; - } - } - } - else { - @relevant_members = @vc_members; - $value = scalar(@vc_members); - } - - $code = $plugin->check_threshold($value); - - $plugin->add_message($code, "$value " . join(" + ", @targets) - . " member" . (($value == 1) ? "" : "s")); - my $label = 'members'; - if (scalar(@targets)) { - $label .= '[' . join('+', @targets) . ']'; - } - $plugin->add_perfdata( - label => $label, - value => $value, - min => 0, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - } - elsif (($check->{'name'} eq 'master') || ($check->{'name'} eq 'backup')) { - my $wanted_role = ($check->{'name'} eq 'master') - ? 'Master' : 'Backup'; - - my @wanted_members = (); - - my $value; - my $code; - - @vc_members = get_vc_members($junos); - - foreach my $member (@vc_members) { - my $role = get_member_role($member); - - if ($role eq $wanted_role) { - push @wanted_members, $member; - } - } - - if (scalar(@targets)) { - my @ok_targets = (); - my @fail_targets = (); - - $code = UNKNOWN; - - foreach my $target (@targets) { - if (scalar(grep { $target eq get_member_serial($_) } @wanted_members)) { - # requested target does have wanted role assigned - if (($code == UNKNOWN) || ($code == OK)) { - $code = OK; - } - else { - # we've had previous errors - $code = WARNING; - } - - push @ok_targets, $target; - } - else { - if (($code == OK) || ($code == WARNING)) { - # we've had previous success - $code = WARNING; - } - else { - $code = CRITICAL; - } - - push @fail_targets, $target; - } - } - - $plugin->add_message($code, scalar(@fail_targets) - . " missing/failed-over " . $check->{'name'} - . ((scalar(@fail_targets) == 1) ? "" : "s") - . (scalar(@fail_targets) - ? " (" . join(", ", @fail_targets) . ")" : "") - . ", " . scalar(@ok_targets) . " active " . $check->{'name'} - . ((scalar(@ok_targets) == 1) ? "" : "s") - . (scalar(@ok_targets) - ? " (" . join(", ", @ok_targets) . ")" : "")); - $plugin->add_perfdata( - label => 'active_' . $check->{'name'}, - value => scalar(@ok_targets), - min => 0, - max => undef, - uom => '', - threshold => undef, - ); - $plugin->add_perfdata( - label => 'failed_' . $check->{'name'}, - value => scalar(@fail_targets), - min => 0, - max => undef, - uom => '', - threshold => undef, - ); - } - else { - $value = scalar @wanted_members; - $code = $plugin->check_threshold($value); - - $plugin->add_message($code, "$value " . $check->{'name'} . " member" - . (($value == 1) ? "" : "s")); - $plugin->add_perfdata( - label => $check->{'name'}, - value => $value, - min => 0, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - } - } - elsif ($check->{'name'} eq 'interfaces') { - my @up_ifaces = (); - my @down_ifaces = (); - - my @vc_interfaces = get_vc_interfaces($junos); - - foreach my $iface (@vc_interfaces) { - my $status = get_iface_status($iface); - - if ($status eq 'up') { - push @up_ifaces, get_iface_name($iface); - next; - } - # else: - - push @down_ifaces, { - name => get_iface_name($iface), - status => $status, - }; - } - - if (scalar(@down_ifaces)) { - $plugin->add_message(CRITICAL, scalar(@down_ifaces) - . " VCP interface" . ((scalar(@down_ifaces) == 1) ? "" : "s") - . " not up (" - . join(", ", - map { "$_->{'name'} $_->{'status'}" } @down_ifaces) - . ")"); - } - elsif ($check->{'warning'} || $check->{'critical'}) { - my $value = scalar @vc_interfaces; - my $code = $plugin->check_threshold($value); - - $plugin->add_message($code, "$value VCP interface" - . (($value == 1) ? "" : "s") . " found (" - . scalar(@up_ifaces) . " up, " - . scalar(@down_ifaces) . " down)"); - } - elsif (! scalar(@up_ifaces)) { - # no VCP interfaces at all - $plugin->add_message(CRITICAL, "no VCP interfaces found"); - } - else { - $plugin->add_message(OK, "all VCP interfaces up"); - } - - $plugin->add_perfdata( - label => 'vcp_interfaces', - value => scalar(@vc_interfaces), - min => 0, - max => undef, - uom => '', - threshold => $plugin->threshold(), - ); - $plugin->add_perfdata( - label => 'up_interfaces', - value => scalar(@up_ifaces), - min => 0, - max => undef, - uom => '', - threshold => undef, - ); - $plugin->add_perfdata( - label => 'down_interfaces', - value => scalar(@down_ifaces), - min => 0, - max => undef, - uom => '', - threshold => undef, - ); - } - elsif ($check->{'name'} eq 'version') { - my %versions = get_versions($junos); - my @v_keys = keys %versions; - - my $first = undef; - - my @base_mismatch = (); - my %mismatches = (); - - foreach my $k (@v_keys) { - my $base = $versions{$k}->{'base'}; - my $other = $versions{$k}->{'other'}; - - foreach my $o (keys %$other) { - if ($other->{$o} ne $base) { - $mismatches{$k}->{$base} = 1; - $mismatches{$k}->{$other->{$o}} = 1; - } - } - } - - $first = shift @v_keys; - $first = $versions{$first}; - foreach my $k (@v_keys) { - if ($first->{'base'} ne $versions{$k}->{'base'}) { - push @base_mismatch, $k; - } - } - - if (scalar @base_mismatch) { - my @first_match = grep { - $versions{$_}->{'base'} eq $first->{'base'} - } keys %versions; - my %mismatches = (); - - foreach my $m (@base_mismatch) { - push @{$mismatches{$versions{$m}->{'base'}}}, $m; - } - - $plugin->add_message(CRITICAL, "version mismatch detected: " - . $first->{'base'} . " @ (" - . join(", ", @first_match) . ") != " - . join(" != ", map { - $_ . " @ (" . join(", ", @{$mismatches{$_}}) . ")" - } keys %mismatches)); - } - elsif (scalar(keys %mismatches)) { - $plugin->add_message(WARNING, "version mismatches detected: " - . join(" / ", map { - "$_: " . join(" != ", keys %{$mismatches{$_}}) - } keys %mismatches)); - } - else { - $plugin->add_message(OK, "all members at version " - . $first->{'base'}); - } - } -} - -# add total numbers to perfdata to ease graphing stuff -if ($have_vc_members) { - $plugin->add_perfdata( - label => 'members', - value => scalar(@vc_members), - min => 0, - max => undef, - uom => '', - threshold => undef, - ); -} - -my ($code, $msg) = $plugin->check_messages(join => ', '); - -$junos->disconnect(); - -$plugin->nagios_exit($code, $msg); - -sub send_query -{ - my $device = shift; - my $query = shift; - my $queryargs = shift; - - my $res; - my $err; - - verbose(3, "Sending query '$query' to router."); - - if (ref $queryargs) { - $res = $device->$query(%$queryargs); - } else { - $res = $device->$query(); - } - - verbose(5, "Got response: " . Dumper(\$res)); - - if (! ref $res) { - return "ERROR: Failed to execute query '$query'"; - } - - $err = $res->getFirstError(); - if ($err) { - return "ERROR: " . $err->{message}; - } - return $res; -} - -sub send_command -{ - my $device = shift; - my $cmd = shift; - - my $res; - my $err; - - verbose(3, "Sending command '$cmd' to router."); - - $res = $device->command($cmd); - - if (! ref $res) { - return "ERROR: Failed to execute command '$cmd'"; - } - - $err = $res->getFirstError(); - if ($err) { - return "ERROR: " . $err->{message}; - } - return $res; -} - -sub get_vc_information -{ - my $device = shift; - - my $cmd = "show virtual-chassis status"; - my $res = send_command($device, $cmd); - my $err; - - if (! ref $res) { - return $res; - } - return $res; -} - -sub get_vc_members -{ - my $device = shift; - - if ($have_vc_members) { - return @vc_members; - } - - $vc = get_vc_information($device); - if (! ref $vc) { - $plugin->die($vc); - } - my $vc_id = ($vc->getElementsByTagName('virtual-chassis-id-information'))[0]; - $vc_id = ($vc_id->getElementsByTagName('virtual-chassis-id'))[0]; - $vc_id = $vc_id->getFirstChild->getNodeValue; - - verbose(3, "Analyzing data from virtual chassis $vc_id."); - - @vc_members = ($vc->getElementsByTagName('member-list'))[0]->getElementsByTagName('member'); - if ($conf{'verbose'} >= 3) { - my @m = map { get_member_id($_) . " => " . get_member_serial($_) } - @vc_members; - verbose(3, "Members: " . join(", ", @m)); - } - $have_vc_members = 1; - return @vc_members; -} - -sub get_vc_interfaces -{ - my $device = shift; - my @ifaces = (); - - my $cmd = "get_interface_information"; - my %args = ( interface_name => 'vcp*' ); - my $res = send_query($device, $cmd, \%args); - - if (! ref $res) { - $plugin->die($res); - } - - @ifaces = $res->getElementsByTagName('physical-interface'); - if ($conf{'verbose'} >= 3) { - my @i = map { get_iface_name($_) . " => " . get_iface_status($_) } - @ifaces; - verbose(3, "VCP Interfaces: " . join(", ", @i)); - } - return @ifaces; -} - -sub get_versions -{ - my $device = shift; - my %versions = (); - - my $cmd = "show version"; - my $res = send_command($device, $cmd); - - my @v = (); - - if (! ref $res) { - $plugin->die($res); - } - - @v = $res->getElementsByTagName('multi-routing-engine-item'); - - foreach my $i (@v) { - my $name = get_obj_element($i, 're-name'); - my @infos = $i->getElementsByTagName('software-information'); - - @infos = $infos[0]->getElementsByTagName('package-information'); - - foreach my $j (@infos) { - my $comment = get_obj_element($j, 'comment'); - my ($desc, $version); - - $comment =~ m/^(.*) \[([^]]+)\]$/; - $desc = $1; - $version = $2; - - if ($desc eq "JUNOS Base OS boot") { - $versions{$name}->{'base'} = $version; - } - else { - $versions{$name}->{'other'}->{$desc} = $version; - } - } - } - return %versions; -} - -sub add_arg -{ - my $plugin = shift; - my $arg = shift; - - my $spec = $arg->{'spec'}; - my $help = $arg->{'usage'}; - - if (defined $arg->{'desc'}) { - my @desc; - - if (ref($arg->{'desc'})) { - @desc = @{$arg->{'desc'}}; - } - else { - @desc = ( $arg->{'desc'} ); - } - - foreach my $d (@desc) { - $help .= "\n $d"; - } - - if (defined $arg->{'default'}) { - $help .= " (default: $arg->{'default'})"; - } - } - elsif (defined $arg->{'default'}) { - $help .= "\n (default: $arg->{'default'})"; - } - - $plugin->add_arg( - spec => $spec, - help => $help, - ); -} - -sub get_conf -{ - my $plugin = shift; - my $arg = shift; - - my ($name, undef) = split(m/\|/, $arg->{'spec'}); - my $value = $plugin->opts->$name || $arg->{'default'}; - - if ($name eq 'password') { - verbose(3, "conf: password => " - . (($value eq '') ? '' : '')); - } - else { - verbose(3, "conf: $name => $value"); - } - return ($name => $value); -} - -sub add_single_check -{ - my $conf = shift; - my @check = split(m/,/, shift); - - my %c = (); - - if ($check[0] !~ m/\b(?:$valid_checks)\b/) { - return "ERROR: invalid check '$check[0]'"; - } - - $c{'name'} = $check[0]; - - $c{'target'} = undef; - if (defined($check[1])) { - $c{'target'} = [ split(m/\+/, $check[1]) ]; - } - - $c{'warning'} = $check[2]; - $c{'critical'} = $check[3]; - - # check for valid thresholds - # set_threshold() will die if any threshold is not valid - $plugin->set_thresholds( - warning => $c{'warning'}, - critical => $c{'critical'}, - ) || $plugin->die("ERROR: Invalid thresholds: " - . "warning => $c{'warning'}, critical => $c{'critical'}"); - - push @{$conf->{'checks'}}, \%c; -} - -sub add_checks -{ - my $conf = shift; - my @checks = @_; - - my $err_str = "ERROR:"; - - if (scalar(@checks) == 0) { - $conf->{'checks'}[0] = { - name => 'members_count', - target => [], - warning => undef, - critical => undef, - }; - return 1; - } - - $conf->{'checks'} = []; - - foreach my $check (@checks) { - my $e; - - $e = add_single_check($conf, $check); - if ($e =~ m/^ERROR: (.*)$/) { - $err_str .= " $1,"; - } - } - - if ($err_str ne "ERROR:") { - $err_str =~ s/,$//; - $plugin->die($err_str); - } -} - -sub get_obj_element -{ - my $obj = shift; - my $elem = shift; - - $elem = $obj->getElementsByTagName($elem); - return $elem->item(0)->getFirstChild->getNodeValue; -} - -sub get_member_id -{ - my $member = shift; - return get_obj_element($member, 'member-id'); -} - -sub get_member_serial -{ - my $member = shift; - return get_obj_element($member, 'member-serial-number'); -} - -sub get_member_status -{ - my $member = shift; - return get_obj_element($member, 'member-status'); -} - -sub get_member_role -{ - my $member = shift; - my $elem; - - $elem = $member->getElementsByTagName('member-role'); - if ($elem && $elem->item(0)) { - $elem = $elem->item(0)->getFirstChild->getNodeValue; - # e.g., '*' may be appended to the member-role - $elem =~ s/\W//g; - return $elem; - } - else { - return ""; - } -} - -sub get_iface_name -{ - my $iface = shift; - return get_obj_element($iface, 'name'); -} - -sub get_iface_status -{ - my $iface = shift; - return get_obj_element($iface, 'oper-status'); -} - -sub verbose -{ - my $level = shift; - my @msgs = @_; - - if ($level > $conf{'verbose'}) { - return; - } - - foreach my $msg (@msgs) { - print "V$level: $msg\n"; - } -} - diff --git a/check_naf_exports.pl b/check_naf_exports.pl deleted file mode 100755 index 8a1404e..0000000 --- a/check_naf_exports.pl +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/perl - -##################################################################### -# (c) 2012 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# This file is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published # -# by the Free Software Foundation, either version 2 of the License, # -# or (at your option) any later version. # -# # -# This file is distributed in the hope that it will be useful, but # -# WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this file. If not, see . # -##################################################################### - -use strict; -use warnings; - -use utf8; - -use FindBin qw( $Bin ); -use lib "$Bin/perl/lib"; -use Nagios::Plugin::NetApp; - -binmode STDOUT, ":utf8"; - -my $plugin = Nagios::Plugin::NetApp->new( - plugin => 'check_naf_exports', - shortname => 'check_naf_exports', - version => '0.1', - url => 'http://oss.teamix.org/projects/monitoringplugins', - blurb => 'Monitor NetApp™ NFS exports.', - usage => -"Usage: %s [-v|--verbose] [-H ] [-p ] [-t ] [-P -"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 License, either version 2 or (at your option) any later version -(see http://opensource.org/licenses/GPL-2.0).", - extra => " -This plugin connects to a NetApp™ filer and checks NFS exports related issues. - -A check-tuple consists of the name of the check and, optionally, a \"target\" -which more closely specifies which characteristics should be checked, and -warning and critical thresholds: -checkname[,target[,warning[,critical]]] - -The following checks are available: - * exportfs_consistent: Check if /etc/exports is consistent with the currently - exported filessytems. - -Warning and critical thresholds may be specified in the format documented at -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT.", -); - -my %checks = ( - exportfs_consistent => \&check_exportfs_consistent, -); - -my $srv = undef; - -$plugin->add_common_args(); - -foreach my $check (keys %checks) { - $plugin->add_check_impl($check, $checks{$check}); -} - -$plugin->set_default_check('exportfs_consistent'); - -# configure removes any options from @ARGV -$plugin->configure(); -$plugin->set_checks(@ARGV); -$srv = $plugin->connect(); - -$plugin->run_checks(); - -my ($code, $msg) = $plugin->check_messages(join => ', '); - -$plugin->nagios_exit($code, $msg); - -sub get_exports_rules -{ - my $srv = shift; - my $persistent = shift; - - my $res = undef; - - $res = $srv->invoke('nfs-exportfs-list-rules', 'persistent', $persistent); - $plugin->die_on_error($res, "Failed to read exports information"); - - if (! $res->child_get('rules')) { - return (); - } - - my %exports = (); - foreach my $rule ($res->child_get('rules')->children_get()) { - my %rule; - my $tmp; - - foreach my $info (qw( actual-pathname anon nosuid pathname )) { - $tmp = $rule->child_get_string($info); - if (defined($tmp)) { - $rule{$info} = $tmp; - } - } - - foreach my $info (qw( read-only read-write root )) { - my %info = (); - - if (! $rule->child_get($info)) { - next; - } - - foreach my $host_info ($rule->child_get($info)->children_get()) { - my $host; - - my $all_hosts = $host_info->child_get_string('all-hosts'); - my $negate = $host_info->child_get_string('negate'); - - $all_hosts ||= "false"; - $negate ||= "false"; - - if ($all_hosts eq 'true') { - $host = '*'; - } - else { - $host = $host_info->child_get_string('name'); - } - - if ($negate eq 'true') { - $info{$host} = 1; - } - else { - $info{$host} = 0; - } - } - - $rule{$info} = \%info; - } - - if ($rule->child_get('sec-flavor')) { - my %sec_flavors = map { - $_->child_get_string('flavor') => 1 - } $rule->child_get('sec-flavor')->children_get(); - $rule{'sec-flavor'} = \%sec_flavors; - } - - $exports{$rule{'pathname'}} = \%rule; - } - - return %exports; -} - -sub check_exportfs_consistent -{ - my $plugin = shift; - my $srv = shift; - my @targets = @_; - - my %exports = get_exports_rules($srv, 'true'); - my %memory = get_exports_rules($srv, 'false'); - - # diff export rules - foreach my $path (keys %memory) { - if (! defined($exports{$path})) { - $plugin->add_message(CRITICAL, - "$path not exported in /etc/exports"); - next; - } - - my %export = %{$exports{$path}}; - my %mem = %{$memory{$path}}; - - foreach my $info (qw( actual-pathname anon nosuid pathname )) { - my $e = $export{$info}; - my $m = $mem{$info}; - - if ((! defined($e)) && (! defined($m))) { - next; - } - - $e ||= ""; - $m ||= ""; - - if ($e ne $m) { - $plugin->add_message(CRITICAL, "$path: $info differ " - . "(exports: $e, exportfs: $m)"); - } - } - - foreach my $info (qw( read-only read-write root )) { - my $e = $export{$info}; - my $m = $mem{$info}; - - if ((! defined($e)) && (! defined($m))) { - next; - } - - foreach my $host (keys %$m) { - if (! defined($e->{$host})) { - $plugin->add_message(CRITICAL, "$path: " - . "$host does not have $info access in /etc/exports"); - next; - } - - if ($m->{$host} != $e->{$host}) { - $plugin->add_message(CRITICAL, "$path: " - . "$host is negated in " - . ($m->{$host} ? "/etc/exports" : "exportfs info")); - } - } - - foreach my $host (keys %$e) { - if (! defined($m->{$host})) { - $plugin->add_message(CRITICAL, "$path: " - . "$host does not have $info access in exportfs info"); - } - } - } - - my $e = $export{'sec-flavor'}; - my $m = $mem{'sec-flavor'}; - - if (! ((! defined($e)) && (! defined($m)))) { - $e ||= {}; - $m ||= {}; - - foreach my $flavor (keys %$m) { - if (! defined($e->{$flavor})) { - $plugin->add_message(CRITICAL, "$path: " - . "security flavor $flavor is not specified " - . "in /etc/exports"); - } - } - - foreach my $flavor (keys %$e) { - if (! defined($m->{$flavor})) { - $plugin->add_message(CRITICAL, "$path: " - . "security flavor $flavor is not specified " - . "in exportfs info"); - } - } - } - } - - foreach my $path (keys %exports) { - if (! defined($memory{$path})) { - $plugin->add_message(CRITICAL, - "$path not exported (according to 'exportfs')"); - } - } -} - diff --git a/perl/lib/Nagios/Plugin/JUNOS.pm b/perl/lib/Nagios/Plugin/JUNOS.pm deleted file mode 100644 index 7f468a0..0000000 --- a/perl/lib/Nagios/Plugin/JUNOS.pm +++ /dev/null @@ -1,540 +0,0 @@ -############################################################################# -# (c) 2011-2012 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -package Nagios::Plugin::JUNOS; - -use Carp; - -use Data::Dumper; - -use POSIX qw( :termios_h ); - -use Nagios::Plugin; -use JUNOS::Device; - -use Nagios::Plugin::Functions qw( %ERRORS %STATUS_TEXT @STATUS_CODES ); - -# re-export Nagios::Plugin's (default) exports -use Exporter; -our @ISA = qw( Nagios::Plugin Exporter ); -our @EXPORT = (@STATUS_CODES); -our @EXPORT_OK = qw( %ERRORS %STATUS_TEXT ); - -sub new -{ - my $class = shift; - my %args = @_; - - my $self = Nagios::Plugin->new(%args); - - $self->{'conf'} = { verbose => 0 }; - $self->{'cl_args'} = []; - $self->{'junos'} = undef; - - return bless($self, $class); -} - -sub add_arg -{ - my $self = shift; - my $arg = shift; - - my $spec = $arg->{'spec'}; - my $help; - - push @{$self->{'cl_args'}}, $arg; - - if (defined $arg->{'usage'}) { - $help = $arg->{'usage'}; - } - else { - $help = $arg->{'help'}; - } - - if (defined $arg->{'desc'}) { - my @desc; - - if (ref($arg->{'desc'})) { - @desc = @{$arg->{'desc'}}; - } - else { - @desc = ( $arg->{'desc'} ); - } - - foreach my $d (@desc) { - $help .= "\n $d"; - } - - if (defined $arg->{'default'}) { - $help .= " (default: $arg->{'default'})"; - } - } - elsif (defined $arg->{'default'}) { - $help .= "\n (default: $arg->{'default'})"; - } - - $self->SUPER::add_arg( - spec => $spec, - help => $help, - ); -} - -sub add_common_args -{ - my $self = shift; - - my @args = ( - { - spec => 'host|H=s', - usage => '-H, --host=HOSTNAME', - desc => 'Hostname/IP of Juniper box to connect to', - default => 'localhost', - }, - { - spec => 'port|p=i', - usage => '-p, --port=PORT', - desc => 'Port to connect to', - default => 22, - }, - { - spec => 'user|U=s', - usage => '-U, --user=USERNAME', - desc => 'Username to log into box as', - default => 'root', - }, - { - spec => 'password|P=s', - usage => '-P, --password=PASSWORD', - desc => 'Password for login username', - default => '', - }, - ); - - foreach my $arg (@args) { - $self->add_arg($arg); - } -} - -sub add_check_impl -{ - my $self = shift; - my $name = shift; - my $sub = shift; - - if ((! $name) || (! $sub) || (ref($sub) ne "CODE")) { - carp "Invalid check specification: $name -> $sub"; - return; - } - - if (! defined($self->{'check_impls'})) { - $self->{'check_impls'} = {}; - } - - $self->{'check_impls'}->{$name} = $sub; -} - -sub get_check_impl -{ - my $self = shift; - my $name = shift; - - if (! defined($self->{'check_impls'}->{$name})) { - return; - } - return $self->{'check_impls'}->{$name}; -} - -sub is_valid_check -{ - my $self = shift; - my $name = shift; - - if (defined $self->{'check_impls'}->{$name}) { - return 1; - } - return; -} - -sub set_default_check -{ - my $self = shift; - my $def = shift; - - if (! $self->is_valid_check($def)) { - carp "set_default_check: Check '$def' does not exist"; - return; - } - - $self->{'default_check'} = $def; -} - -sub configure -{ - my $self = shift; - - # Predefined arguments (by Nagios::Plugin) - my @predefined_args = qw( - usage - help - version - extra-opts - timeout - verbose - ); - - $self->getopts; - # Initialize this first, so it may be used right away. - $self->{'conf'}->{'verbose'} = $self->opts->verbose; - - foreach my $arg (@{$self->{'cl_args'}}) { - my @c = $self->_get_conf($arg); - $self->{'conf'}->{$c[0]} = $c[1]; - } - - foreach my $arg (@predefined_args) { - $self->{'conf'}->{$arg} = $self->opts->$arg; - } -} - -sub _get_conf -{ - my $self = shift; - my $arg = shift; - - my ($name, undef) = split(m/\|/, $arg->{'spec'}); - my $value = $self->opts->$name || $arg->{'default'}; - - if ($name eq 'password') { - $self->verbose(3, "conf: password => " - . (($value eq '') ? '' : '')); - } - else { - $self->verbose(3, "conf: $name => $value"); - } - return ($name => $value); -} - -sub _add_single_check -{ - my $self = shift; - my @check = split(m/,/, shift); - - my %c = (); - - if (! $self->is_valid_check($check[0])) { - return "ERROR: invalid check '$check[0]'"; - } - - $c{'name'} = $check[0]; - - $c{'target'} = undef; - if (defined($check[1])) { - my @tmp = split(m/(\+|\~)/, $check[1]); - - $c{'target'} = []; - $c{'exclude'} = []; - - for (my $i = 0; $i < scalar(@tmp); ++$i) { - my $t = $tmp[$i]; - - if ((($t ne "+") && ($t ne "~")) || ($i == $#tmp)) { - push @{$c{'target'}}, $t; - next; - } - - ++$i; - - if ($t eq "+") { - push @{$c{'target'}}, $tmp[$i]; - } - else { - push @{$c{'exclude'}}, $tmp[$i]; - } - } - } - - $c{'warning'} = $check[2]; - $c{'critical'} = $check[3]; - - # check for valid thresholds - # set_threshold() will die if any threshold is not valid - $self->set_thresholds( - warning => $c{'warning'}, - critical => $c{'critical'}, - ) || $self->die("ERROR: Invalid thresholds: " - . "warning => $c{'warning'}, critical => $c{'critical'}"); - - push @{$self->{'conf'}->{'checks'}}, \%c; -} - -sub set_checks -{ - my $self = shift; - my @checks = @_; - - my $err_str = "ERROR:"; - - if (! defined($self->{'conf'}->{'timeout'})) { - croak "No timeout set -- did you call configure()?"; - } - - if (scalar(@checks) == 0) { - if ($self->{'default_check'}) { - $self->{'conf'}->{'checks'}->[0] = { - name => $self->{'default_check'}, - target => [], - exclude => [], - warning => undef, - critical => undef, - }; - } - return 1; - } - - $self->{'conf'}->{'checks'} = []; - - foreach my $check (@checks) { - my $e; - - $e = $self->_add_single_check($check); - if ($e =~ m/^ERROR: (.*)$/) { - $err_str .= " $1,"; - } - } - - if ($err_str ne "ERROR:") { - $err_str =~ s/,$//; - $self->die($err_str); - } -} - -sub get_checks -{ - my $self = shift; - return @{$self->{'conf'}->{'checks'}}; -} - -sub connect -{ - my $self = shift; - - my $host = $self->{'conf'}->{'host'}; - my $user = $self->{'conf'}->{'user'}; - - if ((! $host) || (! $user)) { - croak "Host and/or user not set -- did you call configure()?"; - } - - if (! $self->opts->password) { - my $term = POSIX::Termios->new(); - my $lflag; - - print "Password: "; - - $term->getattr(fileno(STDIN)); - $lflag = $term->getlflag; - $term->setlflag($lflag & ~POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSANOW); - - $self->{'conf'}->{'password'} = ; - chomp($self->{'conf'}->{'password'}); - - $term->setlflag($lflag | POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSAFLUSH); - print "\n"; - } - - $self->verbose(1, "Connecting to host $host as user $user."); - $junos = JUNOS::Device->new( - hostname => $host, - login => $user, - password => $self->{'conf'}->{'password'}, - access => 'ssh', - 'ssh-compress' => 0); - - if (! ref $junos) { - $self->die("ERROR: failed to connect to $host!"); - } - - $self->{'junos'} = $junos; - return $junos; -} - -sub run_checks -{ - my $self = shift; - - foreach my $check ($self->get_checks()) { - my $targets = []; - my $exclude = []; - - if (defined $check->{'target'}) { - $targets = $check->{'target'}; - } - - if (defined $check->{'exclude'}) { - $exclude = $check->{'exclude'}; - } - - $self->set_thresholds( - warning => $check->{'warning'}, - critical => $check->{'critical'}, - ); - - my $sub = $self->get_check_impl($check->{'name'}); - $sub->($self, $self->{'junos'}, $targets, $exclude); - } -} - -sub send_query -{ - my $self = shift; - my $query = shift; - my $queryargs = shift || {}; - - my $res; - my $err; - - $self->verbose(3, "Sending query '$query' " - . join(", ", map { "$_ => $queryargs->{$_}" } keys %$queryargs) - . " to router."); - - if (scalar(keys %$queryargs)) { - $res = $self->{'junos'}->$query(%$queryargs); - } else { - eval { - $res = $self->{'junos'}->$query(); - }; - if ($@) { - $res = $self->{'junos'}->command($query); - } - } - - $self->verbose(5, "Got response: " . Dumper(\$res)); - - if (! ref $res) { - return "ERROR: Failed to execute query '$query'"; - } - - $err = $res->getFirstError(); - if ($err) { - return "ERROR: " . $err->{message}; - } - return $res; -} - -sub get_query_object -{ - my $self = shift; - my $res = shift; - my $spec = shift; - - if (! $res) { - return; - } - - if (! $spec) { - return $res; - } - - if (! ref($spec)) { - $spec = [ $spec ]; - } - - my $iter = $res; - for (my $i = 0; $i < scalar(@$spec) - 1; ++$i) { - my $tmp = $iter->getElementsByTagName($spec->[$i]); - - if ((! $tmp) || (! $tmp->item(0))) { - return; - } - - $iter = $tmp->item(0); - } - - if (wantarray) { - my @ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]); - return @ret; - } - else { - my $ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]); - if ((! $ret) || (! $ret->item(0))) { - return; - } - return $ret->item(0); - } -} - -sub get_query_object_value -{ - my $self = shift; - my $res = $self->get_query_object(@_); - - if (! $res) { - return; - } - - if (ref($res) eq "XML::DOM::NodeList") { - $res = $res->item(0); - } - - return $res->getFirstChild->getNodeValue; -} - -sub nagios_exit -{ - my $self = shift; - - if ($self->{'junos'}) { - $self->{'junos'}->disconnect(); - } - $self->SUPER::nagios_exit(@_); -} - -sub verbose -{ - my $self = shift; - my $level = shift; - my @msgs = @_; - - if ($level > $self->{'conf'}->{'verbose'}) { - return; - } - - foreach my $msg (@msgs) { - print "V$level: $msg\n"; - } -} - -return 1; - diff --git a/perl/lib/Nagios/Plugin/NetApp.pm b/perl/lib/Nagios/Plugin/NetApp.pm deleted file mode 100644 index 789bb94..0000000 --- a/perl/lib/Nagios/Plugin/NetApp.pm +++ /dev/null @@ -1,453 +0,0 @@ -############################################################################# -# (c) 2011-2012 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -package Nagios::Plugin::NetApp; - -use Carp; - -use POSIX qw( :termios_h ); - -use Nagios::Plugin; -use NaServer; - -use Nagios::Plugin::Functions qw( %ERRORS %STATUS_TEXT @STATUS_CODES ); - -# re-export Nagios::Plugin's (default) exports -use Exporter; -our @ISA = qw( Nagios::Plugin Exporter ); -our @EXPORT = (@STATUS_CODES); -our @EXPORT_OK = qw( %ERRORS %STATUS_TEXT ); - -sub new -{ - my $class = shift; - my %args = @_; - - my $self = Nagios::Plugin->new(%args); - - $self->{'conf'} = { verbose => 0 }; - $self->{'cl_args'} = []; - $self->{'srv'} = undef; - - return bless($self, $class); -} - -sub add_arg -{ - my $self = shift; - my $arg = shift; - - my $spec = $arg->{'spec'}; - my $help; - - push @{$self->{'cl_args'}}, $arg; - - if (defined $arg->{'usage'}) { - $help = $arg->{'usage'}; - } - else { - $help = $arg->{'help'}; - } - - if (defined $arg->{'desc'}) { - my @desc; - - if (ref($arg->{'desc'})) { - @desc = @{$arg->{'desc'}}; - } - else { - @desc = ( $arg->{'desc'} ); - } - - foreach my $d (@desc) { - $help .= "\n $d"; - } - - if (defined $arg->{'default'}) { - $help .= " (default: $arg->{'default'})"; - } - } - elsif (defined $arg->{'default'}) { - $help .= "\n (default: $arg->{'default'})"; - } - - $self->SUPER::add_arg( - spec => $spec, - help => $help, - ); -} - -sub add_common_args -{ - my $self = shift; - - my @args = ( - { - spec => 'host|H=s', - usage => '-H, --host=HOSTNAME', - desc => 'Hostname/IP of NetApp filer to connect to', - default => 'localhost', - }, - { - spec => 'port|p=i', - usage => '-p, --port=PORT', - desc => 'Port to connect to', - }, - { - spec => 'user|U=s', - usage => '-U, --user=USERNAME', - desc => 'Username to log into box as', - default => 'root', - }, - { - spec => 'password|P=s', - usage => '-P, --password=PASSWORD', - desc => 'Password for login username', - default => '', - }, - { - spec => 'transport|t=s', - usage => '-t, --transport=TRANSPORT', - desc => 'Transport for the connection', - default => 'HTTP', - }, - ); - - foreach my $arg (@args) { - $self->add_arg($arg); - } -} - -sub add_check_impl -{ - my $self = shift; - my $name = shift; - my $sub = shift; - - if ((! $name) || (! $sub) || (ref($sub) ne "CODE")) { - carp "Invalid check specification: $name -> $sub"; - return; - } - - if (! defined($self->{'check_impls'})) { - $self->{'check_impls'} = {}; - } - - $self->{'check_impls'}->{$name} = $sub; -} - -sub get_check_impl -{ - my $self = shift; - my $name = shift; - - if (! defined($self->{'check_impls'}->{$name})) { - return; - } - return $self->{'check_impls'}->{$name}; -} - -sub is_valid_check -{ - my $self = shift; - my $name = shift; - - if (defined $self->{'check_impls'}->{$name}) { - return 1; - } - return; -} - -sub set_default_check -{ - my $self = shift; - my $def = shift; - - if (! $self->is_valid_check($def)) { - carp "set_default_check: Check '$def' does not exist"; - return; - } - - $self->{'default_check'} = $def; -} - -sub configure -{ - my $self = shift; - - # Predefined arguments (by Nagios::Plugin) - my @predefined_args = qw( - usage - help - version - extra-opts - timeout - verbose - ); - - $self->getopts; - # Initialize this first, so it may be used right away. - $self->{'conf'}->{'verbose'} = $self->opts->verbose; - - foreach my $arg (@{$self->{'cl_args'}}) { - my @c = $self->_get_conf($arg); - $self->{'conf'}->{$c[0]} = $c[1]; - } - - foreach my $arg (@predefined_args) { - $self->{'conf'}->{$arg} = $self->opts->$arg; - } -} - -sub _get_conf -{ - my $self = shift; - my $arg = shift; - - my ($name, undef) = split(m/\|/, $arg->{'spec'}); - my $value = $self->opts->$name || $arg->{'default'}; - - if ($name eq 'password') { - $self->verbose(3, "conf: password => " - . (($value eq '') ? '' : '')); - } - else { - $self->verbose(3, "conf: $name => $value"); - } - return ($name => $value); -} - -sub _add_single_check -{ - my $self = shift; - my @check = split(m/,/, shift); - - my %c = (); - - if (! $self->is_valid_check($check[0])) { - return "ERROR: invalid check '$check[0]'"; - } - - $c{'name'} = $check[0]; - - $c{'target'} = undef; - if (defined($check[1])) { - $c{'target'} = [ split(m/\+/, $check[1]) ]; - } - - $c{'warning'} = $check[2]; - $c{'critical'} = $check[3]; - - # check for valid thresholds - # set_threshold() will die if any threshold is not valid - $self->set_thresholds( - warning => $c{'warning'}, - critical => $c{'critical'}, - ) || $self->die("ERROR: Invalid thresholds: " - . "warning => $c{'warning'}, critical => $c{'critical'}"); - - push @{$self->{'conf'}->{'checks'}}, \%c; -} - -sub set_checks -{ - my $self = shift; - my @checks = @_; - - my $err_str = "ERROR:"; - - if (! defined($self->{'conf'}->{'timeout'})) { - croak "No timeout set -- did you call configure()?"; - } - - if (scalar(@checks) == 0) { - if ($self->{'default_check'}) { - $self->{'conf'}->{'checks'}->[0] = { - name => $self->{'default_check'}, - target => [], - warning => undef, - critical => undef, - }; - } - return 1; - } - - $self->{'conf'}->{'checks'} = []; - - foreach my $check (@checks) { - my $e; - - $e = $self->_add_single_check($check); - if ($e =~ m/^ERROR: (.*)$/) { - $err_str .= " $1,"; - } - } - - if ($err_str ne "ERROR:") { - $err_str =~ s/,$//; - $self->die($err_str); - } -} - -sub get_checks -{ - my $self = shift; - return @{$self->{'conf'}->{'checks'}}; -} - -sub connect -{ - my $self = shift; - - my $host = $self->{'conf'}->{'host'}; - my $user = $self->{'conf'}->{'user'}; - - my $srv; - - if ((! $host) || (! $user)) { - croak "Host and/or user not set -- did you call configure()?"; - } - - if (! $self->opts->password) { - my $term = POSIX::Termios->new(); - my $lflag; - - print "Password: "; - - $term->getattr(fileno(STDIN)); - $lflag = $term->getlflag; - $term->setlflag($lflag & ~POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSANOW); - - $self->{'conf'}->{'password'} = ; - chomp($self->{'conf'}->{'password'}); - - $term->setlflag($lflag | POSIX::ECHO); - $term->setattr(fileno(STDIN), TCSAFLUSH); - print "\n"; - } - - $self->verbose(1, "Connecting to host $host as user $user."); - $srv = new NaServer($host, 1, 7); - if (! $srv) { - $self->die("ERROR: failed to connect to $host!"); - } - - $srv->set_admin_user($user, $self->{'conf'}->{'password'}); - $srv->set_transport_type($self->{'conf'}->{'transport'}); - - if ($self->{'conf'}->{'port'}) { - $srv->set_port($self->{'conf'}->{'port'}); - } - - $srv->set_timeout($self->{'conf'}->{'timeout'}); - - $self->{'srv'} = $srv; - return $srv; -} - -sub run_checks -{ - my $self = shift; - - foreach my $check ($self->get_checks()) { - my @targets = (); - - if (defined $check->{'target'}) { - @targets = @{$check->{'target'}}; - } - - $self->set_thresholds( - warning => $check->{'warning'}, - critical => $check->{'critical'}, - ); - - my $sub = $self->get_check_impl($check->{'name'}); - $sub->($self, $self->{'srv'}, @targets); - } -} - -sub get_error -{ - my $self = shift; - - my $res = shift; - my $msg = shift; - - if (! defined($res)) { - return "$msg: Unknown error"; - } - elsif ((ref($res) eq "NaElement") && (($res->results_errno != 0) - || ($res->results_status() eq "failed"))) { - return "$msg: " . $res->results_reason(); - } - return; -} - -sub die_on_error -{ - my $self = shift; - - if ($self->get_error(@_)) { - $self->die($self->get_error(@_)); - } - return 1; -} - -sub nagios_exit -{ - my $self = shift; - - if ($self->{'srv'}) { - $self->{'srv'} = undef; - } - $self->SUPER::nagios_exit(@_); -} - -sub verbose -{ - my $self = shift; - my $level = shift; - my @msgs = @_; - - if ($level > $self->{'conf'}->{'verbose'}) { - return; - } - - foreach my $msg (@msgs) { - print "V$level: $msg\n"; - } -} - -return 1; - diff --git a/plugin_wrapper.pl b/plugin_wrapper.pl deleted file mode 100755 index 4390715..0000000 --- a/plugin_wrapper.pl +++ /dev/null @@ -1,79 +0,0 @@ -#! /usr/bin/perl - -##################################################################### -# (c) 2012 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# # -# This file is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published # -# by the Free Software Foundation, either version 2 of the License, # -# or (at your option) any later version. # -# # -# This file is distributed in the hope that it will be useful, but # -# WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this file. If not, see . # -##################################################################### - -use strict; -use warnings; - -my $p_script = shift; -my @p_args = @ARGV; - -if (! $p_script) { - exit_usage(1); -} - -my $p_stdout; -my $p_pid = open($p_stdout, '-|', "$p_script @p_args 2>&1"); -if (! defined($p_pid)) { - print "CRITICAL: Failed to execute plugin ($p_script): $!\n"; - print "Commandline: $p_script @p_args\n"; - exit 2; -} - -my @p_output = <$p_stdout>; -if (waitpid($p_pid, 0) != $p_pid) { - print "UNKNOWN: Lost track of plugin process\n"; - exit 3; -} -my $p_rc = $?; -my $p_sig = $p_rc & 127; -my $p_cd = $p_rc & 128; # core dumped? -$p_rc >>= 8; -close $p_stdout; - -if ($p_sig || $p_cd) { - print "CRITICAL: Plugin died with signal $p_sig (exit code: $p_rc)" - . ($p_cd ? " (core dumped)" : "") . "\n"; - $p_rc = 2; -} - -if ($p_rc == 255) { - print "CRITICAL: Plugin died with status 255 " - . "(see details for more info)\n"; - print "Commandline: $p_script @p_args\n"; -} - -my $p_output = join('', @p_output); -print $p_output; - -if (($p_rc < 0) || ($p_rc > 3)) { - $p_rc = 3; -} - -exit $p_rc; - -sub exit_usage { - my $status = shift || 0; - print STDERR "Usage: $0 []\n"; - exit $status; -} - diff --git a/tools/junos_dump.pl b/tools/junos_dump.pl deleted file mode 100755 index 98a0760..0000000 --- a/tools/junos_dump.pl +++ /dev/null @@ -1,239 +0,0 @@ -#! /usr/bin/perl -w - -############################################################################# -# (c) 2001, 2003 Juniper Networks, Inc. # -# (c) 2011 Sebastian "tokkee" Harl # -# and team(ix) GmbH, Nuernberg, Germany # -# # -# This file is part of "team(ix) Monitoring Plugins" # -# URL: http://oss.teamix.org/projects/monitoringplugins/ # -# It is based on the example diagnose_bgp.pl script of the # -# JUNOScript distribution. # -# # -# All rights reserved. # -# Redistribution and use in source and binary forms, with or without # -# modification, are permitted provided that the following conditions # -# are met: # -# 1. Redistributions of source code must retain the above copyright # -# notice, this list of conditions and the following disclaimer. # -# 2. Redistributions in binary form must reproduce the above copyright # -# notice, this list of conditions and the following disclaimer in the # -# documentation and/or other materials provided with the distribution. # -# 3. The name of the copyright owner may not be used to endorse or # -# promote products derived from this software without specific prior # -# written permission. # -# # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, # -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # -# POSSIBILITY OF SUCH DAMAGE. # -############################################################################# - -use strict; -use warnings; - -use JUNOS::Device; -use JUNOS::Trace; -use Getopt::Std; -use Term::ReadKey; -use File::Basename; - -use Data::Dumper; - -my $jnx; - -# send a query -sub send_query -{ - my $device = shift; - my $query = shift; - my $href_queryargs = shift; - my $res; - unless ( ref $href_queryargs ) { - eval { - $res = $device->$query(); - }; - if ($@) { - $res = $device->command($query); - } - } else { - my %queryargs = %$href_queryargs; - print "$_ => $queryargs{$_}\n" foreach (keys %queryargs); - $res = $device->$query(%queryargs); - } - - unless ( ref $res ) { - print STDERR "ERROR: Failed to execute query '$query'\n"; - return 0; - } - - unless (ref $res) { - print STDERR "ERROR: failed to execute command $query\n"; - return undef; - } - - my $err = $res->getFirstError(); - if ($err) { - print STDERR "ERROR: ", $err->{message}, "\n"; - return 0; - } - - return $res; -} - -# get object identified by the specified spec -sub get_object_by_spec -{ - my $res = shift; - my $spec = shift; - - my $iter = $res; - for (my $i = 0; $i < scalar(@$spec) - 1; ++$i) { - my $tmp = $iter->getElementsByTagName($spec->[$i]); - - if ((! $tmp) || (! $tmp->item(0))) { - return; - } - - $iter = $tmp->item(0); - } - - if (wantarray) { - my @ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]); - return @ret; - } - else { - my $ret = $iter->getElementsByTagName($spec->[scalar(@$spec) - 1]); - if ((! $ret) || (! $ret->item(0))) { - return; - } - return $ret->item(0); - } -} - -# print the usage of this script -sub output_usage -{ - my $usage = "Usage: $0 [options] [= [...]] - -Where: - - The hostname of the target router. - The query to send to the target router. - -Options: - - -l A login name accepted by the target router. - -p The password for the login name. - -m Access method. It can be clear-text, ssl, ssh or telnet. Default: telnet. - -s Specify a value to extract from the output. - -o Output file. Default: dump.xml. - -d Turn on debug, full blast.\n\n"; - - die $usage; -} - -my %opt; -getopts('l:p:dm:x:o:s:h', \%opt) || output_usage(); -output_usage() if $opt{h}; - -# Check whether trace should be turned on -JUNOS::Trace::init(1) if $opt{d}; - -my $hostname = shift || output_usage(); -my $query = shift || output_usage(); - -my %args = map { split m/=/, $_ } @ARGV; -if ($opt{d}) { - print "Args:\n"; - foreach my $key (keys %args) { - print "\t$key => $args{$key}\n"; - } -} - -# Retrieve the access method, can only be telnet or ssh. -my $access = $opt{m} || "telnet"; -use constant VALID_ACCESSES => "telnet|ssh|clear-text|ssl"; -output_usage() unless (VALID_ACCESSES =~ /$access/); - -# Check whether login name has been entered. Otherwise prompt for it -my $login = ""; -if ($opt{l}) { - $login = $opt{l}; -} else { - print "login: "; - $login = ReadLine 0; - chomp $login; -} - -# Check whether password has been entered. Otherwise prompt for it -my $password = ""; -if ($opt{p}) { - $password = $opt{p}; -} else { - print "password: "; - ReadMode 'noecho'; - $password = ReadLine 0; - chomp $password; - ReadMode 'normal'; - print "\n"; -} - -# Get the name of the output file -my $outfile = $opt{o} || 'dump.xml'; - -# Retrieve command line arguments -my %deviceinfo = ( - access => $access, - login => $login, - password => $password, - hostname => $hostname, - 'ssh-compress' => 0, -); - -# -# CONNECT TO the JUNOScript server -# Create a device object that contains all necessary information to -# connect to the JUNOScript server at a specific router. -# - -$jnx = new JUNOS::Device(%deviceinfo); -unless ( ref $jnx ) { - die "ERROR: $deviceinfo{hostname}: failed to connect.\n"; -} - -my $spec = $opt{s} || undef; -if ($spec) { - $spec = [ split(",", $spec) ]; -} - -my $res = send_query($jnx, $query, scalar(keys %args) ? \%args : undef); -while ($res) { - if ($spec) { - $res = get_object_by_spec($res, $spec); - } - - if (! $res) { - print "NO OUTPUT!\n"; - last; - } - - if ($outfile eq "-") { - print STDOUT $res->toString; - } - else { - $res->printToFile($outfile); - } - last; -} - -$jnx->request_end_session(); -$jnx->disconnect(); -