123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- #!/usr/bin/perl
- #####################################################################
- # (c) 2012 Sebastian "tokkee" Harl <sh@teamix.net> #
- # 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 <http://www.gnu.org/licenses/>. #
- #####################################################################
- 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 <host>] [-p <port>] [-t <timeout]
- [-U <user>] [-P <password] 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 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 ||= "<empty>";
- $m ||= "<empty>";
- 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')");
- }
- }
- }
|