From 16e62dcfb256fd19349d48a9dee2b2dff9936738 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Fri, 13 Dec 2013 16:14:12 +0100 Subject: [PATCH] + New centreon plugin system --- .project | 11 - CHANGELOG | 22 - INSTALL | 8 - REQUIREMENT | 13 - centreon/plugins/dbi.pm | 266 + centreon/plugins/misc.pm | 143 + centreon/plugins/mode.pm | 93 + centreon/plugins/options.pm | 143 + centreon/plugins/output.pm | 656 ++ centreon/plugins/perfdata.pm | 253 + centreon/plugins/script.pm | 260 + centreon/plugins/script_custom.pm | 280 + centreon/plugins/script_simple.pm | 194 + centreon/plugins/script_snmp.pm | 213 + centreon/plugins/script_sql.pm | 280 + centreon/plugins/snmp.pm | 702 ++ centreon/plugins/statefile.pm | 185 + ...ss-service-perfdata => centreon_plugins.pl | 32 +- database/mysql/mode/connectiontime.pm | 123 + database/mysql/mode/databasessize.pm | 138 + .../mysql/mode/innodbbufferpoolhitrate.pm | 167 + database/mysql/mode/myisamkeycachehitrate.pm | 167 + database/mysql/mode/openfiles.pm | 134 + database/mysql/mode/queries.pm | 157 + database/mysql/mode/replicationmasterslave.pm | 347 + database/mysql/mode/slowqueries.pm | 153 + database/mysql/mode/threadsconnected.pm | 129 + database/mysql/mode/uptime.pm | 138 + database/mysql/mysqlcmd.pm | 347 + database/mysql/plugin.pm | 118 + database/postgres/mode/backends.pm | 170 + database/postgres/mode/connectiontime.pm | 123 + database/postgres/mode/hitratio.pm | 189 + database/postgres/mode/listdatabases.pm | 127 + database/postgres/mode/locks.pm | 172 + database/postgres/mode/querytime.pm | 167 + database/postgres/mode/timesync.pm | 125 + database/postgres/plugin.pm | 122 + database/postgres/psqlcmd.pm | 360 + example/custommode/simple.pm | 151 + example/mode/getvalue.pm | 126 + example/mode/launchcmd.pm | 122 + .../mode/testcustom.pm | 85 +- .../plugin_command.pm | 65 +- example/plugin_custom.pm | 76 + example/plugin_snmp.pm | 64 + .../server/hpbladechassis/mode/hardware.pm | 634 ++ hardware/server/hpbladechassis/plugin.pm | 64 + hardware/server/hpproliant/mode/hardware.pm | 586 ++ hardware/server/hpproliant/plugin.pm | 64 + install.sh | 234 - network/alteon/5224/plugin.pm | 66 + network/alteon/common/mode/cpu.pm | 159 + network/alteon/common/mode/hardware.pm | 195 + network/alteon/common/mode/memory.pm | 130 + network/bluecoat/mode/clientconnections.pm | 123 + network/bluecoat/mode/clientrequests.pm | 197 + network/bluecoat/mode/clienttraffic.pm | 181 + network/bluecoat/mode/cpu.pm | 157 + network/bluecoat/mode/disk.pm | 125 + network/bluecoat/mode/hardware.pm | 166 + network/bluecoat/mode/memory.pm | 139 + network/bluecoat/mode/serverconnections.pm | 123 + network/bluecoat/plugin.pm | 71 + network/cisco/3750/plugin.pm | 71 + network/cisco/asa/mode/failover.pm | 133 + network/cisco/asa/mode/sessions.pm | 169 + network/cisco/asa/plugin.pm | 71 + network/cisco/common/mode/cpu.pm | 171 + network/cisco/common/mode/environment.pm | 299 + network/cisco/common/mode/memory.pm | 147 + network/cisco/common/mode/stack.pm | 135 + network/juniper/common/mode/cpsessions.pm | 139 + network/juniper/common/mode/cpuforwarding.pm | 126 + network/juniper/common/mode/cpurouting.pm | 154 + network/juniper/common/mode/flowsessions.pm | 139 + network/juniper/common/mode/hardware.pm | 242 + .../juniper/common/mode/memoryforwarding.pm | 126 + network/juniper/common/mode/memoryrouting.pm | 151 + network/juniper/srx/plugin.pm | 74 + os/linux/mode/memory.pm | 176 + os/linux/mode/swap.pm | 150 + os/linux/plugin.pm | 75 + os/windows/mode/memory.pm | 150 + os/windows/mode/service.pm | 197 + os/windows/mode/swap.pm | 150 + os/windows/plugin.pm | 74 + snmp_standard/mode/cpu.pm | 130 + snmp_standard/mode/diskio.pm | 351 + snmp_standard/mode/dynamiccommand.pm | 205 + snmp_standard/mode/listinterfaces.pm | 303 + snmp_standard/mode/liststorages.pm | 264 + snmp_standard/mode/loadaverage.pm | 153 + snmp_standard/mode/numericvalue.pm | 226 + snmp_standard/mode/packeterrors.pm | 528 ++ snmp_standard/mode/processcount.pm | 217 + snmp_standard/mode/spanningtree.pm | 139 + snmp_standard/mode/storage.pm | 371 ++ snmp_standard/mode/stringvalue.pm | 178 + snmp_standard/mode/traffic.pm | 455 ++ snmp_standard/mode/uptime.pm | 122 + snmp_standard/plugin.pm | 66 + src/Centreon/SNMP/Utils.pm | 200 - src/centreon.conf | 51 - src/check_centreon_MS_multiple_services | 222 - src/check_centreon_dummy | 110 - src/check_centreon_ping | 226 - src/check_centreon_snmp_TcpConn | 167 - src/check_centreon_snmp_cpu | 190 - src/check_centreon_snmp_loadaverage | 183 - src/check_centreon_snmp_memory | 280 - src/check_centreon_snmp_multiple_process | 229 - src/check_centreon_snmp_packetErrors | 265 - src/check_centreon_snmp_process | 210 - src/check_centreon_snmp_process_detailed | 516 -- src/check_centreon_snmp_remote_storage | 457 -- src/check_centreon_snmp_string | 242 - src/check_centreon_snmp_traffic | 602 -- src/check_centreon_snmp_uptime | 183 - src/check_centreon_snmp_value | 419 -- src/check_centreon_snmp_value_table.pl | 526 -- src/check_meta_service | 490 -- src/check_snmp_cpfw.pl | 408 -- src/check_snmp_load.pl | 567 -- src/check_snmp_mem.pl | 407 -- src/check_snmp_process.pl | 550 -- src/check_snmp_script_result.pl | 164 - src/check_snmp_storage.pl | 522 -- src/check_snmp_win.pl | 310 - src/traps/conf/snmp.conf | 2 - src/traps/conf/snmptrapd.conf | 23 - src/traps/conf/snmptt | 5855 ----------------- src/traps/conf/snmptt.ini | 488 -- src/traps/conf/snmpttconvertmib | 964 --- storage/hplefthand/mode/hardware.pm | 522 ++ storage/hplefthand/plugin.pm | 64 + storage/netapp/mode/cpuload.pm | 114 + storage/netapp/mode/diskfailed.pm | 99 + storage/netapp/mode/fan.pm | 95 + storage/netapp/mode/filesys.pm | 270 + storage/netapp/mode/globalstatus.pm | 100 + storage/netapp/mode/listfilesys.pm | 202 + storage/netapp/mode/ndmpsessions.pm | 114 + storage/netapp/mode/nvram.pm | 99 + storage/netapp/mode/partnerstatus.pm | 118 + storage/netapp/mode/psu.pm | 95 + storage/netapp/mode/shelf.pm | 378 ++ storage/netapp/mode/snapmirrorlag.pm | 182 + .../netapp/mode/temperature.pm | 98 +- storage/netapp/mode/volumeoptions.pm | 184 + storage/netapp/plugin.pm | 77 + 151 files changed, 20932 insertions(+), 16464 deletions(-) delete mode 100644 .project delete mode 100644 CHANGELOG delete mode 100644 INSTALL delete mode 100644 REQUIREMENT create mode 100644 centreon/plugins/dbi.pm create mode 100644 centreon/plugins/misc.pm create mode 100644 centreon/plugins/mode.pm create mode 100644 centreon/plugins/options.pm create mode 100644 centreon/plugins/output.pm create mode 100644 centreon/plugins/perfdata.pm create mode 100644 centreon/plugins/script.pm create mode 100644 centreon/plugins/script_custom.pm create mode 100644 centreon/plugins/script_simple.pm create mode 100644 centreon/plugins/script_snmp.pm create mode 100644 centreon/plugins/script_sql.pm create mode 100644 centreon/plugins/snmp.pm create mode 100644 centreon/plugins/statefile.pm rename src/process-service-perfdata => centreon_plugins.pl (81%) create mode 100644 database/mysql/mode/connectiontime.pm create mode 100644 database/mysql/mode/databasessize.pm create mode 100644 database/mysql/mode/innodbbufferpoolhitrate.pm create mode 100644 database/mysql/mode/myisamkeycachehitrate.pm create mode 100644 database/mysql/mode/openfiles.pm create mode 100644 database/mysql/mode/queries.pm create mode 100644 database/mysql/mode/replicationmasterslave.pm create mode 100644 database/mysql/mode/slowqueries.pm create mode 100644 database/mysql/mode/threadsconnected.pm create mode 100644 database/mysql/mode/uptime.pm create mode 100644 database/mysql/mysqlcmd.pm create mode 100644 database/mysql/plugin.pm create mode 100644 database/postgres/mode/backends.pm create mode 100644 database/postgres/mode/connectiontime.pm create mode 100644 database/postgres/mode/hitratio.pm create mode 100644 database/postgres/mode/listdatabases.pm create mode 100644 database/postgres/mode/locks.pm create mode 100644 database/postgres/mode/querytime.pm create mode 100644 database/postgres/mode/timesync.pm create mode 100644 database/postgres/plugin.pm create mode 100644 database/postgres/psqlcmd.pm create mode 100644 example/custommode/simple.pm create mode 100644 example/mode/getvalue.pm create mode 100644 example/mode/launchcmd.pm rename src/submit_host_check_result => example/mode/testcustom.pm (65%) rename src/submit_service_check_result => example/plugin_command.pm (62%) create mode 100644 example/plugin_custom.pm create mode 100644 example/plugin_snmp.pm create mode 100644 hardware/server/hpbladechassis/mode/hardware.pm create mode 100644 hardware/server/hpbladechassis/plugin.pm create mode 100644 hardware/server/hpproliant/mode/hardware.pm create mode 100644 hardware/server/hpproliant/plugin.pm delete mode 100755 install.sh create mode 100644 network/alteon/5224/plugin.pm create mode 100644 network/alteon/common/mode/cpu.pm create mode 100644 network/alteon/common/mode/hardware.pm create mode 100644 network/alteon/common/mode/memory.pm create mode 100644 network/bluecoat/mode/clientconnections.pm create mode 100644 network/bluecoat/mode/clientrequests.pm create mode 100644 network/bluecoat/mode/clienttraffic.pm create mode 100644 network/bluecoat/mode/cpu.pm create mode 100644 network/bluecoat/mode/disk.pm create mode 100644 network/bluecoat/mode/hardware.pm create mode 100644 network/bluecoat/mode/memory.pm create mode 100644 network/bluecoat/mode/serverconnections.pm create mode 100644 network/bluecoat/plugin.pm create mode 100644 network/cisco/3750/plugin.pm create mode 100644 network/cisco/asa/mode/failover.pm create mode 100644 network/cisco/asa/mode/sessions.pm create mode 100644 network/cisco/asa/plugin.pm create mode 100644 network/cisco/common/mode/cpu.pm create mode 100644 network/cisco/common/mode/environment.pm create mode 100644 network/cisco/common/mode/memory.pm create mode 100644 network/cisco/common/mode/stack.pm create mode 100644 network/juniper/common/mode/cpsessions.pm create mode 100644 network/juniper/common/mode/cpuforwarding.pm create mode 100644 network/juniper/common/mode/cpurouting.pm create mode 100644 network/juniper/common/mode/flowsessions.pm create mode 100644 network/juniper/common/mode/hardware.pm create mode 100644 network/juniper/common/mode/memoryforwarding.pm create mode 100644 network/juniper/common/mode/memoryrouting.pm create mode 100644 network/juniper/srx/plugin.pm create mode 100644 os/linux/mode/memory.pm create mode 100644 os/linux/mode/swap.pm create mode 100644 os/linux/plugin.pm create mode 100644 os/windows/mode/memory.pm create mode 100644 os/windows/mode/service.pm create mode 100644 os/windows/mode/swap.pm create mode 100644 os/windows/plugin.pm create mode 100644 snmp_standard/mode/cpu.pm create mode 100644 snmp_standard/mode/diskio.pm create mode 100644 snmp_standard/mode/dynamiccommand.pm create mode 100644 snmp_standard/mode/listinterfaces.pm create mode 100644 snmp_standard/mode/liststorages.pm create mode 100644 snmp_standard/mode/loadaverage.pm create mode 100644 snmp_standard/mode/numericvalue.pm create mode 100644 snmp_standard/mode/packeterrors.pm create mode 100644 snmp_standard/mode/processcount.pm create mode 100644 snmp_standard/mode/spanningtree.pm create mode 100644 snmp_standard/mode/storage.pm create mode 100644 snmp_standard/mode/stringvalue.pm create mode 100644 snmp_standard/mode/traffic.pm create mode 100644 snmp_standard/mode/uptime.pm create mode 100644 snmp_standard/plugin.pm delete mode 100644 src/Centreon/SNMP/Utils.pm delete mode 100644 src/centreon.conf delete mode 100644 src/check_centreon_MS_multiple_services delete mode 100644 src/check_centreon_dummy delete mode 100644 src/check_centreon_ping delete mode 100644 src/check_centreon_snmp_TcpConn delete mode 100644 src/check_centreon_snmp_cpu delete mode 100644 src/check_centreon_snmp_loadaverage delete mode 100644 src/check_centreon_snmp_memory delete mode 100644 src/check_centreon_snmp_multiple_process delete mode 100644 src/check_centreon_snmp_packetErrors delete mode 100644 src/check_centreon_snmp_process delete mode 100644 src/check_centreon_snmp_process_detailed delete mode 100644 src/check_centreon_snmp_remote_storage delete mode 100644 src/check_centreon_snmp_string delete mode 100644 src/check_centreon_snmp_traffic delete mode 100644 src/check_centreon_snmp_uptime delete mode 100644 src/check_centreon_snmp_value delete mode 100644 src/check_centreon_snmp_value_table.pl delete mode 100644 src/check_meta_service delete mode 100644 src/check_snmp_cpfw.pl delete mode 100644 src/check_snmp_load.pl delete mode 100644 src/check_snmp_mem.pl delete mode 100644 src/check_snmp_process.pl delete mode 100644 src/check_snmp_script_result.pl delete mode 100644 src/check_snmp_storage.pl delete mode 100644 src/check_snmp_win.pl delete mode 100644 src/traps/conf/snmp.conf delete mode 100644 src/traps/conf/snmptrapd.conf delete mode 100644 src/traps/conf/snmptt delete mode 100644 src/traps/conf/snmptt.ini delete mode 100644 src/traps/conf/snmpttconvertmib create mode 100644 storage/hplefthand/mode/hardware.pm create mode 100644 storage/hplefthand/plugin.pm create mode 100644 storage/netapp/mode/cpuload.pm create mode 100644 storage/netapp/mode/diskfailed.pm create mode 100644 storage/netapp/mode/fan.pm create mode 100644 storage/netapp/mode/filesys.pm create mode 100644 storage/netapp/mode/globalstatus.pm create mode 100644 storage/netapp/mode/listfilesys.pm create mode 100644 storage/netapp/mode/ndmpsessions.pm create mode 100644 storage/netapp/mode/nvram.pm create mode 100644 storage/netapp/mode/partnerstatus.pm create mode 100644 storage/netapp/mode/psu.pm create mode 100644 storage/netapp/mode/shelf.pm create mode 100644 storage/netapp/mode/snapmirrorlag.pm rename src/centreon.pm => storage/netapp/mode/temperature.pm (55%) create mode 100644 storage/netapp/mode/volumeoptions.pm create mode 100644 storage/netapp/plugin.pm diff --git a/.project b/.project deleted file mode 100644 index bc15201e8..000000000 --- a/.project +++ /dev/null @@ -1,11 +0,0 @@ - - - Plugins - - - - - - - - diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index ab35ef867..000000000 --- a/CHANGELOG +++ /dev/null @@ -1,22 +0,0 @@ -########################## -# Centreon Plugins Change Log -########################## - -1.2.3 - 02/11/2005 ----------------- -* Enhanced Oreon Perl Package oreon.pm (wistof) -* Integration of some Manubulon plugins (wistof) -* New install script for plugins (wistof) -* Minor bug fixes - -1.2.2 - xx/08/2005 ----------------- -* Add Oreon Perl Package oreon.pm (gollum123) -* Globalization of paths in oreon.conf (gollum123) -* Management of RRDTOOL errors (wistof) -* Use Net::SNMP instead of snmpwalk and snmpget (wistof) -* Disable regex for '-H' option (wistof) -* Minor bug fixes - - - diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 8c50a6f25..000000000 --- a/INSTALL +++ /dev/null @@ -1,8 +0,0 @@ -################################# -# Centreon Plugins Installation # -################################# - -- just run install.sh in src/ directory -- don't directly copy plugins in Nagios plugins directory - - diff --git a/REQUIREMENT b/REQUIREMENT deleted file mode 100644 index 8f96b4663..000000000 --- a/REQUIREMENT +++ /dev/null @@ -1,13 +0,0 @@ -################################ -# Centreon Plugins Requirement # -################################ - -- Perl in /usr/bin/perl - or just run 'perl script' -- Net::SNMP -- Getopt::Long; -- FindBin::Bin; -- Config::IniFiles -- centreon perl module (centreon.pm) -- Centreon configuration file for Centreon perl module (Centreon.conf) -- file 'utils.pm' in plugins diretory (/usr/local/nagios/libexec) -- sed program for installation script \ No newline at end of file diff --git a/centreon/plugins/dbi.pm b/centreon/plugins/dbi.pm new file mode 100644 index 000000000..f512594d9 --- /dev/null +++ b/centreon/plugins/dbi.pm @@ -0,0 +1,266 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::dbi; + +use strict; +use warnings; +use DBI; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class DBI: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class DBI: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { "datasource:s@" => { name => 'data_source' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "sql-errors-exit:s" => { name => 'sql_errors_exit', default => 'unknown' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'DBI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{instance} = undef; + $self->{statement_handle} = undef; + $self->{version} = undef; + + $self->{data_source} = undef; + $self->{username} = undef; + $self->{password} = undef; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still data_source + # return 0 = no data_source left + + $self->{data_source} = (defined($self->{option_results}->{data_source})) ? shift(@{$self->{option_results}->{data_source}}) : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : undef; + $self->{sql_errors_exit} = $self->{option_results}->{sql_errors_exit}; + + if (!defined($self->{data_source}) || $self->{data_source} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify database arguments."); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + + if (scalar(@{$self->{option_results}->{data_source}}) == 0) { + return 0; + } + return 1; +} + +sub quote { + my $self = shift; + + if (defined($self->{instance})) { + return $self->{instance}->quote($_[0]); + } + return undef; +} + +sub is_version_minimum { + my ($self, %options) = @_; + # $options{version} = string version to check + + my @version_src = split /\./, $self->{version}; + my @versions = split /\./, $options{version}; + for (my $i = 0; $i < scalar(@versions); $i++) { + return 1 if ($versions[$i] eq 'x'); + return 1 if (!defined($version_src[$i])); + $version_src[$i] =~ /^([0-9]*)/; + next if ($versions[$i] == int($1)); + return 0 if ($versions[$i] > int($1)); + return 1 if ($versions[$i] < int($1)); + } + + return 1; +} + +sub connect { + my ($self, %options) = @_; + my $dontquit = (defined($options{dontquit}) && $options{dontquit} == 1) ? 1 : 0; + + $self->{instance} = DBI->connect( + "DBI:". $self->{data_source}, + $self->{username}, + $self->{password}, + { "RaiseError" => 0, "PrintError" => 0, "AutoCommit" => 1 } + ); + + if (!defined($self->{instance})) { + if ($dontquit == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot connect: " . $DBI::errstr); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + return (-1, "Cannot connect: " . $DBI::errstr); + } + + $self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER + return 0; +} + +sub get_id { + my ($self, %options) = @_; + + return $self->{data_source}; +} + +sub get_unique_id4save { + my ($self, %options) = @_; + + return md5_hex($self->{data_source}); +} + +sub fetchall_arrayref { + my ($self, %options) = @_; + + return $self->{statement_handle}->fetchall_arrayref(); +} + +sub fetchrow_array { + my ($self, %options) = @_; + + return $self->{statement_handle}->fetchrow_array(); +} + +sub fetchrow_hashref { + my ($self, %options) = @_; + + return $self->{statement_handle}->fetchrow_hashref(); +} + +sub query { + my ($self, %options) = @_; + + $self->{statement_handle} = $self->{instance}->prepare($options{query}); + if (!defined($self->{statement_handle})) { + $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{instance}->errstr); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + + my $rv = $self->{statement_handle}->execute; + if (!$rv) { + $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{statement_handle}->errstr); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } +} + +1; + +__END__ + +=head1 NAME + +DBI global + +=head1 SYNOPSIS + +dbi class + +=head1 DBI OPTIONS + +=over 8 + +=item B<--datasource> + +Hostname to query (required). + +=item B<--username> + +Database username. + +=item B<--password> + +Database password. + +=item B<--sql-errors-exit> + +Exit code for DB Errors (default: unknown) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/misc.pm b/centreon/plugins/misc.pm new file mode 100644 index 000000000..598d4bbec --- /dev/null +++ b/centreon/plugins/misc.pm @@ -0,0 +1,143 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::misc; + +use strict; +use warnings; + +sub mymodule_load { + my (%options) = @_; + my $file; + ($file = $options{module} . ".pm") =~ s{::}{/}g; + + eval { + local $SIG{__DIE__} = 'IGNORE'; + require $file; + }; + if ($@) { + $options{output}->add_option_msg(long_msg => $@); + $options{output}->add_option_msg(short_msg => $options{error_msg}); + $options{output}->option_exit(); + } +} + +sub backtick { + my %arg = ( + command => undef, + arguments => [], + timeout => 30, + wait_exit => 0, + redirect_stderr => 0, + @_, + ); + my @output; + my $pid; + my $return_code; + + my $sig_do; + if ($arg{wait_exit} == 0) { + $sig_do = 'IGNORE'; + $return_code = undef; + } else { + $sig_do = 'DEFAULT'; + } + local $SIG{CHLD} = $sig_do; + + if (!defined($pid = open( KID, "-|" ))) { + return (-1001, "Cant fork: $!", -1); + } + + if ($pid) { + + eval { + local $SIG{ALRM} = sub { die "Timeout by signal ALARM\n"; }; + alarm( $arg{timeout} ); + while () { + chomp; + push @output, $_; + } + + alarm(0); + }; + + if ($@) { + if ($pid != -1) { + kill -9, $pid; + } + + alarm(0); + return (-1000, "Command too long to execute (timeout)...", -1); + } else { + if ($arg{wait_exit} == 1) { + # We're waiting the exit code + waitpid($pid, 0); + $return_code = ($? >> 8); + } + close KID; + } + } else { + # child + # set the child process to be a group leader, so that + # kill -9 will kill it and all its descendents + setpgrp( 0, 0 ); + + if ($arg{redirect_stderr} == 1) { + open STDERR, ">&STDOUT"; + } + open STDERR, ">&STDOUT"; + if (scalar(@{$arg{arguments}}) <= 0) { + exec($arg{command}); + } else { + exec($arg{command}, @{$arg{arguments}}); + } + exit(0); + } + + return (0, join("\n", @output), $return_code); +} + +sub trim { + # Sometimes there is a null character + $_[0] =~ s/\x00$//; + $_[0] =~ s/^[ \t]+//; + $_[0] =~ s/[ \t]+$//; + return $_[0]; +} + +1; + +__END__ + diff --git a/centreon/plugins/mode.pm b/centreon/plugins/mode.pm new file mode 100644 index 000000000..cc4a895cd --- /dev/null +++ b/centreon/plugins/mode.pm @@ -0,0 +1,93 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::mode; + +use strict; +use warnings; +use centreon::plugins::perfdata; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{perfdata} = centreon::plugins::perfdata->new(output => $options{output}); + %{$self->{option_results}} = (); + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{version} = undef; + + return $self; +} + +sub init { + my ($self, %options) = @_; + # options{default} = [ {option_name => '', option_value => '' }, ] + + %{$self->{option_results}} = %{$options{option_results}}; + # Manage default value + return if (!defined($options{default})); + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + foreach my $value (keys %{$options{default}->{$_}}) { + if (!defined($self->{option_results}->{$value})) { + $self->{option_results}->{$value} = $options{default}->{$_}->{$value}; + } + } + } + } +} + +sub version { + my ($self, %options) = @_; + + $self->{output}->add_option_msg(short_msg => "Mode Version: " . $self->{version}); +} + +sub disco_format { + my ($self, %options) = @_; + +} + +sub disco_show { + my ($self, %options) = @_; + +} + +1; + +__END__ + diff --git a/centreon/plugins/options.pm b/centreon/plugins/options.pm new file mode 100644 index 000000000..73acddc6c --- /dev/null +++ b/centreon/plugins/options.pm @@ -0,0 +1,143 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::options; +use Pod::Usage; +use Pod::Find qw(pod_where); +use Getopt::Long; +Getopt::Long::Configure("pass_through"); +Getopt::Long::Configure('bundling'); + +sub new { + my $class = shift; + my $self = {}; + bless $self, $class; + + $self->{options_stored} = {}; + $self->{options} = {}; + @{$self->{pod_package}} = (); + $self->{pod_packages_once} = {}; + return $self; +} + +sub set_output { + my ($self, %options) = @_; + + $self->{output} = $options{output}; +} + +sub display_help { + my ($self, %options) = @_; + + foreach (@{$self->{pod_package}}) { + my $stdout; + + { + local *STDOUT; + open STDOUT, '>', \$stdout; + pod2usage(-exitval => 'NOEXIT', -input => pod_where({-inc => 1}, $_->{package}), + -verbose => 99, + -sections => $_->{sections}); + } + + $self->{output}->add_option_msg(long_msg => $stdout) if (defined($stdout)); + } +} + +sub add_help { + my ($self, %options) = @_; + # $options{package} = string package + # $options{sections} = string sections + # $options{help_first} = put at the beginning + # $options{once} = put help only one time for a package + + if (defined($options{once}) && defined($self->{pod_packages_once}->{$options{package}})) { + return ; + } + + if (defined($options{help_first})) { + shift @{$self->{pod_package}}, {package => $options{package}, sections => $options{sections}}; + } else { + push @{$self->{pod_package}}, {package => $options{package}, sections => $options{sections}}; + } + + $self->{pod_packages_once}->{$options{package}} = 1; +} + +sub add_options { + my ($self, %options) = @_; + # $options{arguments} = ref to hash table with string and name to store (example: { 'mode:s' => { name => 'mode', default => 'defaultvalue' ) + + foreach (keys %{$options{arguments}}) { + if (defined($options{arguments}->{$_}->{default})) { + $self->{options_stored}->{$options{arguments}->{$_}->{name}} = $options{arguments}->{$_}->{default}; + } else { + $self->{options_stored}->{$options{arguments}->{$_}->{name}} = undef; + } + $self->{options}->{$_} = \$self->{options_stored}->{$options{arguments}->{$_}->{name}}; + } +} + +sub parse_options { + my $self = shift; + #%{$self->{options_stored}} = (); + + GetOptions( + %{$self->{options}} + ); + %{$self->{options}} = (); +} + +sub get_option { + my ($self, %options) = @_; + + return $self->{options_stored}->{$options{argument}}; +} + +sub get_options { + my $self = shift; + + return $self->{options_stored}; +} + +sub clean { + my $self = shift; + + $self->{options_stored} = {}; +} + +1; + +__END__ diff --git a/centreon/plugins/output.pm b/centreon/plugins/output.pm new file mode 100644 index 000000000..9e73949f9 --- /dev/null +++ b/centreon/plugins/output.pm @@ -0,0 +1,656 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::output; +use Encode; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options->{options} = options object + if (!defined($options{options})) { + print "Class Output: Need to specify 'options' argument to load.\n"; + exit 3; + } + + $options{options}->add_options(arguments => + { + "ignore-perfdata" => { name => 'ignore_perfdata' }, + "verbose" => { name => 'verbose' }, + "opt-exit:s" => { name => 'opt_exit', default => 'unknown' }, + "output-xml" => { name => 'output_xml' }, + "output-json" => { name => 'output_json' }, + "disco-format" => { name => 'disco_format' }, + "disco-show" => { name => 'disco_show' }, + }); + %{$self->{option_results}} = (); + + $self->{option_msg} = []; + + $self->{is_output_xml} = 0; + $self->{is_output_json} = 0; + $self->{errors} = {OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => 3, PENDING => 4}; + $self->{myerrors} = {0 => "OK", 1 => "WARNING", 3 => "CRITICAL", 7 => "UNKNOWN"}; + $self->{myerrors_mask} = {CRITICAL => 3, WARNING => 1, UNKNOWN => 7, OK => 0}; + $self->{global_short_concat_outputs} = {OK => undef, WARNING => undef, CRITICAL => undef, UNKNOWN => undef, UNQUALIFIED_YET => undef}; + $self->{global_short_outputs} = {OK => [], WARNING => [], CRITICAL => [], UNKNOWN => [], UNQUALIFIED_YET => []}; + $self->{global_long_output} = []; + $self->{perfdatas} = []; + $self->{global_status} = 0; + + $self->{disco_elements} = []; + $self->{disco_entries} = []; + + $self->{plugin} = ''; + $self->{mode} = ''; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + # $options{option_results} = ref to options result + + %{$self->{option_results}} = %{$options{option_results}}; + $self->{option_results}->{opt_exit} = lc($self->{option_results}->{opt_exit}); + if (!$self->is_litteral_status(status => $self->{option_results}->{opt_exit})) { + $self->add_option_msg(short_msg => "Unknown value '" . $self->{option_results}->{opt_exit} . "' for --opt-exit."); + $self->option_exit(exit_litteral => 'unknown'); + } + # Go in XML Mode + if ($self->is_disco_show() || $self->is_disco_format()) { + # By Default XML + if (!defined($self->{option_results}->{output_json})) { + $self->{option_results}->{output_xml} = 1; + } + } +} + +sub add_option_msg { + my ($self, %options) = @_; + # $options{short_msg} = string msg + # $options{long_msg} = string msg + $options{severity} = 'UNQUALIFIED_YET'; + + $self->output_add(%options); +} + +sub set_status { + my ($self, %options) = @_; + # $options{exit_litteral} = string litteral exit + + # Nothing to do for 'UNQUALIFIED_YET' + if (!$self->{myerrors_mask}->{uc($options{exit_litteral})}) { + return ; + } + $self->{global_status} |= $self->{myerrors_mask}->{uc($options{exit_litteral})}; +} + +sub output_add { + my ($self, %params) = @_; + my %args = ( + severity => 'OK', + separator => ' - ', + short_msg => undef, + long_msg => undef + ); + my $options = {%args, %params}; + + if (defined($options->{short_msg})) { + chomp $options->{short_msg}; + if (defined($self->{global_short_concat_outputs}->{uc($options->{severity})})) { + $self->{global_short_concat_outputs}->{uc($options->{severity})} .= $options->{separator} . $options->{short_msg}; + } else { + $self->{global_short_concat_outputs}->{uc($options->{severity})} = $options->{short_msg}; + } + + push @{$self->{global_short_outputs}->{uc($options->{severity})}}, $options->{short_msg}; + $self->set_status(exit_litteral => $options->{severity}); + } + if (defined($options->{long_msg})) { + chomp $options->{long_msg}; + push @{$self->{global_long_output}}, $options->{long_msg}; + } +} + +sub perfdata_add { + my ($self, %options) = @_; + my $perfdata = {'label' => '', 'value' => '', unit => '', warning => '', critical => '', min => '', max => ''}; + $perfdata = {%$perfdata, %options}; + push @{$self->{perfdatas}}, $perfdata; +} + +sub output_json { + my ($self, %options) = @_; + my $force_ignore_perfdata = defined($options{force_ignore_perfdata}) ? 1 : 0; + my $json_content = {plugin => { + name => $self->{plugin}, + mode => $self->{mode}, + exit => $options{exit_litteral}, + outputs => [], + perfdatas => [] + } + }; + + foreach my $code_litteral (keys %{$self->{global_short_outputs}}) { + foreach (@{$self->{global_short_outputs}->{$code_litteral}}) { + my ($child_output, $child_type, $child_msg, $child_exit); + my $lcode_litteral = ($code_litteral eq 'UNQUALIFIED_YET' ? uc($options{exit_litteral}) : $code_litteral); + + push @{$json_content->{plugin}->{outputs}}, { + type => 1, + msg => ($options{nolabel} == 0 ? ($lcode_litteral . ': ') : '') . $_, + exit => $lcode_litteral + }; + } + } + + if (defined($self->{option_results}->{verbose}) || defined($options{force_long_output})) { + foreach (@{$self->{global_long_output}}) { + push @{$json_content->{plugin}->{outputs}}, { + type => 2, + msg => $_, + }; + } + } + + if (!defined($self->{option_results}->{ignore_perfdata}) && $options{force_ignore_perfdata} == 1) { + foreach (@{$self->{perfdatas}}) { + my %values = (); + foreach my $key (keys %$_) { + $values{$key} = $_->{$key}; + } + + push @{$json_content->{plugin}->{perfdatas}}, { + %values + }; + } + } + + print $self->{json_output}->encode($json_content); +} + +sub output_xml { + my ($self, %options) = @_; + my $force_ignore_perfdata = defined($options{force_ignore_perfdata}) ? 1 : 0; + my ($child_plugin_name, $child_plugin_mode, $child_plugin_exit, $child_plugin_output, $child_plugin_perfdata); + + my $root = $self->{xml_output}->createElement('plugin'); + $self->{xml_output}->setDocumentElement($root); + + $child_plugin_name = $self->{xml_output}->createElement("name"); + $child_plugin_name->appendText($self->{plugin}); + + $child_plugin_mode = $self->{xml_output}->createElement("mode"); + $child_plugin_mode->appendText($self->{mode}); + + $child_plugin_exit = $self->{xml_output}->createElement("exit"); + $child_plugin_exit->appendText($options{exit_litteral}); + + $child_plugin_output = $self->{xml_output}->createElement("outputs"); + $child_plugin_perfdata = $self->{xml_output}->createElement("perfdatas"); + + $root->addChild($child_plugin_name); + $root->addChild($child_plugin_mode); + $root->addChild($child_plugin_exit); + $root->addChild($child_plugin_output); + $root->addChild($child_plugin_perfdata); + + foreach my $code_litteral (keys %{$self->{global_short_outputs}}) { + foreach (@{$self->{global_short_outputs}->{$code_litteral}}) { + my ($child_output, $child_type, $child_msg, $child_exit); + my $lcode_litteral = ($code_litteral eq 'UNQUALIFIED_YET' ? uc($options{exit_litteral}) : $code_litteral); + + $child_output = $self->{xml_output}->createElement("output"); + $child_plugin_output->addChild($child_output); + + $child_type = $self->{xml_output}->createElement("type"); + $child_type->appendText(1); # short + + $child_msg = $self->{xml_output}->createElement("msg"); + $child_msg->appendText(($options{nolabel} == 0 ? ($lcode_litteral . ': ') : '') . $_); + $child_exit = $self->{xml_output}->createElement("exit"); + $child_exit->appendText($lcode_litteral); + + $child_output->addChild($child_type); + $child_output->addChild($child_exit); + $child_output->addChild($child_msg); + } + } + + if (defined($self->{option_results}->{verbose}) || defined($options{force_long_output})) { + foreach (@{$self->{global_long_output}}) { + my ($child_output, $child_type, $child_msg); + + $child_output = $self->{xml_output}->createElement("output"); + $child_plugin_output->addChild($child_output); + + $child_type = $self->{xml_output}->createElement("type"); + $child_type->appendText(2); # long + + $child_msg = $self->{xml_output}->createElement("msg"); + $child_msg->appendText($_); + + $child_output->addChild($child_type); + $child_output->addChild($child_msg); + } + } + + if (!defined($self->{option_results}->{ignore_perfdata}) && $options{force_ignore_perfdata} == 1) { + foreach (@{$self->{perfdatas}}) { + my ($child_perfdata); + $child_perfdata = $self->{xml_output}->createElement("perfdata"); + $child_plugin_perfdata->addChild($child_perfdata); + foreach my $key (keys %$_) { + my $child = $self->{xml_output}->createElement($key); + $child->appendText($_->{$key}); + $child_perfdata->addChild($child); + } + } + } + + print $self->{xml_output}->toString(1); +} + +sub output_txt { + my ($self, %options) = @_; + my $force_ignore_perfdata = defined($options{force_ignore_perfdata}) ? 1 : 0; + + if (defined($self->{global_short_concat_outputs}->{UNQUALIFIED_YET})) { + $self->output_add(severity => uc($options{exit_litteral}), short_msg => $self->{global_short_concat_outputs}->{UNQUALIFIED_YET}); + } + + if (defined($self->{global_short_concat_outputs}->{CRITICAL})) { + print (($options{nolabel} == 0 ? 'CRITICAL: ' : '') . $self->{global_short_concat_outputs}->{CRITICAL} . " "); + } + if (defined($self->{global_short_concat_outputs}->{WARNING})) { + print (($options{nolabel} == 0 ? 'WARNING: ' : '') . $self->{global_short_concat_outputs}->{WARNING} . " "); + } + if (defined($self->{global_short_concat_outputs}->{UNKNOWN})) { + print (($options{nolabel} == 0 ? 'UNKNOWN: ' : '') . $self->{global_short_concat_outputs}->{UNKNOWN} . " "); + } + if (uc($options{exit_litteral}) eq 'OK') { + print (($options{nolabel} == 0 ? 'OK: ' : '') . $self->{global_short_concat_outputs}->{OK}); + } + + if ($force_ignore_perfdata == 1 || defined($self->{option_results}->{ignore_perfdata})) { + print "\n"; + } else { + print "|"; + foreach (@{$self->{perfdatas}}) { + print " '" . $_->{label} . "'=" . $_->{value} . $_->{unit} . ";" . $_->{warning} . ";" . $_->{critical} . ";" . $_->{min} . ";" . $_->{max} . ";"; + } + print "\n"; + } + + if (defined($self->{option_results}->{verbose}) || defined($options{force_long_output})) { + if (scalar(@{$self->{global_long_output}})) { + print join("\n", @{$self->{global_long_output}}); + print "\n"; + } + } +} + +sub display { + my ($self, %options) = @_; + my $nolabel = defined($options{nolabel}) ? 1 : 0; + my $force_ignore_perfdata = defined($options{force_ignore_perfdata}) ? 1 : 0; + + if (defined($self->{option_results}->{output_xml})) { + $self->create_xml_document(); + if ($self->{is_output_xml}) { + $self->output_xml(exit_litteral => $self->get_litteral_status(), + nolabel => $nolabel, force_ignore_perfdata => $force_ignore_perfdata); + return ; + } + } elsif (defined($self->{option_results}->{output_json})) { + $self->create_json_document(); + if ($self->{is_output_json}) { + $self->output_json(exit_litteral => $self->get_litteral_status(), + nolabel => $nolabel, force_ignore_perfdata => $force_ignore_perfdata); + return ; + } + } + + $self->output_txt(exit_litteral => $self->get_litteral_status(), + nolabel => $nolabel, force_ignore_perfdata => $force_ignore_perfdata); +} + +sub die_exit { + my ($self, %options) = @_; + # $options{exit_litteral} = string litteral exit + # $options{nolabel} = interger label display + my $exit_litteral = defined($options{exit_litteral}) ? $options{exit_litteral} : $self->{option_results}->{opt_exit}; + my $nolabel = defined($options{nolabel}) ? 1 : 0; + # ignore long output in the following case + $self->{option_results}->{verbose} = undef; + + if (defined($self->{option_results}->{output_xml})) { + $self->create_xml_document(); + if ($self->{is_output_xml}) { + $self->output_xml(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1); + $self->exit(exit_litteral => $exit_litteral); + } + } elsif (defined($self->{option_results}->{output_json})) { + $self->create_json_document(); + if ($self->{is_output_json}) { + $self->output_json(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1); + $self->exit(exit_litteral => $exit_litteral); + } + } + + $self->output_txt(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1); + $self->exit(exit_litteral => $exit_litteral); +} + +sub option_exit { + my ($self, %options) = @_; + # $options{exit_litteral} = string litteral exit + # $options{nolabel} = interger label display + my $exit_litteral = defined($options{exit_litteral}) ? $options{exit_litteral} : $self->{option_results}->{opt_exit}; + my $nolabel = defined($options{nolabel}) ? 1 : 0; + + if (defined($self->{option_results}->{output_xml})) { + $self->create_xml_document(); + if ($self->{is_output_xml}) { + $self->output_xml(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1, force_long_output => 1); + $self->exit(exit_litteral => $exit_litteral); + } + } elsif (defined($self->{option_results}->{output_json})) { + $self->create_json_document(); + if ($self->{is_output_json}) { + $self->output_json(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1, force_long_output => 1); + $self->exit(exit_litteral => $exit_litteral); + } + } + + $self->output_txt(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1, force_long_output => 1); + $self->exit(exit_litteral => $exit_litteral); +} + +sub exit { + my ($self, %options) = @_; + # $options{exit_litteral} = exit + + if (defined($options{exit_litteral})) { + exit $self->{errors}->{uc($options{exit_litteral})}; + } + exit $self->{errors}->{$self->{myerrors}->{$self->{global_status}}}; +} + +sub get_most_critical { + my ($self, %options) = @_; + my $current_status = 0; # For 'OK' + + foreach (@{$options{status}}) { + if ($self->{myerrors_mask}->{uc($_)} > $current_status) { + $current_status = $self->{myerrors_mask}->{uc($_)}; + } + } + return $self->{myerrors}->{$current_status}; +} + +sub get_litteral_status { + my ($self, %options) = @_; + + if (defined($options{status})) { + if (defined($self->{myerrors}->{$options{status}})) { + return $self->{myerrors}->{$options{status}}; + } + return $options{status}; + } else { + return $self->{myerrors}->{$self->{global_status}}; + } +} + +sub is_status { + my ($self, %options) = @_; + # $options{value} = string status + # $options{litteral} = value is litteral + # $options{compare} = string status + + if (defined($options{litteral})) { + my $value = defined($options{value}) ? $options{value} : $self->get_litteral_status(); + + if (uc($value) eq uc($options{compare})) { + return 1; + } + return 0; + } + + my $value = defined($options{value}) ? $options{value} : $self->{global_status}; + my $dec_val = $self->{myerrors_mask}->{$value}; + my $lresult = $value & $dec_val; + # Need to manage 0 + if ($lresult > 0 || ($dec_val == 0 && $value == 0)) { + return 1; + } + return 0; +} + +sub is_litteral_status { + my ($self, %options) = @_; + # $options{status} = string status + + if (defined($self->{errors}->{uc($options{status})})) { + return 1; + } + + return 0; +} + +sub create_json_document { + my ($self) = @_; + + require JSON; + $self->{is_output_json} = 1; + $self->{json_output} = JSON->new->utf8(); +} + +sub create_xml_document { + my ($self) = @_; + + require XML::LibXML; + $self->{is_output_xml} = 1; + $self->{xml_output} = XML::LibXML::Document->new('1.0', 'utf-8'); +} + +sub plugin { + my ($self, %options) = @_; + # $options{name} = string name + + if (defined($options{name})) { + $self->{plugin} = $options{name}; + } + return $self->{plugin}; +} + +sub mode { + my ($self, %options) = @_; + # $options{name} = string name + + if (defined($options{name})) { + $self->{mode} = $options{name}; + } + return $self->{mode}; +} + +sub add_disco_format { + my ($self, %options) = @_; + + push @{$self->{disco_elements}}, @{$options{elements}}; +} + +sub display_disco_format { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{output_xml})) { + $self->create_xml_document(); + + my $root = $self->{xml_output}->createElement('data'); + $self->{xml_output}->setDocumentElement($root); + + foreach (@{$self->{disco_elements}}) { + my $child = $self->{xml_output}->createElement("element"); + $child->appendText($_); + $root->addChild($child); + } + + print $self->{xml_output}->toString(1); + } elsif (defined($self->{option_results}->{output_json})) { + $self->create_json_document(); + my $json_content = {data => [] }; + foreach (@{$self->{disco_elements}}) { + push @{$json_content->{data}}, $_; + } + + print $self->{json_output}->encode($json_content); + } +} + +sub display_disco_show { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{output_xml})) { + $self->create_xml_document(); + + my $root = $self->{xml_output}->createElement('data'); + $self->{xml_output}->setDocumentElement($root); + + foreach (@{$self->{disco_entries}}) { + my $child = $self->{xml_output}->createElement("label"); + foreach my $key (keys %$_) { + $child->setAttribute($key, $_->{$key}); + } + $root->addChild($child); + } + + print $self->{xml_output}->toString(1); + } elsif (defined($self->{option_results}->{output_json})) { + $self->create_json_document(); + my $json_content = {data => [] }; + foreach (@{$self->{disco_entries}}) { + my %values = (); + foreach my $key (keys %$_) { + $values{$key} = $_->{$key}; + } + push @{$json_content->{data}}, {%values}; + } + + print $self->{json_output}->encode($json_content); + } +} + +sub to_utf8 { + my ($self, $value) = @_; + + return centreon::plugins::misc::trim(Encode::decode('UTF-8', $value, Encode::PERLQQ)); +} + +sub add_disco_entry { + my ($self, %options) = @_; + + push @{$self->{disco_entries}}, {%options}; +} + +sub is_disco_format { + my ($self) = @_; + + if (defined($self->{option_results}->{disco_format}) ) { + return 1; + } + return 0; +} + +sub is_disco_show { + my ($self) = @_; + + if ( defined($self->{option_results}->{disco_show}) ) { + return 1; + } + return 0; +} + +1; + +__END__ + +=head1 NAME + +Output class + +=head1 SYNOPSIS + +- + +=head1 OUTPUT OPTIONS + +=over 8 + +=item B<--verbose> + +Display long output. + +=item B<--ignore-perfdata> + +Don't display perfdata. + +=item B<--opt-exit> + +Exit code for an option error, usage (default: unknown). + +=item B<--output-xml> + +Display output in XML Format. + +=item B<--output-json> + +Display output in JSON Format. + +=item B<--disco-format> + +Display discovery arguments (if the mode manages it). + +=item B<--disco-show> + +Display discovery values (if the mode manages it). + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/perfdata.pm b/centreon/plugins/perfdata.pm new file mode 100644 index 000000000..7f9e0d803 --- /dev/null +++ b/centreon/plugins/perfdata.pm @@ -0,0 +1,253 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::perfdata; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + $self->{output} = $options{output}; + # Typical Nagios Perfdata 'with ~ @ ..' + $self->{threshold_label} = {}; + + return $self; +} + +sub get_perfdata_for_output { + my ($self, %options) = @_; + # $options{label} : threshold label + # $options{total} : percent threshold to transform in global + # $options{cast_int} : cast absolute to int + + my $perf_output = $self->{threshold_label}->{$options{label}}->{value}; + if (defined($perf_output) && $perf_output ne '' && defined($options{total})) { + $perf_output = ($self->{threshold_label}->{$options{label}}->{arobase} == 1 ? "@" : "") . + (($self->{threshold_label}->{$options{label}}->{infinite_neg} == 0) ? (defined($options{cast_int}) ? sprintf("%d", ($self->{threshold_label}->{$options{label}}->{start} * $options{total} / 100)) : sprintf("%.2f", ($self->{threshold_label}->{$options{label}}->{start} * $options{total} / 100))) : "") . + ":" . + (($self->{threshold_label}->{$options{label}}->{infinite_pos} == 0) ? (defined($options{cast_int}) ? sprintf("%d", ($self->{threshold_label}->{$options{label}}->{end} * $options{total} / 100)) : sprintf("%.2f", ($self->{threshold_label}->{$options{label}}->{end} * $options{total} / 100))) : ""); + } + + if (!defined($perf_output)) { + $perf_output = ''; + } + return $perf_output; +} + +sub threshold_validate { + my ($self, %options) = @_; + # $options{label} : threshold label + # $options{value} : threshold value + + my $status = 1; + $self->{threshold_label}->{$options{label}} = {'value' => $options{value}, 'start' => undef, 'end' => undef, 'arobase' => undef, infinite_neg => undef, intinite_pos => undef}; + if (!defined($options{value}) || $options{value} eq '') { + return $status; + } + + ($status, $self->{threshold_label}->{$options{label}}->{start}, $self->{threshold_label}->{$options{label}}->{end}, $self->{threshold_label}->{$options{label}}->{arobase}, $self->{threshold_label}->{$options{label}}->{infinite_neg}, $self->{threshold_label}->{$options{label}}->{infinite_pos}) = $self->parse_threshold($options{value}); + + return $status; +} + +sub threshold_check { + my ($self, %options) = @_; + # Can check multiple threshold. First match: out. Order is important + # options{value}: value to compare + # options{threshold}: ref to an array (example: [ {label => 'warning', exit_litteral => 'warning' }, {label => 'critical', exit_litteral => 'critical'} ] + foreach (@{$options{threshold}}) { + next if (!defined($self->{threshold_label}->{$_->{label}})); + next if (!defined($self->{threshold_label}->{$_->{label}}->{value}) || $self->{threshold_label}->{$_->{label}}->{value} eq ''); + if ($self->{threshold_label}->{$_->{label}}->{arobase} == 0 && ($options{value} < $self->{threshold_label}->{$_->{label}}->{start} || $options{value} > $self->{threshold_label}->{$_->{label}}->{end})) { + return $_->{exit_litteral}; + } elsif ($self->{threshold_label}->{$_->{label}}->{arobase} == 1 && ($options{value} >= $self->{threshold_label}->{$_->{label}}->{end} && $options{value} <= $self->{threshold_label}->{$_->{label}}->{end})) { + return $_->{exit_litteral}; + } + } + + return 'ok'; +} + +sub trim { + my ($self, $value) = @_; + + $value =~ s/^[ \t]+//; + $value =~ s/[ \t]+$//; + return $value; +} + +sub continue_to { + my $self = shift; + my ($forbidden, $stop1, $not_stop_after) = @_; + my $value = ""; + + while ($self->{perfdata_pos} < $self->{perfdata_size}) { + if (defined($forbidden) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] =~ /$forbidden/) { + return undef; + } + if (${$self->{perfdata_chars}}[$self->{perfdata_pos}] =~ /$stop1/) { + if (!defined($not_stop_after)) { + return $value; + } + if (!($self->{perfdata_pos} + 1 < $self->{perfdata_size} && ${$self->{perfdata_chars}}[$self->{perfdata_pos} + 1] =~ /$not_stop_after/)) { + $self->{perfdata_pos}++; + return $value; + } + $self->{perfdata_pos}++; + } + + $value .= ${$self->{perfdata_chars}}[$self->{perfdata_pos}]; + $self->{perfdata_pos}++; + } + + return $value; +} + +sub parse_threshold { + my $self = shift; + + @{$self->{perfdata_chars}} = split //, $self->trim($_[0]); + $self->{perfdata_pos} = 0; + $self->{perfdata_size} = scalar(@{$self->{perfdata_chars}}); + + my $neg = 1; + my $value_tmp = ""; + + my $arobase = 0; + my $infinite_neg = 0; + my $infinite_pos = 0; + my $value_start = ""; + my $value_end = ""; + my $global_status = 1; + + if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "@") { + $arobase = 1; + $self->{perfdata_pos}++; + } + + if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "~") { + $infinite_neg = 1; + $self->{perfdata_pos}++; + } else { + if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "-") { + $neg = -1; + $self->{perfdata_pos}++; + } + $value_tmp = $self->continue_to(undef, "[^0-9\.,]"); + if (defined($value_tmp) && $value_tmp ne "") { + $value_tmp =~ s/,/./g; + $value_tmp = $value_tmp * $neg; + } + $neg = 1; + } + + if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq ":") { + if ($value_tmp ne "") { + $value_start = $value_tmp; + } else { + $value_start = 0; + } + $self->{perfdata_pos}++; + + if (defined(${$self->{perfdata_chars}}[$self->{perfdata_pos}]) && ${$self->{perfdata_chars}}[$self->{perfdata_pos}] eq "-") { + $neg = -1; + $self->{perfdata_pos}++; + } + $value_end = $self->continue_to(undef, "[^0-9\.,]"); + if (defined($value_tmp) && $value_end ne "") { + $value_end =~ s/,/./g; + $value_end = $value_end * $neg; + } else { + $infinite_pos = 1; + } + } else { + $value_start = 0; + $value_end = $value_tmp; + } + + my $value = $self->continue_to(undef, "[ \t;]"); + if ($value ne '') { + $global_status = 0; + } + + if ($infinite_neg == 1) { + $value_start = '-1e500'; + } + if ($infinite_pos == 1) { + $value_end = '1e500'; + } + + return ($global_status, $value_start, $value_end, $arobase, $infinite_neg, $infinite_pos); +} + +sub change_bytes { + my ($self, %options) = @_; + + my $unit = defined($options{network}) ? 'b' : 'B'; + my $divide = defined($options{network}) ? 1000 : 1024; + + if (($options{value} / $divide) >= 1) { + $options{value} = $options{value} / $divide; + $unit = defined($options{network}) ? 'Kb' : 'KB'; + } + if (($options{value} / $divide) >= 1) { + $options{value} = $options{value} / $divide; + $unit = defined($options{network}) ? 'Mb' : 'MB'; + } + if (($options{value} / $divide) >= 1) { + $options{value} = $options{value} / $divide; + $unit = defined($options{network}) ? 'Gb' : 'GB'; + } + return (sprintf("%.2f", $options{value}), $unit); +} + +1; + +__END__ + +=head1 NAME + +Perfdata class + +=head1 SYNOPSIS + +- + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/script.pm b/centreon/plugins/script.pm new file mode 100644 index 000000000..2b435358d --- /dev/null +++ b/centreon/plugins/script.pm @@ -0,0 +1,260 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::script; + +use strict; +use warnings; +use centreon::plugins::options; +use centreon::plugins::output; +use centreon::plugins::misc; +use FindBin; +use Pod::Usage; +use Pod::Find qw(pod_where); + +my %handlers = ('DIE' => {}); + +sub new { + my $class = shift; + my $self = {}; + bless $self, $class; + + $self->{options} = undef; + $self->{plugin} = undef; + $self->{help} = undef; + + $self->set_signal_handlers; + return $self; +} + +sub set_signal_handlers { + my $self = shift; + + $SIG{__DIE__} = \&class_handle_DIE; + $handlers{DIE}->{$self} = sub { $self->handle_DIE($_[0]) }; +} + +sub class_handle_DIE { + my ($msg) = @_; + + foreach (keys %{$handlers{DIE}}) { + &{$handlers{DIE}->{$_}}($msg); + } +} + +sub handle_DIE { + my ($self, $msg) = @_; + + # For 'mod_perl' + die $msg if $^S; + $self->{output}->add_option_msg(short_msg => $msg); + $self->{output}->die_exit(); +} + +sub get_plugin { + my $self = shift; + + ###### + # Need to load global 'Output' and 'Options' + ###### + $self->{options} = centreon::plugins::options->new(); + $self->{output} = centreon::plugins::output->new(options => $self->{options}); + $self->{options}->set_output(output => $self->{output}); + + $self->{options}->add_options(arguments => { + 'plugin:s' => { name => 'plugin' }, + 'help' => { name => 'help' }, + 'version' => { name => 'version' }, + 'runas:s' => { name => 'runas' }, + 'environment:s%' => { name => 'environment' }, + } ); + + $self->{options}->parse_options(); + + $self->{plugin} = $self->{options}->get_option(argument => 'plugin' ); + $self->{help} = $self->{options}->get_option(argument => 'help' ); + $self->{version} = $self->{options}->get_option(argument => 'version' ); + $self->{runas} = $self->{options}->get_option(argument => 'runas' ); + $self->{environment} = $self->{options}->get_option(argument => 'environment' ); + + $self->{output}->mode(name => $self->{mode}); + $self->{output}->plugin(name => $self->{plugin}); + $self->{output}->check_options(option_results => $self->{options}->get_options()); + + $self->{options}->clean(); +} + +sub display_local_help { + my $self = shift; + + my $stdout; + if ($self->{help}) { + local *STDOUT; + open STDOUT, '>', \$stdout; + pod2usage(-exitval => "NOEXIT", -input => pod_where({-inc => 1}, __PACKAGE__)); + } + + $self->{output}->add_option_msg(long_msg => $stdout) if (defined($stdout)); +} + +sub check_relaunch { + my $self = shift; + my $need_restart = 0; + my $cmd = $FindBin::Bin . "/" . $FindBin::Script; + my @args = (); + + if (defined($self->{environment})) { + foreach (keys %{$self->{environment}}) { + if ($_ ne '' && (!defined($ENV{$_}) || $ENV{$_} ne $self->{environment}->{$_})) { + $ENV{$_} = $self->{environment}->{$_}; + $need_restart = 1; + } + } + } + + if (defined($self->{runas}) && $self->{runas} ne '') { + # Check if it's already me and user exist ;) + my ($name, $passwd, $uid) = getpwnam($self->{runas}); + if (!defined($uid)) { + $self->{output}->add_option_msg(short_msg => "Runas user '" . $self->{runas} . "' not exist."); + $self->{output}->option_exit(); + } + if ($uid != $>) { + if ($> == 0) { + unshift @args, "-s", "/bin/bash", "-l", $self->{runas}, "-c", join(" ", $cmd, "--plugin=" . $self->{plugin}, @ARGV); + $cmd = "su"; + } else { + unshift @args, "-S", "-u", $self->{runas}, $cmd, "--plugin=" . $self->{plugin}, @ARGV; + $cmd = "sudo"; + } + $need_restart = 1; + } + } + + if ($need_restart == 1) { + if (scalar(@args) <= 0) { + unshift @args, @ARGV, "--plugin=" . $self->{plugin} + } + + my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( + command => $cmd, + arguments => [@args], + timeout => 30, + wait_exit => 1 + ); + if ($exit_code <= -1000) { + if ($exit_code == -1000) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => $stdout); + } + $self->{output}->display(); + $self->{output}->exit(); + } + print $stdout; + # We put unknown + if (!($exit_code >= 0 && $exit_code <= 4)) { + exit 3; + } + exit $exit_code; + } +} + +sub run { + my $self = shift; + + $self->get_plugin(); + + if (defined($self->{help}) && !defined($self->{plugin})) { + $self->display_local_help(); + $self->{output}->option_exit(); + } + if (!defined($self->{plugin}) || $self->{plugin} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify '--plugin' option."); + $self->{output}->option_exit(); + } + + $self->check_relaunch(); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{plugin}, + error_msg => "Cannot load module --plugin."); + my $plugin = $self->{plugin}->new(options => $self->{options}, output => $self->{output}); + $plugin->init(help => $self->{help}, + version => $self->{version}); + $plugin->run(); +} + +1; + +__END__ + +=head1 NAME + +centreon_plugins.pl - main program to call Merethis plugins. + +=head1 SYNOPSIS + +centreon_plugins.pl [options] + +=head1 OPTIONS + +=over 8 + +=item B<--plugin> + +Specify the path to the plugin. + +=item B<--version> + +Print plugin version. + +=item B<--help> + +Print a brief help message and exits. + +=item B<--runas> + +Run the script as a different user (prefer to use directly the good user). + +=item B<--environment> + +Set environment variables for the script (prefer to set it before running it for better performance). + +=back + +=head1 DESCRIPTION + +B . + +=cut diff --git a/centreon/plugins/script_custom.pm b/centreon/plugins/script_custom.pm new file mode 100644 index 000000000..9a7238ac9 --- /dev/null +++ b/centreon/plugins/script_custom.pm @@ -0,0 +1,280 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::script_custom; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{package} = parent package caller + # $options{options} = options object + # $options{output} = output object + $self->{options} = $options{options}; + $self->{output} = $options{output}; + + $self->{options}->add_options( + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'custommode:s' => { name => 'custommode_name' }, + 'list-custommode' => { name => 'list_custommode' }, + 'multiple' => { name => 'multiple' }, + } + ); + $self->{version} = '1.0'; + %{$self->{modes}} = (); + %{$self->{custom_modes}} = (); + $self->{default} = undef; + $self->{customdefault} = {}; + $self->{custommode_current} = undef; + $self->{custommode_stored} = []; + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + foreach (keys %{$self->{option_results}}) { + $self->{$_} = $self->{option_results}->{$_}; + } + $self->{options}->clean(); + + $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); + $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + + return $self; +} + +sub init { + my ($self, %options) = @_; + # $options{version} = string version + # $options{help} = string help + + if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version}) && !defined($self->{mode_name})&& !defined($self->{dynmode_name})) { + $self->version(); + } + if (defined($self->{list_mode})) { + $self->list_mode(); + } + if (defined($self->{list_custommode})) { + $self->list_custommode(); + } + + # Output HELP + $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); + + if (defined($self->{custommode_name}) && $self->{custommode_name} ne '') { + $self->is_custommode(custommode => $self->{custommode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{custom_modes}{$self->{custommode_name}}, + error_msg => "Cannot load module --custommode."); + $self->{custommode_current} = $self->{custom_modes}{$self->{custommode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{custommode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--custommode'."); + $self->{output}->option_exit(); + } + + # Load mode + if (defined($self->{mode_name}) && $self->{mode_name} ne '') { + $self->is_mode(mode => $self->{mode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{modes}{$self->{mode_name}}, + error_msg => "Cannot load module --mode."); + $self->{mode} = $self->{modes}{$self->{mode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } elsif (defined($self->{dynmode_name}) && $self->{dynmode_name} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{dynmode_name}, + error_msg => "Cannot load module --dyn-mode."); + $self->{mode} = $self->{dynmode_name}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--mode' or '--dyn-mode' option."); + $self->{output}->option_exit(); + } + + if (defined($options{help})) { + $self->{options}->add_help(package => $self->{modes}{$self->{mode_name}}, sections => 'MODE'); + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version})) { + $self->{mode}->version(); + $self->{output}->option_exit(nolabel => 1); + } + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + + push @{$self->{custommode_stored}}, $self->{custommode_current}; + $self->{custommode_current}->set_options(option_results => $self->{option_results}); + $self->{custommode_current}->set_defaults(default => $self->{customdefault}); + + while ($self->{custommode_current}->check_options()) { + $self->{custommode_current} = $self->{custom_modes}{$self->{custommode_name}}->new(noptions => 1, options => $self->{options}, output => $self->{output}, mode => $self->{custommode_name}); + $self->{custommode_current}->set_options(option_results => $self->{option_results}); + push @{$self->{custommode_stored}}, $self->{custommode_current}; + } + $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}); +} + +sub run { + my $self = shift; + + if ($self->{output}->is_disco_format()) { + $self->{mode}->disco_format(); + $self->{output}->display_disco_format(); + $self->{output}->exit(exit_litteral => 'ok'); + } + + if ($self->{output}->is_disco_show()) { + if (defined($self->{multiple})) { + $self->{mode}->disco_show(custom => $self->{custommode}); + } else { + $self->{mode}->disco_show(custom => $self->{custommode_stored}[0]); + } + $self->{output}->display_disco_show(); + $self->{output}->exit(exit_litteral => 'ok'); + } else { + if (defined($self->{multiple})) { + $self->{mode}->run(custom => $self->{custommode_stored}); + } else { + $self->{mode}->run(custom => $self->{custommode_stored}[0]); + } + } +} + +sub is_mode { + my ($self, %options) = @_; + + # $options->{mode} = mode + if (!defined($self->{modes}{$options{mode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{mode} . "' doesn't exist (use --list-mode option to show available modes)."); + $self->{output}->option_exit(); + } +} + +sub is_custommode { + my ($self, %options) = @_; + + # $options->{custommode} = mode + if (!defined($self->{custom_modes}{$options{custommode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{custommode} . "' doesn't exist (use --list-custommode option to show available modes)."); + $self->{output}->option_exit(); + } +} + + +sub version { + my $self = shift; + $self->{output}->add_option_msg(short_msg => "Plugin Version: " . $self->{version}); + $self->{output}->option_exit(nolabel => 1); +} + +sub list_mode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "Modes Available:"); + foreach (keys %{$self->{modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +sub list_custommode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "Custom Modes Available:"); + foreach (keys %{$self->{custom_modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +1; + +__END__ + +=head1 NAME + +- + +=head1 SYNOPSIS + +- + +=head1 GLOBAL OPTIONS + +=over 8 + +=item B<--mode> + +Choose a mode. + +=item B<--list-mode> + +List available modes. + +=item B<--version> + +Display plugin version. + +=item B<--dyn-mode> + +Specify a mode with the path (separated by '::'). + +=item B<--custommode> + +Choose a custom mode. + +=item B<--list-custommode> + +List available custom modes. + +=item B<--multiple> + +Multiple custom mode objects (some mode needs it). + +=back + +=head1 DESCRIPTION + +B<>. + +=cut diff --git a/centreon/plugins/script_simple.pm b/centreon/plugins/script_simple.pm new file mode 100644 index 000000000..43cf8bfe9 --- /dev/null +++ b/centreon/plugins/script_simple.pm @@ -0,0 +1,194 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::script_simple; + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{package} = parent package caller + # $options{options} = options object + # $options{output} = output object + $self->{options} = $options{options}; + $self->{output} = $options{output}; + + $self->{options}->add_options( + arguments => { + 'mode:s' => { name => 'mode' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + } + ); + $self->{version} = '1.0'; + %{$self->{modes}} = (); + $self->{default} = undef; + + $self->{options}->parse_options(); + $self->{mode_name} = $self->{options}->get_option(argument => 'mode' ); + $self->{list_mode} = $self->{options}->get_option(argument => 'list_mode' ); + $self->{options}->clean(); + + $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); + $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + + return $self; +} + +sub init { + my ($self, %options) = @_; + # $options{version} = string version + # $options{help} = string help + + if (defined($options{help}) && !defined($self->{mode_name})) { + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version}) && !defined($self->{mode_name})) { + $self->version(); + } + if (defined($self->{list_mode})) { + $self->list_mode(); + } + + # Output HELP + $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); + + # Load mode + if (defined($self->{mode_name}) && $self->{mode_name} ne '') { + $self->is_mode(mode => $self->{mode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{modes}{$self->{mode_name}}, + error_msg => "Cannot load module --mode."); + $self->{mode} = $self->{modes}{$self->{mode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } elsif (defined($self->{dynmode_name}) && $self->{dynmode_name} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{dynmode_name}, + error_msg => "Cannot load module --dyn-mode."); + $self->{mode} = $self->{dynmode_name}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--mode' or '--dyn-mode' option."); + $self->{output}->option_exit(); + } + + if (defined($options{help})) { + $self->{options}->add_help(package => $self->{modes}{$self->{mode_name}}, sections => 'MODE'); + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version})) { + $self->{mode}->version(); + $self->{output}->option_exit(nolabel => 1); + } + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + + $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}); +} + +sub run { + my $self = shift; + + $self->{mode}->run(); +} + +sub is_mode { + my ($self, %options) = @_; + + # $options->{mode} = mode + if (!defined($self->{modes}{$options{mode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{mode} . "' doesn't exist (use --list option to show available modes)."); + $self->{output}->option_exit(); + } +} + +sub version { + my $self = shift; + $self->{output}->add_option_msg(short_msg => "Plugin Version: " . $self->{version}); + $self->{output}->option_exit(nolabel => 1); +} + +sub list_mode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "Modes Available:"); + foreach (keys %{$self->{modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +1; + +__END__ + +=head1 NAME + +- + +=head1 SYNOPSIS + +- + +=head1 GLOBAL OPTIONS + +=over 8 + +=item B<--mode> + +Choose a mode. + +=item B<--dyn-mode> + +Specify a mode with the path (separated by '::'). + +=item B<--list-mode> + +List available modes. + +=item B<--version> + +Display plugin version. + +=back + +=head1 DESCRIPTION + +B<>. + +=cut diff --git a/centreon/plugins/script_snmp.pm b/centreon/plugins/script_snmp.pm new file mode 100644 index 000000000..f5bf29dc7 --- /dev/null +++ b/centreon/plugins/script_snmp.pm @@ -0,0 +1,213 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::script_snmp; + +use strict; +use warnings; +use centreon::plugins::snmp; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{package} = parent package caller + # $options{options} = options object + # $options{output} = output object + $self->{options} = $options{options}; + $self->{output} = $options{output}; + + $self->{options}->add_options( + arguments => { + 'mode:s' => { name => 'mode' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + } + ); + $self->{version} = '1.0'; + %{$self->{modes}} = (); + $self->{default} = undef; + + $self->{options}->parse_options(); + $self->{mode_name} = $self->{options}->get_option(argument => 'mode' ); + $self->{list_mode} = $self->{options}->get_option(argument => 'list_mode' ); + $self->{options}->clean(); + + $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); + $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + + return $self; +} + +sub init { + my ($self, %options) = @_; + # $options{version} = string version + # $options{help} = string help + + if (defined($options{help}) && !defined($self->{mode_name})) { + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version}) && !defined($self->{mode_name})) { + $self->version(); + } + if (defined($self->{list_mode})) { + $self->list_mode(); + } + + # Output HELP + $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); + + # SNMP + $self->{snmp} = centreon::plugins::snmp->new(options => $self->{options}, output => $self->{output}); + + # Load mode + if (defined($self->{mode_name}) && $self->{mode_name} ne '') { + $self->is_mode(mode => $self->{mode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{modes}{$self->{mode_name}}, + error_msg => "Cannot load module --mode."); + $self->{mode} = $self->{modes}{$self->{mode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } elsif (defined($self->{dynmode_name}) && $self->{dynmode_name} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{dynmode_name}, + error_msg => "Cannot load module --dyn-mode."); + $self->{mode} = $self->{dynmode_name}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--mode' or '--dyn-mode' option."); + $self->{output}->option_exit(); + } + + if (defined($options{help})) { + $self->{options}->add_help(package => $self->{modes}{$self->{mode_name}}, sections => 'MODE'); + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version})) { + $self->{mode}->version(); + $self->{output}->option_exit(nolabel => 1); + } + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + + $self->{snmp}->check_options(option_results => $self->{option_results}); + $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}); +} + +sub run { + my $self = shift; + + if ($self->{output}->is_disco_format()) { + $self->{mode}->disco_format(); + $self->{output}->display_disco_format(); + $self->{output}->exit(exit_litteral => 'ok'); + } + + $self->{snmp}->connect(); + if ($self->{output}->is_disco_show()) { + $self->{mode}->disco_show(snmp => $self->{snmp}); + $self->{output}->display_disco_show(); + $self->{output}->exit(exit_litteral => 'ok'); + } else { + $self->{mode}->run(snmp => $self->{snmp}); + } +} + +sub is_mode { + my ($self, %options) = @_; + + # $options->{mode} = mode + if (!defined($self->{modes}{$options{mode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{mode} . "' doesn't exist (use --list-mode option to show available modes)."); + $self->{output}->option_exit(); + } +} + +sub version { + my $self = shift; + $self->{output}->add_option_msg(short_msg => "Plugin Version: " . $self->{version}); + $self->{output}->option_exit(nolabel => 1); +} + +sub list_mode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "Modes Available:"); + foreach (keys %{$self->{modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +1; + +__END__ + +=head1 NAME + +- + +=head1 SYNOPSIS + +- + +=head1 GLOBAL OPTIONS + +=over 8 + +=item B<--mode> + +Choose a mode. + +=item B<--dyn-mode> + +Specify a mode with the path (separated by '::'). + +=item B<--list-mode> + +List available modes. + +=item B<--version> + +Display plugin version. + +=back + +=head1 DESCRIPTION + +B<>. + +=cut diff --git a/centreon/plugins/script_sql.pm b/centreon/plugins/script_sql.pm new file mode 100644 index 000000000..92c92fc49 --- /dev/null +++ b/centreon/plugins/script_sql.pm @@ -0,0 +1,280 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::script_sql; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{package} = parent package caller + # $options{options} = options object + # $options{output} = output object + $self->{options} = $options{options}; + $self->{output} = $options{output}; + + $self->{options}->add_options( + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'sqlmode:s' => { name => 'sqlmode_name', default => 'dbi' }, + 'list-sqlmode' => { name => 'list_sqlmode' }, + 'multiple' => { name => 'multiple' }, + } + ); + $self->{version} = '1.0'; + %{$self->{modes}} = (); + %{$self->{sql_modes}} = ('dbi' => 'centreon::plugins::dbi'); + $self->{default} = undef; + $self->{sqldefault} = {}; + $self->{sqlmode_current} = undef; + $self->{sqlmode_stored} = []; + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + foreach (keys %{$self->{option_results}}) { + $self->{$_} = $self->{option_results}->{$_}; + } + $self->{options}->clean(); + + $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); + $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + + return $self; +} + +sub init { + my ($self, %options) = @_; + # $options{version} = string version + # $options{help} = string help + + if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version}) && !defined($self->{mode_name})&& !defined($self->{dynmode_name})) { + $self->version(); + } + if (defined($self->{list_mode})) { + $self->list_mode(); + } + if (defined($self->{list_sqlmode})) { + $self->list_sqlmode(); + } + + # Output HELP + $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); + + if (defined($self->{sqlmode_name}) && $self->{sqlmode_name} ne '') { + $self->is_sqlmode(sqlmode => $self->{sqlmode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{sql_modes}{$self->{sqlmode_name}}, + error_msg => "Cannot load module --sqlmode."); + $self->{sqlmode_current} = $self->{sql_modes}{$self->{sqlmode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{sqlmode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--sqlmode'."); + $self->{output}->option_exit(); + } + + # Load mode + if (defined($self->{mode_name}) && $self->{mode_name} ne '') { + $self->is_mode(mode => $self->{mode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{modes}{$self->{mode_name}}, + error_msg => "Cannot load module --mode."); + $self->{mode} = $self->{modes}{$self->{mode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } elsif (defined($self->{dynmode_name}) && $self->{dynmode_name} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{dynmode_name}, + error_msg => "Cannot load module --dyn-mode."); + $self->{mode} = $self->{dynmode_name}->new(options => $self->{options}, output => $self->{output}, mode => $self->{mode_name}); + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify '--mode' or '--dyn-mode' option."); + $self->{output}->option_exit(); + } + + if (defined($options{help})) { + $self->{options}->add_help(package => $self->{modes}{$self->{mode_name}}, sections => 'MODE'); + $self->{options}->display_help(); + $self->{output}->option_exit(); + } + if (defined($options{version})) { + $self->{mode}->version(); + $self->{output}->option_exit(nolabel => 1); + } + + $self->{options}->parse_options(); + $self->{option_results} = $self->{options}->get_options(); + + push @{$self->{sqlmode_stored}}, $self->{sqlmode_current}; + $self->{sqlmode_current}->set_options(option_results => $self->{option_results}); + $self->{sqlmode_current}->set_defaults(default => $self->{sqldefault}); + + while ($self->{sqlmode_current}->check_options()) { + $self->{sqlmode_current} = $self->{sql_modes}{$self->{sqlmode_name}}->new(noptions => 1, options => $self->{options}, output => $self->{output}, mode => $self->{sqlmode_name}); + $self->{sqlmode_current}->set_options(option_results => $self->{option_results}); + push @{$self->{sqlmode_stored}}, $self->{sqlmode_current}; + } + $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}); +} + +sub run { + my $self = shift; + + if ($self->{output}->is_disco_format()) { + $self->{mode}->disco_format(); + $self->{output}->display_disco_format(); + $self->{output}->exit(exit_litteral => 'ok'); + } + + if ($self->{output}->is_disco_show()) { + if (defined($self->{multiple})) { + $self->{mode}->disco_show(sql => $self->{sqlmode}); + } else { + $self->{mode}->disco_show(sql => $self->{sqlmode_stored}[0]); + } + $self->{output}->display_disco_show(); + $self->{output}->exit(exit_litteral => 'ok'); + } else { + if (defined($self->{multiple})) { + $self->{mode}->run(sql => $self->{sqlmode_stored}); + } else { + $self->{mode}->run(sql => $self->{sqlmode_stored}[0]); + } + } +} + +sub is_mode { + my ($self, %options) = @_; + + # $options->{mode} = mode + if (!defined($self->{modes}{$options{mode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{mode} . "' doesn't exist (use --list-mode option to show available modes)."); + $self->{output}->option_exit(); + } +} + +sub is_sqlmode { + my ($self, %options) = @_; + + # $options->{sqlmode} = mode + if (!defined($self->{sql_modes}{$options{sqlmode}})) { + $self->{output}->add_option_msg(short_msg => "mode '" . $options{sqlmode} . "' doesn't exist (use --list-sqlmode option to show available modes)."); + $self->{output}->option_exit(); + } +} + + +sub version { + my $self = shift; + $self->{output}->add_option_msg(short_msg => "Plugin Version: " . $self->{version}); + $self->{output}->option_exit(nolabel => 1); +} + +sub list_mode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "Modes Available:"); + foreach (keys %{$self->{modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +sub list_sqlmode { + my $self = shift; + $self->{options}->display_help(); + + $self->{output}->add_option_msg(long_msg => "SQL Modes Available:"); + foreach (keys %{$self->{sql_modes}}) { + $self->{output}->add_option_msg(long_msg => " " . $_); + } + $self->{output}->option_exit(nolabel => 1); +} + +1; + +__END__ + +=head1 NAME + +- + +=head1 SYNOPSIS + +- + +=head1 GLOBAL OPTIONS + +=over 8 + +=item B<--mode> + +Choose a mode. + +=item B<--list-mode> + +List available modes. + +=item B<--version> + +Display plugin version. + +=item B<--dyn-mode> + +Specify a mode with the path (separated by '::'). + +=item B<--sqlmode> + +Choose a sql mode (Default: "dbi"). + +=item B<--list-sqlmode> + +List available sql modes. + +=item B<--multiple> + +Multiple database connections (some mode needs it). + +=back + +=head1 DESCRIPTION + +B<>. + +=cut diff --git a/centreon/plugins/snmp.pm b/centreon/plugins/snmp.pm new file mode 100644 index 000000000..af4985ddc --- /dev/null +++ b/centreon/plugins/snmp.pm @@ -0,0 +1,702 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::snmp; + +use strict; +use warnings; +use SNMP; +use Socket; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + + if (!defined($options{output})) { + print "Class SNMP: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class SNMP: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + $options{options}->add_options(arguments => + { "hostname|host:s" => { name => 'host' }, + "snmp-community:s" => { name => 'snmp_community', default => 'public' }, + "snmp-version:s" => { name => 'snmp_version', default => 1 }, + "snmp-port:s" => { name => 'snmp_port', default => 161 }, + "snmp-timeout:s" => { name => 'snmp_timeout', default => 1 }, + "snmp-retries:s" => { name => 'snmp_retries', default => 5 }, + "maxrepetitions:s" => { name => 'maxrepetitions', default => 50 }, + "subsetleef:s" => { name => 'subsetleef', default => 50 }, + "snmp-username:s" => { name => 'snmp_security_name' }, + "authpassphrase:s" => { name => 'snmp_auth_passphrase' }, + "authprotocol:s" => { name => 'snmp_auth_protocol' }, + "privpassphrase:s" => { name => 'snmp_priv_passphrase' }, + "privprotocol:s" => { name => 'snmp_priv_protocol' }, + "contextname:s" => { name => 'snmp_context_name' }, + "contextengineid:s" => { name => 'snmp_context_engine_id' }, + "securityengineid:s" => { name => 'snmp_security_engine_id' }, + "snmp-errors-exit:s" => { name => 'snmp_errors_exit', default => 'unknown' }, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'SNMP OPTIONS'); + + ##### + $self->{session} = undef; + $self->{output} = $options{output}; + $self->{maxrepetitions} = undef; + $self->{snmp_params} = {}; + + # Dont load MIB + $SNMP::auto_init_mib = 0; + # For snmpv v1 - get request retries when you have "NoSuchName" + $self->{RetryNoSuch} = 1; + # Dont try to translate OID (we keep value) + $self->{UseNumeric} = 1; + + $self->{error_msg} = undef; + $self->{error_status} = 0; + + return $self; +} + +sub connect { + my ($self, %options) = @_; + # $options{exit_value} = integer + + my ($exit_value) = defined($options{exit_value}) ? $options{exit_value} : $self->{global_exit_value}; + + $self->{snmp_params}->{RetryNoSuch} = $self->{RetryNoSuch}; + $self->{snmp_params}->{UseNumeric} = $self->{UseNumeric}; + + if (!$self->{output}->is_litteral_status(status => $self->{snmp_errors_exit})) { + $self->{output}->add_option_msg(short_msg => "Unknown value '" . $self->{snmp_errors_exit} . "' for --snmp-errors-exit."); + $self->{output}->option_exit(exit_litteral => 'unknown'); + } + + $self->{session} = new SNMP::Session(%{$self->{snmp_params}}); + if ($self->{session}->{ErrorNum}) { + $self->{output}->add_option_msg(short_msg => 'UNKNOWN: SNMP Session : ' . $self->{session}->{ErrorStr}); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } +} + +sub load { + my ($self, %options) = @_; + # $options{oids} = ref to array of oids (example: ['.1.2', '.1.2']) + # $options{instances} = ref to array of oids instances + # $options{begin}, $args->{end} = integer instance end + # $options{instance_regexp} = str + # 3 way to use: with instances, with end, none + + if (defined($options{end})) { + for (my $i = $options{begin}; $i <= $options{end}; $i++) { + foreach (@{$options{oids}}) { + push @{$self->{oids_loaded}}, $_ . "." . $i; + } + } + return ; + } + + if (defined($options{instances})) { + $options{instance_regexp} = defined($options{instance_regexp}) ? $options{instance_regexp} : '(\d+)$'; + foreach my $instance (@{$options{instances}}) { + $instance =~ /$options{instance_regexp}/; + foreach (@{$options{oids}}) { + push @{$self->{oids_loaded}}, $_ . "." . $1; + } + } + return ; + } + + push @{$self->{oids_loaded}}, @{$options{oids}}; +} + +sub get_leef { + my ($self, %options) = @_; + # $options{dont_quit} = integer + # $options{nothing_quit} = integer + # $options{oids} = ref to array of oids (example: ['.1.2', '.1.2']) + + # Returns array + # 'undef' value for an OID means NoSuchValue + + my ($dont_quit) = (defined($options{dont_quit}) && $options{dont_quit} == 1) ? 1 : 0; + my ($nothing_quit) = (defined($options{nothing_quit}) && $options{nothing_quit} == 1) ? 1 : 0; + $self->set_error(); + + if (!defined($options{oids})) { + if ($#{$self->{oids_loaded}} < 0) { + if ($dont_quit == 1) { + $self->set_error(error_status => -1, error_msg => "Need to specify OIDs"); + return undef; + } + $self->{output}->add_option_msg(short_msg => 'Need to specify OIDs'); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + push @{$options{oids}}, @{$self->{oids_loaded}}; + @{$self->{oids_loaded}} = (); + } + + my $results = {}; + my @array_ref_ar = (); + my $subset_current = 0; + my $subset_construct = []; + foreach my $oid (@{$options{oids}}) { + # Get last value + next if ($oid !~ /(.*)\.(\d+)([\.\s]*)$/); + + my ($oid, $instance) = ($1, $2); + $results->{$oid . "." . $instance} = undef; + push @$subset_construct, [$oid, $instance]; + $subset_current++; + if ($subset_current == $self->{subsetleef}) { + push @array_ref_ar, \@$subset_construct; + $subset_construct = []; + $subset_current = 0; + } + } + if ($subset_current) { + push @array_ref_ar, \@$subset_construct; + } + + ############################ + # If wrong oid with SNMP v1, packet resent (2 packets more). Not the case with SNMP > 1. + # Can have "NoSuchName", if nothing works... + # = v1: wrong oid + # bless( [ + # '.1.3.6.1.2.1.1.3', + # '0', + # '199720062', + # 'TICKS' + # ], 'SNMP::Varbind' ), + # bless( [ + # '.1.3.6.1.2.1.1.999', + # '0' + # ], 'SNMP::Varbind' ), + # bless( [ + # '.1.3.6.1.2.1.1', + # '1000' + # ], 'SNMP::Varbind' ) + # > v1: wrong oid + # bless( [ + # '.1.3.6.1.2.1.1.3', + # '0', + # '199728713', + # 'TICKS' + # ], 'SNMP::Varbind' ), + # bless( [ + # '.1.3.6.1.2.1.1', + # '3', + # 'NOSUCHINSTANCE', + # 'TICKS' + # ], 'SNMP::Varbind' ) + # bless( [ + # '.1.3.6.1.2.1.1.999', + # '0', + # 'NOSUCHOBJECT', + # 'NOSUCHOBJECT' + # ], 'SNMP::Varbind' ), + # bless( [ + # '.1.3.6.1.2.1.1', + # '1000', + # 'NOSUCHOBJECT', + # 'NOSUCHOBJECT' + # ], 'SNMP::Varbind' ) + ############################ + + my $total = 0; + foreach (@array_ref_ar) { + my $vb = new SNMP::VarList(@{$_}); + $self->{session}->get($vb); + if ($self->{session}->{ErrorNum}) { + # 0 noError Pas d'erreurs. + # 1 tooBig Reponse de taille trop grande. + # 2 noSuchName Variable inexistante. + if ($self->{session}->{ErrorNum} == 2) { + # We are at the end with snmpv1. We next. + next; + } + + my $msg = 'SNMP GET Request : ' . $self->{session}->{ErrorStr}; + + if ($dont_quit == 0) { + $self->{output}->add_option_msg(short_msg => $msg); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + $self->set_error(error_status => -1, error_msg => $msg); + return undef; + } + + foreach my $entry (@$vb) { + if ($#$entry < 3) { + # Can be snmpv1 not find + next; + } + if (${$entry}[2] eq 'NOSUCHOBJECT' || ${$entry}[2] eq 'NOSUCHINSTANCE') { + # Error in snmp > 1 + next; + } + + $total++; + $results->{${$entry}[0] . "." . ${$entry}[1]} = ${$entry}[2]; + } + } + + if ($nothing_quit == 1 && $total == 0) { + $self->{output}->add_option_msg(short_msg => "SNMP GET Request : Cant get a single value."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + return $results; +} + +sub get_table { + my ($self, %options) = @_; + # $options{dont_quit} = integer + # $options{oid} = string (example: '.1.2') + # $options{start} = string (example: '.1.2') + # $options{end} = string (example: '.1.2') + + my ($dont_quit) = (defined($options{dont_quit}) && $options{dont_quit} == 1) ? 1 : 0; + my ($nothing_quit) = (defined($options{nothing_quit}) && $options{nothing_quit} == 1) ? 1 : 0; + $self->set_error(); + + if (defined($options{start})) { + $options{start} = $self->clean_oid($options{start}); + } + my ($end_base, $end_instance); + if (defined($options{end})) { + $options{end} = $self->clean_oid($options{end}); + } + + # we use a medium (UDP have a PDU limit. SNMP protcol cant send multiples for one request) + # So we need to manage + # It's for "bulk". We ask 50 next values. If you set 1, it's like a getnext (snmp v1) + my $repeat_count = 50; + if (defined($self->{maxrepetitions}) && + $self->{maxrepetitions} =~ /^d+$/) { + $repeat_count = $self->{maxrepetitions}; + } + + # Transform asking + if ($options{oid} !~ /(.*)\.(\d+)([\.\s]*)$/) { + if ($dont_quit == 1) { + $self->set_error(error_status => -1, error_msg => "Method 'get_table': Wrong OID '" . $options{oid} . "'."); + return undef; + } + $self->{output}->add_option_msg(short_msg => "Method 'get_table': Wrong OID '" . $options{oid} . "'."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + my $main_indice = $1 . "." . $2; + my $results = {}; + + # Quit if base not the same or 'ENDOFMIBVIEW' value + my $leave = 1; + my $last_oid; + + if (defined($options{start})) { + $last_oid = $options{start}; + } else { + $last_oid = $options{oid}; + } + while ($leave) { + $last_oid =~ /(.*)\.(\d+)([\.\s]*)$/; + my $vb = new SNMP::VarList([$1, $2]); + + if ($self->is_snmpv1()) { + $self->{session}->getnext($vb); + } else { + $self->{session}->getbulk(0, $repeat_count, $vb); + } + + # Error + if ($self->{session}->{ErrorNum}) { + # 0 noError Pas d'erreurs. + # 1 tooBig Reponse de taille trop grande. + # 2 noSuchName Variable inexistante. + if ($self->{session}->{ErrorNum} == 2) { + # We are at the end with snmpv1. We quit. + last; + } + my $msg = 'SNMP Table Request : ' . $self->{session}->{ErrorStr}; + + if ($dont_quit == 0) { + $self->{output}->add_option_msg(short_msg => $msg); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + $self->set_error(error_status => -1, error_msg => $msg); + return undef; + } + + # Manage + foreach my $entry (@$vb) { + if (${$entry}[2] eq 'ENDOFMIBVIEW') { + # END mib + $leave = 0; + last; + } + + # Not in same table + my $complete_oid = ${$entry}[0] . "." . ${$entry}[1]; + if ($complete_oid !~ /^$main_indice\./ || + (defined($options{end}) && $self->check_oid_up($complete_oid, $options{end}) )) { + $leave = 0; + last; + } + + $results->{$complete_oid} = ${$entry}[2]; + $last_oid = $complete_oid; + } + } + + if ($nothing_quit == 1 && scalar(keys %$results) == 0) { + $self->{output}->add_option_msg(short_msg => "SNMP Table Request: Cant get a single value."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + return $results; +} + +sub set { + my ($self, %options) = @_; + # $options{dont_quit} = integer + # $options{oids} = ref to hash table + my ($dont_quit) = (defined($options{dont_quit}) && $options{dont_quit} == 1) ? 1 : 0; + $self->set_error(); + + my $vars = []; + foreach my $oid (keys %{$options{oids}}) { + # Get last value + next if ($oid !~ /(.*)\.(\d+)([\.\s]*)$/); + + my $value = $options{oids}->{$oid}; + my ($oid, $instance) = ($1, $2); + + push @$vars, [$oid, $instance, $value]; + } + + $self->{session}->set($vars); + if ($self->{session}->{ErrorNum}) { + # 0 noError Pas d'erreurs. + # 1 tooBig Reponse de taille trop grande. + # 2 noSuchName Variable inexistante. + + my $msg = 'SNMP SET Request : ' . $self->{session}->{ErrorStr}; + + if ($dont_quit == 0) { + $self->{output}->add_option_msg(short_msg => $msg); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{snmp_errors_exit}); + } + + $self->set_error(error_status => -1, error_msg => $msg); + return undef; + } + + return 0; +} + +sub is_snmpv1 { + my $self = shift; + + if ($self->{snmp_params}->{Version} eq '1') { + return 1; + } + return 0; +} + +sub clean_oid { + my $self = shift; + + $_[0] =~ s/\.$//; + $_[0] =~ s/^(\d)/\.$1/; + return $_[0]; +} + +sub check_oid_up { + my $self = shift; + my ($current_oid, $end_oid) = @_; + + my @current_oid_splitted = split /\./, $current_oid; + my @end_oid_splitted = split /\./, $end_oid; + # Skip first value (before first '.' empty) + for (my $i = 1; $i <= $#current_oid_splitted && $i <= $#end_oid_splitted; $i++) { + if (int($current_oid_splitted[$i]) > int($end_oid_splitted[$i])) { + return 1; + } + } + + return 0; +} + +sub check_options { + my ($self, %options) = @_; + # $options{option_results} = ref to options result + + if (!defined($options{option_results}->{host})) { + $self->{output}->add_option_msg(short_msg => "Missing parameter --hostname."); + $self->{output}->option_exit(); + } + + $options{option_results}->{snmp_version} =~ s/^v//; + if ($options{option_results}->{snmp_version} !~ /1|2c|2|3/) { + $self->{output}->add_option_msg(short_msg => "Unknown snmp version."); + $self->{output}->option_exit(); + } + + $self->{maxrepetitions} = $options{option_results}->{maxrepetitions}; + $self->{subsetleef} = (defined($options{option_results}->{subsetleef}) && $options{option_results}->{subsetleef} =~ /^[0-9]+$/) ? $options{option_results}->{subsetleef} : 50; + $self->{snmp_errors_exit} = $options{option_results}->{snmp_errors_exit}; + + %{$self->{snmp_params}} = (DestHost => $options{option_results}->{host}, + Community => $options{option_results}->{snmp_community}, + Version => $options{option_results}->{snmp_version}, + RemotePort => $options{option_results}->{snmp_port}); + + if (defined($options{option_results}->{snmp_timeout}) && $options{option_results}->{snmp_timeout} =~ /^[0-9]+$/) { + $self->{snmp_params}->{Timeout} = $options{option_results}->{snmp_timeout} * (10**6); + } + if (defined($options{option_results}->{snmp_retries}) && $options{option_results}->{snmp_retries} =~ /^[0-9]+$/) { + $self->{snmp_params}->{Retries} = $options{option_results}->{snmp_retries}; + } + + if ($options{option_results}->{snmp_version} eq "3") { + + $self->{snmp_params}->{Context} = $options{option_results}->{snmp_context_name} if (defined($options{option_results}->{snmp_context_name})); + $self->{snmp_params}->{ContextEngineId} = $options{option_results}->{snmp_context_engine_id} if (defined($options{option_results}->{snmp_context_engine_id})); + $self->{snmp_params}->{SecEngineId} = $options{option_results}->{snmp_security_engine_id} if (defined($options{option_results}->{snmp_security_engine_id})); + $self->{snmp_params}->{SecName} = $options{option_results}->{snmp_security_name} if (defined($options{option_results}->{snmp_security_name})); + + # Certificate SNMPv3. Need net-snmp > 5.6 + if ($options{option_results}->{host} =~ /^(dtls|tls|ssh).*:/) { + $self->{snmp_params}->{OurIdentity} = $options{option_results}->{snmp_our_identity} if (defined($options{option_results}->{snmp_our_identity})); + $self->{snmp_params}->{TheirIdentity} = $options{option_results}->{snmp_their_identity} if (defined($options{option_results}->{snmp_their_identity})); + $self->{snmp_params}->{TheirHostname} = $options{option_results}->{snmp_their_hostname} if (defined($options{option_results}->{snmp_their_hostname})); + $self->{snmp_params}->{TrustCert} = $options{option_results}->{snmp_trust_cert} if (defined($options{option_results}->{snmp_trust_cert})); + $self->{snmp_params}->{SecLevel} = 'authPriv'; + return ; + } + + + if (!defined($options{option_results}->{snmp_security_name})) { + $self->{output}->add_option_msg(short_msg => "Missing paramater Security Name."); + $self->{output}->option_exit(); + } + + # unauthenticated and unencrypted + if (!defined($options{option_results}->{snmp_auth_passphrase}) && !defined($options{option_results}->{snmp_priv_passphrase})) { + $self->{snmp_params}->{SecLevel} = 'noAuthNoPriv'; + return ; + } + + if (defined($options{option_results}->{snmp_auth_passphrase}) && !defined($options{option_results}->{snmp_auth_protocol})) { + $self->{output}->add_option_msg(short_msg => "Missing parameter authenticate protocol."); + $self->{output}->option_exit(); + } + $options{option_results}->{snmp_auth_protocol} = lc($options{option_results}->{snmp_auth_protocol}); + if ($options{option_results}->{snmp_auth_protocol} ne "md5" && $options{option_results}->{snmp_auth_protocol} ne "sha") { + $self->{output}->add_option_msg(short_msg => "Wrong authentication protocol. Must be MD5 or SHA."); + $self->{output}->option_exit(); + } + + $self->{snmp_params}->{SecLevel} = 'authNoPriv'; + $self->{snmp_params}->{AuthProto} = $options{option_results}->{snmp_auth_protocol}; + $self->{snmp_params}->{AuthPass} = $options{option_results}->{snmp_auth_passphrase}; + + if (defined($options{option_results}->{snmp_priv_passphrase}) && !defined($options{option_results}->{snmp_priv_protocol})) { + $self->{output}->add_option_msg(short_msg => "Missing parameter privacy protocol."); + $self->{output}->option_exit(); + } + + if (defined($options{option_results}->{snmp_priv_protocol})) { + $options{option_results}->{snmp_priv_protocol} = lc($options{option_results}->{snmp_priv_protocol}); + if ($options{option_results}->{snmp_priv_protocol} ne 'des' && $options{option_results}->{snmp_priv_protocol} ne 'aes') { + $self->{output}->add_option_msg(short_msg => "Wrong privacy protocol. Must be DES or AES."); + $self->{output}->option_exit(); + } + + $self->{snmp_params}->{SecLevel} = 'authPriv'; + $self->{snmp_params}->{PrivPass} = $options{option_results}->{snmp_priv_passphrase}; + $self->{snmp_params}->{PrivProto} = $options{option_results}->{snmp_priv_protocol}; + } + } +} + +sub set_error { + my ($self, %options) = @_; + # $options{error_msg} = string error + # $options{error_status} = integer status + + $self->{error_status} = defined($options{error_status}) ? $options{error_status} : 0; + $self->{error_msg} = defined($options{error_msg}) ? $options{error_msg} : undef; +} + +sub error_status { + my ($self) = @_; + + return $self->{error_status}; +} + +sub error { + my ($self) = @_; + + return $self->{error_msg}; +} + +sub get_hostname { + my ($self) = @_; + + my $host = $self->{snmp_params}->{DestHost}; + $host =~ s/.*://; + return $host; +} + +sub oid_lex_sort { + my $self = shift; + + if (@_ <= 1) { + return @_; + } + + return map { $_->[0] } + sort { $a->[1] cmp $b->[1] } + map + { + my $oid = $_; + $oid =~ s/^\.//; + $oid =~ s/ /\.0/g; + [$_, pack 'N*', split m/\./, $oid] + } @_; +} + +1; + +__END__ + +=head1 NAME + +SNMP global + +=head1 SYNOPSIS + +snmp class + +=head1 SNMP OPTIONS + +=over 8 + +=item B<--hostname> + +Hostname to query (required). + +=item B<--snmp-community> + +Read community (defaults to public). + +=item B<--snmp-version> + +Version: 1 for SNMP v1 (default), 2 for SNMP v2c, 3 for SNMP v3. + +=item B<--snmp-port> + +Port (default: 161). + +=item B<--snmp-timeout> + +Timeout in secondes (default: 1) before retries. + +=item B<--snmp-retries> + +Set the number of retries (default: 5) before failure. + +=item B<--maxrepetitions> + +Max repititions value (default: 50) (only for SNMP v2 and v3). + +=item B<--subsetleef> + +How many oid values per SNMP request (default: 50) (for get_leef method. Be cautious whe you set it. Prefer to let the default value). + +=item B<--snmp-username> + +Security name (only for SNMP v3). + +=item B<--authpassphrase> + +Authentication protocol pass phrase. + +=item B<--authprotocol> + +Authentication protocol (MD5|SHA) + +=item B<--privpassphrase> + +Privacy protocol pass phrase + +=item B<--privprotocol> + +Privacy protocol (DES|AES) + +=item B<--contextname> + +Context name + +=item B<--contextengineid> + +Context engine ID + +=item B<--securityengineid> + +Security engine ID + +=item B<--snmp-errors-exit> + +Exit code for SNMP Errors (default: unknown) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/statefile.pm b/centreon/plugins/statefile.pm new file mode 100644 index 000000000..a1fa0756a --- /dev/null +++ b/centreon/plugins/statefile.pm @@ -0,0 +1,185 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::plugins::statefile; +use Data::Dumper; +use vars qw($datas); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (defined($options{options})) { + $options{options}->add_options(arguments => + { + "memcached:s" => { name => 'memcached' }, + "statefile-dir:s" => { name => 'statefile_dir', default => '/var/lib/centreon/centplugins' }, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'RETENTION OPTIONS', once => 1); + } + + $self->{output} = $options{output}; + $self->{datas} = {}; + $self->{memcached} = undef; + + $self->{statefile_dir} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + if (defined($options{option_results}) && defined($options{option_results}->{memcached})) { + require Memcached::libmemcached; + $self->{memcached} = Memcached::libmemcached->new(); + Memcached::libmemcached::memcached_server_add($self->{memcached}, $options{option_results}->{memcached}); + } + $self->{statefile_dir} = $options{option_results}->{statefile_dir}; +} + +sub read { + my ($self, %options) = @_; + $self->{statefile_dir} = defined($options{statefile_dir}) ? $options{statefile_dir} : $self->{statefile_dir}; + $self->{statefile} = defined($options{statefile}) ? $options{statefile} : $self->{statefile}; + + if (defined($self->{memcached})) { + # if "SUCCESS" or "NOT FOUND" is ok. Other with use the file + my $val = Memcached::libmemcached::memcached_get($self->{memcached}, $self->{statefile_dir} . "/" . $self->{statefile}); + if (defined($self->{memcached}->errstr) && $self->{memcached}->errstr =~ /^SUCCESS|NOT FOUND$/i) { + if (defined($val)) { + eval( $val ); + $self->{datas} = $datas; + $datas = {}; + return 1; + } + return 0; + } + $self->{memcached_ok} = 0; + } + + if (! -e $self->{statefile_dir} . "/" . $self->{statefile}) { + if (! -w $self->{statefile_dir}) { + $self->{output}->add_option_msg(short_msg => "Cannot write statefile '" . $self->{statefile_dir} . "/" . $self->{statefile} . "'. Need write permissions on directory."); + $self->{output}->option_exit(); + } + return 0; + } elsif (! -w $self->{statefile_dir} . "/" . $self->{statefile}) { + $self->{output}->add_option_msg(short_msg => "Cannot write statefile '" . $self->{statefile_dir} . "/" . $self->{statefile} . "'. Need write permissions on file."); + $self->{output}->option_exit(); + } + + unless (my $return = do $self->{statefile_dir} . "/" . $self->{statefile}) { + if ($@) { + $self->{output}->add_option_msg(short_msg => "Couldn't parse '" . $self->{statefile_dir} . "/" . $self->{statefile} . "': $@"); + $self->{output}->option_exit(); + } + unless (defined($return)) { + $self->{output}->add_option_msg(short_msg => "Couldn't do '" . $self->{statefile_dir} . "/" . $self->{statefile} . "': $!"); + $self->{output}->option_exit(); + } + unless ($return) { + $self->{output}->add_option_msg(short_msg => "Couldn't run '" . $self->{statefile_dir} . "/" . $self->{statefile} . "': $!"); + $self->{output}->option_exit(); + } + } + $self->{datas} = $datas; + $datas = {}; + + return 1; +} + +sub get_string_content { + my ($self, %options) = @_; + + return Data::Dumper::Dumper($self->{datas}); +} + +sub get { + my ($self, %options) = @_; + + if (defined($self->{datas}->{$options{name}})) { + return $self->{datas}->{$options{name}}; + } + return undef; +} + +sub write { + my ($self, %options) = @_; + + if (defined($self->{memcached})) { + Memcached::libmemcached::memcached_set($self->{memcached}, $self->{statefile_dir} . "/" . $self->{statefile}, + Data::Dumper->Dump([$options{data}], ["datas"])); + if (defined($self->{memcached}->errstr) && $self->{memcached}->errstr =~ /^SUCCESS$/i) { + return ; + } + } + open FILE, ">", $self->{statefile_dir} . "/" . $self->{statefile}; + print FILE Data::Dumper->Dump([$options{data}], ["datas"]); + close FILE; +} + +1; + +__END__ + +=head1 NAME + +Statefile class + +=head1 SYNOPSIS + +- + +=head1 RETENTION OPTIONS + +=over 8 + +=item B<--memcached> + +Memcached server to use (only one server). + +=item B<--statefile-dir> + +Directory for statefile (Default: '/var/lib/centreon/centplugins'). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/src/process-service-perfdata b/centreon_plugins.pl similarity index 81% rename from src/process-service-perfdata rename to centreon_plugins.pl index 3a97b64eb..9b6fb19d1 100644 --- a/src/process-service-perfdata +++ b/centreon_plugins.pl @@ -1,6 +1,6 @@ -#! /bin/sh +#!/usr/bin/perl ################################################################################ -# Copyright 2004-2011 MERETHIS +# Copyright 2005-2013 MERETHIS # Centreon is developped by : Julien Mathis and Romain Le Merlus under # GPL Licence 2.0. # @@ -30,26 +30,16 @@ # do not wish to do so, delete this exception statement from your version. # # For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ +# Authors : Quentin Garnier # #################################################################################### -# -# Script init -# -# Set perfdata file -PERFFILE="@NAGIOS_VAR@/service-perfdata" +use strict; +use warnings; +use centreon::plugins::script; +# Not perl embedded compliant at all +use FindBin; +use lib "$FindBin::Bin"; +# use lib '/usr/lib/nagios/plugins/'; -# some parameters passed on command line -TIMET=$1 -HOSTNAME=$2 -SERVICEDESC=$3 -HARDSTATE=$4 -SERVICESTATE=$5 -PERFDATA=$6 - -# Write data in perfdata file -/usr/bin/printf "%b" "$TIMET\t$HOSTNAME\t$SERVICEDESC\t$HARDSTATE\t$SERVICESTATE\t$PERFDATA\n" >> $PERFFILE -chmod 664 $PERFFILE +centreon::plugins::script->new()->run(); diff --git a/database/mysql/mode/connectiontime.pm b/database/mysql/mode/connectiontime.pm new file mode 100644 index 000000000..4e311f9a3 --- /dev/null +++ b/database/mysql/mode/connectiontime.pm @@ -0,0 +1,123 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::connectiontime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Time::HiRes; +use POSIX; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + my $now = Time::HiRes::time(); + my ($exit, $msg_error) = $self->{sql}->connect(dontquit => 1); + my $now2 = Time::HiRes::time(); + + if ($exit == -1) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => $msg_error); + } else { + my $milliseconds = $now2 - $now; + $milliseconds = floor($milliseconds * 1000); + my $exit_code = $self->{perfdata}->threshold_check(value => $milliseconds, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Connection established in %.3fs.", $milliseconds / 1000)); + $self->{output}->perfdata_add(label => 'connection_time', unit => 'ms', + value => $milliseconds, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MySQL connection time. + +=over 8 + +=item B<--warning> + +Threshold warning in milliseconds. + +=item B<--critical> + +Threshold critical in milliseconds. + +=back + +=cut diff --git a/database/mysql/mode/databasessize.pm b/database/mysql/mode/databasessize.pm new file mode 100644 index 000000000..2959dfc8a --- /dev/null +++ b/database/mysql/mode/databasessize.pm @@ -0,0 +1,138 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::databasessize; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "filter:s" => { name => 'filter', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + $self->{sql}->query(query => 'SELECT table_schema AS NAME, SUM(data_length+index_length) + FROM information_schema.tables + GROUP BY table_schema'); + my $result = $self->{sql}->fetchall_arrayref(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported."); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => "All databases are ok."); + foreach my $row (@$result) { + next if (defined($self->{option_results}->{filter}) && + $$row[0] !~ /$self->{option_results}->{filter}/); + + my $exit_code = $self->{perfdata}->threshold_check(value => $$row[1], threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($value, $value_unit) = $self->{perfdata}->change_bytes(value => $$row[1]); + $self->{output}->output_add(long_msg => sprintf("DB '" . $$row[0] . "' size: %.3f%s", $value, $value_unit)); + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("DB '" . $$row[0] . "' size: %.3f%s", $value, $value_unit)); + } + $self->{output}->perfdata_add(label => $$row[0] . '_size', + value => $$row[1], + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MySQL databases size. + +=over 8 + +=item B<--warning> + +Threshold warning in bytes. + +=item B<--critical> + +Threshold critical in bytes. + +=item B<--filter> + +Filter database to checks. + +=back + +=cut diff --git a/database/mysql/mode/innodbbufferpoolhitrate.pm b/database/mysql/mode/innodbbufferpoolhitrate.pm new file mode 100644 index 000000000..ca176ae71 --- /dev/null +++ b/database/mysql/mode/innodbbufferpoolhitrate.pm @@ -0,0 +1,167 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::innodbbufferpoolhitrate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "lookback" => { name => 'lookback', }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS WHERE Variable_name IN ('Innodb_buffer_pool_read_requests', 'Innodb_buffer_pool_reads')}); + my $new_datas = {Innodb_buffer_pool_read_requests => undef, Innodb_buffer_pool_reads => undef}; + my $result = $self->{sql}->fetchall_arrayref(); + foreach my $row (@{$result}) { + $new_datas->{$$row[0]} = $$row[1]; + } + foreach (keys %$new_datas) { + if (!defined($new_datas->{$_})) { + $self->{output}->add_option_msg(short_msg => "Cannot get '$_' variable."); + $self->{output}->option_exit(); + } + } + + $self->{statefile_cache}->read(statefile => 'mysql_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); + $new_datas->{last_timestamp} = time(); + + my $old_read_request = $self->{statefile_cache}->get(name => 'Innodb_buffer_pool_read_requests'); + my $old_read = $self->{statefile_cache}->get(name => 'Innodb_buffer_pool_reads'); + if (defined($old_read_request) && defined($old_read) && + $new_datas->{Innodb_buffer_pool_read_requests} >= $old_read_request && + $new_datas->{Innodb_buffer_pool_reads} >= $old_read) { + + + my %prcts = (); + my $total_read_requests = $new_datas->{Innodb_buffer_pool_read_requests} - $old_read_request; + my $total_read_disk = $new_datas->{Innodb_buffer_pool_reads} - $old_read; + $prcts{bufferpool_hitrate_now} = ($total_read_requests == 0) ? 100 : ($total_read_requests - $total_read_disk) * 100 / $total_read_requests; + $prcts{bufferpool_hitrate} = ($new_datas->{Innodb_buffer_pool_read_requests} == 0) ? 100 : ($new_datas->{Innodb_buffer_pool_read_requests} - $new_datas->{Innodb_buffer_pool_reads}) * 100 / $new_datas->{Innodb_buffer_pool_read_requests}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $prcts{'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '' )}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("innodb buffer pool hitrate at %.2f%%", $prcts{'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '' : '_now')}) + ); + $self->{output}->perfdata_add(label => 'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '' : '_now'), unit => '%', + value => sprintf("%.2f", $prcts{'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{output}->perfdata_add(label => 'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : ''), unit => '%', + value => sprintf("%.2f", $prcts{'bufferpool_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + min => 0); + } + + $self->{statefile_cache}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check hitrate in the InnoDB Buffer Pool. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--lookback> + +Threshold isn't on the percent calculated from the difference ('bufferpool_hitrate_now'). + +=back + +=cut diff --git a/database/mysql/mode/myisamkeycachehitrate.pm b/database/mysql/mode/myisamkeycachehitrate.pm new file mode 100644 index 000000000..ff21d57af --- /dev/null +++ b/database/mysql/mode/myisamkeycachehitrate.pm @@ -0,0 +1,167 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::myisamkeycachehitrate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "lookback" => { name => 'lookback', }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS WHERE Variable_name IN ('Key_read_requests', 'Key_reads')}); + my $new_datas = {Key_read_requests => undef, Key_reads => undef}; + my $result = $self->{sql}->fetchall_arrayref(); + foreach my $row (@{$result}) { + $new_datas->{$$row[0]} = $$row[1]; + } + foreach (keys %$new_datas) { + if (!defined($new_datas->{$_})) { + $self->{output}->add_option_msg(short_msg => "Cannot get '$_' variable."); + $self->{output}->option_exit(); + } + } + + $self->{statefile_cache}->read(statefile => 'mysql_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); + $new_datas->{last_timestamp} = time(); + + my $old_read_request = $self->{statefile_cache}->get(name => 'Key_read_requests'); + my $old_read = $self->{statefile_cache}->get(name => 'Key_reads'); + if (defined($old_read_request) && defined($old_read) && + $new_datas->{Key_read_requests} >= $old_read_request && + $new_datas->{Key_reads} >= $old_read) { + + + my %prcts = (); + my $total_read_requests = $new_datas->{Key_read_requests} - $old_read_request; + my $total_read_disk = $new_datas->{Key_reads} - $old_read; + $prcts{keycache_hitrate_now} = ($total_read_requests == 0) ? 100 : ($total_read_requests - $total_read_disk) * 100 / $total_read_requests; + $prcts{keycache_hitrate} = ($new_datas->{Key_read_requests} == 0) ? 100 : ($new_datas->{Key_read_requests} - $new_datas->{Key_reads}) * 100 / $new_datas->{Key_read_requests}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $prcts{'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '' )}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("myisam keycache hitrate at %.2f%%", $prcts{'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '' : '_now')}) + ); + $self->{output}->perfdata_add(label => 'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '' : '_now'), unit => '%', + value => sprintf("%.2f", $prcts{'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{output}->perfdata_add(label => 'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : ''), unit => '%', + value => sprintf("%.2f", $prcts{'keycache_hitrate' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + min => 0); + } + + $self->{statefile_cache}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check hitrate in the Myisam Key Cache. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--lookback> + +Threshold isn't on the percent calculated from the difference ('keycache_hitrate_now'). + +=back + +=cut diff --git a/database/mysql/mode/openfiles.pm b/database/mysql/mode/openfiles.pm new file mode 100644 index 000000000..edbfe8218 --- /dev/null +++ b/database/mysql/mode/openfiles.pm @@ -0,0 +1,134 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::openfiles; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW VARIABLES LIKE 'open_files_limit'}); + my ($dummy, $open_files_limit) = $self->{sql}->fetchrow_array(); + if (!defined($open_files_limit)) { + $self->{output}->add_option_msg(short_msg => "Cannot get ope files limit."); + $self->{output}->option_exit(); + } + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Open_files'}); + ($dummy, my $open_files) = $self->{sql}->fetchrow_array(); + if (!defined($open_files)) { + $self->{output}->add_option_msg(short_msg => "Cannot get open files."); + $self->{output}->option_exit(); + } + + my $prct_open = int(100 * $open_files / $open_files_limit); + my $exit_code = $self->{perfdata}->threshold_check(value => $prct_open, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%.2f%% of the open files limit reached (%d of max. %d)", + $prct_open, $open_files, $open_files_limit)); + $self->{output}->perfdata_add(label => 'open_files', + value => $open_files, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $open_files_limit, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $open_files_limit, cast_int => 1), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check number of open files. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/database/mysql/mode/queries.pm b/database/mysql/mode/queries.pm new file mode 100644 index 000000000..15f3dccef --- /dev/null +++ b/database/mysql/mode/queries.pm @@ -0,0 +1,157 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::queries; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + $self->{sql}->query(query => q{ + SHOW /*!50000 global */ STATUS WHERE Variable_name IN ('Queries', 'Com_update', 'Com_delete', 'Com_insert', 'Com_truncate', 'Com_select') + }); + my $result = $self->{sql}->fetchall_arrayref(); + + if (!($self->{sql}->is_version_minimum(version => '5.0.76'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.0.76')."); + $self->{output}->option_exit(); + } + + my $new_datas = {}; + $self->{statefile_cache}->read(statefile => 'mysql_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); + $new_datas->{last_timestamp} = time(); + + if (defined($old_timestamp) && $new_datas->{last_timestamp} - $old_timestamp == 0) { + $self->{output}->add_option_msg(short_msg => "Need at least one second between two checks."); + $self->{output}->option_exit(); + } + + foreach my $row (@{$result}) { + next if ($$row[0] !~ /^(Queries|Com_update|Com_delete|Com_insert|Com_truncate|Com_select)/i); + + $new_datas->{$$row[0]} = $$row[1]; + my $old_val = $self->{statefile_cache}->get(name => $$row[0]); + next if (!defined($old_val) || $$row[1] < $old_val); + + my $value = int(($$row[1] - $old_val) / ($new_datas->{last_timestamp} - $old_timestamp)); + if ($$row[0] ne 'Queries') { + $self->{output}->perfdata_add(label => $$row[0] . '_requests', + value => $value, + min => 0); + next; + } + + my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Total requests = %d.", $value)); + $self->{output}->perfdata_add(label => 'total_requests', + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + + $self->{statefile_cache}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check average number of queries executed. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut diff --git a/database/mysql/mode/replicationmasterslave.pm b/database/mysql/mode/replicationmasterslave.pm new file mode 100644 index 000000000..7ceb65b17 --- /dev/null +++ b/database/mysql/mode/replicationmasterslave.pm @@ -0,0 +1,347 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::replicationmasterslave; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + + if (ref($options{sql}) ne 'ARRAY') { + $self->{output}->add_option_msg(short_msg => "Need to use --multiple options."); + $self->{output}->option_exit(); + } + if (scalar(@{$options{sql}}) < 2) { + $self->{output}->add_option_msg(short_msg => "Need to specify two MySQL Server."); + $self->{output}->option_exit(); + } + + my ($sql_one, $sql_two) = @{$options{sql}}; + my ($slave_status, $slave_status_error) = (0, ""); + my ($position_status, $position_status_error) = (0, ""); + my ($connection_status_name_srv1, $connection_status_name_srv2) = ($sql_one->get_id(), $sql_two->get_id()); + my ($master_save, $slave_save); + + my ($exit1, $msg_error1) = $sql_one->connect(dontquit => 1); + my ($exit2, $msg_error2) = $sql_two->connect(dontquit => 1); + $self->{output}->output_add(severity => 'OK', + short_msg => "No problems. Replication is ok."); + if ($exit1 == -1) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Connection Status '" . $sql_one->get_id() . "': " . $msg_error1); + } else { + $self->{output}->output_add(long_msg => "Connection Status '" . $sql_one->get_id() . "' [OK]"); + } + if ($exit2 == -1) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Connection Status '" . $sql_two->get_id() . "': " . $msg_error2); + } else { + $self->{output}->output_add(long_msg => "Connection Status '" . $sql_two->get_id() . "' [OK]"); + } + + ##### + # Find SLAVE + ##### + my ($total_srv1, $total_srv2); + my ($last_error1, $last_error2); + + my ($io_thread_status_srv1, $sql_thread_status_srv1); + if ($exit1 != -1) { + $sql_one->query(query => q{ + SHOW SLAVE STATUS + }); + my $result = $sql_one->fetchrow_hashref(); + my $slave_io_running = $result->{Slave_IO_Running}; + my $slave_sql_running = $result->{Slave_SQL_Running}; + $last_error1 = $result->{Last_Error}; + + if (defined($slave_io_running) && $slave_io_running =~ /^yes$/i) { + $io_thread_status_srv1 = 0; + } else { + $io_thread_status_srv1 = 1; + } + if (defined($slave_sql_running) && $slave_sql_running =~ /^yes$/i) { + $sql_thread_status_srv1 = 0; + } else { + $sql_thread_status_srv1 = 1; + } + } else { + $io_thread_status_srv1 = 100; + $sql_thread_status_srv1 = 100; + } + + my ($io_thread_status_srv2, $sql_thread_status_srv2); + if ($exit2 != -1) { + $sql_two->query(query => q{ + SHOW SLAVE STATUS + }); + my $result = $sql_two->fetchrow_hashref(); + my $slave_io_running = $result->{Slave_IO_Running}; + my $slave_sql_running = $result->{Slave_SQL_Running}; + $last_error2 = $result->{Last_Error}; + + if (defined($slave_io_running) && $slave_io_running =~ /^yes$/i) { + $io_thread_status_srv2 = 0; + } else { + $io_thread_status_srv2 = 1; + } + if (defined($slave_sql_running) && $slave_sql_running =~ /^yes$/i) { + $sql_thread_status_srv2 = 0; + } else { + $sql_thread_status_srv2 = 1; + } + } else { + $io_thread_status_srv2 = 100; + $sql_thread_status_srv2 = 100; + } + + $total_srv1 = $io_thread_status_srv1 + $sql_thread_status_srv1; + $total_srv2 = $io_thread_status_srv2 + $sql_thread_status_srv2; + + # Check If there is two slave + if ($total_srv1 < 2 && $total_srv2 < 2) { + $slave_status = 1; + $slave_status_error = "Two slave. Need to have only one."; + } else { + # Check if a thread is down + if ($total_srv1 == 1) { + $slave_status = -1; + $slave_status_error = "A Replication thread is down on '" . $sql_one->get_id() . "'."; + if ($sql_thread_status_srv1 != 0) { + if (defined($last_error1) && $last_error1 ne "") { + $slave_status = 1; + $slave_status_error .= " SQL Thread is stopped because of an error (error='" . $last_error1 . "')."; + } + } + } + if ($total_srv2 == 1) { + $slave_status = -1; + $slave_status_error = "A Replication thread is down on '" . $sql_two->get_id() . "'."; + if ($sql_thread_status_srv2 != 0) { + if (defined($last_error2) && $last_error2 ne "") { + $slave_status = 1; + $slave_status_error .= " SQL Thread is stopped because of an error (error='" . $last_error2 . "')."; + } + } + } + + # Check if we need to SKIP + if ($io_thread_status_srv1 == 100) { + $slave_status = -1; + $slave_status_error .= " Skip check on '" . $sql_one->get_id() . "'."; + } + if ($io_thread_status_srv2 == 100) { + $slave_status = -1; + $slave_status_error .= " Skip check on '" . $sql_two->get_id() . "'."; + } + + # Save Slave + if ($total_srv1 < 2) { + $slave_save = $sql_one; + $master_save = $sql_two; + } + if ($total_srv2 < 2) { + $slave_save = $sql_two; + $master_save = $sql_one; + } + + if ($total_srv2 > 1 && $total_srv1 > 1) { + $slave_status = 1; + $slave_status_error .= " No slave (maybe because we cannot check a server)."; + } + } + + #### + # Check Slave position + #### + if (!defined($slave_save)) { + $position_status = -2; + $position_status_error = "Skip because we can't identify a unique slave."; + } else { + if ($master_save->get_id() eq $connection_status_name_srv1 && $exit1 == -1) { + $position_status = -1; + $position_status_error = "Can't get master position on '" . $master_save->get_id() . "'."; + } elsif ($master_save->get_id() eq $connection_status_name_srv2 && $exit2 == -1) { + $position_status = -1; + $position_status_error = "Can't get master position on '" . $master_save->get_id() . "'."; + } else { + # Get Master Position + $master_save->query(query => q{ + SHOW MASTER STATUS + }); + my $result = $master_save->fetchrow_hashref(); + my $master_file = $result->{File}; + my $master_position = $result->{Position}; + + $slave_save->query(query => q{ + SHOW SLAVE STATUS + }); + my $result2 = $slave_save->fetchrow_hashref(); + my $slave_file = $result2->{Master_Log_File}; # 'Master_Log_File' + my $slave_position = $result2->{Read_Master_Log_Pos}; # 'Read_Master_Log_Pos' + my $num_sec_lates = $result2->{Seconds_Behind_Master}; + + my $exit_code_sec = $self->{perfdata}->threshold_check(value => $num_sec_lates, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + if (!$self->{output}->is_status(value => $exit_code_sec, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code_sec, + short_msg => sprintf("Slave has %d seconds latency behind master", $num_sec_lates)); + } + $self->{output}->perfdata_add(label => 'slave_latency', unit => 's', + value => $num_sec_lates, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + my $slave_sql_thread_ko = 1; + my $slave_sql_thread_warning = 1; + my $slave_sql_thread_ok = 1; + + $slave_save->query(query => q{ + SHOW FULL PROCESSLIST + }); + while ((my $row = $slave_save->fetchrow_hashref())) { + my $state = $row->{State}; + $slave_sql_thread_ko = 0 if (defined($state) && $state =~ /^(Waiting to reconnect after a failed binlog dump request|Connecting to master|Reconnecting after a failed binlog dump request|Waiting to reconnect after a failed master event read|Waiting for the slave SQL thread to free enough relay log space)$/i); + $slave_sql_thread_warning = 0 if (defined($state) && $state =~ /^Waiting for the next event in relay log|Reading event from the relay log$/i); + $slave_sql_thread_ok = 0 if (defined($state) && $state =~ /^Has read all relay log; waiting for the slave I\/O thread to update it$/i); + } + + if ($slave_sql_thread_ko == 0) { + $position_status = 1; + $position_status_error .= " Slave replication has connection issue with the master."; + } elsif (($master_file ne $slave_file || $master_position != $slave_position) && $slave_sql_thread_warning == 0) { + $position_status = -1; + $position_status_error .= " Slave replication is late but it's progressing.."; + } elsif (($master_file ne $slave_file || $master_position != $slave_position) && $slave_sql_thread_ok == 0) { + $position_status = -1; + $position_status_error .= " Slave replication is late but it's progressing.."; + } + } + } + + + + $self->replication_add($slave_status, "Slave Thread Status", $slave_status_error); + $self->replication_add($position_status, "Position Status", $position_status_error); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub replication_add { + my ($self, $lstate, $str_display, $lerr) = @_; + my $status; + my $status_msg; + + if ($lstate == 0) { + $status = 'OK'; + } elsif ($lstate == -1) { + $status = 'WARNING'; + } elsif ($lstate == -2) { + $status = 'CRITICAL'; + $status_msg = 'SKIP'; + } else { + $status = 'CRITICAL'; + } + + my $output; + if (defined($lerr) && $lerr ne "") { + $output = $str_display . " [" . (defined($status_msg) ? $status_msg : $status) . "] [" . $lerr . "]"; + } else { + $output = $str_display . " [" . (defined($status_msg) ? $status_msg : $status) . "]"; + } + if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $status, + short_msg => $output); + } + + $self->{output}->output_add(long_msg => $output); +} + +1; + +__END__ + +=head1 MODE + +Check MySQL replication master/slave (need to use --multiple). + +=over 8 + +=item B<--warning> + +Threshold warning in seconds (slave latency). + +=item B<--critical> + +Threshold critical in seconds (slave latency). + +=back + +=cut diff --git a/database/mysql/mode/slowqueries.pm b/database/mysql/mode/slowqueries.pm new file mode 100644 index 000000000..25a05442a --- /dev/null +++ b/database/mysql/mode/slowqueries.pm @@ -0,0 +1,153 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::slowqueries; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Slow_queries'}); + my ($name, $result) = $self->{sql}->fetchrow_array(); + if (!defined($result)) { + $self->{output}->add_option_msg(short_msg => "Cannot get slow queries."); + $self->{output}->option_exit(); + } + + + my $new_datas = {}; + $self->{statefile_cache}->read(statefile => 'mysql_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); + $new_datas->{last_timestamp} = time(); + + if (defined($old_timestamp) && $new_datas->{last_timestamp} - $old_timestamp == 0) { + $self->{output}->add_option_msg(short_msg => "Need at least one second between two checks."); + $self->{output}->option_exit(); + } + + $new_datas->{$name} = $result; + my $old_val = $self->{statefile_cache}->get(name => $name); + if (defined($old_val) && $result >= $old_val) { + my $value = sprintf("%.2f", ($result - $old_val) / ($new_datas->{last_timestamp} - $old_timestamp)); + + my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%d slow queries in %d seconds (%.2f/sec)", + ($result - $old_val), ($new_datas->{last_timestamp} - $old_timestamp), $value) + ); + $self->{output}->perfdata_add(label => 'slow_queries_rate', + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + + $self->{statefile_cache}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check average number of queries detected as "slow" (per seconds). + +=over 8 + +=item B<--warning> + +Threshold warning in queries per seconds. + +=item B<--critical> + +Threshold critical in queries per seconds. + +=back + +=cut diff --git a/database/mysql/mode/threadsconnected.pm b/database/mysql/mode/threadsconnected.pm new file mode 100644 index 000000000..c10095f95 --- /dev/null +++ b/database/mysql/mode/threadsconnected.pm @@ -0,0 +1,129 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::threadsconnected; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Threads_connected'}); + my ($dummy, $result) = $self->{sql}->fetchrow_array(); + if (!defined($result)) { + $self->{output}->add_option_msg(short_msg => "Cannot get number of open connections."); + $self->{output}->option_exit(); + } + + + my $value = $result; + + my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%d client connection threads", $value) + ); + $self->{output}->perfdata_add(label => 'threads_connected', + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check number of open connections. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut diff --git a/database/mysql/mode/uptime.pm b/database/mysql/mode/uptime.pm new file mode 100644 index 000000000..d1b53bdb8 --- /dev/null +++ b/database/mysql/mode/uptime.pm @@ -0,0 +1,138 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mode::uptime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use POSIX; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "seconds" => { name => 'seconds', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Uptime'}); + my ($dummy, $result) = $self->{sql}->fetchrow_array(); + if (!defined($result)) { + $self->{output}->add_option_msg(short_msg => "Cannot get uptime."); + $self->{output}->option_exit(); + } + + my $value = $result; + + my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $msg = sprintf("database is up since %d days", floor($value / 86400)); + if (defined($self->{option_results}->{seconds})) { + $msg = sprintf("database is up since %d seconds", $value); + } + + $self->{output}->output_add(severity => $exit_code, + short_msg => $msg); + $self->{output}->perfdata_add(label => 'uptime', unit => 's', + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MySQL uptime. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--seconds> + +Display uptime in seconds. + +=back + +=cut diff --git a/database/mysql/mysqlcmd.pm b/database/mysql/mysqlcmd.pm new file mode 100644 index 000000000..6b7c90131 --- /dev/null +++ b/database/mysql/mysqlcmd.pm @@ -0,0 +1,347 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::mysqlcmd; + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class mysqlcmd: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Mysqlcmd: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { "mysql-cmd:s" => { name => 'mysql_cmd', default => '/usr/bin/mysql' }, + "host:s@" => { name => 'host' }, + "port:s@" => { name => 'port' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "sql-errors-exit:s" => { name => 'sql_errors_exit', default => 'unknown' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'MYSQLCMD OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{args} = undef; + $self->{stdout} = undef; + $self->{columns} = undef; + $self->{version} = undef; + + $self->{host} = undef; + $self->{port} = undef; + $self->{username} = undef; + $self->{password} = undef; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still data_source + # return 0 = no data_source left + + $self->{host} = (defined($self->{option_results}->{host})) ? shift(@{$self->{option_results}->{host}}) : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : undef; + $self->{sql_errors_exit} = $self->{option_results}->{sql_errors_exit}; + $self->{mysql_cmd} = $self->{option_results}->{mysql_cmd}; + + if (!defined($self->{host}) || $self->{host} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify host argument."); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + + $self->{args} = ['--batch', '--raw', '--host', $self->{host}]; + if (defined($self->{port})) { + push @{$self->{args}}, "--port", $self->{port}; + } + if (defined($self->{username})) { + push @{$self->{args}}, "--user", $self->{username}; + } + if (defined($self->{password}) && $self->{password} ne '') { + push @{$self->{args}}, "-p" . $self->{password}; + } + + if (scalar(@{$self->{option_results}->{host}}) == 0) { + return 0; + } + return 1; +} + +sub is_version_minimum { + my ($self, %options) = @_; + # $options{version} = string version to check + + my @version_src = split /\./, $self->{version}; + my @versions = split /\./, $options{version}; + for (my $i = 0; $i < scalar(@versions); $i++) { + return 1 if ($versions[$i] eq 'x'); + return 1 if (!defined($version_src[$i])); + $version_src[$i] =~ /^([0-9]*)/; + next if ($versions[$i] == int($1)); + return 0 if ($versions[$i] > int($1)); + return 1 if ($versions[$i] < int($1)); + } + + return 1; +} + +sub get_id { + my ($self, %options) = @_; + + my $msg = $self->{host}; + if (defined($self->{port})) { + $msg .= ":" . $self->{port}; + } + return $msg; +} + + +sub get_unique_id4save { + my ($self, %options) = @_; + + my $msg = $self->{host}; + if (defined($self->{port})) { + $msg .= ":" . $self->{port}; + } + return md5_hex($msg); +} + +sub quote { + my $self = shift; + + return undef; +} + +sub command_execution { + my ($self, %options) = @_; + + my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( + command => $self->{mysql_cmd}, + arguments => [@{$self->{args}}, '-e', $options{request}], + timeout => 30, + wait_exit => 1, + redirect_stderr => 1 + ); + if ($exit_code <= -1000) { + if ($exit_code == -1000) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => $stdout); + } + $self->{output}->display(); + $self->{output}->exit(); + } + + return ($exit_code, $stdout); +} + +# Connection initializer +sub connect { + my ($self, %options) = @_; + my $dontquit = (defined($options{dontquit}) && $options{dontquit} == 1) ? 1 : 0; + + (my $exit_code, $self->{stdout}) = $self->command_execution(request => "SHOW VARIABLES LIKE 'version'"); + if ($exit_code != 0) { + if ($dontquit == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot connect: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + return (-1, "Cannot connect: " . $self->{stdout}); + } + + my $row = $self->fetchrow_hashref(); + $self->{version} = $row->{Value}; + + return 0; +} + +sub fetchall_arrayref { + my ($self, %options) = @_; + my $array_ref = []; + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)(\n|$)//; + @{$self->{columns}} = split(/\t/, $1); + } + foreach (split /\n/, $self->{stdout}) { + push @$array_ref, [map({ s/\\n/\x{0a}/g; s/\\t/\x{09}/g; s/\\/\x{5c}/g; $_; } split(/\t/, $_))]; + } + + return $array_ref; +} + +sub fetchrow_array { + my ($self, %options) = @_; + my @array_result = (); + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)(\n|$)//; + @{$self->{columns}} = split(/\t/, $1); + } + if (($self->{stdout} =~ s/^(.*?)(\n|$)//)) { + push @array_result, map({ s/\\n/\x{0a}/g; s/\\t/\x{09}/g; s/\\/\x{5c}/g; $_; } split(/\t/, $1)); + } + + return @array_result; +} + +sub fetchrow_hashref { + my ($self, %options) = @_; + my $array_result = undef; + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)(\n|$)//; + @{$self->{columns}} = split(/\t/, $1); + } + if ($self->{stdout} ne '' && $self->{stdout} =~ s/^(.*?)(\n|$)//) { + $array_result = {}; + my @values = split(/\t/, $1); + for (my $i = 0; $i < scalar(@values); $i++) { + my $value = $values[$i]; + $value =~ s/\\n/\x{0a}/g; + $value =~ s/\\t/\x{09}/g; + $value =~ s/\\/\x{5c}/g; + $array_result->{$self->{columns}[$i]} = $value; + } + } + + return $array_result; +} + +sub query { + my ($self, %options) = @_; + + $self->{columns} = undef; + (my $exit_code, $self->{stdout}) = $self->command_execution(request => $options{query}); + + if ($exit_code != 0) { + $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + +} + +1; + +__END__ + +=head1 NAME + +mysqlcmd global + +=head1 SYNOPSIS + +mysqlcmd class + +=head1 MYSQLCMD OPTIONS + +=over 8 + +=item B<--mysql-cmd> + +mysql command (Default: '/usr/bin/mysql'). + +=item B<--host> + +Database hostname. + +=item B<--port> + +Database port. + +=item B<--username> + +Database username. + +=item B<--password> + +Database password. + +=item B<--sql-errors-exit> + +Exit code for DB Errors (default: unknown) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/database/mysql/plugin.pm b/database/mysql/plugin.pm new file mode 100644 index 000000000..8ca7976c5 --- /dev/null +++ b/database/mysql/plugin.pm @@ -0,0 +1,118 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::mysql::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_sql); + +sub new { + my ($class, %options) = @_; + + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'connection-time' => 'database::mysql::mode::connectiontime', + 'databases-size' => 'database::mysql::mode::databasessize', + 'queries' => 'database::mysql::mode::queries', + 'slow-queries' => 'database::mysql::mode::slowqueries', + 'threads-connected' => 'database::mysql::mode::threadsconnected', + 'uptime' => 'database::mysql::mode::uptime', + 'open-files' => 'database::mysql::mode::openfiles', + 'innodb-bufferpool-hitrate' => 'database::mysql::mode::innodbbufferpoolhitrate', + 'myisam-keycache-hitrate' => 'database::mysql::mode::myisamkeycachehitrate', + 'replication-master-slave' => 'database::mysql::mode::replicationmasterslave', + ); + $self->{sql_modes}{mysqlcmd} = 'database::mysql::mysqlcmd'; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->{options}->add_options( + arguments => { + 'host:s@' => { name => 'db_host' }, + 'port:s@' => { name => 'db_port' }, + } + ); + $self->{options}->parse_options(); + my $options_result = $self->{options}->get_options(); + $self->{options}->clean(); + + if (defined($options_result->{db_host})) { + @{$self->{sqldefault}->{dbi}} = (); + @{$self->{sqldefault}->{mysqlcmd}} = (); + for (my $i = 0; $i < scalar(@{$options_result->{db_host}}); $i++) { + $self->{sqldefault}->{dbi}[$i] = { data_source => 'mysql:host=' . $options_result->{db_host}[$i] }; + $self->{sqldefault}->{mysqlcmd}[$i] = { host => $options_result->{db_host}[$i] }; + if (defined($options_result->{db_port}[$i])) { + $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';port=' . $options_result->{db_port}[$i]; + $self->{sqldefault}->{mysqlcmd}[$i]->{port} = $options_result->{db_port}[$i]; + } + } + } + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check MySQL Server. + +=over 8 + +You can use following options or options from 'sqlmode' directly. + +=item B<--host> + +Hostname to query. + +=item B<--port> + +Database Server Port. + +=back + +=cut diff --git a/database/postgres/mode/backends.pm b/database/postgres/mode/backends.pm new file mode 100644 index 000000000..edfe644cb --- /dev/null +++ b/database/postgres/mode/backends.pm @@ -0,0 +1,170 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::backends; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "exclude:s" => { name => 'exclude', }, + "noidle" => { name => 'noidle', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + my $noidle = ''; + if (defined($self->{option_results}->{noidle})) { + if ($self->{sql}->is_version_minimum(version => '9.2')) { + $noidle = " AND state <> 'idle'"; + } else { + $noidle = " AND current_query <> ''"; + } + } + + my $query = "SELECT COUNT(datid) AS current, + (SELECT setting AS mc FROM pg_settings WHERE name = 'max_connections') AS mc, + d.datname +FROM pg_database d +LEFT JOIN pg_stat_activity s ON (s.datid = d.oid $noidle) +GROUP BY d.datname +ORDER BY d.datname"; + $self->{sql}->query(query => $query); + + $self->{output}->output_add(severity => 'OK', + short_msg => "All client database connections are ok."); + + my $database_check = 0; + my $result = $self->{sql}->fetchall_arrayref(); + + foreach my $row (@{$result}) { + if (defined($self->{option_results}->{exclude}) && $$row[2] !~ /$self->{option_results}->{exclude}/) { + $self->{output}->output_add(long_msg => "Skipping database '" . $$row[2] . '"'); + next; + } + + $database_check++; + my $used = $$row[0]; + my $max_connections = $$row[1]; + my $database_name = $$row[2]; + + my $prct_used = ($used * 100) / $max_connections; + my $exit_code = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(long_msg => sprintf("Database '%s': %.2f%% client connections limit reached (%d of max. %d)", + $database_name, $prct_used, $used, $max_connections)); + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Database '%s': %.2f%% client connections limit reached (%d of max. %d)", + $database_name, $prct_used, $used, $max_connections)); + } + + $self->{output}->perfdata_add(label => 'connections_' . $database_name, + value => $used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => $max_connections); + } + if ($database_check == 0) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'No database checked. (permission or a wrong exclude filter)'); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check the current number of connections for one or more databases + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=item B<--exclude> + +Filter databases. + +=item B<--noidle> + +Idle connections are not counted. + +=back + +=cut diff --git a/database/postgres/mode/connectiontime.pm b/database/postgres/mode/connectiontime.pm new file mode 100644 index 000000000..9ea4d56df --- /dev/null +++ b/database/postgres/mode/connectiontime.pm @@ -0,0 +1,123 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::connectiontime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Time::HiRes; +use POSIX; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + my $now = Time::HiRes::time(); + my ($exit, $msg_error) = $self->{sql}->connect(dontquit => 1); + my $now2 = Time::HiRes::time(); + + if ($exit == -1) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => $msg_error); + } else { + my $milliseconds = $now2 - $now; + $milliseconds = floor($milliseconds * 1000); + my $exit_code = $self->{perfdata}->threshold_check(value => $milliseconds, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Connection established in %.3fs.", $milliseconds / 1000)); + $self->{output}->perfdata_add(label => 'connection_time', unit => 'ms', + value => $milliseconds, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Postgres connection time. + +=over 8 + +=item B<--warning> + +Threshold warning in milliseconds. + +=item B<--critical> + +Threshold critical in milliseconds. + +=back + +=cut diff --git a/database/postgres/mode/hitratio.pm b/database/postgres/mode/hitratio.pm new file mode 100644 index 000000000..1846ab409 --- /dev/null +++ b/database/postgres/mode/hitratio.pm @@ -0,0 +1,189 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::hitratio; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "lookback" => { name => 'lookback', }, + "exclude:s" => { name => 'exclude', }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + $self->{sql}->query(query => q{ +SELECT sd.blks_hit, sd.blks_read, d.datname +FROM pg_stat_database sd, pg_database d +WHERE d.oid=sd.datid + }); + + $self->{statefile_cache}->read(statefile => 'postgres_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); + + my $database_check = 0; + my $new_datas = {}; + $new_datas->{last_timestamp} = time(); + my $result = $self->{sql}->fetchall_arrayref(); + + $self->{output}->output_add(severity => 'OK', + short_msg => "All databases hitratio are ok."); + + + foreach my $row (@{$result}) { + $new_datas->{$$row[2] . '_blks_hit'} = $$row[0]; + $new_datas->{$$row[2] . '_blks_read'} = $$row[1]; + + if (defined($self->{option_results}->{exclude}) && $$row[2] !~ /$self->{option_results}->{exclude}/) { + $self->{output}->output_add(long_msg => "Skipping database '" . $$row[2] . '"'); + next; + } + + my $old_blks_hit = $self->{statefile_cache}->get(name => $$row[2] . '_blks_hit'); + my $old_blks_read = $self->{statefile_cache}->get(name => $$row[2] . '_blks_read'); + + next if (!defined($old_blks_hit) || !defined($old_blks_read)); + $old_blks_hit = 0 if ($$row[0] <= $old_blks_hit); + $old_blks_read = 0 if ($$row[1] <= $old_blks_read); + + $database_check++; + my %prcts = (); + my $total_read_requests = $new_datas->{$$row[2] . '_blks_hit'} - $old_blks_hit; + my $total_read_disk = $new_datas->{$$row[2] . '_blks_read'} - $old_blks_read; + $prcts{hitratio_now} = ($total_read_requests == 0) ? 100 : ($total_read_requests - $total_read_disk) * 100 / $total_read_requests; + $prcts{hitratio} = ($new_datas->{$$row[2] . '_blks_hit'} == 0) ? 100 : ($new_datas->{$$row[2] . '_blks_hit'} - $new_datas->{$$row[2] . '_blks_read'}) * 100 / $new_datas->{$$row[2] . '_blks_hit'}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $prcts{'hitratio' . ((defined($self->{option_results}->{lookback})) ? '_now' : '' )}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(long_msg => sprintf("Database '%s' hitratio at %.2f%%", + $$row[2], $prcts{'hitratio' . ((defined($self->{option_results}->{lookback})) ? '' : '_now')}) + ); + + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Database '%s' hitratio at %.2f%%", + $$row[2], $prcts{'hitratio' . ((defined($self->{option_results}->{lookback})) ? '' : '_now')}) + ); + } + $self->{output}->perfdata_add(label => $$row[2] . '_hitratio' . ((defined($self->{option_results}->{lookback})) ? '' : '_now'), unit => '%', + value => sprintf("%.2f", $prcts{'hitratio' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => $$row[2] . '_hitratio' . ((defined($self->{option_results}->{lookback})) ? '_now' : ''), unit => '%', + value => sprintf("%.2f", $prcts{'hitratio' . ((defined($self->{option_results}->{lookback})) ? '_now' : '')}), + min => 0, max => 100); + } + + $self->{statefile_cache}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + if (defined($old_timestamp) && $database_check == 0) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'No database checked. (permission or a wrong exclude filter)'); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check hitratio (in buffer cache) for databases. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--lookback> + +Threshold isn't on the percent calculated from the difference ('xxx_hitratio_now'). + +=item B<--exclude> + +Filter databases. + +=back + +=cut diff --git a/database/postgres/mode/listdatabases.pm b/database/postgres/mode/listdatabases.pm new file mode 100644 index 000000000..709b8fee5 --- /dev/null +++ b/database/postgres/mode/listdatabases.pm @@ -0,0 +1,127 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::listdatabases; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Time::HiRes; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "exclude:s" => { name => 'exclude', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{sql}->connect(); + + $self->{sql}->query(query => q{ +SELECT datname FROM pg_database +}); + $self->{list_db} = []; + while ((my $row = $self->{sql}->fetchrow_hashref())) { + if (defined($self->{option_results}->{exclude}) && $row->{datname} !~ /$self->{option_results}->{exclude}/) { + next; + } + push @{$self->{list_db}}, $row->{datname}; + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->manage_selection(); + + $self->{output}->output_add(severity => 'OK', + short_msg => "List of databases: " . join(', ', @{$self->{list_db}})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name']); +} + +sub disco_show { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{sql} = $options{sql}; + + $self->manage_selection(); + foreach (sort @{$self->{list_db}}) { + $self->{output}->add_disco_entry(name => $_); + } +} + +1; + +__END__ + +=head1 MODE + +Display databases + +=over 8 + +=item B<--exclude> + +Filter databases. + +=back + +=cut diff --git a/database/postgres/mode/locks.pm b/database/postgres/mode/locks.pm new file mode 100644 index 000000000..bca88341e --- /dev/null +++ b/database/postgres/mode/locks.pm @@ -0,0 +1,172 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::locks; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', default => ''}, + "critical:s" => { name => 'critical', default => ''}, + "exclude:s" => { name => 'exclude', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + my @warns = split /,/, $self->{option_results}->{warning}; + my @crits = split /,/, $self->{option_results}->{critical}; + + foreach my $val (@warns) { + next if (!defined($val)); + my ($label, $value) = split /=/, $val; + next if (!defined($label) || !defined($value)); + + if (($self->{perfdata}->threshold_validate(label => 'warn-' . $label, value => $value)) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning ('$label' locks) threshold '" . $value . "'."); + $self->{output}->option_exit(); + } + } + + foreach my $val (@crits) { + next if (!defined($val)); + my ($label, $value) = split /=/, $val; + next if (!defined($label) || !defined($value)); + + if (($self->{perfdata}->threshold_validate(label => 'crit-' . $label, value => $value)) == 0) { + $self->{output}->add_option_msg(short_msg => "Critical warning ('$label' locks) threshold '" . $value . "'."); + $self->{output}->option_exit(); + } + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + $self->{sql}->query(query => q{ +SELECT granted, mode, datname FROM pg_database d LEFT JOIN pg_locks l ON (d.oid=l.database) WHERE d.datallowconn +}); + + $self->{output}->output_add(severity => 'OK', + short_msg => "All databases locks are ok."); + + my $result = $self->{sql}->fetchall_arrayref(); + my $dblocks = {}; + foreach my $row (@{$result}) { + my ($granted, $mode, $dbname) = ($$row[0], $$row[1], $$row[2]); + if (defined($self->{option_results}->{exclude}) && $dbname !~ /$self->{option_results}->{exclude}/) { + next; + } + + if (!defined($dblocks->{$dbname})) { + $dblocks->{$dbname} = {total => 0, waiting => 0}; + # Empty. no lock (left join) + next if (!defined($mode) || $mode eq ''); + } + $dblocks->{$dbname}->{total}++; + $mode =~ s{lock$}{}; + $dblocks->{$dbname}->{lc($mode)}++; + $dblocks->{$dbname}->{waiting}++ if (!$granted); + } + + foreach my $dbname (keys %$dblocks) { + foreach my $locktype (keys %{$dblocks->{$dbname}}) { + $self->{output}->output_add(long_msg => sprintf("Database '%s' lock '%s': %d", + $dbname, $locktype, $dblocks->{$dbname}->{$locktype})); + my $exit_code = $self->{perfdata}->threshold_check(value => $dblocks->{$dbname}->{$locktype}, threshold => [ { label => 'crit-' . $locktype, 'exit_litteral' => 'critical' }, { label => 'warn-' . $locktype, exit_litteral => 'warning' } ]); + + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Database '%s' lock '%s': %d", + $dbname, $locktype, $dblocks->{$dbname}->{$locktype})); + } + + $self->{output}->perfdata_add(label => $dbname . '_' . $locktype, + value => $dblocks->{$dbname}->{$locktype}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn-' . $locktype), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit-' . $locktype), + min => 0); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check locks for one or more databases + +=over 8 + +=item B<--warning> + +Threshold warning. (example: "total=250,waiting=5,exclusive=20") +'total', 'waiting', or the name of a lock type used by Postgres. + +=item B<--critical> + +Threshold critical. (example: "total=250,waiting=5,exclusive=20") +'total', 'waiting', or the name of a lock type used by Postgres. + +=item B<--exclude> + +Filter databases. + +=back + +=cut diff --git a/database/postgres/mode/querytime.pm b/database/postgres/mode/querytime.pm new file mode 100644 index 000000000..4d4513979 --- /dev/null +++ b/database/postgres/mode/querytime.pm @@ -0,0 +1,167 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::querytime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "exclude:s" => { name => 'exclude', }, + "exclude-user:s" => { name => 'exclude_user', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + my $query; + if ($self->{sql}->is_version_minimum(version => '9.2')) { + $query = q{ +SELECT datname, datid, pid, usename, client_addr, query AS current_query, state AS state, + CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, + COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds +FROM pg_stat_activity WHERE (query_start IS NOT NULL AND (state NOT LIKE 'idle%' OR state IS NULL)) +ORDER BY query_start, pid DESC +}; + } else { + $query = q{ +SELECT datname, datid, procpid AS pid, usename, client_addr, current_query AS current_query, '' AS state, + CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, + COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds +FROM pg_stat_activity WHERE (query_start IS NOT NULL AND current_query NOT LIKE '%') +ORDER BY query_start, procpid DESC +}; + } + + $self->{sql}->query(query => $query); + + $self->{output}->output_add(severity => 'OK', + short_msg => "All databases queries time are ok."); + my $dbquery = {}; + while ((my $row = $self->{sql}->fetchrow_hashref())) { + if (defined($self->{option_results}->{exclude}) && $row->{datname} !~ /$self->{option_results}->{exclude}/) { + next; + } + if (defined($self->{option_results}->{exclude_user}) && $row->{usename} !~ /$self->{option_results}->{exclude_user}/) { + next; + } + + my $exit_code = $self->{perfdata}->threshold_check(value => $row->{seconds}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + if ($self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(long_msg => sprintf("Request from client '%s' too long (%d sec) on database '%s': %s", + $row->{client_addr}, $row->{seconds}, $row->{datname}, $row->{current_query})); + $dbquery->{$row->{datname}}->{total}++; + $dbquery->{$row->{datname}}->{code}->{$exit_code}++; + } + } + + foreach my $dbname (keys %$dbquery) { + $self->{output}->perfdata_add(label => $dbname . '_qtime_num', + value => $dbquery->{$dbname}->{total}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + foreach my $exit_code (keys %{$dbquery->{$dbname}->{code}}) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%d request exceed " . lc($exit_code) . " threshold on database '%s'", + $dbquery->{$dbname}->{code}->{$exit_code}, $dbname)); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Checks the time of running queries for one or more databases + +=over 8 + +=item B<--warning> + +Threshold warning in seconds. + +=item B<--critical> + +Threshold critical in seconds. + +=item B<--exclude> + +Filter databases. + +=item B<--exclude-user> + +Filter users. + +=back + +=cut diff --git a/database/postgres/mode/timesync.pm b/database/postgres/mode/timesync.pm new file mode 100644 index 000000000..11e77e624 --- /dev/null +++ b/database/postgres/mode/timesync.pm @@ -0,0 +1,125 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::mode::timesync; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Time::HiRes; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + $self->{sql}->query(query => q{ +SELECT extract(epoch FROM now()) AS epok +}); + + my ($result) = $self->{sql}->fetchrow_array(); + my $ltime = Time::HiRes::time(); + if (!defined($result)) { + $self->{output}->add_option_msg(short_msg => "Cannot get server time."); + $self->{output}->option_exit(); + } + + my $diff = $result - $ltime; + my $exit_code = $self->{perfdata}->threshold_check(value => $result, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%.3fs time diff between servers", $diff)); + $self->{output}->perfdata_add(label => 'timediff', unit => 's', + value => sprintf("%.3f", $diff), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Compares the local system time with the time reported by Postgres + +=over 8 + +=item B<--warning> + +Threshold warning in seconds. (use a range. it can be -0.3s or +0.3s.) + +=item B<--critical> + +Threshold critical in seconds. (use a range. it can be -0.3s or +0.3s.) + +=back + +=cut diff --git a/database/postgres/plugin.pm b/database/postgres/plugin.pm new file mode 100644 index 000000000..5f51df5a3 --- /dev/null +++ b/database/postgres/plugin.pm @@ -0,0 +1,122 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_sql); + +sub new { + my ($class, %options) = @_; + + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'backends' => 'database::postgres::mode::backends', + 'connection-time' => 'database::postgres::mode::connectiontime', + 'hitratio' => 'database::postgres::mode::hitratio', + 'locks' => 'database::postgres::mode::locks', + 'list-databases' => 'database::postgres::mode::listdatabases', + 'query-time' => 'database::postgres::mode::querytime', + 'timesync' => 'database::postgres::mode::timesync', + ); + $self->{sql_modes}{psqlcmd} = 'database::postgres::psqlcmd'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->{options}->add_options( + arguments => { + 'host:s@' => { name => 'db_host' }, + 'port:s@' => { name => 'db_port' }, + 'database:s@' => { name => 'db_name' }, + } + ); + $self->{options}->parse_options(); + my $options_result = $self->{options}->get_options(); + $self->{options}->clean(); + + if (defined($options_result->{db_host})) { + @{$self->{sqldefault}->{dbi}} = (); + @{$self->{sqldefault}->{psqlcmd}} = (); + for (my $i = 0; $i < scalar(@{$options_result->{db_host}}); $i++) { + $self->{sqldefault}->{dbi}[$i] = { data_source => 'Pg:host=' . $options_result->{db_host}[$i] }; + $self->{sqldefault}->{psqlcmd}[$i] = { host => $options_result->{db_host}[$i] }; + if (defined($options_result->{db_port}[$i])) { + $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';port=' . $options_result->{db_port}[$i]; + $self->{sqldefault}->{psqlcmd}[$i]->{port} = $options_result->{db_port}[$i]; + } + $options_result->{db_name}[$i] = (defined($options_result->{db_name}[$i])) ? $options_result->{db_name}[$i] : 'postgres'; + $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';database=' . $options_result->{db_name}[$i]; + $self->{sqldefault}->{psqlcmd}[$i]->{dbname} = $options_result->{db_name}[$i]; + } + } + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Postgres Server. + +=over 8 + +You can use following options or options from 'sqlmode' directly. + +=item B<--host> + +Hostname to query. + +=item B<--port> + +Database Server Port. + +=item B<--database> + +Database Name. (default: postgres) + +=back + +=cut diff --git a/database/postgres/psqlcmd.pm b/database/postgres/psqlcmd.pm new file mode 100644 index 000000000..178310995 --- /dev/null +++ b/database/postgres/psqlcmd.pm @@ -0,0 +1,360 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package database::postgres::psqlcmd; + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class psqlcmd: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class psqlcmd: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { "psql-cmd:s" => { name => 'psql_cmd', default => '/usr/bin/psql' }, + "host:s@" => { name => 'host' }, + "port:s@" => { name => 'port' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "dbname:s@" => { name => 'dbname' }, + "sql-errors-exit:s" => { name => 'sql_errors_exit', default => 'unknown' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'PSQLCMD OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{args} = undef; + $self->{stdout} = undef; + $self->{columns} = undef; + $self->{version} = undef; + + $self->{host} = undef; + $self->{port} = undef; + $self->{username} = undef; + $self->{password} = undef; + $self->{dbname} = undef; + + $self->{record_separator} = '-====-'; + $self->{field_separator} = '#====#'; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still data_source + # return 0 = no data_source left + + $self->{host} = (defined($self->{option_results}->{host})) ? shift(@{$self->{option_results}->{host}}) : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : undef; + $self->{dbname} = (defined($self->{option_results}->{dbname})) ? shift(@{$self->{option_results}->{dbname}}) : undef; + $self->{sql_errors_exit} = $self->{option_results}->{sql_errors_exit}; + $self->{psql_cmd} = $self->{option_results}->{psql_cmd}; + + # If we want a command line: password with variable "PGPASSWORD". + # psql -d template1 -A -R '-====-' -F '#====#' -c "select code from films" + + if (!defined($self->{host}) || $self->{host} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify host argument."); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + + $self->{args} = ['-A', '-R', $self->{record_separator}, '-F', $self->{field_separator}, '--pset', 'footer=off', '-h', $self->{host}]; + if (defined($self->{port})) { + push @{$self->{args}}, "-p", $self->{port}; + } + if (defined($self->{username})) { + push @{$self->{args}}, "-U", $self->{username}; + } + if (defined($self->{password}) && $self->{password} ne '') { + $ENV{PGPASSWORD} = $self->{password}; + } + if (defined($self->{dbname}) && $self->{dbname} ne '') { + push @{$self->{args}}, "-d", $self->{dbname}; + } + + if (scalar(@{$self->{option_results}->{host}}) == 0) { + return 0; + } + return 1; +} + +sub is_version_minimum { + my ($self, %options) = @_; + # $options{version} = string version to check + + my @version_src = split /\./, $self->{version}; + my @versions = split /\./, $options{version}; + for (my $i = 0; $i < scalar(@versions); $i++) { + return 1 if ($versions[$i] eq 'x'); + return 1 if (!defined($version_src[$i])); + $version_src[$i] =~ /^([0-9]*)/; + next if ($versions[$i] == int($1)); + return 0 if ($versions[$i] > int($1)); + return 1 if ($versions[$i] < int($1)); + } + + return 1; +} + +sub get_id { + my ($self, %options) = @_; + + my $msg = $self->{host}; + if (defined($self->{port})) { + $msg .= ":" . $self->{port}; + } + return $msg; +} + + +sub get_unique_id4save { + my ($self, %options) = @_; + + my $msg = $self->{host}; + if (defined($self->{port})) { + $msg .= ":" . $self->{port}; + } + return md5_hex($msg); +} + +sub quote { + my $self = shift; + + return undef; +} + +sub command_execution { + my ($self, %options) = @_; + + my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( + command => $self->{psql_cmd}, + arguments => [@{$self->{args}}, '-c', $options{request}], + timeout => 30, + wait_exit => 1, + redirect_stderr => 1 + ); + if ($exit_code <= -1000) { + if ($exit_code == -1000) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => $stdout); + } + $self->{output}->display(); + $self->{output}->exit(); + } + + return ($exit_code, $stdout); +} + +# Connection initializer +sub connect { + my ($self, %options) = @_; + my $dontquit = (defined($options{dontquit}) && $options{dontquit} == 1) ? 1 : 0; + + (my $exit_code, $self->{stdout}) = $self->command_execution(request => "SELECT current_setting('server_version') as version"); + if ($exit_code != 0) { + if ($dontquit == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot connect: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + return (-1, "Cannot connect: " . $self->{stdout}); + } + + my $row = $self->fetchrow_hashref(); + $self->{version} = $row->{version}; + + return 0; +} + +sub fetchall_arrayref { + my ($self, %options) = @_; + my $array_ref = []; + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms; + @{$self->{columns}} = split(/\Q$self->{field_separator}\E/, $1); + } + foreach (split /\Q$self->{record_separator}\E/, $self->{stdout}) { + push @$array_ref, [split(/\Q$self->{field_separator}\E/, $_)]; + } + + return $array_ref; +} + +sub fetchrow_array { + my ($self, %options) = @_; + my @array_result = (); + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms; + @{$self->{columns}} = split(/\Q$self->{field_separator}\E/, $1); + } + if (($self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms)) { + push @array_result, split(/\Q$self->{field_separator}\E/, $1); + } + + return @array_result; +} + +sub fetchrow_hashref { + my ($self, %options) = @_; + my $array_result = undef; + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms; + @{$self->{columns}} = split(/\Q$self->{field_separator}\E/, $1); + } + if ($self->{stdout} ne '' && $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms) { + $array_result = {}; + my @values = split(/\Q$self->{field_separator}\E/, $1); + for (my $i = 0; $i < scalar(@values); $i++) { + my $value = $values[$i]; + $array_result->{$self->{columns}[$i]} = $value; + } + } + + return $array_result; +} + +sub query { + my ($self, %options) = @_; + + $self->{columns} = undef; + (my $exit_code, $self->{stdout}) = $self->command_execution(request => $options{query}); + + if ($exit_code != 0) { + $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); + } + +} + +1; + +__END__ + +=head1 NAME + +psqlcmd global + +=head1 SYNOPSIS + +psqlcmd class + +=head1 PSQLCMD OPTIONS + +=over 8 + +=item B<--psql-cmd> + +postgres command (Default: '/usr/bin/psql'). + +=item B<--host> + +Database hostname. + +=item B<--port> + +Database port. + +=item B<--dbname> + +Database name to connect (default: postgres). + +=item B<--username> + +Database username. + +=item B<--password> + +Database password. + +=item B<--sql-errors-exit> + +Exit code for DB Errors (default: unknown) + +=back + +=head1 DESCRIPTION + +B<>. + +=cut diff --git a/example/custommode/simple.pm b/example/custommode/simple.pm new file mode 100644 index 000000000..6d73ae3ae --- /dev/null +++ b/example/custommode/simple.pm @@ -0,0 +1,151 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package example::custommode::simple; + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { "customarg:s@" => { name => 'customarg' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CUSTOM OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + $self->{customarg} = undef; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still customarg + # return 0 = no customarg left + + $self->{customarg} = (defined($self->{option_results}->{customarg})) ? shift(@{$self->{option_results}->{customarg}}) : undef; + + if (!defined($self->{customarg}) || + scalar(@{$self->{option_results}->{customarg}}) == 0) { + return 0; + } + return 1; +} + +############## +# Specific methods +############## +sub test { + my ($self, %options) = @_; + + use Data::Dumper; + print Data::Dumper::Dumper($self); +} + +1; + +__END__ + +=head1 NAME + +My Custom global + +=head1 SYNOPSIS + +my custom class example + +=head1 CUSTOM OPTIONS + +=over 8 + +=item B<--customarg> + +Argument test. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/example/mode/getvalue.pm b/example/mode/getvalue.pm new file mode 100644 index 000000000..26c9b0154 --- /dev/null +++ b/example/mode/getvalue.pm @@ -0,0 +1,126 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package example::mode::getvalue; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "oid:s" => { name => 'oid' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{oid})) { + $self->{output}->add_option_msg(short_msg => "Need to specify an OID."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + my $result = $self->{snmp}->get_leef(oids => [$self->{option_results}->{oid}], nothing_quit => 1); + my $value = $result->{$self->{option_results}->{oid}}; + + my $exit = $self->{perfdata}->threshold_check(value => $value, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("SNMP Value is %s.", $value)); + + $self->{output}->perfdata_add(label => 'value', unit => undef, + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => undef, max => undef); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check an SNMP Integer value. + +=over 8 + +=item B<--oid> + +Check OID Integer value. + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut diff --git a/example/mode/launchcmd.pm b/example/mode/launchcmd.pm new file mode 100644 index 000000000..45d584206 --- /dev/null +++ b/example/mode/launchcmd.pm @@ -0,0 +1,122 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package example::mode::launchcmd; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "cmd:s" => { name => 'cmd' }, + "timeout:s" => { name => 'timeout', default => 30 } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{cmd})) { + $self->{output}->add_option_msg(short_msg => "Need to specify a command."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( + command => $self->{option_results}->{cmd}, + timeout => $self->{option_results}->{timeout}, + wait_exit => 1 + ); + $stdout =~ s/\r//g; + if ($exit_code <= -1000) { + if ($exit_code == -1000) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => $stdout); + } + $self->{output}->display(); + $self->{output}->exit(); + } + if ($exit_code != 0) { + $stdout =~ s/\n/ - /g; + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Command error: $stdout"); + $self->{output}->display(); + $self->{output}->exit(); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'Command executed with no errors.'); + $self->{output}->output_add(long_msg => $stdout); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Launch a local command. Use --verbose to see the command output. + +=over 8 + +=item B<--cmd> + +Command to execute. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=back + +=cut diff --git a/src/submit_host_check_result b/example/mode/testcustom.pm similarity index 65% rename from src/submit_host_check_result rename to example/mode/testcustom.pm index c581f086e..f4bc99828 100644 --- a/src/submit_host_check_result +++ b/example/mode/testcustom.pm @@ -1,6 +1,5 @@ -#!/bin/sh ################################################################################ -# Copyright 2004-2011 MERETHIS +# Copyright 2005-2013 MERETHIS # Centreon is developped by : Julien Mathis and Romain Le Merlus under # GPL Licence 2.0. # @@ -30,42 +29,62 @@ # do not wish to do so, delete this exception statement from your version. # # For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ +# Authors : Quentin Garnier # #################################################################################### -# -# Script init -# -# Arguments: -# $1 = host_name (Short name of host that the service is -# associated with) -# $2 = state_string (A string representing the status of -# the given service - "UP", "DOWN", "UNREACHABLE" -# $3 = plugin_output (A text string that should be used -# as the plugin output for the service checks) -# +package example::mode::testcustom; -# pipe the service check info into the send_nsca program, which -# in turn transmits the data to the nsca daemon on the central -# monitoring server +use base qw(centreon::plugins::mode); +use strict; +use warnings; +use centreon::plugins::misc; - return_code=-1 +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "timeout:s" => { name => 'timeout', default => 30 } + }); - case "$2" in - UP) - return_code=0 - ;; - DOWN) - return_code=1 - ;; - UNREACHABLE) - return_code=2 - ;; - esac + return $self; +} -# Test everything works fine -/usr/bin/printf "%s\t%s\t%s\n" "$1" "$return_code" "$3" | /usr/sbin/send_nsca IP -p PORT -c /etc/send_nsca.cfg +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + +} + +sub run { + my ($self, %options) = @_; + my $custom = $options{custom}; + + $custom->test(); + + #$self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +For custom mode example test. + +=over 8 + +=item B<--timeout> + +Timeout in seconds. + +=back + +=cut diff --git a/src/submit_service_check_result b/example/plugin_command.pm similarity index 62% rename from src/submit_service_check_result rename to example/plugin_command.pm index 32d57a7c1..c5f8d9dd2 100644 --- a/src/submit_service_check_result +++ b/example/plugin_command.pm @@ -1,6 +1,5 @@ -#!/bin/sh ################################################################################ -# Copyright 2004-2011 MERETHIS +# Copyright 2005-2013 MERETHIS # Centreon is developped by : Julien Mathis and Romain Le Merlus under # GPL Licence 2.0. # @@ -30,46 +29,36 @@ # do not wish to do so, delete this exception statement from your version. # # For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ +# Authors : Quentin Garnier # #################################################################################### -# -# Script init -# -# Arguments: -# $1 = host_name (Short name of host that the service is -# associated with) -# $2 = svc_description (Description of the service) -# $3 = state_string (A string representing the status of -# the given service - "OK", "WARNING", "CRITICAL" -# or "UNKNOWN") -# $4 = plugin_output (A text string that should be used -# as the plugin output for the service checks) -# +package example::plugin_command; -# pipe the service check info into the send_nsca program, which -# in turn transmits the data to the nsca daemon on the central -# monitoring server +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); - return_code=-1 +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object - case "$3" in - OK) - return_code=0 - ;; - WARNING) - return_code=1 - ;; - CRITICAL) - return_code=2 - ;; - UNKNOWN) - return_code=-1 - ;; - esac + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'launchcmd' => 'example::mode::launchcmd' + ); -# Test everything works fine -/usr/bin/printf "%s\t%s\t%s\t%s|%s\n" "$1" "$2" "$return_code" "$4" "$5" | /usr/sbin/send_nsca IP -p PORT -c /etc/send_nsca.cfg + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +An example of local command plugin. + +=cut diff --git a/example/plugin_custom.pm b/example/plugin_custom.pm new file mode 100644 index 000000000..e47106915 --- /dev/null +++ b/example/plugin_custom.pm @@ -0,0 +1,76 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package example::plugin_custom; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'testcustom' => 'example::mode::testcustom', + ); + $self->{custom_modes}{mycustommodetest} = 'example::custommode::simple'; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Custom mode (an example for creating test with a same line argument). + +=over 8 + +=back + +=cut diff --git a/example/plugin_snmp.pm b/example/plugin_snmp.pm new file mode 100644 index 000000000..c496f3ae2 --- /dev/null +++ b/example/plugin_snmp.pm @@ -0,0 +1,64 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package example::plugin_snmp; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'getvalue' => 'example::mode::getvalue' + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +An example of SNMP plugin type. + +=cut diff --git a/hardware/server/hpbladechassis/mode/hardware.pm b/hardware/server/hpbladechassis/mode/hardware.pm new file mode 100644 index 000000000..ecb3982ed --- /dev/null +++ b/hardware/server/hpbladechassis/mode/hardware.pm @@ -0,0 +1,634 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package hardware::server::hpbladechassis::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %conditions = (1 => ['other', 'CRITICAL'], + 2 => ['ok', 'OK'], + 3 => ['degraded', 'WARNING'], + 4 => ['failed', 'CRITICAL']); +my %present_map = (1 => 'other', + 2 => 'absent', + 3 => 'present', + 4 => 'Weird!!!', # for blades it can return 4, which is NOT spesified in MIB +); +my %device_type = (1 => 'noconnect', + 2 => 'network', + 3 => 'fibrechannel', + 4 => 'sas', + 5 => 'inifiband', + 6 => 'pciexpress' +); +my %psu_status = (1 => 'noError', + 2 => 'generalFailure', + 3 => 'bistFailure', + 4 => 'fanFailure', + 5 => 'tempFailure', + 6 => 'interlockOpen', + 7 => 'epromFailed', + 8 => 'vrefFailed', + 9 => 'dacFailed', + 10 => 'ramTestFailed', + 11 => 'voltageChannelFailed', + 12 => 'orringdiodeFailed', + 13 => 'brownOut', + 14 => 'giveupOnStartup', + 15 => 'nvramInvalid', + 16 => 'calibrationTableInvalid', +); +my %inputline_status = (1 => 'noError', + 2 => 'lineOverVoltage', + 3 => 'lineUnderVoltage', + 4 => 'lineHit', + 5 => 'brownOut', + 6 => 'linePowerLoss', +); +my %map_role = (1 => 'Standby', + 2 => 'Active', +); +my %map_has = (1 => 'false', + 2 => 'true', +); +my %map_temp_type = (1 => 'other', + 5 => 'blowout', + 9 => 'caution', + 15 => 'critical', +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "exclude" => { name => 'exclude' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{components_fans} = 0; + $self->{components_blades} = 0; + $self->{components_nc} = 0; + $self->{components_psu} = 0; + $self->{components_temperatures} = 0; + $self->{components_fuse} = 0; + + $self->check_enclosure_status(); + $self->check_managers(); + $self->check_fans(); + $self->check_blades(); + $self->check_iom(); + $self->check_psu(); + $self->check_temperatures(); + $self->check_fuse(); + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %d components [%d fans, %d blades, %d network connectors, %d psu, %d temperatures, %d fuses] are ok.", + ($self->{components_fans} + $self->{components_blades} + $self->{components_nc} + $self->{components_psu} + $self->{components_temperatures} + $self->{components_fuse}), + $self->{components_fans}, $self->{components_blades}, $self->{components_nc}, $self->{components_psu}, $self->{components_temperatures}, $self->{components_fuse})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_enclosure_status { + my ($self) = @_; + + my $oid_cpqRackCommonEnclosurePartNumber = '.1.3.6.1.4.1.232.22.2.3.1.1.1.5.1'; + my $oid_cpqRackCommonEnclosureSparePartNumber = '.1.3.6.1.4.1.232.22.2.3.1.1.1.6.1'; + my $oid_cpqRackCommonEnclosureSerialNum = '.1.3.6.1.4.1.232.22.2.3.1.1.1.7.1'; + my $oid_cpqRackCommonEnclosureFWRev = '.1.3.6.1.4.1.232.22.2.3.1.1.1.8.1'; + my $oid_cpqRackCommonEnclosureCondition = '.1.3.6.1.4.1.232.22.2.3.1.1.1.16.1'; + my $oid_cpqRackCommonEnclosureHasServerBlades = '.1.3.6.1.4.1.232.22.2.3.1.1.1.17.1'; + my $oid_cpqRackCommonEnclosureHasPowerSupplies = '.1.3.6.1.4.1.232.22.2.3.1.1.1.18.1'; + my $oid_cpqRackCommonEnclosureHasNetConnectors = '.1.3.6.1.4.1.232.22.2.3.1.1.1.19.1'; + my $oid_cpqRackCommonEnclosureHasTempSensors = '.1.3.6.1.4.1.232.22.2.3.1.1.1.20.1'; + my $oid_cpqRackCommonEnclosureHasFans = '.1.3.6.1.4.1.232.22.2.3.1.1.1.21.1'; + my $oid_cpqRackCommonEnclosureHasFuses = '.1.3.6.1.4.1.232.22.2.3.1.1.1.22.1'; + #my $oid_cpqRackServerBladeHasManagementDevice = '.1.3.6.1.4.1.232.22.2.4.1.1.1.29.1'; + + $self->{global_results} = $self->{snmp}->get_leef(oids => [$oid_cpqRackCommonEnclosurePartNumber, $oid_cpqRackCommonEnclosureSparePartNumber, + $oid_cpqRackCommonEnclosureSerialNum, $oid_cpqRackCommonEnclosureFWRev, + $oid_cpqRackCommonEnclosureCondition, $oid_cpqRackCommonEnclosureHasServerBlades, + $oid_cpqRackCommonEnclosureHasPowerSupplies, $oid_cpqRackCommonEnclosureHasNetConnectors, + $oid_cpqRackCommonEnclosureHasTempSensors, $oid_cpqRackCommonEnclosureHasFans, + $oid_cpqRackCommonEnclosureHasFuses], nothing_quit => 1); + + $self->{output}->output_add(long_msg => sprintf("Enclosure overall health condition is %s [part: %s, spare: %s, sn: %s, fw: %s].", + ${$conditions{$self->{global_results}->{$oid_cpqRackCommonEnclosureCondition}}}[0], + $self->{global_results}->{$oid_cpqRackCommonEnclosurePartNumber}, + $self->{global_results}->{$oid_cpqRackCommonEnclosureSparePartNumber}, + $self->{global_results}->{$oid_cpqRackCommonEnclosureSerialNum}, + $self->{global_results}->{$oid_cpqRackCommonEnclosureFWRev})); + if ($self->{global_results}->{$oid_cpqRackCommonEnclosureCondition} != 2) { + $self->{output}->output_add(severity => ${$conditions{$self->{global_results}->{$oid_cpqRackCommonEnclosureCondition}}}[1], + short_msg => sprintf("Enclosure overall health condition is %s", ${$conditions{$self->{global_results}->{$oid_cpqRackCommonEnclosureCondition}}}[0])); + } +} + +sub check_managers { + my ($self) = @_; + + #my $oid_cpqRackServerBladeHasManagementDevice = '.1.3.6.1.4.1.232.22.2.4.1.1.1.29.1'; + #if (defined($map_has{$global_results->{$oid_cpqRackServerBladeHasManagementDevice}}) && + # $map_has{$global_results->{$oid_cpqRackServerBladeHasManagementDevice}} =~ /^false$/i) { + # output_add(long_msg => sprintf("Skipping Managers: enclosure doesnt contain managers.")); + # return ; + #} + + return if ($self->check_exclude('managers')); + + # No check if OK + if ($self->{output}->is_status(compare => 'ok', litteral => 1)) { + return ; + } + $self->{output}->output_add(long_msg => "Checking managers"); + + my $oid_cpqRackCommonEnclosureManagerIndex = '.1.3.6.1.4.1.232.22.2.3.1.6.1.3'; + my $oid_cpqRackCommonEnclosureManagerPartNumber = '.1.3.6.1.4.1.232.22.2.3.1.6.1.6'; + my $oid_cpqRackCommonEnclosureManagerSparePartNumber = '.1.3.6.1.4.1.232.22.2.3.1.6.1.7'; + my $oid_cpqRackCommonEnclosureManagerSerialNum = '.1.3.6.1.4.1.232.22.2.3.1.6.1.8'; + my $oid_cpqRackCommonEnclosureManagerRole = '.1.3.6.1.4.1.232.22.2.3.1.6.1.9'; + my $oid_cpqRackCommonEnclosureManagerCondition = '.1.3.6.1.4.1.232.22.2.3.1.6.1.12'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackCommonEnclosureManagerIndex); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_cpqRackCommonEnclosureManagerPartNumber, $oid_cpqRackCommonEnclosureManagerSparePartNumber, + $oid_cpqRackCommonEnclosureManagerSerialNum, $oid_cpqRackCommonEnclosureManagerRole, + $oid_cpqRackCommonEnclosureManagerCondition], + instances => [keys %$result]); + my $result2 = $self->{snmp}->get_leef(); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + $key =~ /(\d+)$/; + my $instance = $1; + + my $man_part = $result2->{$oid_cpqRackCommonEnclosureManagerPartNumber . '.' . $instance}; + my $man_spare = $result2->{$oid_cpqRackCommonEnclosureManagerSparePartNumber . '.' . $instance}; + my $man_serial = $result2->{$oid_cpqRackCommonEnclosureManagerSerialNum . '.' . $instance}; + my $man_role = $result2->{$oid_cpqRackCommonEnclosureManagerRole . '.' . $instance}; + my $man_condition = $result2->{$oid_cpqRackCommonEnclosureManagerCondition . '.' . $instance}; + + $self->{output}->output_add(long_msg => sprintf("Enclosure management module %d is %s, status is %s [serial: %s, part: %s, spare: %s].", + $instance, ${$conditions{$man_condition}}[0], $map_role{$man_role}, + $man_serial, $man_part, $man_spare)); + if ($man_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$man_condition}}[1], + short_msg => sprintf("Enclosure management module %d is %s, status is %s", + $instance, ${$conditions{$man_condition}}[0], $map_role{$man_role})); + } + } +} + +sub check_fans { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + return if ($self->check_exclude('fans')); + + my $oid_cpqRackCommonEnclosureHasFans = '.1.3.6.1.4.1.232.22.2.3.1.1.1.21.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasFans}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasFans}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping Fans: enclosure cannot house fans (??!!)."); + return ; + } + + my $oid_cpqRackCommonEnclosureFanPresent = '.1.3.6.1.4.1.232.22.2.3.1.3.1.8'; + my $oid_cpqRackCommonEnclosureFanIndex = '.1.3.6.1.4.1.232.22.2.3.1.3.1.3'; + my $oid_cpqRackCommonEnclosureFanPartNumber = '.1.3.6.1.4.1.232.22.2.3.1.3.1.6'; + my $oid_cpqRackCommonEnclosureFanSparePartNumber = '.1.3.6.1.4.1.232.22.2.3.1.3.1.7'; + my $oid_cpqRackCommonEnclosureFanCondition = '.1.3.6.1.4.1.232.22.2.3.1.3.1.11'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackCommonEnclosureFanPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + $key =~ /\.([0-9]+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackCommonEnclosureFanIndex . "." . $oid_end, $oid_cpqRackCommonEnclosureFanPartNumber . "." . $oid_end, + $oid_cpqRackCommonEnclosureFanSparePartNumber . "." . $oid_end, $oid_cpqRackCommonEnclosureFanCondition . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my $fan_index = $result->{$oid_cpqRackCommonEnclosureFanIndex . '.' . $_}; + my $fan_condition = $result->{$oid_cpqRackCommonEnclosureFanCondition . '.' . $_}; + my $fan_part = $result->{$oid_cpqRackCommonEnclosureFanPartNumber . '.' . $_}; + my $fan_spare = $result->{$oid_cpqRackCommonEnclosureFanSparePartNumber . '.' . $_}; + + $self->{components_fans}++; + $self->{output}->output_add(long_msg => sprintf("Fan %d condition is %s [part: %s, spare: %s].", + $fan_index, ${$conditions{$fan_condition}}[0], + $fan_part, $fan_spare)); + if ($fan_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$fan_condition}}[1], + short_msg => sprintf("Fan %d condition is %s", $fan_index, ${$conditions{$fan_condition}}[0])); + } + } +} + +sub check_blades { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking blades"); + return if ($self->check_exclude('blades')); + + my $oid_cpqRackCommonEnclosureHasServerBlades = '.1.3.6.1.4.1.232.22.2.3.1.1.1.17.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasServerBlades}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasServerBlades}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping Blades: enclosure cannot house blades (??!!)."); + return ; + } + + my $oid_cpqRackServerBladePresent = '.1.3.6.1.4.1.232.22.2.4.1.1.1.12'; + my $oid_cpqRackServerBladeIndex = '.1.3.6.1.4.1.232.22.2.4.1.1.1.3'; + my $oid_cpqRackServerBladeName = '.1.3.6.1.4.1.232.22.2.4.1.1.1.4'; + my $oid_cpqRackServerBladePartNumber = '.1.3.6.1.4.1.232.22.2.4.1.1.1.6'; + my $oid_cpqRackServerBladeSparePartNumber = '.1.3.6.1.4.1.232.22.2.4.1.1.1.7'; + my $oid_cpqRackServerBladeProductId = '.1.3.6.1.4.1.232.22.2.4.1.1.1.17'; + my $oid_cpqRackServerBladeStatus = '.1.3.6.1.4.1.232.22.2.4.1.1.1.21'; # v2 + my $oid_cpqRackServerBladeFaultDiagnosticString = '.1.3.6.1.4.1.232.22.2.4.1.1.1.24'; # v2 + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackServerBladePresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + $key =~ /\.([0-9]+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackServerBladeIndex . "." . $oid_end, $oid_cpqRackServerBladeName . "." . $oid_end, + $oid_cpqRackServerBladePartNumber . "." . $oid_end, $oid_cpqRackServerBladeSparePartNumber . "." . $oid_end, + $oid_cpqRackServerBladeProductId . "." . $oid_end, + $oid_cpqRackServerBladeStatus . "." . $oid_end, $oid_cpqRackServerBladeFaultDiagnosticString . "." . $oid_end; + } + + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my $blade_index = $result->{$oid_cpqRackServerBladeIndex . '.' . $_}; + my $blade_status = defined($result->{$oid_cpqRackServerBladeStatus . '.' . $_}) ? $result->{$oid_cpqRackServerBladeStatus . '.' . $_} : ''; + my $blade_name = $result->{$oid_cpqRackServerBladeName . '.' . $_}; + my $blade_part = $result->{$oid_cpqRackServerBladePartNumber . '.' . $_}; + my $blade_spare = $result->{$oid_cpqRackServerBladeSparePartNumber . '.' . $_}; + my $blade_productid = $result->{$oid_cpqRackServerBladeProductId . '.' . $_}; + my $blade_diago = defined($result->{$oid_cpqRackServerBladeFaultDiagnosticString . '.' . $_}) ? $result->{$oid_cpqRackServerBladeFaultDiagnosticString . '.' . $_} : ''; + + $self->{components_blades}++; + if ($blade_status eq '') { + $self->{output}->output_add(long_msg => sprintf("Skipping Blade %d (%s, %s). Cant get status.", + $blade_index, $blade_name, $blade_productid)); + next; + } + $self->{output}->output_add(long_msg => sprintf("Blade %d (%s, %s) status is %s [part: %s, spare: %s]%s.", + $blade_index, $blade_name, $blade_productid, + ${$conditions{$blade_status}}[0], + $blade_part, $blade_spare, + ($blade_diago ne '') ? " (Diagnostic '$blade_diago')" : '' + )); + if ($blade_status != 2) { + $self->{output}->output_add(severity => ${$conditions{$blade_status}}[1], + short_msg => sprintf("Blade %d (%s, %s) status is %s", + $blade_index, $blade_name, $blade_productid, + ${$conditions{$blade_status}}[0] + )); + } + } +} + + +sub check_iom { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking network connectors"); + return if ($self->check_exclude('network')); + + my $oid_cpqRackCommonEnclosureHasNetConnectors = '.1.3.6.1.4.1.232.22.2.3.1.1.1.19.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasNetConnectors}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasNetConnectors}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping Network Connectors: enclosure cannot house network connectors (??!!)."); + return ; + } + + my $oid_cpqRackNetConnectorPresent = '.1.3.6.1.4.1.232.22.2.6.1.1.1.13'; + my $oid_cpqRackNetConnectorIndex = '.1.3.6.1.4.1.232.22.2.6.1.1.1.3'; + my $oid_cpqRackNetConnectorModel = '.1.3.6.1.4.1.232.22.2.6.1.1.1.6'; + my $oid_cpqRackNetConnectorSerialNum = '.1.3.6.1.4.1.232.22.2.6.1.1.1.7'; + my $oid_cpqRackNetConnectorPartNumber = '.1.3.6.1.4.1.232.22.2.6.1.1.1.8'; + my $oid_cpqRackNetConnectorSparePartNumber = '.1.3.6.1.4.1.232.22.2.6.1.1.1.9'; + my $oid_cpqRackNetConnectorDeviceType = '.1.3.6.1.4.1.232.22.2.6.1.1.1.17'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackNetConnectorPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + $key =~ /\.([0-9]+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackNetConnectorIndex . "." . $oid_end, $oid_cpqRackNetConnectorModel . "." . $oid_end, + $oid_cpqRackNetConnectorSerialNum . "." . $oid_end, $oid_cpqRackNetConnectorPartNumber . "." . $oid_end, + $oid_cpqRackNetConnectorSparePartNumber . "." . $oid_end, $oid_cpqRackNetConnectorDeviceType . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my $nc_index = $result->{$oid_cpqRackNetConnectorIndex . '.' . $_}; + my $nc_model = $result->{$oid_cpqRackNetConnectorModel . '.' . $_}; + my $nc_serial = $result->{$oid_cpqRackNetConnectorSerialNum . '.' . $_}; + my $nc_part = $result->{$oid_cpqRackNetConnectorPartNumber . '.' . $_}; + my $nc_spare = $result->{$oid_cpqRackNetConnectorSparePartNumber . '.' . $_}; + my $nc_device = $result->{$oid_cpqRackNetConnectorDeviceType . '.' . $_}; + + $self->{components_nc}++; + $self->{output}->output_add(long_msg => sprintf("Network Connector %d (%s) type '%s' is present [serial: %s, part: %s, spare: %s].", + $nc_index, $nc_model, + $device_type{$nc_device}, + $nc_serial, $nc_part, $nc_spare + )); + } +} + +sub check_psu { + my ($self) = @_; + + # We dont check 'cpqRackPowerEnclosureTable' (the overall power system status) + # We check 'cpqRackPowerSupplyTable' (unitary) + + $self->{output}->output_add(long_msg => "Checking power supplies"); + return if ($self->check_exclude('psu')); + + my $oid_cpqRackCommonEnclosureHasPowerSupplies = '.1.3.6.1.4.1.232.22.2.3.1.1.1.18.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasPowerSupplies}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasPowerSupplies}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping PSU: enclosure cannot house power supplies (??!!)."); + return ; + } + + my $oid_cpqRackPowerSupplyPresent = '.1.3.6.1.4.1.232.22.2.5.1.1.1.16'; + my $oid_cpqRackPowerSupplyIndex = '.1.3.6.1.4.1.232.22.2.5.1.1.1.3'; + my $oid_cpqRackPowerSupplySerialNum = '.1.3.6.1.4.1.232.22.2.5.1.1.1.5'; + my $oid_cpqRackPowerSupplyPartNumber = '.1.3.6.1.4.1.232.22.2.5.1.1.1.6'; + my $oid_cpqRackPowerSupplySparePartNumber = '.1.3.6.1.4.1.232.22.2.5.1.1.1.7'; + my $oid_cpqRackPowerSupplyStatus = '.1.3.6.1.4.1.232.22.2.5.1.1.1.14'; + my $oid_cpqRackPowerSupplyInputLineStatus = '.1.3.6.1.4.1.232.22.2.5.1.1.1.15'; + my $oid_cpqRackPowerSupplyCondition = '.1.3.6.1.4.1.232.22.2.5.1.1.1.17'; + my $oid_cpqRackPowerSupplyCurPwrOutput = '.1.3.6.1.4.1.232.22.2.5.1.1.1.10'; # Watts + my $oid_cpqRackPowerSupplyIntakeTemp = '.1.3.6.1.4.1.232.22.2.5.1.1.1.12'; + my $oid_cpqRackPowerSupplyExhaustTemp = '.1.3.6.1.4.1.232.22.2.5.1.1.1.13'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackPowerSupplyPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + $key =~ /\.([0-9]+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackPowerSupplyIndex . "." . $oid_end, $oid_cpqRackPowerSupplySerialNum . "." . $oid_end, + $oid_cpqRackPowerSupplyPartNumber . "." . $oid_end, $oid_cpqRackPowerSupplySparePartNumber . "." . $oid_end, + $oid_cpqRackPowerSupplyStatus . "." . $oid_end, $oid_cpqRackPowerSupplyInputLineStatus . "." . $oid_end, + $oid_cpqRackPowerSupplyCondition . "." . $oid_end, $oid_cpqRackPowerSupplyCurPwrOutput . "." . $oid_end, + $oid_cpqRackPowerSupplyIntakeTemp . "." . $oid_end, $oid_cpqRackPowerSupplyExhaustTemp . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + my $total_watts = 0; + foreach (@oids_end) { + my $psu_index = $result->{$oid_cpqRackPowerSupplyIndex . '.' . $_}; + my $psu_status = $result->{$oid_cpqRackPowerSupplyStatus . '.' . $_}; + my $psu_serial = $result->{$oid_cpqRackPowerSupplySerialNum . '.' . $_}; + my $psu_part = $result->{$oid_cpqRackPowerSupplyPartNumber . '.' . $_}; + my $psu_spare = $result->{$oid_cpqRackPowerSupplySparePartNumber . '.' . $_}; + my $psu_inputlinestatus = $result->{$oid_cpqRackPowerSupplyInputLineStatus . '.' . $_}; + my $psu_condition = $result->{$oid_cpqRackPowerSupplyCondition . '.' . $_}; + my $psu_pwrout = $result->{$oid_cpqRackPowerSupplyCurPwrOutput . '.' . $_}; + my $psu_intemp = $result->{$oid_cpqRackPowerSupplyIntakeTemp . '.' . $_}; + my $psu_exhtemp = $result->{$oid_cpqRackPowerSupplyExhaustTemp . '.' . $_}; + + $total_watts += $psu_pwrout; + $self->{components_psu}++; + $self->{output}->output_add(long_msg => sprintf("PSU %d status is %s [serial: %s, part: %s, spare: %s] (input line status %s) (status %s).", + $psu_index, ${$conditions{$psu_condition}}[0], + $psu_serial, $psu_part, $psu_spare, + $inputline_status{$psu_inputlinestatus}, + $psu_status{$psu_status} + )); + if ($psu_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$psu_condition}}[1], + short_msg => sprintf("PSU %d status is %s", + $psu_index, ${$conditions{$psu_condition}}[0])); + } + + $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_power", unit => 'W', + value => $psu_pwrout); + if (defined($psu_intemp) && $psu_intemp != -1) { + $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_temp_intake", unit => 'C', + value => $psu_intemp); + } + if (defined($psu_exhtemp) && $psu_exhtemp != -1) { + $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_temp_exhaust", unit => 'C', + value => $psu_exhtemp); + } + } + + $self->{output}->perfdata_add(label => "total_power", unit => 'W', + value => $total_watts); +} + +sub check_temperatures { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + return if ($self->check_exclude('temperatures')); + + my $oid_cpqRackCommonEnclosureHasTempSensors = '.1.3.6.1.4.1.232.22.2.3.1.1.1.20.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasTempSensors}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasTempSensors}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping Temperatures: enclosure doesnt contain temperatures sensors."); + return ; + } + + my $oid_cpqRackCommonEnclosureTempSensorIndex = '.1.3.6.1.4.1.232.22.2.3.1.2.1.3'; + my $oid_cpqRackCommonEnclosureTempSensorEnclosureName = '.1.3.6.1.4.1.232.22.2.3.1.2.1.4'; + my $oid_cpqRackCommonEnclosureTempLocation = '.1.3.6.1.4.1.232.22.2.3.1.2.1.5'; + my $oid_cpqRackCommonEnclosureTempCurrent = '.1.3.6.1.4.1.232.22.2.3.1.2.1.6'; + my $oid_cpqRackCommonEnclosureTempThreshold = '.1.3.6.1.4.1.232.22.2.3.1.2.1.7'; + my $oid_cpqRackCommonEnclosureTempCondition = '.1.3.6.1.4.1.232.22.2.3.1.2.1.8'; + my $oid_cpqRackCommonEnclosureTempType = '.1.3.6.1.4.1.232.22.2.3.1.2.1.9'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackCommonEnclosureTempSensorIndex); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + my $oid_end = $result->{$key}; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackCommonEnclosureTempSensorEnclosureName . "." . $oid_end, $oid_cpqRackCommonEnclosureTempLocation . "." . $oid_end, + $oid_cpqRackCommonEnclosureTempCurrent . "." . $oid_end, $oid_cpqRackCommonEnclosureTempThreshold . "." . $oid_end, + $oid_cpqRackCommonEnclosureTempCondition . "." . $oid_end, $oid_cpqRackCommonEnclosureTempType . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my $temp_index = $_; + my $temp_name = $result->{$oid_cpqRackCommonEnclosureTempSensorEnclosureName . '.' . $_}; + my $temp_location = $result->{$oid_cpqRackCommonEnclosureTempLocation . '.' . $_}; + my $temp_current = $result->{$oid_cpqRackCommonEnclosureTempCurrent . '.' . $_}; + my $temp_threshold = $result->{$oid_cpqRackCommonEnclosureTempThreshold . '.' . $_}; + my $temp_condition = $result->{$oid_cpqRackCommonEnclosureTempCondition . '.' . $_}; + my $temp_type = $result->{$oid_cpqRackCommonEnclosureTempType . '.' . $_}; + + $self->{components_temperatures}++; + $self->{output}->output_add(long_msg => sprintf("Temperature %d status is %s [name: %s, location: %s] (value = %s, threshold = %s%s).", + $temp_index, ${$conditions{$temp_condition}}[0], + $temp_name, $temp_location, + $temp_current, $temp_threshold, + defined($map_temp_type{$temp_type}) ? ", status type = " . $map_temp_type{$temp_type} : '')); + if ($temp_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$temp_condition}}[1], + short_msg => sprintf("Temperature %d status is %s", + $temp_index, ${$conditions{$temp_condition}}[0])); + } + + $self->{output}->perfdata_add(label => "temp_" . $temp_index, unit => 'C', + value => $temp_current, + warning => $temp_threshold); + } +} + +sub check_fuse { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fuse"); + return if ($self->check_exclude('fuse')); + + my $oid_cpqRackCommonEnclosureHasFuses = '.1.3.6.1.4.1.232.22.2.3.1.1.1.22.1'; + if (defined($map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasFuses}}) && + $map_has{$self->{global_results}->{$oid_cpqRackCommonEnclosureHasFuses}} =~ /^false$/i) { + $self->{output}->output_add(long_msg => "Skipping Fuse: enclosure doesnt contain fuse."); + return ; + } + + my $oid_cpqRackCommonEnclosureFusePresent = '.1.3.6.1.4.1.232.22.2.3.1.4.1.6'; + my $oid_cpqRackCommonEnclosureFuseIndex = '.1.3.6.1.4.1.232.22.2.3.1.4.1.3'; + my $oid_cpqRackCommonEnclosureFuseEnclosureName = '.1.3.6.1.4.1.232.22.2.3.1.4.1.4'; + my $oid_cpqRackCommonEnclosureFuseLocation = '.1.3.6.1.4.1.232.22.2.3.1.4.1.5'; + my $oid_cpqRackCommonEnclosureFuseCondition = '.1.3.6.1.4.1.232.22.2.3.1.4.1.7'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqRackCommonEnclosureFusePresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + $key =~ /\.([0-9]+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqRackCommonEnclosureFuseIndex . "." . $oid_end, $oid_cpqRackCommonEnclosureFuseEnclosureName . "." . $oid_end, + $oid_cpqRackCommonEnclosureFuseLocation . "." . $oid_end, $oid_cpqRackCommonEnclosureFuseCondition . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my $fuse_index = $result->{$oid_cpqRackCommonEnclosureFuseIndex . '.' . $_}; + my $fuse_name = $result->{$oid_cpqRackCommonEnclosureFuseEnclosureName . '.' . $_}; + my $fuse_location = $result->{$oid_cpqRackCommonEnclosureFuseLocation . '.' . $_}; + my $fuse_condition = $result->{$oid_cpqRackCommonEnclosureFuseCondition . '.' . $_}; + + $self->{components_fuse}++; + $self->{output}->output_add(long_msg => sprintf("Fuse %d status is %s [name: %s, location: %s].", + $fuse_index, ${$conditions{$fuse_condition}}[0], + $fuse_name, $fuse_location)); + if ($fuse_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$fuse_condition}}[1], + short_msg => sprintf("Fuse %d status is %s", + $fuse_index, ${$conditions{$fuse_condition}}[0])); + } + } +} + +sub check_exclude { + my ($self, $section) = @_; + + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$section(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $section section.")); + return 1; + } + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check Hardware (Fans, Power Supplies, Blades, Temperatures, Fuses). + +=over 8 + +=item B<--exclude> + +Exclude some parts (comma seperated list) (Example: --exclude=temperatures,psu). + +=back + +=cut + \ No newline at end of file diff --git a/hardware/server/hpbladechassis/plugin.pm b/hardware/server/hpbladechassis/plugin.pm new file mode 100644 index 000000000..7b48efa1c --- /dev/null +++ b/hardware/server/hpbladechassis/plugin.pm @@ -0,0 +1,64 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package hardware::server::hpbladechassis::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'hardware::server::hpbladechassis::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check HP Blades chassis in SNMP. + +=cut diff --git a/hardware/server/hpproliant/mode/hardware.pm b/hardware/server/hpproliant/mode/hardware.pm new file mode 100644 index 000000000..4e92ee886 --- /dev/null +++ b/hardware/server/hpproliant/mode/hardware.pm @@ -0,0 +1,586 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package hardware::server::hpproliant::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +my %cpustatus = ( + 1 => ['unknown', 'UNKNOWN'], + 2 => ['ok', 'OK'], + 3 => ['degraded', 'WARNING'], + 4 => ['failed', 'CRITICAL'], + 5 => ['disabled', 'OK'] +); +my %conditions = ( + 1 => ['other', 'CRITICAL'], + 2 => ['ok', 'OK'], + 3 => ['degraded', 'WARNING'], + 4 => ['failed', 'CRITICAL'] +); +my %present_map = ( + 1 => 'other', + 2 => 'absent', + 3 => 'present', +); +my %redundant_map = ( + 1 => 'other', + 2 => 'not redundant', + 3 => 'redundant', +); +my %psustatus = ( + 1 => 'noError', + 2 => 'generalFailure', + 3 => 'bistFailure', + 4 => 'fanFailure', + 5 => 'tempFailure', + 6 => 'interlockOpen', + 7 => 'epromFailed', + 8 => 'vrefFailed', + 9 => 'dacFailed', + 10 => 'ramTestFailed', + 11 => 'voltageChannelFailed', + 12 => 'orringdiodeFailed', + 13 => 'brownOut', + 14 => 'giveupOnStartup', + 15 => 'nvramInvalid', + 16 => 'calibrationTableInvalid', +); +my %location_map = ( + 1 => "other", + 2 => "unknown", + 3 => "system", + 4 => "systemBoard", + 5 => "ioBoard", + 6 => "cpu", + 7 => "memory", + 8 => "storage", + 9 => "removableMedia", + 10 => "powerSupply", + 11 => "ambient", + 12 => "chassis", + 13 => "bridgeCard", +); +my %fanspeed = ( + 1 => "other", + 2 => "normal", + 3 => "high", +); +my %map_pnic_role = ( + 1 => "unknown", + 2 => "primary", + 3 => "secondary", + 4 => "member", + 5 => "txRx", + 6 => "tx", + 7 => "standby", + 8 => "none", + 255 => "notApplicable", +); +my %map_nic_state = ( + 1 => "unknown", + 2 => "ok", + 3 => "standby", + 4 => "failed", +); +my %map_pnic_status = ( + 1 => "unknown", + 2 => "ok", + 3 => "generalFailure", + 4 => "linkFailure", +); +my %map_lnic_status = ( + 1 => "unknown", + 2 => "ok", + 3 => "primaryFailed", + 4 => "standbyFailed", + 5 => "groupFailed", + 6 => "redundancyReduced", + 7 => "redundancyLost", +); +my %map_nic_duplex = ( + 1 => "unknown", + 2 => "half", + 3 => "full", +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "exclude" => { name => 'exclude' }, + }); + + $self->{product_name} = undef; + $self->{serial} = undef; + $self->{romversion} = undef; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{components_cpu} = 0; + $self->{components_psu} = 0; + $self->{components_pc} = 0; + $self->{components_fan} = 0; + $self->{components_temperature} = 0; + $self->{components_pnic} = 0; + $self->{components_lnic} = 0; + + $self->get_system_information(); + $self->check_cpu(); + $self->check_psu(); + $self->check_pc(); + $self->check_fan(); + $self->check_temperature(); + $self->check_pnic(); + $self->check_lnic(); + +# $self->{output}->output_add(severity => 'OK', +# short_msg => sprintf("All %d components [%d fans, %d blades, %d network connectors, %d psu, %d temperatures, %d fuses] are ok.", +# ($self->{components_fans} + $self->{components_blades} + $self->{components_nc} + $self->{components_psu} + $self->{components_temperatures} + $self->{components_fuse}), +# $self->{components_fans}, $self->{components_blades}, $self->{components_nc}, $self->{components_psu}, $self->{components_temperatures}, $self->{components_fuse})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_system_information { + my ($self) = @_; + + # In 'CPQSINFO-MIB' + my $oid_cpqSiSysSerialNum = "1.3.6.1.4.1.232.2.2.2.1.0"; + my $oid_cpqSiProductName = "1.3.6.1.4.1.232.2.2.4.2.0"; + my $oid_cpqSeSysRomVer = "1.3.6.1.4.1.232.1.2.6.1.0"; + + my $result = $self->{snmp}->get_leef(oids => [$oid_cpqSiSysSerialNum, $oid_cpqSiProductName, $oid_cpqSeSysRomVer]); + + $self->{product_name} = defined($result->{$oid_cpqSiProductName}) ? centreon::plugins::misc::trim($result->{$oid_cpqSiProductName}) : 'unknown'; + $self->{serial} = defined($result->{$oid_cpqSiSysSerialNum}) ? centreon::plugins::misc::trim($result->{$oid_cpqSiSysSerialNum}) : 'unknown'; + $self->{romversion} = defined($result->{$oid_cpqSeSysRomVer}) ? centreon::plugins::misc::trim($result->{$oid_cpqSeSysRomVer}) : 'unknown'; +} + +sub check_cpu { + my ($self) = @_; + # In MIB 'CPQSTDEQ-MIB.mib' + + $self->{output}->output_add(long_msg => "Checking cpu"); + return if ($self->check_exclude('cpu')); + + my $oid_cpqSeCpuUnitIndex = '.1.3.6.1.4.1.232.1.2.2.1.1.1'; + my $oid_cpqSeCpuSlot = '.1.3.6.1.4.1.232.1.2.2.1.1.2'; + my $oid_cpqSeCpuName = '.1.3.6.1.4.1.232.1.2.2.1.1.3'; + my $oid_cpqSeCpuStatus = '.1.3.6.1.4.1.232.1.2.2.1.1.6'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqSeCpuUnitIndex); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_cpqSeCpuSlot, $oid_cpqSeCpuName, + $oid_cpqSeCpuStatus], + instances => [keys %$result]); + my $result2 = $self->{snmp}->get_leef(); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + $key =~ /(\d+)$/; + my $instance = $1; + + my $cpu_slot = $result2->{$oid_cpqSeCpuSlot . '.' . $instance}; + my $cpu_name = $result2->{$oid_cpqSeCpuName . '.' . $instance}; + my $cpu_status = $result2->{$oid_cpqSeCpuStatus . '.' . $instance}; + + $self->{components_cpu}++; + $self->{output}->output_add(long_msg => sprintf("cpu [slot: %s, unit: %s, name: %s] status is %s.", + $cpu_slot, $result->{$key}, $cpu_name, + ${$cpustatus{$cpu_status}}[0])); + if (${$cpustatus{$cpu_status}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$cpustatus{$cpu_status}}[1], + short_msg => sprintf("cpu %d is %s", + $result->{$key}, ${$cpustatus{$cpu_status}}[0])); + } + } +} + +sub check_psu { + my ($self) = @_; + + # In MIB 'CPQHLTH-MIB.mib' + $self->{output}->output_add(long_msg => "Checking power supplies"); + return if ($self->check_exclude('psu')); + + my $oid_cpqHeFltTolPowerSupplyPresent = '.1.3.6.1.4.1.232.6.2.9.3.1.3'; + my $oid_cpqHeFltTolPowerSupplyChassis = '.1.3.6.1.4.1.232.6.2.9.3.1.1'; + my $oid_cpqHeFltTolPowerSupplyBay = '.1.3.6.1.4.1.232.6.2.9.3.1.2'; + my $oid_cpqHeFltTolPowerSupplyCondition = '.1.3.6.1.4.1.232.6.2.9.3.1.4'; + my $oid_cpqHeFltTolPowerSupplyStatus = '.1.3.6.1.4.1.232.6.2.9.3.1.5'; + my $oid_cpqHeFltTolPowerSupplyRedundant = '.1.3.6.1.4.1.232.6.2.9.3.1.9'; + my $oid_cpqHeFltTolPowerSupplyCapacityUsed = '.1.3.6.1.4.1.232.6.2.9.3.1.7'; # Watts + my $oid_cpqHeFltTolPowerSupplyCapacityMaximum = '.1.3.6.1.4.1.232.6.2.9.3.1.8'; + my $oid_cpqHeFltTolPowerSupplyMainVoltage = '.1.3.6.1.4.1.232.6.2.9.3.1.6'; # Volts + my $oid_cpqHeFltTolPowerSupplyRedundantPartner = '.1.3.6.1.4.1.232.6.2.9.3.1.17'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqHeFltTolPowerSupplyPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + # Chassis + Bay + $key =~ /(\d+\.\d+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, + $oid_cpqHeFltTolPowerSupplyCondition . "." . $oid_end, $oid_cpqHeFltTolPowerSupplyStatus . "." . $oid_end, + $oid_cpqHeFltTolPowerSupplyRedundant . "." . $oid_end, $oid_cpqHeFltTolPowerSupplyCapacityUsed . "." . $oid_end, + $oid_cpqHeFltTolPowerSupplyCapacityMaximum . "." . $oid_end, $oid_cpqHeFltTolPowerSupplyMainVoltage . "." . $oid_end, + $oid_cpqHeFltTolPowerSupplyRedundantPartner . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my ($psu_chassis, $psu_bay) = split /\./; + my $psu_condition = $result->{$oid_cpqHeFltTolPowerSupplyCondition . '.' . $_}; + my $psu_status = $result->{$oid_cpqHeFltTolPowerSupplyStatus . '.' . $_}; + my $psu_redundant = $result->{$oid_cpqHeFltTolPowerSupplyRedundant . '.' . $_}; + my $psu_redundantpartner = $result->{$oid_cpqHeFltTolPowerSupplyRedundantPartner . '.' . $_}; + my $psu_capacityused = $result->{$oid_cpqHeFltTolPowerSupplyCapacityUsed . '.' . $_}; + my $psu_capacitymaximum = $result->{$oid_cpqHeFltTolPowerSupplyCapacityMaximum . '.' . $_}; + my $psu_voltage = $result->{$oid_cpqHeFltTolPowerSupplyMainVoltage . '.' . $_}; + + $self->{components_psu}++; + $self->{output}->output_add(long_msg => sprintf("powersupply %d status is %s [chassis: %s, redundance: %s, redundant partner: %s] (status %s).", + $psu_bay, ${$conditions{$psu_condition}}[0], + $psu_chassis, $redundant_map{$psu_redundant}, $psu_redundantpartner, + $psustatus{$psu_status} + )); + if ($psu_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$psu_condition}}[1], + short_msg => sprintf("powersupply %d status is %s", + $psu_bay, ${$conditions{$psu_condition}}[0])); + } + + $self->{output}->perfdata_add(label => "psu_" . $psu_bay . "_power", unit => 'W', + value => $psu_capacityused, + critical => $psu_capacitymaximum); + $self->{output}->perfdata_add(label => "psu_" . $psu_bay . "_voltage", unit => 'V', + value => $psu_voltage); + } +} + +sub check_pc { + my ($self) = @_; + + # In MIB 'CPQHLTH-MIB.mib' + $self->{output}->output_add(long_msg => "Checking power converters"); + return if ($self->check_exclude('pc')); + + my $oid_cpqHePwrConvPresent = '.1.3.6.1.4.1.232.6.2.13.3.1.3'; + my $oid_cpqHePwrConvIndex = '.1.3.6.1.4.1.232.6.2.13.3.1.2'; + my $oid_cpqHePwrConvChassis = '.1.3.6.1.4.1.232.6.2.13.3.1.1'; + my $oid_cpqHePwrConvCondition = '.1.3.6.1.4.1.232.6.2.13.3.1.8'; + my $oid_cpqHePwrConvRedundant = '.1.3.6.1.4.1.232.6.2.13.3.1.6'; + my $oid_cpqHePwrConvRedundantGroupId = '.1.3.6.1.4.1.232.6.2.13.3.1.7'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqHePwrConvPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + # Chassis + index + $key =~ /(\d+\.\d+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqHePwrConvCondition . "." . $oid_end, $oid_cpqHePwrConvRedundant . "." . $oid_end, + $oid_cpqHePwrConvRedundantGroupId . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my ($pc_chassis, $pc_index) = split /\./; + my $pc_condition = $result->{$oid_cpqHePwrConvIndex . '.' . $_}; + my $pc_redundant = $result->{$oid_cpqHePwrConvRedundant . '.' . $_}; + my $pc_redundantgroup = $result->{$oid_cpqHePwrConvRedundantGroupId . '.' . $_}; + + $self->{components_pc}++; + $self->{output}->output_add(long_msg => sprintf("powerconverter %d status is %s [chassis: %s, redundance: %s, redundant group: %s].", + $pc_index, ${$conditions{$pc_condition}}[0], + $pc_chassis, $redundant_map{$pc_redundant}, $pc_redundantgroup + )); + if ($pc_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$pc_condition}}[1], + short_msg => sprintf("powerconverter %d status is %s", + $pc_index, ${$conditions{$pc_condition}}[0])); + } + } +} + +sub check_fan { + my ($self) = @_; + + # In MIB 'CPQHLTH-MIB.mib' + $self->{output}->output_add(long_msg => "Checking fans"); + return if ($self->check_exclude('fan')); + + my $oid_cpqHeFltTolFanPresent = '.1.3.6.1.4.1.232.6.2.6.7.1.4'; + my $oid_cpqHeFltTolFanChassis = '.1.3.6.1.4.1.232.6.2.6.7.1.1'; + my $oid_cpqHeFltTolFanIndex = '.1.3.6.1.4.1.232.6.2.6.7.1.2'; + my $oid_cpqHeFltTolFanLocale = '.1.3.6.1.4.1.232.6.2.6.7.1.3'; + my $oid_cpqHeFltTolFanCondition = '.1.3.6.1.4.1.232.6.2.6.7.1.9'; + my $oid_cpqHeFltTolFanSpeed = '.1.3.6.1.4.1.232.6.2.6.7.1.6'; + my $oid_cpqHeFltTolFanCurrentSpeed = '.1.3.6.1.4.1.232.6.2.6.7.1.12'; + my $oid_cpqHeFltTolFanRedundant = '.1.3.6.1.4.1.232.6.2.6.7.1.7'; + my $oid_cpqHeFltTolFanRedundantPartner = '.1.3.6.1.4.1.232.6.2.6.7.1.8'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqHeFltTolFanPresent); + return if (scalar(keys %$result) <= 0); + my @get_oids = (); + my @oids_end = (); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($present_map{$result->{$key}} ne 'present'); + # Chassis + index + $key =~ /(\d+\.\d+)$/; + my $oid_end = $1; + + push @oids_end, $oid_end; + push @get_oids, $oid_cpqHeFltTolFanLocale . "." . $oid_end, $oid_cpqHeFltTolFanCondition . "." . $oid_end, + $oid_cpqHeFltTolFanCurrentSpeed . "." . $oid_end, $oid_cpqHeFltTolFanSpeed . "." . $oid_end, + $oid_cpqHeFltTolFanRedundant . "." . $oid_end, $oid_cpqHeFltTolFanRedundantPartner . "." . $oid_end; + } + $result = $self->{snmp}->get_leef(oids => \@get_oids); + foreach (@oids_end) { + my ($fan_chassis, $fan_index) = split /\./; + my $fan_locale = $result->{$oid_cpqHeFltTolFanLocale . '.' . $_}; + my $fan_condition = $result->{$oid_cpqHeFltTolFanCondition . '.' . $_}; + my $fan_speed = $result->{$oid_cpqHeFltTolFanSpeed . '.' . $_}; + my $fan_currentspeed = $result->{$oid_cpqHeFltTolFanCurrentSpeed . '.' . $_}; + my $fan_redundant = $result->{$oid_cpqHeFltTolFanRedundant . '.' . $_}; + my $fan_redundantpartner = $result->{$oid_cpqHeFltTolFanRedundantPartner . '.' . $_}; + + $self->{components_fan}++; + $self->{output}->output_add(long_msg => sprintf("fan %d status is %s, speed is %s [chassis: %s, location: %s, redundance: %s, redundant partner: %s].", + $fan_index, ${$conditions{$fan_condition}}[0], $fanspeed{$fan_speed}, + $fan_chassis, $location_map{$fan_locale}, + $redundant_map{$fan_redundant}, $fan_redundantpartner + )); + if ($fan_condition != 2) { + $self->{output}->output_add(severity => ${$conditions{$fan_condition}}[1], + short_msg => sprintf("fan %d status is %s", + $fan_index, ${$conditions{$fan_condition}}[0])); + } + + $self->{output}->perfdata_add(label => "fan_" . $fan_index . "_speed", unit => 'rpm', + value => $fan_currentspeed); + } +} + +sub check_temperature { + my ($self) = @_; + # In MIB 'CPQSTDEQ-MIB.mib' + + $self->{output}->output_add(long_msg => "Checking temperatures"); + return if ($self->check_exclude('temperature')); + + my $oid_cpqHeTemperatureEntry = '.1.3.6.1.4.1.232.6.2.6.8.1'; + my $oid_cpqHeTemperatureCondition = '.1.3.6.1.4.1.232.6.2.6.8.1.6'; + my $oid_cpqHeTemperatureLocale = '.1.3.6.1.4.1.232.6.2.6.8.1.3'; + my $oid_cpqHeTemperatureCelsius = '.1.3.6.1.4.1.232.6.2.6.8.1.4'; + my $oid_cpqHeTemperatureThreshold = '.1.3.6.1.4.1.232.6.2.6.8.1.5'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqHeTemperatureEntry); + return if (scalar(keys %$result) <= 0); + + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + # work when we have condition + next if ($key !~ /^$oid_cpqHeTemperatureCondition/); + # Chassis + index + $key =~ /(\d+)\.(\d+)$/; + my $temp_chassis = $1; + my $temp_index = $2; + my $instance = $temp_chassis . "." . $temp_index; + + my $temp_condition = $result->{$key}; + my $temp_current = $result->{$oid_cpqHeTemperatureCelsius . '.' . $instance}; + my $temp_threshold = $result->{$oid_cpqHeTemperatureThreshold . '.' . $instance}; + my $temp_locale = $result->{$oid_cpqHeTemperatureLocale . '.' . $instance}; + + $self->{components_temperature}++; + $self->{output}->output_add(long_msg => sprintf("%s %s temperature is %dC (%d max) (status is %s).", + $temp_index, $location_map{$temp_locale}, $temp_current, + $temp_threshold, + ${$conditions{$temp_condition}}[0])); + if (${$conditions{$temp_condition}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$conditions{$temp_condition}}[1], + short_msg => sprintf("temperature %d %s status is %s", + $temp_index, $location_map{$temp_locale}, ${$conditions{$temp_condition}}[0])); + } + + $self->{output}->perfdata_add(label => "temp_" . $temp_index . "_" . $location_map{$temp_locale}, unit => 'C', + value => $temp_current, + critical => (($temp_threshold != -1) ? $temp_threshold : -1)); + } +} + +sub check_pnic { + my ($self) = @_; + # In MIB 'CPQNIC-MIB.mib' + + $self->{output}->output_add(long_msg => "Checking physical nics"); + return if ($self->check_exclude('pnic')); + + my $oid_cpqNicIfPhysAdapterIndex = '.1.3.6.1.4.1.232.18.2.3.1.1.1'; + my $oid_cpqNicIfPhysAdapterRole = '.1.3.6.1.4.1.232.18.2.3.1.1.3'; + my $oid_cpqNicIfPhysAdapterCondition = '.1.3.6.1.4.1.232.18.2.3.1.1.12'; + my $oid_cpqNicIfPhysAdapterState = '.1.3.6.1.4.1.232.18.2.3.1.1.13'; + my $oid_cpqNicIfPhysAdapterStatus = '.1.3.6.1.4.1.232.18.2.3.1.1.14'; + my $oid_cpqNicIfPhysAdapterDuplexState = '.1.3.6.1.4.1.232.18.2.3.1.1.11'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqNicIfPhysAdapterIndex); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_cpqNicIfPhysAdapterRole, $oid_cpqNicIfPhysAdapterCondition, + $oid_cpqNicIfPhysAdapterState, $oid_cpqNicIfPhysAdapterStatus, + $oid_cpqNicIfPhysAdapterDuplexState], + instances => [keys %$result]); + my $result2 = $self->{snmp}->get_leef(); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + $key =~ /(\d+)$/; + my $instance = $1; + + my $nic_index = $result->{$key}; + my $nic_role = $result2->{$oid_cpqNicIfPhysAdapterRole . '.' . $instance}; + my $nic_condition = $result2->{$oid_cpqNicIfPhysAdapterCondition . '.' . $instance}; + my $nic_state = $result2->{$oid_cpqNicIfPhysAdapterState . '.' . $instance}; + my $nic_status = $result2->{$oid_cpqNicIfPhysAdapterStatus . '.' . $instance}; + my $nic_duplex = $result2->{$oid_cpqNicIfPhysAdapterDuplexState . '.' . $instance}; + + $self->{components_pnic}++; + $self->{output}->output_add(long_msg => sprintf("physical nic %s [duplex: %s, role: %s, state: %s, status: %s] condition is %s.", + $nic_index, $map_nic_duplex{$nic_duplex}, $map_pnic_role{$nic_role}, + $map_nic_state{$nic_state}, $map_pnic_status{$nic_status}, + ${$conditions{$nic_condition}}[0])); + if (${$conditions{$nic_condition}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$conditions{$nic_condition}}[1], + short_msg => sprintf("physical nic %d is %s", + $nic_index, ${$conditions{$nic_condition}}[0])); + } + } +} + +sub check_lnic { + my ($self) = @_; + # In MIB 'CPQNIC-MIB.mib' + + $self->{output}->output_add(long_msg => "Checking logical nics"); + return if ($self->check_exclude('pnic')); + + my $oid_cpqNicIfLogMapIndex = '.1.3.6.1.4.1.232.18.2.2.1.1.1'; + my $oid_cpqNicIfLogMapDescription = '.1.3.6.1.4.1.232.18.2.2.1.1.3'; + my $oid_cpqNicIfLogMapAdapterCount = '.1.3.6.1.4.1.232.18.2.2.1.1.5'; + my $oid_cpqNicIfLogMapCondition = '.1.3.6.1.4.1.232.18.2.2.1.1.10'; + my $oid_cpqNicIfLogMapStatus = '.1.3.6.1.4.1.232.18.2.2.1.1.11'; + + my $result = $self->{snmp}->get_table(oid => $oid_cpqNicIfLogMapIndex); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_cpqNicIfLogMapDescription, $oid_cpqNicIfLogMapAdapterCount, + $oid_cpqNicIfLogMapCondition, $oid_cpqNicIfLogMapStatus], + instances => [keys %$result]); + my $result2 = $self->{snmp}->get_leef(); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + $key =~ /(\d+)$/; + my $instance = $1; + + my $nic_index = $result->{$key}; + my $nic_description = centreon::plugins::misc::trim($result2->{$oid_cpqNicIfLogMapDescription . '.' . $instance}); + my $nic_count = $result2->{$oid_cpqNicIfLogMapAdapterCount . '.' . $instance}; + my $nic_condition = $result2->{$oid_cpqNicIfLogMapCondition . '.' . $instance}; + my $nic_status = $result2->{$oid_cpqNicIfLogMapStatus . '.' . $instance}; + + $self->{components_lnic}++; + $self->{output}->output_add(long_msg => sprintf("logical nic %s [adapter count: %s, description: %s, status: %s] condition is %s.", + $nic_index, $nic_count, $nic_description, + $map_lnic_status{$nic_status}, + ${$conditions{$nic_condition}}[0])); + if (${$conditions{$nic_condition}}[0] !~ /^other|ok$/i) { + $self->{output}->output_add(severity => ${$conditions{$nic_condition}}[1], + short_msg => sprintf("logical nic %d is %s (%s)", + $nic_index, ${$conditions{$nic_condition}}[0], $map_lnic_status{$nic_status})); + } + } +} + +sub check_exclude { + my ($self, $section) = @_; + + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$section(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $section section.")); + return 1; + } + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check Hardware (CPUs, Power Supplies, Power converters, Fans). + +=over 8 + +=item B<--exclude> + +Exclude some parts (comma seperated list) (Example: --exclude=psu,pc). + +=back + +=cut + \ No newline at end of file diff --git a/hardware/server/hpproliant/plugin.pm b/hardware/server/hpproliant/plugin.pm new file mode 100644 index 000000000..023c4f680 --- /dev/null +++ b/hardware/server/hpproliant/plugin.pm @@ -0,0 +1,64 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package hardware::server::hpproliant::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'hardware::server::hpproliant::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check HP Proliant servers in SNMP. + +=cut diff --git a/install.sh b/install.sh deleted file mode 100755 index 7ff5e2863..000000000 --- a/install.sh +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh -################################################################### -# Oreon is developped with GPL Licence 2.0 -# -# GPL License: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -# -# Developped by : Julien Mathis - Romain Le Merlus -# Christophe Coraboeuf - Sugumaran Mathavarajan -# -################################################################### -# This program 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 program 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. -# -# For information : contact@merethis.com -#################################################################### - -#Load install script functions -. ../functions - -## -## VARIABLES -## -## Make sure you know what you do if you modify it !! - -PWD=`pwd` - -PLUGINS_DIR="" - -LOG_FILE="../log/install_oreon.log" - -date > $LOG_FILE - -echo -echo "##########################################################################" -echo "# OREON Project (www.oreon-project.org) #" -echo "# Thanks for using OREON #" -echo "# #" -echo "# #" -echo "# infos@oreon-project.org #" -echo "# #" -echo "# Make sure you have installed and configured #" -echo "# perl - sed #" -echo "# #" -echo "# #" -echo "##########################################################################" -echo "# The Team OREON #" -echo "##########################################################################" -echo "" -echo "" -$SETCOLOR_WARNING -echo " Make sure you have root permissions !" -$SETCOLOR_NORMAL -echo "" - -echo "Are you sure to continue?" -echo -n "[y/n], default to [n]:" -read temp -if [ -z $temp ];then - temp=n -fi - -if [ $temp = "n" ];then - echo "Bye bye !" - exit -fi - -test_answer() -{ - #$1 variable to fill - #$2 text typed by user - if [ ! -z $2 ];then - if [ $2 != "" ];then - eval $1=$2 - fi - fi -} - -## -## CONFIGURATION -## -if test -a $OREON_CONF ; then - echo "" - echo_success "Finding Oreon configuration file '$OREON_CONF' :" "OK" - echo "You already seem to have to install Oreon." - echo "Do you want use last Oreon install parameters ?" - echo -n "[y/n], default to [y]:" - read temp - if [ -z $temp ];then - temp=y - fi - - if [ $temp = "y" ];then - echo "" - echo_passed "Using '$OREON_CONF' :" "PASSED" - . $OREON_CONF - echo "" - else - echo "" - echo "First, let's talk about you !" - echo "-----------------------------" - echo "" - fi -fi - if [ -z $INSTALL_DIR_NAGIOS ];then - INSTALL_DIR_NAGIOS="/usr/local/nagios" - echo "Where is installed Nagios ?" - echo -n "default to [$INSTALL_DIR_NAGIOS]:" - read temp - test_answer INSTALL_DIR_NAGIOS $temp - echo "" - fi - - if [ -z $NAGIOS_ETC ];then - #nagios etc directory for oreon - NAGIOS_ETC="$INSTALL_DIR_NAGIOS/etc" - echo "Where are your nagios etc directory ?" - echo -n "default to [$NAGIOS_ETC]:" - read temp - test_answer NAGIOS_ETC $temp - echo "" - fi - - if [ -z $NAGIOS_PLUGINS ];then - #nagios plugins directory for oreon - NAGIOS_PLUGINS="$INSTALL_DIR_NAGIOS/libexec" - echo "Where are your nagios plugin / libexec directory ?" - echo -n "default to [$NAGIOS_PLUGINS]:" - read temp - test_answer NAGIOS_PLUGINS $temp - echo "" - fi - - if [ -z $INSTALL_DIR_OREON ];then - #setup directory for oreon - INSTALL_DIR_OREON="/usr/local/oreon" - echo "Where do I install Oreon ?" - echo -n "default to [$INSTALL_DIR_OREON]:" - read temp - test_answer INSTALL_DIR_OREON $temp - echo "" - fi - - if [ -z $SUDO_FILE ];then - #Configuration file for sudo - SUDO_FILE="/etc/sudoers" - echo "Where is sudo ?" - echo -n "default to [$SUDO_FILE]:" - read temp - test_answer SUDO_FILE $temp - echo "" - fi - - if [ -z $RRD_PERL ];then - #RRDTOOL perl module directory - RRD_PERL="/usr/local/rrdtool/lib/perl" - echo "Where is RRD perl modules RRDs.pm ?" - echo -n "default to [$RRD_PERL]:" - read temp - test_answer RRD_PERL $temp - echo "" - fi - -## -## FUNCTION -## - -# When exit on error - -function error() -{ - echo "ERROR" - exit 2 -} - -# install OREON PLUGIN - -function confirm_oreon() -{ - install_oreon_plugins -} - -# installation script - -#check_group_nagios -#check_user_nagios -#check_group_nagiocmd -#confirm_oreon - -## -## INSTALL -## -echo "Users Management" -echo "----------------" -# check for httpd directory -check_httpd_directory -## group apache -check_group_apache -## user apache -check_user_apache -check_group_nagios -check_user_nagios -echo "" - -echo "Other Stuff" -echo "------------" -if test -d $NAGIOS_PLUGINS ; then - echo_success "Nagios libexec directory" "OK" -else - mkdir -p $NAGIOS_PLUGINS > /dev/null - echo_success "Nagios libexec directory created" "OK" -fi - -# installation script - -confirm_oreon -#oreon_post_install - -echo "" -echo "###############################################################################" -echo "# #" -echo "# Report bugs at bugs@oreon-project.org #" -echo "# #" -echo "# Thanks for using OREON. #" -echo "# ----------------------- #" -echo "# Contact : infos@oreon-project.org #" -echo "# http://www.oreon-project.org #" -echo "###############################################################################" diff --git a/network/alteon/5224/plugin.pm b/network/alteon/5224/plugin.pm new file mode 100644 index 000000000..ce44064d4 --- /dev/null +++ b/network/alteon/5224/plugin.pm @@ -0,0 +1,66 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::alteon::5224::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::alteon::common::mode::cpu', + 'hardware' => 'network::alteon::common::mode::hardware', + 'memory' => 'network::alteon::common::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Alteon 5224 in SNMP. + +=cut diff --git a/network/alteon/common/mode/cpu.pm b/network/alteon/common/mode/cpu.pm new file mode 100644 index 000000000..3e87f66c6 --- /dev/null +++ b/network/alteon/common/mode/cpu.pm @@ -0,0 +1,159 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::alteon::common::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', default => '' }, + "critical:s" => { name => 'critical', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + ($self->{warn1s}, $self->{warn4s}, $self->{warn64s}) = split /,/, $self->{option_results}->{warning}; + ($self->{crit1s}, $self->{crit4s}, $self->{crit64s}) = split /,/, $self->{option_results}->{critical}; + + if (($self->{perfdata}->threshold_validate(label => 'warn1s', value => $self->{warn1s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (1sec) threshold '" . $self->{warn1s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn4s', value => $self->{warn4s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (4sec) threshold '" . $self->{warn4s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn64s', value => $self->{warn64s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (64sec) threshold '" . $self->{warn64s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit1s', value => $self->{crit1s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (1sec) threshold '" . $self->{crit1s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit4s', value => $self->{crit4s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (4sec) threshold '" . $self->{crit4s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit64s', value => $self->{crit64s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (64sec) threshold '" . $self->{crit64s} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_mpCpuStatsUtil1Second = '.1.3.6.1.4.1.1872.2.5.1.2.2.1.0'; + my $oid_mpCpuStatsUtil4Seconds = '.1.3.6.1.4.1.1872.2.5.1.2.2.2.0'; + my $oid_mpCpuStatsUtil64Seconds = '.1.3.6.1.4.1.1872.2.5.1.2.2.3.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_mpCpuStatsUtil1Second, $oid_mpCpuStatsUtil4Seconds, + $oid_mpCpuStatsUtil64Seconds], nothing_quit => 1); + + my $cpu1sec = $result->{$oid_mpCpuStatsUtil1Second}; + my $cpu4sec = $result->{$oid_mpCpuStatsUtil4Seconds}; + my $cpu64sec = $result->{$oid_mpCpuStatsUtil64Seconds}; + + my $exit1 = $self->{perfdata}->threshold_check(value => $cpu1sec, + threshold => [ { label => 'crit1s', 'exit_litteral' => 'critical' }, { label => 'warn1s', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $cpu4sec, + threshold => [ { label => 'crit4s', 'exit_litteral' => 'critical' }, { label => 'warn4s', exit_litteral => 'warning' } ]); + my $exit3 = $self->{perfdata}->threshold_check(value => $cpu64sec, + threshold => [ { label => 'crit64s', 'exit_litteral' => 'critical' }, { label => 'warn64s', exit_litteral => 'warning' } ]); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3 ]); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("MP CPU Usage: %.2f%% (1sec), %.2f%% (4sec), %.2f%% (64sec)", + $cpu1sec, $cpu4sec, $cpu64sec)); + + $self->{output}->perfdata_add(label => "cpu_1s", + value => $cpu1sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn1s'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit1s'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => "cpu_4s", + value => $cpu4sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn4s'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit4s'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => "cpu_64s", + value => $cpu64sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn64s'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit64s'), + min => 0, max => 100); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MP cpu usage (ALTEON-CHEETAH-SWITCH-MIB). + +=over 8 + +=item B<--warning> + +Threshold warning in percent (1s,4s,64s). + +=item B<--critical> + +Threshold critical in percent (1s,4s,64s). + +=back + +=cut + \ No newline at end of file diff --git a/network/alteon/common/mode/hardware.pm b/network/alteon/common/mode/hardware.pm new file mode 100644 index 000000000..0908ca5cf --- /dev/null +++ b/network/alteon/common/mode/hardware.pm @@ -0,0 +1,195 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::alteon::common::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %states_temp_cpu = ( + 1 => ['normal', 'OK'], + 2 => ['warning', 'WARNING'], + 3 => ['critical', 'CRITICAL'], +); +my %states_temp = ( + 1 => ['ok', 'OK'], + 2 => ['exceed', 'WARNING'], +); +my %states_psu = ( + 1 => ['single power supply ok', 'WARNING'], + 2 => ['first powerSupply failed', 'CRITICAL'], + 3 => ['second power supply failed', 'CRITICAL'], + 4 => ['double power supply ok', 'OK'], + 5 => ['unknown power supply failed', 'UNKNOWN'], +); +my %states_fan = ( + 1 => ['ok', 'OK'], + 2 => ['fail', 'CRITICAL'], +); +my $oid_hwTemperatureStatus = '.1.3.6.1.4.1.1872.2.5.1.3.1.3.0'; +my $oid_hwFanStatus = '.1.3.6.1.4.1.1872.2.5.1.3.1.4.0'; +my $oid_hwTemperatureThresholdStatusCPU1Get = '.1.3.6.1.4.1.1872.2.5.1.3.1.28.3.0'; +my $oid_hwTemperatureThresholdStatusCPU2Get = '.1.3.6.1.4.1.1872.2.5.1.3.1.28.4.0'; +my $oid_hwPowerSupplyStatus = '.1.3.6.1.4.1.1872.2.5.1.3.1.29.2.0'; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{components_fans} = 0; + $self->{components_psus} = 0; + $self->{components_temperatures} = 0; + + $self->{global_result} = $self->{snmp}->get_leef(oids => [$oid_hwTemperatureStatus, $oid_hwFanStatus, + $oid_hwTemperatureThresholdStatusCPU1Get, $oid_hwTemperatureThresholdStatusCPU2Get, + $oid_hwPowerSupplyStatus], + nothing_quit => 1); + + $self->check_fans(); + $self->check_psus(); + $self->check_temperatures(); + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %d components [%d fans, %d power supplies, %d temperatures] are ok", + ($self->{components_fans} + $self->{components_psus} + $self->{components_temperatures}), + $self->{components_fans}, $self->{components_psus}, $self->{components_temperatures})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_fans { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + return if (!defined($self->{global_result}->{$oid_hwFanStatus})); + + $self->{components_fans}++; + my $fan_state = $self->{global_result}->{$oid_hwFanStatus}; + + $self->{output}->output_add(long_msg => sprintf("Fan status is %s.", ${$states_fan{$fan_state}}[0])); + if (${$states_fan{$fan_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states_fan{$fan_state}}[1], + short_msg => sprintf("Fan status is %s.", ${$states_fan{$fan_state}}[0])); + } +} + +sub check_psus { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + return if (!defined($self->{global_result}->{$oid_hwPowerSupplyStatus})); + + $self->{components_psus}++; + my $psu_state = $self->{global_result}->{$oid_hwPowerSupplyStatus}; + + $self->{output}->output_add(long_msg => sprintf("Power supplies status is %s.", ${$states_psu{$psu_state}}[0])); + if (${$states_psu{$psu_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states_psu{$psu_state}}[1], + short_msg => sprintf("Power supplies status is %s.", ${$states_psu{$psu_state}}[0])); + } +} + +sub check_temperatures { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures global"); + return if (!defined($self->{global_result}->{$oid_hwTemperatureStatus})); + + $self->{components_temperatures}++; + my $temp_state = $self->{global_result}->{$oid_hwTemperatureStatus}; + + $self->{output}->output_add(long_msg => sprintf("Global temperature sensor status is %s.", ${$states_temp{$temp_state}}[0])); + if (${$states_temp{$temp_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states_temp{$temp_state}}[1], + short_msg => sprintf("Global temperature sensor status is %s.", ${$states_temp{$temp_state}}[0])); + } + + $self->{output}->output_add(long_msg => "Checking temperatures cpus"); + return if (!defined($self->{global_result}->{$oid_hwTemperatureThresholdStatusCPU1Get}) && + !defined($self->{global_result}->{$oid_hwTemperatureThresholdStatusCPU2Get})); + + $self->{components_temperatures} += 2; + my $temp_cpu1_state = $self->{global_result}->{$oid_hwTemperatureThresholdStatusCPU1Get}; + my $temp_cpu2_state = $self->{global_result}->{$oid_hwTemperatureThresholdStatusCPU2Get}; + + $self->{output}->output_add(long_msg => sprintf("Temperature cpu 1 status is %s.", ${$states_temp_cpu{$temp_cpu1_state}}[0])); + if (${$states_temp_cpu{$temp_cpu1_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states_temp_cpu{$temp_cpu1_state}}[1], + short_msg => sprintf("Temperature cpu 1 status is %s.", ${$states_temp_cpu{$temp_cpu1_state}}[0])); + } + + $self->{output}->output_add(long_msg => sprintf("Temperature cpu 2 status is %s.", ${$states_temp_cpu{$temp_cpu2_state}}[0])); + if (${$states_temp_cpu{$temp_cpu2_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states_temp_cpu{$temp_cpu2_state}}[1], + short_msg => sprintf("Temperature cpu 2 status is %s.", ${$states_temp_cpu{$temp_cpu2_state}}[0])); + } +} + +1; + +__END__ + +=head1 MODE + +Check Hardware (ALTEON-CHEETAH-SWITCH-MIB) (Fans, Power Supplies, Temperatures). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/network/alteon/common/mode/memory.pm b/network/alteon/common/mode/memory.pm new file mode 100644 index 000000000..9452a05d5 --- /dev/null +++ b/network/alteon/common/mode/memory.pm @@ -0,0 +1,130 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::alteon::common::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_mpMemStatsTotal = '.1.3.6.1.4.1.1872.2.5.1.2.8.1.0'; + my $oid_mpMemStatsFree = '.1.3.6.1.4.1.1872.2.5.1.2.8.3.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_mpMemStatsTotal, $oid_mpMemStatsFree], nothing_quit => 1); + + my $total_size = $result->{$oid_mpMemStatsTotal}; + my $memory_free = $result->{$oid_mpMemStatsFree}; + my $memory_used = $total_size - $memory_free; + + my $prct_used = $memory_used * 100 / $total_size; + my $prct_free = 100 - $prct_used; + + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("MP Memory Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + + $self->{output}->perfdata_add(label => "used", + value => $memory_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MP memory usage (ALTEON-CHEETAH-SWITCH-MIB). + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut + \ No newline at end of file diff --git a/network/bluecoat/mode/clientconnections.pm b/network/bluecoat/mode/clientconnections.pm new file mode 100644 index 000000000..411a31315 --- /dev/null +++ b/network/bluecoat/mode/clientconnections.pm @@ -0,0 +1,123 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::clientconnections; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.3.1.0', + '.1.3.6.1.4.1.3417.2.11.3.1.3.2.0', + '.1.3.6.1.4.1.3417.2.11.3.1.3.3.0'], nothing_quit => 1); + my $client_connections = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.1.0'}; + my $client_connections_active = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.2.0'}; + my $client_connections_idle = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.3.0'}; + + my $exit = $self->{perfdata}->threshold_check(value => $client_connections_active, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => "Client connections: Active " . $client_connections_active . ", Idle " . $client_connections_idle); + $self->{output}->perfdata_add(label => 'con', + value => $client_connections, + min => 0); + $self->{output}->perfdata_add(label => 'con_active', + value => $client_connections_active, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{output}->perfdata_add(label => 'con_idle', + value => $client_connections_idle, + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current client connections. + +=over 8 + +=item B<--warning> + +Threshold warning (on active connections). + +=item B<--critical> + +Threshold critical (on active connections. + +=back + +=cut diff --git a/network/bluecoat/mode/clientrequests.pm b/network/bluecoat/mode/clientrequests.pm new file mode 100644 index 000000000..e12ca30a7 --- /dev/null +++ b/network/bluecoat/mode/clientrequests.pm @@ -0,0 +1,197 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::clientrequests; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-errors:s" => { name => 'warning_errors' }, + "critical-errors:s" => { name => 'critical_errors' }, + "warning-misses:s" => { name => 'warning_misses' }, + "critical-misses:s" => { name => 'critical_misses' }, + }); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning_errors', value => $self->{option_results}->{warning_errors})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'errors' threshold '" . $self->{option_results}->{warning_errors} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical_errors', value => $self->{option_results}->{critical_errors})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'errors' threshold '" . $self->{option_results}->{critical_errors} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning_misses', value => $self->{option_results}->{warning_misses})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'misses' threshold '" . $self->{option_results}->{warning_misses} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical_misses', value => $self->{option_results}->{critical_misses})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'misses' threshold '" . $self->{option_results}->{critical_misses} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{statefile_value}->read(statefile => 'bluecoat_' . $self->{hostname} . '_' . $self->{mode}); + my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.1.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.2.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.3.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.4.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'], nothing_quit => 1); + + my $new_datas = {}; + my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + my $old_client_http_requests = $self->{statefile_value}->get(name => 'client_http_requests'); + my $old_client_http_hits = $self->{statefile_value}->get(name => 'client_http_hits'); + my $old_client_http_partial_hits = $self->{statefile_value}->get(name => 'client_http_partial_hits'); + my $old_client_http_misses = $self->{statefile_value}->get(name => 'client_http_misses'); + my $old_client_http_errors = $self->{statefile_value}->get(name => 'client_http_errors'); + + $new_datas->{last_timestamp} = time(); + $new_datas->{client_http_requests} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.1.0'}; + $new_datas->{client_http_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0'}; + $new_datas->{client_http_partial_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0'}; + $new_datas->{client_http_misses} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0'}; + $new_datas->{client_http_errors} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'}; + + $self->{statefile_value}->write(data => $new_datas); + + if (!defined($old_timestamp) || !defined($old_client_http_misses)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + $self->{output}->exit(); + } + + if ($new_datas->{client_http_requests} < $old_client_http_requests) { + # We set 0. Has reboot. + $old_client_http_requests = 0; + $old_client_http_hits = 0; + $old_client_http_partial_hits = 0; + $old_client_http_misses = 0; + $old_client_http_errors = 0; + } + + my $delta_http_requests = $new_datas->{client_http_requests} - $old_client_http_requests; + my $prct_misses = sprintf("%.2f", ($new_datas->{client_http_misses} - $old_client_http_misses) * 100 / $delta_http_requests); + my $prct_hits = sprintf("%.2f", ($new_datas->{client_http_hits} - $old_client_http_hits) * 100 / $delta_http_requests); + my $prct_partial_hits = sprintf("%.2f", ($new_datas->{client_http_partial_hits} - $old_client_http_partial_hits) * 100 / $delta_http_requests); + my $prct_errors = sprintf("%.2f", ($new_datas->{client_http_errors} - $old_client_http_errors) * 100 / $delta_http_requests); + + my $exit1 = $self->{perfdata}->threshold_check(value => $prct_errors, threshold => [ { label => 'critical_errors', 'exit_litteral' => 'critical' }, { label => 'warning_errors', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $prct_misses, threshold => [ { label => 'critical_misses', 'exit_litteral' => 'critical' }, { label => 'warning_misses', exit_litteral => 'warning' } ]); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + + $self->{output}->output_add(severity => $exit, + short_msg => "Client Requests: Hits = $prct_hits%, Partial Hits = $prct_partial_hits%, Misses = $prct_misses%, Errors = $prct_errors%"); + $self->{output}->perfdata_add(label => 'hits', unit => '%', + value => $prct_hits, + min => 0); + $self->{output}->perfdata_add(label => 'partial_hits', unit => '%', + value => $prct_partial_hits, + min => 0); + $self->{output}->perfdata_add(label => 'misses', unit => '%', + value => $prct_misses, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_misses'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_misses'), + min => 0); + $self->{output}->perfdata_add(label => 'errors', unit => '%', + value => $prct_errors, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_errors'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_errors'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check http client requests (in percent by type: hit, partial, misses, errors) + +=over 8 + +=item B<--warning-errors> + +Threshold warning of client http errors in percent. + +=item B<--critical-errors> + +Threshold critical of client http errors in percent. + +=item B<--warning-misses> + +Threshold warning of client http misses in percent. + +=item B<--critical-misses> + +Threshold critial of client http misses in percent. + +=back + +=cut diff --git a/network/bluecoat/mode/clienttraffic.pm b/network/bluecoat/mode/clienttraffic.pm new file mode 100644 index 000000000..b770a095a --- /dev/null +++ b/network/bluecoat/mode/clienttraffic.pm @@ -0,0 +1,181 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::clienttraffic; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-received:s" => { name => 'warning_received' }, + "critical-received:s" => { name => 'critical_received' }, + "warning-delivered:s" => { name => 'warning_delivered' }, + "critical-delivered:s" => { name => 'critical_delivered' }, + }); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning_received', value => $self->{option_results}->{warning_received})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'received' threshold '" . $self->{option_results}->{warning_received} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical_received', value => $self->{option_results}->{critical_received})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'received' threshold '" . $self->{option_results}->{critical_received} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning_delivered', value => $self->{option_results}->{warning_delivered})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'delivered' threshold '" . $self->{option_results}->{warning_delivered} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical_delivered', value => $self->{option_results}->{critical_delivered})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'delivered' threshold '" . $self->{option_results}->{critical_delivered} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{statefile_value}->read(statefile => 'bluecoat_' . $self->{hostname} . '_' . $self->{mode}); + + my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.9.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.10.0'], nothing_quit => 1); + + my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + my $old_client_in_bytes = $self->{statefile_value}->get(name => 'client_in_bytes'); + my $old_client_out_bytes = $self->{statefile_value}->get(name => 'client_out_bytes'); + + my $new_datas = {}; + $new_datas->{last_timestamp} = time(); + $new_datas->{client_in_bytes} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.9.0'}; + $new_datas->{client_out_bytes} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.10.0'}; + + $self->{statefile_value}->write(data => $new_datas); + + if (!defined($old_timestamp) || !defined($old_client_in_bytes)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + $self->{output}->exit(); + } + + if ($new_datas->{client_in_bytes} < $old_client_in_bytes) { + # We set 0. Has reboot. + $old_client_in_bytes = 0; + $old_client_out_bytes = 0; + } + + my $delta_time = $new_datas->{last_timestamp} - $old_timestamp; + my $in_bytes_sec = sprintf("%.2f", ($new_datas->{client_in_bytes} - $old_client_in_bytes) / $delta_time); + my $out_bytes_sec = sprintf("%.2f", ($new_datas->{client_out_bytes} - $old_client_out_bytes) / $delta_time); + + my $exit1 = $self->{perfdata}->threshold_check(value => $in_bytes_sec, threshold => [ { label => 'critical_received', 'exit_litteral' => 'critical' }, { label => 'warning_received', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $out_bytes_sec, threshold => [ { label => 'critical_delivered', 'exit_litteral' => 'critical' }, { label => 'warning_delivered', exit_litteral => 'warning' } ]); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + + my ($value_in, $unit_in) = $self->{perfdata}->change_bytes(value => $in_bytes_sec); + my ($value_out, $unit_out) = $self->{perfdata}->change_bytes(value => $out_bytes_sec); + + $self->{output}->output_add(severity => $exit, + short_msg => "Traffic: In $value_in $unit_in/s, Out $value_out $unit_out/s"); + $self->{output}->perfdata_add(label => 'traffic_in', unit => 'B/s', + value => $in_bytes_sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_received'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_received'), + min => 0); + $self->{output}->perfdata_add(label => 'traffic_out', unit => 'B/s', + value => $out_bytes_sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_delivered'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_delivered'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check bytes/s received/delivered to clients + +=over 8 + +=item B<--warning-received> + +Threshold warning for received (in bytes/s). + +=item B<--critical-received> + +Threshold critical for received (in bytes/s). + +=item B<--warning-delivered> + +Threshold warning2 for delivered (in bytes/s). + +=item B<--critical-delivered> + +Threshold critical for delivered (in bytes/s). + +=back + +=cut diff --git a/network/bluecoat/mode/cpu.pm b/network/bluecoat/mode/cpu.pm new file mode 100644 index 000000000..30a2bb0d5 --- /dev/null +++ b/network/bluecoat/mode/cpu.pm @@ -0,0 +1,157 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + my $new_datas = {}; + my $old_timestamp = undef; + + $self->{statefile_value}->read(statefile => 'bluecoat_' . $self->{hostname} . '_' . $self->{mode}); + + my $result = $self->{snmp}->get_table(oid => '.1.3.6.1.4.1.3417.2.11.2.4.1', nothing_quit => 1); + $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + $new_datas->{last_timestamp} = time(); + for (my $i = 1; defined($result->{'.1.3.6.1.4.1.3417.2.11.2.4.1.3.' . $i}); $i++) { + $new_datas->{'cpu_' . $i . '_busy'} = $result->{'.1.3.6.1.4.1.3417.2.11.2.4.1.3.' . $i}; + $new_datas->{'cpu_' . $i . '_idle'} = $result->{'.1.3.6.1.4.1.3417.2.11.2.4.1.4.' . $i}; + + if (!defined($old_timestamp)) { + next; + } + + my $old_cpu_busy = $self->{statefile_value}->get(name => 'cpu_' . $i . '_busy'); + my $old_cpu_idle = $self->{statefile_value}->get(name => 'cpu_' . $i . '_idle'); + if (!defined($old_cpu_busy) || !defined($old_cpu_idle)) { + next; + } + + if ($new_datas->{'cpu_' . $i . '_busy'} < $old_cpu_busy) { + # We set 0. Has reboot. + $old_cpu_busy = 0; + $old_cpu_idle = 0; + } + + my $total_elapsed = (($new_datas->{'cpu_' . $i . '_busy'} - $old_cpu_busy) + ($new_datas->{'cpu_' . $i . '_idle'} - $old_cpu_idle)); + my $prct_usage = (($new_datas->{'cpu_' . $i . '_busy'} - $old_cpu_busy) * 100 / ($total_elapsed)); + my $exit = $self->{perfdata}->threshold_check(value => $prct_usage, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU $i Usage is %.2f%%", $prct_usage)); + $self->{output}->perfdata_add(label => 'cpu_' . $i, unit => '%', + value => sprintf("%.2f", $prct_usage), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + } + + $self->{statefile_value}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check CPU Usage + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/bluecoat/mode/disk.pm b/network/bluecoat/mode/disk.pm new file mode 100644 index 000000000..7c23d7da5 --- /dev/null +++ b/network/bluecoat/mode/disk.pm @@ -0,0 +1,125 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::disk; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $disk_num = 1; + my $result = $self->{snmp}->get_table(oid => '.1.3.6.1.4.1.3417.2.4.1.1.1'); + for (my $i = 1; defined($result->{'.1.3.6.1.4.1.3417.2.4.1.1.1.3.' . $i}); $i++) { + if ($result->{'.1.3.6.1.4.1.3417.2.4.1.1.1.3.' . $i} !~ /^DISK$/i) { + next; + } + + my $disk_usage = $result->{'.1.3.6.1.4.1.3417.2.4.1.1.1.4.' . $i}; + my $exit = $self->{perfdata}->threshold_check(value => $disk_usage, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk $disk_num usage is %.2f%%", $disk_usage)); + $self->{output}->perfdata_add(label => 'disk_' . $disk_num, unit => '%', + value => sprintf("%.2f", $disk_usage), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + $disk_num++; + } + + if ($disk_num == 1) { + $self->{output}->add_option_msg(short_msg => "No disk information found..."); + $self->{output}->option_exit(); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check disks usage. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/bluecoat/mode/hardware.pm b/network/bluecoat/mode/hardware.pm new file mode 100644 index 000000000..4b2558773 --- /dev/null +++ b/network/bluecoat/mode/hardware.pm @@ -0,0 +1,166 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %device_status_msg = (2 => "unaivalable", 3 => "non operationnal"); +my %device_units = ( + 1 => '', # other + 2 => '', # truthvalue + 3 => '', # specialEnum + 4 => 'volts', + 5 => 'celsius', + 6 => 'rpm' + ); + my %device_code = ( + 1 => ["The device sensor '%s' is ok", 'OK'], 2 => ["The device sensor '%s' is unknown", 'UNKNOWN'], 3 => ["The device sensor '%s' is not installed", 'UNKNOWN'], + 4 => ["The device sensor '%s' has a low voltage", 'WARNING'], 5 => ["The device sensor '%s' has a low voltage", 'CRITICAL'], + 6 => ["The device sensor '%s' has no power", 'CRITICAL'], + 7 => ["The device sensor '%s' has a high voltage", 'WARNING'], + 8 => ["The device sensor '%s' has a high voltage", 'CRITICAL'], + 9 => ["The device sensor '%s' has a very (!!!) high voltage", 'CRITICAL'], + 10 => ["The device sensor '%s' has a high temperature", 'WARNING'], + 11 => ["The device sensor '%s' has a high temperature", 'CRITICAL'], + 12 => ["The device sensor '%s' has a very high (!!!) temperature", 'CRITICAL'], + 13 => ["The fan '%s' is slow", 'WARNING'], + 14 => ["The fan '%s' is slow", 'CRITICAL'], + 15 => ["The fan '%s' is stopped", 'CRITICAL'], + ); +my %disk_status = ( + 1 => ["Disk '%s' is present", 'OK'], 2 => ["Disk '%s' is initializing", 'OK'], 3 => ["Disk '%s' is inserted", 'OK'], + 4 => ["Disk '%s' is offline", 'WARNING'], 5 => ["Disk '%s' is removed", 'WARNING'], + 6 => ["Disk '%s' is not present", 'WARNING'], + 7 => ["Disk '%s' is empty", 'WARNING'], + 8 => ["Disk '%s' has io errors", 'CRITICAL'], + 9 => ["Disk '%s' is unusable", 'CRITICAL'], + 10 => ["Disk status '%s' is unknown", 'UNKNOWN'], + ); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "skip" => { name => 'skip' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{output}->output_add(severity => 'OK', + short_msg => "All disks and sensors are ok."); + + my $oid_DeviceSensorValueEntry = '.1.3.6.1.4.1.3417.2.1.1.1.1.1'; + my $result = $self->{snmp}->get_table(oid => $oid_DeviceSensorValueEntry, nothing_quit => 1); + + for (my $i = 0; defined($result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.9.' . $i}); $i++) { + my $sensor_name = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.9.' . $i}; + my $sensor_status = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.7.' . $i}; + my $sensor_units = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.3.' . $i}; + my $sensor_code = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.4.' . $i}; + my $sensor_value = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.5.' . $i}; + my $sensor_scale = $result->{'.1.3.6.1.4.1.3417.2.1.1.1.1.1.4.' . $i}; + + $self->{output}->output_add(long_msg => "Device sensor '" . $sensor_name . "' status = '" . $sensor_status . "', code = '" . $sensor_code . "'"); + + # Check 'nonoperationnal' and 'unavailable' + if ($sensor_status == 2 || $sensor_status == 3) { + if (!defined($self->{option_results}->{skip})) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Device sensor '" . $sensor_name . "' is " . $sensor_status); + } + next; + } + + if ($sensor_code != 1) { + $self->{output}->output_add(severity => ${$device_code{$sensor_code}}[1], + short_msg => sprintf(${$device_code{$sensor_code}}[0], $sensor_name)); + } + + $self->{output}->perfdata_add(label => $sensor_name, unit => $device_units{sensor_units}, + value => ($sensor_value * (10 ** $sensor_scale))); + } + + $result = $self->{snmp}->get_table(oid => '.1.3.6.1.4.1.3417.2.2.1.1.1.1'); + for (my $i = 0; defined($result->{'.1.3.6.1.4.1.3417.2.2.1.1.1.1.8.' . $i}); $i++) { + my $disk_serial = $result->{'.1.3.6.1.4.1.3417.2.2.1.1.1.1.8.' . $i}; + my $disk_status = $result->{'.1.3.6.1.4.1.3417.2.2.1.1.1.1.3.' . $i}; + + if ($disk_status > 3) { + $self->{output}->output_add(severity => ${$disk_status{$disk_status}}[1], + short_msg => sprintf(${$disk_status{$disk_status}}[0], $disk_serial)); + } + $self->{output}->output_add(long_msg => sprintf(${$disk_status{$disk_status}}[0], $disk_serial)); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check bluecoat hardware sensors and disks. + +=over 8 + +=item B<--skip> + +Skip 'nonoperationnal' and 'unavailable' sensors. + +=back + +=cut diff --git a/network/bluecoat/mode/memory.pm b/network/bluecoat/mode/memory.pm new file mode 100644 index 000000000..8931365bf --- /dev/null +++ b/network/bluecoat/mode/memory.pm @@ -0,0 +1,139 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "nocache" => { name => 'nocache' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + my $result = $self->{snmp}->get_table(oid => '.1.3.6.1.4.1.3417.2.11.2.3', nothing_quit => 1); + + my $mem_total = $result->{'.1.3.6.1.4.1.3417.2.11.2.3.1.0'}; + my $mem_cache = $result->{'.1.3.6.1.4.1.3417.2.11.2.3.2.0'}; + my $mem_sys = $result->{'.1.3.6.1.4.1.3417.2.11.2.3.3.0'}; + my $mem_used; + + if (defined($self->{option_results}->{nocache})) { + $mem_used = $mem_sys; + } else { + $mem_used = $mem_sys + $mem_cache; + } + + my $prct_used = sprintf("%.2f", $mem_used * 100 / $mem_total); + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $mem_used); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $mem_total); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory used : %s - size : %s - percent : " . $prct_used . " %", + $used_value . " " . $used_unit, $total_value . " " . $total_unit)); + + $self->{output}->perfdata_add(label => 'used', + value => sprintf("%.2f", $mem_used), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $mem_total), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $mem_total), + min => 0, max => $mem_total); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check bluecoat memory. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=item B<--nocache> + +Skip cache value. + +=back + +=cut diff --git a/network/bluecoat/mode/serverconnections.pm b/network/bluecoat/mode/serverconnections.pm new file mode 100644 index 000000000..4d8e64f9b --- /dev/null +++ b/network/bluecoat/mode/serverconnections.pm @@ -0,0 +1,123 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::mode::serverconnections; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.3.4.0', + '.1.3.6.1.4.1.3417.2.11.3.1.3.5.0', + '.1.3.6.1.4.1.3417.2.11.3.1.3.6.0'], nothing_quit => 1); + my $server_connections = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.4.0'}; + my $server_connections_active = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.5.0'}; + my $server_connections_idle = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.3.6.0'}; + + my $exit = $self->{perfdata}->threshold_check(value => $server_connections_active, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => "Server connections: Active " . $server_connections_active . ", Idle " . $server_connections_idle); + $self->{output}->perfdata_add(label => 'con', + value => $server_connections, + min => 0); + $self->{output}->perfdata_add(label => 'con_active', + value => $server_connections_active, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{output}->perfdata_add(label => 'con_idle', + value => $server_connections_idle, + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current client connections. + +=over 8 + +=item B<--warning> + +Threshold warning (on active connections). + +=item B<--critical> + +Threshold critical (on active connections. + +=back + +=cut diff --git a/network/bluecoat/plugin.pm b/network/bluecoat/plugin.pm new file mode 100644 index 000000000..227e2de70 --- /dev/null +++ b/network/bluecoat/plugin.pm @@ -0,0 +1,71 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::bluecoat::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'client-connections' => 'network::bluecoat::mode::clientconnections', + 'client-requests' => 'network::bluecoat::mode::clientrequests', + 'client-traffic' => 'network::bluecoat::mode::clienttraffic', + 'cpu' => 'network::bluecoat::mode::cpu', + 'disk' => 'network::bluecoat::mode::disk', + 'hardware' => 'network::bluecoat::mode::hardware', + 'memory' => 'network::bluecoat::mode::memory', + 'server-connections' => 'network::bluecoat::mode::serverconnections', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Bluecoat hardware in SNMP. + +=cut diff --git a/network/cisco/3750/plugin.pm b/network/cisco/3750/plugin.pm new file mode 100644 index 000000000..3d9eae31e --- /dev/null +++ b/network/cisco/3750/plugin.pm @@ -0,0 +1,71 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::3750::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::cisco::common::mode::cpu', + 'environment' => 'network::cisco::common::mode::environment', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::cisco::common::mode::memory', + 'packet-errors' => 'snmp_standard::mode::packeterrors', + 'spanning-tree' => 'snmp_standard::mode::spanningtree', + 'stack' => 'network::cisco::common::mode::stack', + 'traffic' => 'snmp_standard::mode::traffic', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco 3750 in SNMP. + +=cut diff --git a/network/cisco/asa/mode/failover.pm b/network/cisco/asa/mode/failover.pm new file mode 100644 index 000000000..bf7217733 --- /dev/null +++ b/network/cisco/asa/mode/failover.pm @@ -0,0 +1,133 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::asa::mode::failover; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_failover = ( + 1 => 'other', + 2 => 'up', # for '.4' index + 3 => 'down', # can be + 4 => 'error', # maybe + 5 => 'overTemp', + 6 => 'busy', + 7 => 'noMedia', + 8 => 'backup', + 9 => 'active', # can be + 10 => 'standby' # can be +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "dont-warn-notstandby" => { name => 'dont_warn_notstandby' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $active_units = 0; + my $exit = 'ok'; + # primary is '.6' index and secondary is '.7' index (it's like that. '.4' is the global interface) + my $oid_cfwHardwareStatusValue_primary = '.1.3.6.1.4.1.9.9.147.1.2.1.1.1.3.6'; + my $oid_cfwHardwareStatusValue_secondary = '.1.3.6.1.4.1.9.9.147.1.2.1.1.1.3.7'; + my $oid_cfwHardwareStatusDetail_primary = '.1.3.6.1.4.1.9.9.147.1.2.1.1.1.4.6'; + my $oid_cfwHardwareStatusDetail_secondary = '.1.3.6.1.4.1.9.9.147.1.2.1.1.1.4.7'; + my $result = $self->{snmp}->get_leef(oids => [$oid_cfwHardwareStatusValue_primary, $oid_cfwHardwareStatusValue_secondary, + $oid_cfwHardwareStatusDetail_primary, $oid_cfwHardwareStatusDetail_secondary], nothing_quit => 1); + + if ($result->{$oid_cfwHardwareStatusValue_primary} == 9 || $result->{$oid_cfwHardwareStatusValue_primary} == 10 ) { + $active_units++; + } + if ($result->{$oid_cfwHardwareStatusValue_secondary} == 9 || $result->{$oid_cfwHardwareStatusValue_secondary} == 10 ) { + $active_units++; + } + if ($active_units == 0) { + $exit = 'critical'; + } elsif ($active_units == 1 && !defined($self->{option_results}->{dont_warn_notstandby})) { + # No redundant interface + $exit = 'warning'; + } + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Primary unit is '%s' [details: '%s'], Secondary unit is '%s' [details : '%s']", + $map_failover{$result->{$oid_cfwHardwareStatusValue_primary}}, $result->{$oid_cfwHardwareStatusDetail_primary}, + $map_failover{$result->{$oid_cfwHardwareStatusValue_secondary}}, $result->{$oid_cfwHardwareStatusDetail_secondary})); + + $self->{output}->perfdata_add(label => "active_units", + value => $active_units, + min => 0, max => 2); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current/average connections on Cisco ASA (CISCO-UNIFIED-FIREWALL-MIB). + +=over 8 + +=item B<--dont-warn-notstandby> + +Don't return warning if a unit is active and the other unit is not in standby status. + +=back + +=cut + \ No newline at end of file diff --git a/network/cisco/asa/mode/sessions.pm b/network/cisco/asa/mode/sessions.pm new file mode 100644 index 000000000..d77ec8810 --- /dev/null +++ b/network/cisco/asa/mode/sessions.pm @@ -0,0 +1,169 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::asa::mode::sessions; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-average:s" => { name => 'warning_average', default => '' }, + "critical-average:s" => { name => 'critical_average', default => '' }, + "warning-current:s" => { name => 'warning_current' }, + "critical-current:s" => { name => 'critical_current' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + ($self->{warn_avg1m}, $self->{warn_avg5m}) = split /,/, $self->{option_results}->{warning_average}; + ($self->{crit_avg1m}, $self->{crit_avg5m}) = split /,/, $self->{option_results}->{critical_average}; + + if (($self->{perfdata}->threshold_validate(label => 'warn_avg1m', value => $self->{warn_avg1m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning average (1min) threshold '" . $self->{warn_avg1m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_avg5m', value => $self->{warn_avg5m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning average (5min) threshold '" . $self->{warn_avg5m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_avg1m', value => $self->{crit_avg1m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical average (1min) threshold '" . $self->{crit_avg1m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_avg5m', value => $self->{crit_avg5m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical average (5min) threshold '" . $self->{crit_avg5m} . "'."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning_current', value => $self->{option_results}->{warning_current})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning current threshold '" . $self->{option_results}->{warning_current} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical_current', value => $self->{option_results}->{critical_current})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical current threshold '" . $self->{option_results}->{critical_current} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_cufwConnGlobalNumActive = '.1.3.6.1.4.1.9.9.491.1.1.1.6.0'; + my $oid_cufwConnGlobalConnSetupRate1 = '.1.3.6.1.4.1.9.9.491.1.1.1.10.0'; + my $oid_cufwConnGlobalConnSetupRate5 = '.1.3.6.1.4.1.9.9.491.1.1.1.11.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_cufwConnGlobalNumActive, $oid_cufwConnGlobalConnSetupRate1, + $oid_cufwConnGlobalConnSetupRate5], nothing_quit => 1); + + my $exit1 = $self->{perfdata}->threshold_check(value => $result->{$oid_cufwConnGlobalConnSetupRate1}, + threshold => [ { label => 'crit_avg1m', 'exit_litteral' => 'critical' }, { label => 'warn_avg1m', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $result->{$oid_cufwConnGlobalConnSetupRate5}, + threshold => [ { label => 'crit_avg5m', 'exit_litteral' => 'critical' }, { label => 'warn_avg5m', exit_litteral => 'warning' } ]); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Average Connections per seconds: %d (last 1min), %d (last 5min)", + $result->{$oid_cufwConnGlobalConnSetupRate1}, $result->{$oid_cufwConnGlobalConnSetupRate5})); + + $exit = $self->{perfdata}->threshold_check(value => $result->{$oid_cufwConnGlobalNumActive}, + threshold => [ { label => 'critical_current', 'exit_litteral' => 'critical' }, { label => 'warning_current', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Current active connections: %d", + $result->{$oid_cufwConnGlobalNumActive})); + + $self->{output}->perfdata_add(label => "connections_1m", unit => 'con/s', + value => $result->{$oid_cufwConnGlobalConnSetupRate1}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_avg1m'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_avg1m'), + min => 0); + $self->{output}->perfdata_add(label => "connections_5m", unit => 'con/s', + value => $result->{$oid_cufwConnGlobalConnSetupRate1}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_avg1m'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_avg1m'), + min => 0); + $self->{output}->perfdata_add(label => "connections_current", + value => $result->{$oid_cufwConnGlobalNumActive}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_current'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_current'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current/average connections on Cisco ASA (CISCO-UNIFIED-FIREWALL-MIB). + +=over 8 + +=item B<--warning-average> + +Threshold warning: averaged number of connections which the firewall establishing per second (1min,5min). + +=item B<--critical-average> + +Threshold critical: averaged number of connections which the firewall establishing per second (1min,5min). + +=item B<--warning-current> + +Threshold warning: number of connections which are currently active. + +=item B<--critical-current> + +Threshold critical: number of connections which are currently active. + +=back + +=cut + \ No newline at end of file diff --git a/network/cisco/asa/plugin.pm b/network/cisco/asa/plugin.pm new file mode 100644 index 000000000..6294a78d2 --- /dev/null +++ b/network/cisco/asa/plugin.pm @@ -0,0 +1,71 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::asa::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::cisco::common::mode::cpu', + 'failover' => 'network::cisco::asa::mode::failover', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::cisco::common::mode::memory', + 'packet-errors' => 'snmp_standard::mode::packeterrors', + 'sessions' => 'network::cisco::asa::mode::sessions', + 'traffic' => 'snmp_standard::mode::traffic', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco ASA in SNMP. +!!! Be careful: Cisco ASA had an internal SNMP buffer of 512B. Use --subsetleef=20 (or lower) option !!! + +=cut diff --git a/network/cisco/common/mode/cpu.pm b/network/cisco/common/mode/cpu.pm new file mode 100644 index 000000000..e527d2a65 --- /dev/null +++ b/network/cisco/common/mode/cpu.pm @@ -0,0 +1,171 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::common::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', default => '' }, + "critical:s" => { name => 'critical', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + ($self->{warn5s}, $self->{warn1m}, $self->{warn5m}) = split /,/, $self->{option_results}->{warning}; + ($self->{crit5s}, $self->{crit1m}, $self->{crit5m}) = split /,/, $self->{option_results}->{critical}; + + if (($self->{perfdata}->threshold_validate(label => 'warn5s', value => $self->{warn5s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (5sec) threshold '" . $self->{warn5s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn1m', value => $self->{warn1m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (1min) threshold '" . $self->{warn1m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn5m', value => $self->{warn5m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (5min) threshold '" . $self->{warn5m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit5s', value => $self->{crit5s})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (5sec) threshold '" . $self->{crit5s} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit1m', value => $self->{crit1m})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (1min) threshold '" . $self->{crit1m} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit5m', value => $self->{crit5})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (5min) threshold '" . $self->{crit5m} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_cpmCPUTotalEntry = '.1.3.6.1.4.1.9.9.109.1.1.1.1'; + my $oid_cpmCPUTotal5sec = '.1.3.6.1.4.1.9.9.109.1.1.1.1.3'; + my $oid_cpmCPUTotal1min = '.1.3.6.1.4.1.9.9.109.1.1.1.1.4'; + my $oid_cpmCPUTotal5min = '.1.3.6.1.4.1.9.9.109.1.1.1.1.5'; + my $result = $self->{snmp}->get_table(oid => $oid_cpmCPUTotalEntry, nothing_quit => 1); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All CPUs are ok.'); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_cpmCPUTotal5sec/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + my $cpu5sec = $result->{$oid}; + my $cpu1min = $result->{$oid_cpmCPUTotal1min . '.' . $instance}; + my $cpu5min =$result->{$oid_cpmCPUTotal5min . '.' . $instance}; + + my $exit1 = $self->{perfdata}->threshold_check(value => $cpu5sec, + threshold => [ { label => 'crit5s', 'exit_litteral' => 'critical' }, { label => 'warn5s', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $cpu1min, + threshold => [ { label => 'crit1m', 'exit_litteral' => 'critical' }, { label => 'warn1m', exit_litteral => 'warning' } ]); + my $exit3 = $self->{perfdata}->threshold_check(value => $cpu5min, + threshold => [ { label => 'crit5m', 'exit_litteral' => 'critical' }, { label => 'warn5m', exit_litteral => 'warning' } ]); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3 ]); + + $self->{output}->output_add(long_msg => sprintf("CPU '%s': %.2f%% (5sec), %.2f%% (1min), %.2f%% (5min)", $instance, + $cpu5sec, $cpu1min, $cpu5min)); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU '%s': %.2f%% (5sec), %.2f%% (1min), %.2f%% (5min)", $instance, + $cpu5sec, $cpu1min, $cpu5min)); + } + + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5s", + value => $cpu5sec, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5s'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5s'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_1m", + value => $cpu1min, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn1m'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit1m'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5m", + value => $cpu5min, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5m'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5m'), + min => 0, max => 100); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check cpu usage (CISCO-PROCESS-MIB). + +=over 8 + +=item B<--warning> + +Threshold warning in percent (5s,1min,5min). + +=item B<--critical> + +Threshold critical in percent (5s,1min,5min). + +=back + +=cut + \ No newline at end of file diff --git a/network/cisco/common/mode/environment.pm b/network/cisco/common/mode/environment.pm new file mode 100644 index 000000000..0fb57d760 --- /dev/null +++ b/network/cisco/common/mode/environment.pm @@ -0,0 +1,299 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::common::mode::environment; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_type_mon = ( + 1 => 'oldAgs', + 2 => 'ags', + 3 => 'c7000', + 4 => 'ci', + 6 => 'cAccessMon', + 7 => 'cat6000', + 8 => 'ubr7200', + 9 => 'cat4000', + 10 => 'c10000', + 11 => 'osr7600', + 12 => 'c7600', + 13 => 'c37xx', + 14 => 'other' +); +my %states = ( + 1 => ['normal', 'OK'], + 2 => ['warning', 'WARNING'], + 3 => ['critical', 'CRITICAL'], + 4 => ['shutdown', 'OK'], + 5 => ['not present', 'OK'], + 6 => ['not functioning', 'WARNING'], +); +my %map_psu_source = ( + 1 => 'unknown', + 2 => 'ac', + 3 => 'dc', + 4 => 'externalPowerSupply', + 5 => 'internalRedundant' +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "exclude" => { name => 'exclude' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{components_fans} = 0; + $self->{components_psus} = 0; + $self->{components_temperatures} = 0; + $self->{components_voltages} = 0; + + $self->get_type(); + $self->check_fans(); + $self->check_psus(); + $self->check_temperatures(); + $self->check_voltages(); + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %d components [%d fans, %d power supplies, %d temperatures, %d voltages] are ok, Environment type: %s", + ($self->{components_fans} + $self->{components_psus} + $self->{components_temperatures} + $self->{components_voltages}), + $self->{components_fans}, $self->{components_psus}, $self->{components_temperatures}, $self->{components_voltages}, $self->{env_type})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_type { + my ($self) = @_; + + my $oid_ciscoEnvMonPresent = ".1.3.6.1.4.1.9.9.13.1.1.0"; + + my $result = $self->{snmp}->get_leef(oids => [$oid_ciscoEnvMonPresent]); + + $self->{env_type} = defined($result->{$oid_ciscoEnvMonPresent}) ? $map_type_mon{$result->{$oid_ciscoEnvMonPresent}} : 'unknown'; +} + +sub check_fans { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + return if ($self->check_exclude('fans')); + + my $oid_ciscoEnvMonFanStatusEntry = '.1.3.6.1.4.1.9.9.13.1.4.1'; + my $oid_ciscoEnvMonFanStatusDescr = '.1.3.6.1.4.1.9.9.13.1.4.1.2'; + my $oid_ciscoEnvMonFanState = '.1.3.6.1.4.1.9.9.13.1.4.1.3'; + + my $result = $self->{snmp}->get_table(oid => $oid_ciscoEnvMonFanStatusEntry); + return if (scalar(keys %$result) <= 0); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_ciscoEnvMonFanStatusDescr/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $fan_descr = $result->{$oid}; + my $fan_state = $result->{$oid_ciscoEnvMonFanState . '.' . $instance}; + + $self->{components_fans}++; + $self->{output}->output_add(long_msg => sprintf("Fan '%s' state is %s.", + $fan_descr, ${$states{$fan_state}}[0])); + if (${$states{$fan_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$fan_state}}[1], + short_msg => sprintf("Fan '%s' state is %s.", $fan_descr, ${$states{$fan_state}}[0])); + } + } +} + +sub check_psus { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + return if ($self->check_exclude('psu')); + + my $oid_ciscoEnvMonSupplyStatusEntry = '.1.3.6.1.4.1.9.9.13.1.5.1'; + my $oid_ciscoEnvMonSupplyStatusDescr = '.1.3.6.1.4.1.9.9.13.1.5.1.2'; + my $oid_ciscoEnvMonSupplyState = '.1.3.6.1.4.1.9.9.13.1.5.1.3'; + my $oid_ciscoEnvMonSupplySource = '.1.3.6.1.4.1.9.9.13.1.5.1.4'; + + my $result = $self->{snmp}->get_table(oid => $oid_ciscoEnvMonSupplyStatusEntry); + return if (scalar(keys %$result) <= 0); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_ciscoEnvMonSupplyStatusDescr/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $psu_descr = $result->{$oid}; + my $psu_state = $result->{$oid_ciscoEnvMonSupplyState . '.' . $instance}; + my $psu_source = $result->{$oid_ciscoEnvMonSupplySource . '.' . $instance}; + + $self->{components_psus}++; + $self->{output}->output_add(long_msg => sprintf("Power Supply '%s' [type: %s] state is %s.", + $psu_descr, $map_psu_source{$psu_source}, ${$states{$psu_state}}[0])); + if (${$states{$psu_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$psu_state}}[1], + short_msg => sprintf("Power Supply '%s' state is %s.", $psu_descr, ${$states{$psu_state}}[0])); + } + } +} + +sub check_voltages { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + return if ($self->check_exclude('voltages')); + + my $oid_ciscoEnvMonVoltageStatusEntry = '.1.3.6.1.4.1.9.9.13.1.2.1'; + my $oid_ciscoEnvMonVoltageStatusDescr = '.1.3.6.1.4.1.9.9.13.1.2.1.2'; + my $oid_ciscoEnvMonVoltageStatusValue = '.1.3.6.1.4.1.9.9.13.1.2.1.3'; + my $oid_ciscoEnvMonVoltageThresholdLow = '.1.3.6.1.4.1.9.9.13.1.2.1.4'; + my $oid_ciscoEnvMonVoltageThresholdHigh = '.1.3.6.1.4.1.9.9.13.1.2.1.5'; + my $oid_ciscoEnvMonVoltageState = '.1.3.6.1.4.1.9.9.13.1.2.1.7'; + + my $result = $self->{snmp}->get_table(oid => $oid_ciscoEnvMonVoltageStatusEntry); + return if (scalar(keys %$result) <= 0); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_ciscoEnvMonVoltageStatusDescr/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $voltage_descr = $result->{$oid}; + my $voltage_state = $result->{$oid_ciscoEnvMonVoltageState . '.' . $instance}; + my $voltage_value = $result->{$oid_ciscoEnvMonVoltageStatusValue . '.' . $instance}; + my $voltage_low = $result->{$oid_ciscoEnvMonVoltageThresholdLow . '.' . $instance}; + my $voltage_high = $result->{$oid_ciscoEnvMonVoltageThresholdHigh . '.' . $instance}; + + $self->{components_voltages}++; + $self->{output}->output_add(long_msg => sprintf("Voltage '%s' state is %s.", + $voltage_descr, ${$states{$voltage_state}}[0])); + if (${$states{$voltage_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$voltage_state}}[1], + short_msg => sprintf("Power Supply '%s' state is %s.", $voltage_descr, ${$states{$voltage_state}}[0])); + } + + $self->{output}->perfdata_add(label => 'voltage_' . $voltage_descr, unit => 'V', + value => $voltage_value, + critical => $voltage_low . ":" . $voltage_high); + } +} + +sub check_temperatures { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + return if ($self->check_exclude('temperatures')); + + my $oid_ciscoEnvMonTemperatureStatusEntry = '.1.3.6.1.4.1.9.9.13.1.3.1'; + my $oid_ciscoEnvMonTemperatureStatusDescr = '.1.3.6.1.4.1.9.9.13.1.3.1.2'; + my $oid_ciscoEnvMonTemperatureStatusValue = '.1.3.6.1.4.1.9.9.13.1.3.1.3'; + my $oid_ciscoEnvMonTemperatureThreshold = '.1.3.6.1.4.1.9.9.13.1.3.1.4'; + my $oid_ciscoEnvMonTemperatureState = '.1.3.6.1.4.1.9.9.13.1.3.1.6'; + + my $result = $self->{snmp}->get_table(oid => $oid_ciscoEnvMonTemperatureStatusEntry); + return if (scalar(keys %$result) <= 0); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_ciscoEnvMonTemperatureStatusDescr/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $temp_descr = $result->{$oid}; + my $temp_state = $result->{$oid_ciscoEnvMonTemperatureState . '.' . $instance}; + my $temp_value = $result->{$oid_ciscoEnvMonTemperatureStatusValue . '.' . $instance}; + my $temp_threshold = $result->{$oid_ciscoEnvMonTemperatureThreshold . '.' . $instance}; + + $self->{components_temperatures}++; + $self->{output}->output_add(long_msg => sprintf("Temperature '%s' state is %s.", + $temp_descr, ${$states{$temp_state}}[0])); + if (${$states{$temp_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$temp_state}}[1], + short_msg => sprintf("Temperature '%s' state is %s.", $temp_descr, ${$states{$temp_state}}[0])); + } + + $self->{output}->perfdata_add(label => 'temp_' . $temp_descr, unit => 'C', + value => $temp_value, + critical => "~:" . $temp_threshold); + } +} + +sub check_exclude { + my ($self, $section) = @_; + + if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$section(\s|,|$)/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $section section.")); + return 1; + } + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check Environment monitor (CISCO-ENVMON-MIB) (Fans, Power Supplies, Temperatures, Voltages). + +=over 8 + +=item B<--exclude> + +Exclude some parts (comma seperated list) (Example: --exclude=temperatures,psu). + +=back + +=cut + \ No newline at end of file diff --git a/network/cisco/common/mode/memory.pm b/network/cisco/common/mode/memory.pm new file mode 100644 index 000000000..ed344f9ee --- /dev/null +++ b/network/cisco/common/mode/memory.pm @@ -0,0 +1,147 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::common::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_ciscoMemoryPoolEntry = '.1.3.6.1.4.1.9.9.48.1.1.1'; + my $oid_ciscoMemoryPoolName = '.1.3.6.1.4.1.9.9.48.1.1.1.2'; + my $oid_ciscoMemoryPoolUsed = '.1.3.6.1.4.1.9.9.48.1.1.1.5'; # in B + my $oid_ciscoMemoryPoolFree = '.1.3.6.1.4.1.9.9.48.1.1.1.6'; # in B + my $result = $self->{snmp}->get_table(oid => $oid_ciscoMemoryPoolEntry, nothing_quit => 1); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All pool memories are ok.'); + + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_ciscoMemoryPoolName/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + my $memory_name = $result->{$oid}; + my $memory_used = $result->{$oid_ciscoMemoryPoolUsed . '.' . $instance}; + my $memory_free =$result->{$oid_ciscoMemoryPoolFree . '.' . $instance}; + + my $total_size = $memory_used + $memory_free; + my $prct_used = $memory_used * 100 / $total_size; + my $prct_free = 100 - $prct_used; + + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); + + $self->{output}->output_add(long_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + } + + $self->{output}->perfdata_add(label => "used_" . $memory_name, + value => $memory_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check memory usage (CISCO-MEMORY-POOL-MIB). + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut + \ No newline at end of file diff --git a/network/cisco/common/mode/stack.pm b/network/cisco/common/mode/stack.pm new file mode 100644 index 000000000..3410645fb --- /dev/null +++ b/network/cisco/common/mode/stack.pm @@ -0,0 +1,135 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::cisco::common::mode::stack; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_role = ( + 1 => 'master', + 2 => 'member', + 3 => 'notMember', + 4 => 'standby' +); +my %states = ( + 1 => ['waiting', 'WARNING'], + 2 => ['progressing', 'WARNING'], + 3 => ['added', 'WARNING'], + 4 => ['ready', 'OK'], + 5 => ['sdmMismatch', 'CRITICAL'], + 6 => ['verMismatch', 'CRITICAL'], + 7 => ['featureMismatch', 'CRITICAL'], + 8 => ['newMasterInit', 'WARNING'], + 9 => ['provisioned', 'OK'], + 10 => ['invalid', 'WARNING'], + 11 => ['removed', 'WARNING'], +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_cswRingRedundant = '.1.3.6.1.4.1.9.9.500.1.1.3.0'; + my $oid_cswSwitchRole = '.1.3.6.1.4.1.9.9.500.1.2.1.1.3'; + my $oid_cswSwitchState = '.1.3.6.1.4.1.9.9.500.1.2.1.1.6'; + my $result = $self->{snmp}->get_leef(oids => [$oid_cswRingRedundant], nothing_quit => 1); + my $result_state = $self->{snmp}->get_table(oid => $oid_cswSwitchState, nothing_quit => 1); + my $result_role = $self->{snmp}->get_table(oid => $oid_cswSwitchRole); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'Stack ring is redundant'); + if ($result->{$oid_cswRingRedundant} != 1) { + $self->{output}->output_add(severity => 'WARNING', + short_msg => 'Stack ring is not redundant'); + } + + foreach my $oid (keys %$result_state) { + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $state = $result_state->{$oid}; + my $role = defined($result_role->{$oid_cswSwitchRole . '.' . $instance}) ? $result_role->{$oid_cswSwitchRole . '.' . $instance} : 'unknown'; + # .1001, .2001 the instance. + my $number = int(($instance - 1) / 1000); + + $self->{output}->output_add(long_msg => sprintf("Member '%s' state is %s [Role is '%s']", $number, + ${$states{$state}}[0], $map_role{$role})); + if (${$states{$state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$state}}[1], + short_msg => sprintf("Member '%s' state is %s", $number, + ${$states{$state}}[0])); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Cisco Stack (CISCO-STACKWISE-MIB). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/network/juniper/common/mode/cpsessions.pm b/network/juniper/common/mode/cpsessions.pm new file mode 100644 index 000000000..98a71a6f7 --- /dev/null +++ b/network/juniper/common/mode/cpsessions.pm @@ -0,0 +1,139 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::cpsessions; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxJsSPUMonitoringSPUIndex = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.3'; + my $oid_jnxJsSPUMonitoringCurrentCPSession = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.8'; + my $oid_jnxJsSPUMonitoringMaxCPSession = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.9'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxJsSPUMonitoringSPUIndex, nothing_quit => 1); + $self->{snmp}->load(oids => [$oid_jnxJsSPUMonitoringCurrentCPSession, $oid_jnxJsSPUMonitoringMaxCPSession], + instances => [keys %$result], + instance_regexp => '\.(\d+)$'); + my $result2 = $self->{snmp}->get_leef(nothing_quit => 1); + + my $spu_done = 0; + foreach my $oid (keys %$result) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $cp_total = $result2->{$oid_jnxJsSPUMonitoringMaxCPSession . '.' . $instance}; + my $cp_used = $result2->{$oid_jnxJsSPUMonitoringCurrentCPSession . '.' . $instance}; + + next if ($cp_total == 0); + my $prct_used = $cp_used * 100 / $cp_total; + + $spu_done = 1; + my $exit_code = $self->{perfdata}->threshold_check(value => $prct_used, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("SPU '%d': %.2f%% of the cp sessions limit reached (%d of max. %d)", + $instance, $prct_used, $cp_used, $cp_total)); + $self->{output}->perfdata_add(label => 'sessions_' . $instance, + value => $cp_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $cp_total), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $cp_total), + min => 0, max => $cp_total); + } + + if ($spu_done == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot check cp sessions usage (no total values)."); + $self->{output}->option_exit(); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check CP ('central point') sessions usage. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/common/mode/cpuforwarding.pm b/network/juniper/common/mode/cpuforwarding.pm new file mode 100644 index 000000000..45880e833 --- /dev/null +++ b/network/juniper/common/mode/cpuforwarding.pm @@ -0,0 +1,126 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::cpuforwarding; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxJsSPUMonitoringSPUIndex = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.3'; + my $oid_jnxJsSPUMonitoringCPUUsage = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.4'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxJsSPUMonitoringSPUIndex, nothing_quit => 1); + $self->{snmp}->load(oids => [$oid_jnxJsSPUMonitoringCPUUsage], + instances => [keys %$result], + instance_regexp => '\.(\d+)$'); + my $result2 = $self->{snmp}->get_leef(nothing_quit => 1); + + foreach my $oid (keys %$result) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $cpu_usage = $result2->{$oid_jnxJsSPUMonitoringCPUUsage . '.' . $instance}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $cpu_usage, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("CPU '%d' average usage is: %s%%", $instance, $cpu_usage)); + $self->{output}->perfdata_add(label => 'cpu_' . $instance, unit => '%', + value => $cpu_usage, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check CPU Usage of packet forwarding engine. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/common/mode/cpurouting.pm b/network/juniper/common/mode/cpurouting.pm new file mode 100644 index 000000000..c5e104280 --- /dev/null +++ b/network/juniper/common/mode/cpurouting.pm @@ -0,0 +1,154 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::cpurouting; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxOperatingDescr = '.1.3.6.1.4.1.2636.3.1.13.1.5'; + my $oid_jnxOperatingCPU = '.1.3.6.1.4.1.2636.3.1.13.1.8'; + my $oid_jnxOperating1MinLoadAvg = '.1.3.6.1.4.1.2636.3.1.13.1.20'; + my $oid_jnxOperating5MinLoadAvg = '.1.3.6.1.4.1.2636.3.1.13.1.21'; + my $oid_jnxOperating15MinLoadAvg = '.1.3.6.1.4.1.2636.3.1.13.1.22'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxOperatingDescr, nothing_quit => 1); + my $routing_engine_find = 0; + my $oid_routing_engine; + foreach my $oid (keys %$result) { + if ($result->{$oid} =~ /routing/i) { + $routing_engine_find = 1; + $oid_routing_engine = $oid; + last; + } + } + + if ($routing_engine_find == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot find operating with 'routing' in description."); + $self->{output}->option_exit(); + } + + $self->{snmp}->load(oids => [$oid_jnxOperatingCPU, $oid_jnxOperating1MinLoadAvg, $oid_jnxOperating5MinLoadAvg, $oid_jnxOperating15MinLoadAvg], + instances => [$oid_routing_engine], + instance_regexp => "^" . $oid_jnxOperatingDescr . '\.(.+)'); + my $result2 = $self->{snmp}->get_leef(); + + $oid_routing_engine =~ /^$oid_jnxOperatingDescr\.(.+)/; + my $instance = $1; + my $cpu_usage = $result2->{$oid_jnxOperatingCPU . '.' . $instance}; + my $cpu_load1 = $result2->{$oid_jnxOperating1MinLoadAvg . '.' . $instance}; + my $cpu_load5 = $result2->{$oid_jnxOperating5MinLoadAvg . '.' . $instance}; + my $cpu_load15 = $result2->{$oid_jnxOperating15MinLoadAvg . '.' . $instance}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $cpu_usage, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("CPU(s) average usage is: %s%%", $cpu_usage)); + $self->{output}->perfdata_add(label => 'cpu', unit => '%', + value => $cpu_usage, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => 'load1', + value => $cpu_load1, + min => 0); + $self->{output}->perfdata_add(label => 'load5', + value => $cpu_load5, + min => 0); + $self->{output}->perfdata_add(label => 'load15', + value => $cpu_load15, + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check CPU Usage of routing engine. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/common/mode/flowsessions.pm b/network/juniper/common/mode/flowsessions.pm new file mode 100644 index 000000000..a93af914f --- /dev/null +++ b/network/juniper/common/mode/flowsessions.pm @@ -0,0 +1,139 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::flowsessions; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxJsSPUMonitoringSPUIndex = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.3'; + my $oid_jnxJsSPUMonitoringCurrentFlowSession = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.6'; + my $oid_jnxJsSPUMonitoringMaxFlowSession = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.7'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxJsSPUMonitoringSPUIndex, nothing_quit => 1); + $self->{snmp}->load(oids => [$oid_jnxJsSPUMonitoringCurrentFlowSession, $oid_jnxJsSPUMonitoringMaxFlowSession], + instances => [keys %$result], + instance_regexp => '\.(\d+)$'); + my $result2 = $self->{snmp}->get_leef(nothing_quit => 1); + + my $spu_done = 0; + foreach my $oid (keys %$result) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $flow_total = $result2->{$oid_jnxJsSPUMonitoringMaxFlowSession . '.' . $instance}; + my $flow_used = $result2->{$oid_jnxJsSPUMonitoringCurrentFlowSession . '.' . $instance}; + + next if ($flow_total == 0); + my $prct_used = $flow_used * 100 / $flow_total; + + $spu_done = 1; + my $exit_code = $self->{perfdata}->threshold_check(value => $prct_used, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("SPU '%d': %.2f%% of the flow sessions limit reached (%d of max. %d)", + $instance, $prct_used, $flow_used, $flow_total)); + $self->{output}->perfdata_add(label => 'sessions_' . $instance, + value => $flow_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $flow_total), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $flow_total), + min => 0, max => $flow_total); + } + + if ($spu_done == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot check flow sessions usage (no total values)."); + $self->{output}->option_exit(); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Packet Forwarding Engine sessions usage. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/common/mode/hardware.pm b/network/juniper/common/mode/hardware.pm new file mode 100644 index 000000000..c52573130 --- /dev/null +++ b/network/juniper/common/mode/hardware.pm @@ -0,0 +1,242 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_fru_offline = ( + 1 => 'unknown', 2 => 'none', 3 => 'error', 4 => 'noPower', 5 => 'configPowerOff', 6 => 'configHoldInReset', + 7 => 'cliCommand', 8 => 'buttonPress', 9 => 'cliRestart', 10 => 'overtempShutdown', 11 => 'masterClockDown', + 12 => 'singleSfmModeChange', 13 => 'packetSchedulingModeChange', 14 => 'physicalRemoval', 15 => 'unresponsiveRestart', + 16 => 'sonetClockAbsent', 17 => 'rddPowerOff', 18 => 'majorErrors', 19 => 'minorErrors', 20 => 'lccHardRestart', + 21 => 'lccVersionMismatch', 22 => 'powerCycle', 23 => 'reconnect', 24 => 'overvoltage', 25 => 'pfeVersionMismatch', + 26 => 'febRddCfgChange', 27 => 'fpcMisconfig', 28 => 'fruReconnectFail', 29 => 'fruFwddReset', 30 => 'fruFebSwitch', + 31 => 'fruFebOffline', 32 => 'fruInServSoftUpgradeError', 33 => 'fruChasdPowerRatingExceed', 34 => 'fruConfigOffline', + 35 => 'fruServiceRestartRequest', 36 => 'spuResetRequest', 37 => 'spuFlowdDown', 38 => 'spuSpi4Down', 39 => 'spuWatchdogTimeout', + 40 => 'spuCoreDump', 41 => 'fpgaSpi4LinkDown', 42 => 'i3Spi4LinkDown', 43 => 'cppDisconnect', 44 => 'cpuNotBoot', + 45 => 'spuCoreDumpComplete', 46 => 'rstOnSpcSpuFailure', 47 => 'softRstOnSpcSpuFailure', 48 => 'hwAuthenticationFailure', + 49 => 'reconnectFpcFail', 50 => 'fpcAppFailed', 51 => 'fpcKernelCrash', 52 => 'spuFlowdDownNoCore', 53 => 'spuFlowdCoreDumpIncomplete', + 54 => 'spuFlowdCoreDumpComplete', 55 => 'spuIdpdDownNoCore', 56 => 'spuIdpdCoreDumpIncomplete', 57 => 'spuIdpdCoreDumpComplete', + 58 => 'spuCoreDumpIncomplete', 59 => 'spuIdpdDown', 60 => 'fruPfeReset', 61 => 'fruReconnectNotReady', 62 => 'fruSfLinkDown', + 63 => 'fruFabricDown', 64 => 'fruAntiCounterfeitRetry', 65 => 'fruFPCChassisClusterDisable', 66 => 'spuFipsError', + 67 => 'fruFPCFabricDownOffline', 68 => 'febCfgChange', 69 => 'routeLocalizationRoleChange', 70 => 'fruFpcUnsupported', + 71 => 'psdVersionMismatch', 72 => 'fruResetThresholdExceeded', 73 => 'picBounce', 74 => 'badVoltage', 75 => 'fruFPCReducedFabricBW', + 76 => 'fruAutoheal', 77 => 'builtinPicBounce', 78 => 'fruFabricDegraded', 79 => 'fruFPCFabricDegradedOffline', 80 => 'fruUnsupportedSlot', + 81 => 'fruRouteLocalizationMisCfg', 82 => 'fruTypeConfigMismatch', 83 => 'lccModeChanged', 84 => 'hwFault', 85 => 'fruPICOfflineOnEccErrors', + 86 => 'fruFpcIncompatible', 87 => 'fruFpcFanTrayPEMIncompatible', 88 => 'fruUnsupportedFirmware', + 89 => 'openflowConfigChange', 90 => 'fruFpcScbIncompatible', 91 => 'fruReUnresponsive' +); +my %map_fru_type = ( + 1 => 'other', 2 => 'clockGenerator', 3 => 'flexiblePicConcentrator', 4 => 'switchingAndForwardingModule', 5 => 'controlBoard', + 6 => 'routingEngine', 7 => 'powerEntryModule', 8 => 'frontPanelModule', 9 => 'switchInterfaceBoard', 10 => 'processorMezzanineBoardForSIB', + 11 => 'portInterfaceCard', 12 => 'craftInterfacePanel', 13 => 'fan', 14 => 'lineCardChassis', 15 => 'forwardingEngineBoard', + 16 => 'protectedSystemDomain', 17 => 'powerDistributionUnit', 18 => 'powerSupplyModule', 19 => 'switchFabricBoard', 20 => 'adapterCard' +); +my %fru_states = ( + 1 => ['unknown', 'UNKNOWN'], + 2 => ['empty', 'OK'], + 3 => ['present', 'OK'], + 4 => ['ready', 'OK'], + 5 => ['announce online', 'OK'], + 6 => ['online', 'OK'], + 7 => ['announce offline', 'WARNING'], + 8 => ['offline', 'CRITICAL'], + 9 => ['diagnostic', 'WARNING'], + 10 => ['standby', 'WARNING'], +); +my %operating_states = ( + 1 => ['unknown', 'UNKNOWN'], + 2 => ['running', 'OK'], + 3 => ['ready', 'OK'], + 4 => ['reset', 'WARNING'], + 5 => ['runningAtFullSpeed', 'WARNING'], + 6 => ['down', 'CRITICAL'], + 7 => ['standby', 'OK'], +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->{components_frus} = 0; + $self->{components_operating} = 0; + + $self->get_type(); + $self->check_frus(); + $self->check_operating(); + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %d components [%d frus, %d operating] are ok, Environment type: %s", + ($self->{components_frus} + $self->{components_operating}), + $self->{components_frus}, $self->{components_operating}, $self->{env_type})); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_type { + my ($self) = @_; + + my $oid_jnxBoxDescr = ".1.3.6.1.4.1.2636.3.1.2.0"; + + my $result = $self->{snmp}->get_leef(oids => [$oid_jnxBoxDescr]); + + $self->{env_type} = defined($result->{$oid_jnxBoxDescr}) ? $result->{$oid_jnxBoxDescr} : 'unknown'; +} + +sub check_frus { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking frus"); + + my $oid_jnxFruName = '.1.3.6.1.4.1.2636.3.1.15.1.5'; + my $oid_jnxFruType = '.1.3.6.1.4.1.2636.3.1.15.1.6'; + my $oid_jnxFruState = '.1.3.6.1.4.1.2636.3.1.15.1.8'; + my $oid_jnxFruTemp = '.1.3.6.1.4.1.2636.3.1.15.1.9'; + my $oid_jnxFruOfflineReason = '.1.3.6.1.4.1.2636.3.1.15.1.10'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxFruName); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_jnxFruType, $oid_jnxFruState, $oid_jnxFruTemp, $oid_jnxFruOfflineReason], + instances => [keys %$result], + instance_regexp => "^" . $oid_jnxFruName . '\.(.+)'); + my $result2 = $self->{snmp}->get_leef(); + + foreach my $oid (keys %$result) { + $oid =~ /^$oid_jnxFruName\.(.+)/; + my $instance = $1; + + my $fru_name = $result->{$oid}; + my $fru_type = $result2->{$oid_jnxFruType . "." . $instance}; + my $fru_state = $result2->{$oid_jnxFruState . "." . $instance}; + my $fru_temp = $result2->{$oid_jnxFruTemp . "." . $instance}; + my $fru_offlinereason = $result2->{$oid_jnxFruOfflineReason . "." . $instance}; + + # Empty. Skip + if ($fru_state == 2) { + $self->{output}->output_add(long_msg => sprintf("Skipping fru '%s' [type: %s]: empty.", + $fru_name, $map_fru_type{$fru_type})); + next; + } + + $self->{components_frus}++; + $self->{output}->output_add(long_msg => sprintf("Fru '%s' state is %s [type: %s, offline reason: %s]", + $fru_name, ${$fru_states{$fru_state}}[0], + $map_fru_type{$fru_type}, $map_fru_offline{$fru_offlinereason})); + if (${$fru_states{$fru_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$fru_states{$fru_state}}[1], + short_msg => sprintf("Fru '%s' state is %s [offline reason: %s]", $fru_name, ${$fru_states{$fru_state}}[0], + $map_fru_offline{$fru_offlinereason})); + } + + if ($fru_temp != 0) { + $self->{output}->perfdata_add(label => 'temp_' . $fru_name, unit => 'C', + value => $fru_temp); + } + } +} + +sub check_operating { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking operating"); + + my $oid_jnxOperatingDescr = '.1.3.6.1.4.1.2636.3.1.13.1.5'; + my $oid_jnxOperatingState = '.1.3.6.1.4.1.2636.3.1.13.1.6'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxOperatingDescr); + return if (scalar(keys %$result) <= 0); + + $self->{snmp}->load(oids => [$oid_jnxOperatingState], + instances => [keys %$result], + instance_regexp => "^" . $oid_jnxOperatingDescr . '\.(.+)'); + my $result2 = $self->{snmp}->get_leef(); + + foreach my $oid (keys %$result) { + $oid =~ /^$oid_jnxOperatingDescr\.(.+)/; + my $instance = $1; + + my $operating_descr = $result->{$oid}; + my $operating_state = $result2->{$oid_jnxOperatingState . "." . $instance}; + + $self->{components_operating}++; + $self->{output}->output_add(long_msg => sprintf("Operating '%s' state is %s", + $operating_descr, ${$operating_states{$operating_state}}[0])); + if (${$operating_states{$operating_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$operating_states{$operating_state}}[1], + short_msg => sprintf("Operating '%s' state is %s", + $operating_descr, ${$operating_states{$operating_state}}[0])); + } + } +} + +1; + +__END__ + +=head1 MODE + +Check Hardware (mib-jnx-chassis) (frus, operating). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/network/juniper/common/mode/memoryforwarding.pm b/network/juniper/common/mode/memoryforwarding.pm new file mode 100644 index 000000000..eb0c0c159 --- /dev/null +++ b/network/juniper/common/mode/memoryforwarding.pm @@ -0,0 +1,126 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::memoryforwarding; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxJsSPUMonitoringSPUIndex = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.3'; + my $oid_jnxJsSPUMonitoringMemoryUsage = '.1.3.6.1.4.1.2636.3.39.1.12.1.1.1.5'; + + my $result = $self->{snmp}->get_table(oid => $oid_jnxJsSPUMonitoringSPUIndex, nothing_quit => 1); + $self->{snmp}->load(oids => [$oid_jnxJsSPUMonitoringMemoryUsage], + instances => [keys %$result], + instance_regexp => '\.(\d+)$'); + my $result2 = $self->{snmp}->get_leef(nothing_quit => 1); + + foreach my $oid (keys %$result) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $mem_usage = $result2->{$oid_jnxJsSPUMonitoringMemoryUsage . '.' . $instance}; + + my $exit_code = $self->{perfdata}->threshold_check(value => $mem_usage, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Memory '%d' usage is: %s%%", $instance, $mem_usage)); + $self->{output}->perfdata_add(label => 'mem_' . $instance, unit => '%', + value => $mem_usage, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Memory Usage of packet forwarding engine. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/common/mode/memoryrouting.pm b/network/juniper/common/mode/memoryrouting.pm new file mode 100644 index 000000000..4dd0564c9 --- /dev/null +++ b/network/juniper/common/mode/memoryrouting.pm @@ -0,0 +1,151 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::common::mode::memoryrouting; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_jnxOperatingDescr = '.1.3.6.1.4.1.2636.3.1.13.1.5'; + my $oid_jnxOperatingBuffer = '.1.3.6.1.4.1.2636.3.1.13.1.11'; + my $oid_jnxOperatingMemory = '.1.3.6.1.4.1.2636.3.1.13.1.15'; # MB + + my $result = $self->{snmp}->get_table(oid => $oid_jnxOperatingDescr, nothing_quit => 1); + my $routing_engine_find = 0; + my $oid_routing_engine; + foreach my $oid (keys %$result) { + if ($result->{$oid} =~ /routing/i) { + $routing_engine_find = 1; + $oid_routing_engine = $oid; + last; + } + } + + if ($routing_engine_find == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot find operating with 'routing' in description."); + $self->{output}->option_exit(); + } + + $self->{snmp}->load(oids => [$oid_jnxOperatingBuffer, $oid_jnxOperatingMemory], + instances => [$oid_routing_engine], + instance_regexp => "^" . $oid_jnxOperatingDescr . '\.(.+)'); + my $result2 = $self->{snmp}->get_leef(); + + $oid_routing_engine =~ /^$oid_jnxOperatingDescr\.(.+)/; + my $instance = $1; + my $total_size = $result2->{$oid_jnxOperatingMemory . '.' . $instance} * 1024 * 1024; + my $prct_used = $result2->{$oid_jnxOperatingBuffer . '.' . $instance}; + my $prct_free = 100 - $prct_used; + my $memory_used = $total_size * $prct_used / 100; + my $memory_free = $total_size - $memory_used; + + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + + $self->{output}->perfdata_add(label => "used", + value => $memory_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Memory Usage of routing engine. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/network/juniper/srx/plugin.pm b/network/juniper/srx/plugin.pm new file mode 100644 index 000000000..c4616f45f --- /dev/null +++ b/network/juniper/srx/plugin.pm @@ -0,0 +1,74 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package network::juniper::srx::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'network::juniper::common::mode::hardware', + 'cpu-routing' => 'network::juniper::common::mode::cpurouting', # routing engine + 'cpu-forwarding' => 'network::juniper::common::mode::cpuforwarding', # packet forwarding engine + 'memory-routing' => 'network::juniper::common::mode::memoryrouting', # routing engine + 'memory-forwarding' => 'network::juniper::common::mode::memoryforwarding', # packet forwarding engine + 'cp-sessions' => 'network::juniper::common::mode::cpsessions', # CP = 'central point' + 'flow-sessions' => 'network::juniper::common::mode::flowsessions', + 'traffic' => 'snmp_standard::mode::traffic', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'storage' => 'snmp_standard::mode::storage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Juniper SRX in SNMP. + +=cut diff --git a/os/linux/mode/memory.pm b/os/linux/mode/memory.pm new file mode 100644 index 000000000..387a6ff3b --- /dev/null +++ b/os/linux/mode/memory.pm @@ -0,0 +1,176 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::linux::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + $self->{cached_memory_id} = undef; + $self->{buffer_memory_id} = undef; + $self->{physical_memory_id} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_hrStorageDescr = '.1.3.6.1.2.1.25.2.3.1.3'; + + my $result = $self->{snmp}->get_table(oid => $oid_hrStorageDescr); + + foreach my $key (keys %$result) { + next if ($key !~ /\.([0-9]+)$/); + my $oid = $1; + if ($result->{$key} =~ /^Physical memory$/i) { + $self->{physical_memory_id} = $oid; + } + if ($result->{$key} =~ /^Cached memory$/i) { + $self->{cached_memory_id} = $oid; + } + if ($result->{$key} =~ /^Memory buffers$/i) { + $self->{buffer_memory_id} = $oid; + } + } + + if (!defined($self->{physical_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find physical memory informations."); + $self->{output}->option_exit(); + } + if (!defined($self->{cached_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find cached memory informations."); + $self->{output}->option_exit(); + } + if (!defined($self->{buffer_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find buffer memory informations."); + $self->{output}->option_exit(); + } + + my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; + my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; + my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; + + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], + instances => [$self->{physical_memory_id}, $self->{cached_memory_id}, $self->{buffer_memory_id}]); + $result = $self->{snmp}->get_leef(); + + my $cached_used = $result->{$oid_hrStorageUsed . "." . $self->{cached_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{cached_memory_id}}; + my $buffer_used = $result->{$oid_hrStorageUsed . "." . $self->{buffer_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{buffer_memory_id}}; + my $physical_used = $result->{$oid_hrStorageUsed . "." . $self->{physical_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{physical_memory_id}}; + my $nobuf_used = $physical_used - $buffer_used - $cached_used; + + my $total_size = $result->{$oid_hrStorageSize . "." . $self->{physical_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{physical_memory_id}}; + + my $prct_used = $nobuf_used * 100 / $total_size; + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($nobuf_value, $nobuf_unit) = $self->{perfdata}->change_bytes(value => $nobuf_used); + my ($buffer_value, $buffer_unit) = $self->{perfdata}->change_bytes(value => $buffer_used); + my ($cached_value, $cached_unit) = $self->{perfdata}->change_bytes(value => $cached_used); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Ram used (-buffers/cache) %s (%.2f%%), Buffer: %s, Cached: %s", + $nobuf_value . " " . $nobuf_unit, $prct_used, + $buffer_value . " " . $buffer_unit, + $cached_value . " " . $cached_unit)); + + $self->{output}->perfdata_add(label => "cached", + value => $cached_used, + min => 0); + $self->{output}->perfdata_add(label => "buffer", + value => $buffer_used, + min => 0); + $self->{output}->perfdata_add(label => "used", + value => $nobuf_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Linux physical memory. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/os/linux/mode/swap.pm b/os/linux/mode/swap.pm new file mode 100644 index 000000000..99bf206a3 --- /dev/null +++ b/os/linux/mode/swap.pm @@ -0,0 +1,150 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::linux::mode::swap; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + $self->{swap_memory_id} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_hrStorageDescr = '.1.3.6.1.2.1.25.2.3.1.3'; + + my $result = $self->{snmp}->get_table(oid => $oid_hrStorageDescr); + + foreach my $key (keys %$result) { + next if ($key !~ /\.([0-9]+)$/); + my $oid = $1; + if ($result->{$key} =~ /^Swap space$/i) { + $self->{swap_memory_id} = $oid; + } + } + + if (!defined($self->{swap_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find swap space informations."); + $self->{output}->option_exit(); + } + + my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; + my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; + my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; + + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], + instances => [$self->{swap_memory_id}]); + $result = $self->{snmp}->get_leef(); + + my $swap_used = $result->{$oid_hrStorageUsed . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}}; + my $total_size = $result->{$oid_hrStorageSize . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}}; + + my $prct_used = $swap_used * 100 / $total_size; + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($swap_used_value, $swap_used_unit) = $self->{perfdata}->change_bytes(value => $swap_used); + my ($swap_free_value, $swap_free_unit) = $self->{perfdata}->change_bytes(value => ($total_size - $swap_used)); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Swap Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $swap_used_value . " " . $swap_used_unit, $prct_used, + $swap_free_value . " " . $swap_free_unit, (100 - $prct_used))); + + $self->{output}->perfdata_add(label => "used", + value => $swap_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Linux swap memory. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/os/linux/plugin.pm b/os/linux/plugin.pm new file mode 100644 index 000000000..0de4b54b0 --- /dev/null +++ b/os/linux/plugin.pm @@ -0,0 +1,75 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::linux::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'cpu' => 'snmp_standard::mode::cpu', + 'diskio' => 'snmp_standard::mode::diskio', + 'load' => 'snmp_standard::mode::loadaverage', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'memory' => 'os::linux::mode::memory', + 'packet-errors' => 'snmp_standard::mode::packeterrors', + 'processcount' => 'snmp_standard::mode::processcount', + 'storage' => 'snmp_standard::mode::storage', + 'swap' => 'os::linux::mode::swap', + 'traffic' => 'snmp_standard::mode::traffic', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Linux operating systems in SNMP. + +=cut diff --git a/os/windows/mode/memory.pm b/os/windows/mode/memory.pm new file mode 100644 index 000000000..40334d2a1 --- /dev/null +++ b/os/windows/mode/memory.pm @@ -0,0 +1,150 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::windows::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + $self->{physical_memory_id} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_hrStorageDescr = '.1.3.6.1.2.1.25.2.3.1.3'; + + my $result = $self->{snmp}->get_table(oid => $oid_hrStorageDescr); + + foreach my $key (keys %$result) { + next if ($key !~ /\.([0-9]+)$/); + my $oid = $1; + if ($result->{$key} =~ /^Physical memory$/i) { + $self->{physical_memory_id} = $oid; + } + } + + if (!defined($self->{physical_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find physical memory informations."); + $self->{output}->option_exit(); + } + + my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; + my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; + my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; + + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], + instances => [$self->{physical_memory_id}]); + $result = $self->{snmp}->get_leef(); + + my $physical_used = $result->{$oid_hrStorageUsed . "." . $self->{physical_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{physical_memory_id}}; + my $total_size = $result->{$oid_hrStorageSize . "." . $self->{physical_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{physical_memory_id}}; + + my $prct_used = $physical_used * 100 / $total_size; + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($physical_used_value, $physical_used_unit) = $self->{perfdata}->change_bytes(value => $physical_used); + my ($physical_free_value, $physical_free_unit) = $self->{perfdata}->change_bytes(value => $total_size - $physical_used); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("RAM Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $physical_used_value . " " . $physical_used_unit, $prct_used, + $physical_free_value . " " . $physical_free_unit, 100 - $prct_used)); + + $self->{output}->perfdata_add(label => "used", + value => $physical_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Windows physical memory. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/os/windows/mode/service.pm b/os/windows/mode/service.pm new file mode 100644 index 000000000..06f2bf91d --- /dev/null +++ b/os/windows/mode/service.pm @@ -0,0 +1,197 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::windows::mode::service; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_installed_state = ( + 1 => 'uninstalled', + 2 => 'install-pending', + 3 => 'uninstall-pending', + 4 => 'installed' +); +my %map_operating_state = ( + 1 => 'active', + 2 => 'continue-pending', + 3 => 'pause-pending', + 4 => 'paused' +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "service:s@" => { name => 'service', }, + "regexp" => { name => 'use_regexp', }, + "state:s" => { name => 'state', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{service})) { + $self->{output}->add_option_msg(short_msg => "Need to specify at least one '--service' option."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_svSvcEntry = '.1.3.6.1.4.1.77.1.2.3.1'; + my $oid_svSvcName = '.1.3.6.1.4.1.77.1.2.3.1.1'; + my $oid_svSvcInstalledState = '.1.3.6.1.4.1.77.1.2.3.1.2'; + my $oid_svSvcOperatingState = '.1.3.6.1.4.1.77.1.2.3.1.3'; + my $result = $self->{snmp}->get_table(oid => $oid_svSvcEntry); + + my %services_match = (); + $self->{output}->output_add(severity => 'OK', + short_msg => 'All service states is ok'); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($oid !~ /^$oid_svSvcName/); + $oid =~ /^$oid_svSvcName\.([0-9\.]+)$/; + my $instance = $1; + + my $svc_name = $self->{output}->to_utf8($result->{$oid}); + my $svc_installed_state = $result->{$oid_svSvcInstalledState . '.' . $instance}; + my $svc_operating_state = $result->{$oid_svSvcOperatingState . '.' . $instance}; + + for (my $i = 0; $i < scalar(@{$self->{option_results}->{service}}); $i++) { + my $filter = ${$self->{option_results}->{service}}[$i]; + if (defined($self->{option_results}->{use_regexp}) && $svc_name =~ /$filter/) { + $services_match{$i}{$svc_name}{operating_state} = $svc_operating_state; + $services_match{$i}{$svc_name}{installed_state} = $svc_installed_state; + } elsif ($svc_name eq $filter) { + $services_match{$i}{$svc_name}{operating_state} = $svc_operating_state; + $services_match{$i}{$svc_name}{installed_state} = $svc_installed_state; + } + } + } + + for (my $i = 0; $i < scalar(@{$self->{option_results}->{service}}); $i++) { + my $numbers = 0; + my %svc_name_state_wrong = (); + foreach my $svc_name (keys %{$services_match{$i}}) { + my $operating_state = $services_match{$i}{$svc_name}{operating_state}; + my $installed_state = $services_match{$i}{$svc_name}{installed_state}; + $self->{output}->output_add(long_msg => sprintf("Service '%s' match (pattern: '%s') [operating state = %s, installed state = %s]", + $svc_name, ${$self->{option_results}->{service}}[$i], + $map_operating_state{$operating_state}, $map_installed_state{$installed_state})); + if (defined($self->{option_results}->{state}) && $map_operating_state{$operating_state} !~ /$self->{option_results}->{state}/) { + delete $services_match{$i}{$svc_name}; + $svc_name_state_wrong{$svc_name} = $operating_state; + next; + } + $numbers++; + } + + my $exit = $self->{perfdata}->threshold_check(value => $numbers, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(long_msg => sprintf("Service pattern '%s': service list %s", + ${$self->{option_results}->{service}}[$i], + join(', ', keys %{$services_match{$i}}))); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + if (scalar(keys %svc_name_state_wrong) > 0) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Service pattern '%s' problem: %s [following services match but has the wrong state]", + ${$self->{option_results}->{service}}[$i], join(', ', keys %svc_name_state_wrong))); + } else { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Service problem '%s'", ${$self->{option_results}->{service}}[$i])); + } + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Windows Services in SNMP + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--service> + +Services to check. (can set multiple times) + +=item B<--regexp> + +Allows to use regexp to filter services. + +=item B<--state> + +Service state. (Regexp allowed) + +=back + +=cut diff --git a/os/windows/mode/swap.pm b/os/windows/mode/swap.pm new file mode 100644 index 000000000..49a3e6ea1 --- /dev/null +++ b/os/windows/mode/swap.pm @@ -0,0 +1,150 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::windows::mode::swap; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + $self->{swap_memory_id} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_hrStorageDescr = '.1.3.6.1.2.1.25.2.3.1.3'; + + my $result = $self->{snmp}->get_table(oid => $oid_hrStorageDescr); + + foreach my $key (keys %$result) { + next if ($key !~ /\.([0-9]+)$/); + my $oid = $1; + if ($result->{$key} =~ /^Virtual memory$/i) { + $self->{swap_memory_id} = $oid; + } + } + + if (!defined($self->{swap_memory_id})) { + $self->{output}->add_option_msg(short_msg => "Cannot find physical memory informations."); + $self->{output}->option_exit(); + } + + my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; + my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; + my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; + + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], + instances => [$self->{swap_memory_id}]); + $result = $self->{snmp}->get_leef(); + + my $swap_used = $result->{$oid_hrStorageUsed . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}}; + my $total_size = $result->{$oid_hrStorageSize . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}}; + + my $prct_used = $swap_used * 100 / $total_size; + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($swap_used_value, $swap_used_unit) = $self->{perfdata}->change_bytes(value => $swap_used); + my ($swap_free_value, $swap_free_unit) = $self->{perfdata}->change_bytes(value => $total_size - $swap_used); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Swap Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $swap_used_value . " " . $swap_used_unit, $prct_used, + $swap_free_value . " " . $swap_free_unit, 100 - $prct_used)); + + $self->{output}->perfdata_add(label => "used", + value => $swap_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Windows swap memory. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/os/windows/plugin.pm b/os/windows/plugin.pm new file mode 100644 index 000000000..50b71cf20 --- /dev/null +++ b/os/windows/plugin.pm @@ -0,0 +1,74 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package os::windows::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'cpu' => 'snmp_standard::mode::cpu', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'memory' => 'os::windows::mode::memory', + 'packet-errors' => 'snmp_standard::mode::packeterrors', + 'processcount' => 'snmp_standard::mode::processcount', + 'service' => 'os::windows::mode::service', + 'storage' => 'snmp_standard::mode::storage', + 'swap' => 'os::windows::mode::swap', + 'traffic' => 'snmp_standard::mode::traffic', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Windows operating systems in SNMP. + +=cut diff --git a/snmp_standard/mode/cpu.pm b/snmp_standard/mode/cpu.pm new file mode 100644 index 000000000..0a6543236 --- /dev/null +++ b/snmp_standard/mode/cpu.pm @@ -0,0 +1,130 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_cputable = '.1.3.6.1.2.1.25.3.3.1.2'; + my $result = $self->{snmp}->get_table(oid => $oid_cputable); + + my $cpu = 0; + my $i = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + $key =~ /\.([0-9]+)$/; + my $cpu_num = $1; + + $cpu += $result->{$key}; + $i++; + + $self->{output}->output_add(long_msg => sprintf("CPU $i Usage is %.2f%%", $result->{$key})); + $self->{output}->perfdata_add(label => 'cpu' . $cpu_num, + value => sprintf("%.2f", $result->{$key}), + min => 0, max => 100); + } + + my $avg_cpu = $cpu / $i; + my $exit_code = $self->{perfdata}->threshold_check(value => $avg_cpu, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("CPU(s) average usage is: %.2f%%", $avg_cpu)); + $self->{output}->perfdata_add(label => 'total_cpu_avg', + value => sprintf("%.2f", $avg_cpu), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check system CPUs. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/snmp_standard/mode/diskio.pm b/snmp_standard/mode/diskio.pm new file mode 100644 index 000000000..2dcacb653 --- /dev/null +++ b/snmp_standard/mode/diskio.pm @@ -0,0 +1,351 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::diskio; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-read:s" => { name => 'warning_read' }, + "critical-read:s" => { name => 'critical_read' }, + "warning-write:s" => { name => 'warning_write' }, + "critical-write:s" => { name => 'critical_write' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + "name" => { name => 'use_name' }, + "device:s" => { name => 'device' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "show-cache" => { name => 'show_cache' }, + }); + + $self->{device_id_selected} = []; + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning-read', value => $self->{option_results}->{warning_read})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'read' threshold '" . $self->{option_results}->{warning_read} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-read', value => $self->{option_results}->{critical_read})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'read' threshold '" . $self->{option_results}->{critical_read} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning-write', value => $self->{option_results}->{warning_write})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'write' threshold '" . $self->{option_results}->{warning_write} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-write', value => $self->{option_results}->{critical_write})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'write' threshold '" . $self->{option_results}->{critical_write} . "'."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{hostname} = $self->{snmp}->get_hostname(); + + $self->manage_selection(); + + my $oid_diskIODevice = '.1.3.6.1.4.1.2021.13.15.1.1.2'; + my $oid_diskIONReadX = '.1.3.6.1.4.1.2021.13.15.1.1.12'; # in B + my $oid_diskIONWrittenX = '.1.3.6.1.4.1.2021.13.15.1.1.13'; # in B + + my $new_datas = {}; + $self->{statefile_value}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{device}) ? md5_hex($self->{option_results}->{device}) : md5_hex('all'))); + + $self->{snmp}->load(oids => [$oid_diskIONReadX, $oid_diskIONWrittenX], + instances => $self->{device_id_selected}); + my $result = $self->{snmp}->get_leef(); + $new_datas->{last_timestamp} = time(); + my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + if (!defined($self->{option_results}->{device}) || defined($self->{option_results}->{use_regexp})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All devices are ok.'); + } + + foreach (sort @{$self->{device_id_selected}}) { + my $device_name = $self->{statefile_cache}->get(name => "device_" . $_); + + if ($result->{$oid_diskIONReadX . "." . $_} == 0 && $result->{$oid_diskIONWrittenX . "." . $_} == 0 && + (!defined($self->{option_results}->{device}) || defined($self->{option_results}->{use_regexp}))) { + $self->{output}->add_option_msg(long_msg => "Skip device '" . $device_name . "' with no values."); + next; + } + + $new_datas->{'readio_' . $_} = $result->{$oid_diskIONReadX . "." . $_}; + $new_datas->{'writeio_' . $_} = $result->{$oid_diskIONWrittenX . "." . $_}; + + my $old_readio = $self->{statefile_value}->get(name => 'readio_' . $_); + my $old_writeio = $self->{statefile_value}->get(name => 'writeio_' . $_); + if (!defined($old_timestamp) || !defined($old_readio) || !defined($old_writeio)) { + next; + } + if ($new_datas->{'readio_' . $_} < $old_readio) { + # We set 0. Has reboot. + $old_readio = 0; + } + if ($new_datas->{'writeio_' . $_} < $old_writeio) { + # We set 0. Has reboot. + $old_writeio = 0; + } + + my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; + if ($time_delta <= 0) { + # At least one second. two fast calls ;) + $time_delta = 1; + } + + my $readio_absolute_per_sec = ($new_datas->{'readio_' . $_} - $old_readio) / $time_delta; + my $writeio_absolute_per_sec = ($new_datas->{'writeio_' . $_} - $old_writeio) / $time_delta; + + ########### + # Manage Output + ########### + my $exit1 = $self->{perfdata}->threshold_check(value => $readio_absolute_per_sec, threshold => [ { label => 'critical-read', 'exit_litteral' => 'critical' }, { label => 'warning-read', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $writeio_absolute_per_sec, threshold => [ { label => 'critical-write', 'exit_litteral' => 'critical' }, { label => 'warning-write', exit_litteral => 'warning' } ]); + + my ($readio_value, $readio_unit) = $self->{perfdata}->change_bytes(value => $readio_absolute_per_sec); + my ($writeio_value, $writeio_unit) = $self->{perfdata}->change_bytes(value => $writeio_absolute_per_sec); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + $self->{output}->output_add(long_msg => sprintf("Device '%s' Read I/O : %s/s, Write I/O : %s/s", $device_name, + $readio_value . $readio_unit, + $writeio_value . $writeio_unit)); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{device}) && !defined($self->{option_results}->{use_regexp}))) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Device '%s' Read I/O : %s/s, Write I/O : %s/s", $device_name, + $readio_value . $readio_unit, + $writeio_value . $writeio_unit)); + } + + my $extra_label = ''; + $extra_label = '_' . $device_name if (!defined($self->{option_results}->{device}) || defined($self->{option_results}->{use_regexp})); + $self->{output}->perfdata_add(label => 'readio' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $readio_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-read'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-read'), + min => 0); + $self->{output}->perfdata_add(label => 'writeio' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $writeio_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-write'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-write'), + min => 0); + } + + $self->{statefile_value}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub reload_cache { + my ($self) = @_; + my $datas = {}; + + my $oid_diskIODevice = '.1.3.6.1.4.1.2021.13.15.1.1.2'; + my $result = $self->{snmp}->get_table(oid => $oid_diskIODevice); + my $last_num = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{"device_" . $1} = $result->{$key}; + $last_num = $1; + } + + if (scalar(keys %$datas) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + $datas->{total_device} = $last_num; + $self->{statefile_cache}->write(data => $datas); +} + +sub manage_selection { + my ($self, %options) = @_; + + # init cache file + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{mode}); + if (defined($self->{option_results}->{show_cache})) { + $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); + $self->{output}->option_exit(); + } + + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + if ($has_cache_file == 0 || + (defined($timestamp_cache) && (time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(); + $self->{statefile_cache}->read(); + } + + my $total_device = $self->{statefile_cache}->get(name => 'total_device'); + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{device})) { + # get by ID + push @{$self->{device_id_selected}}, $self->{option_results}->{device}; + my $name = $self->{statefile_cache}->get(name => "device_" . $self->{option_results}->{device}); + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No device for id '" . $self->{option_results}->{device} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_device; $i++) { + my $filter_name = $self->{statefile_cache}->get(name => "device_" . $i); + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{device})) { + push @{$self->{device_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{device}/i) { + push @{$self->{device_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{device}/) { + push @{$self->{device_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{device}) { + push @{$self->{device_id_selected}}, $i; + } + } + + if (scalar(@{$self->{device_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No device found for name '" . $self->{option_results}->{device} . "' (maybe you should reload cache file)."); + $self->{output}->option_exit(); + } + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'deviceid']); +} + +sub disco_show { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + $self->manage_selection(); + foreach (sort @{$self->{device_id_selected}}) { + $self->{output}->add_disco_entry(name => $self->{statefile_cache}->get(name => "device_" . $_), + deviceid => $_); + } +} + +1; + +__END__ + +=head1 MODE + +Check read/write I/O disks. + +=over 8 + +=item B<--warning-read> + +Threshold warning in bytes for 'read' io disks. + +=item B<--critical-read> + +Threshold critical in bytes for 'read' io disks. + +=item B<--warning-write> + +Threshold warning in bytes for 'write' io disks. + +=item B<--critical-write> + +Threshold critical in bytes for 'write' io disks. + +=item B<--device> + +Set the device (number expected) ex: 1, 2,... (empty means 'check all devices'). + +=item B<--name> + +Allows to use device name with option --device instead of devoce oid index. + +=item B<--regexp> + +Allows to use regexp to filter devices (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/snmp_standard/mode/dynamiccommand.pm b/snmp_standard/mode/dynamiccommand.pm new file mode 100644 index 000000000..7529eade0 --- /dev/null +++ b/snmp_standard/mode/dynamiccommand.pm @@ -0,0 +1,205 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::dynamiccommand; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $oid_nsExtendArgs = '.1.3.6.1.4.1.8072.1.3.2.2.1.3'; +my $oid_nsExtendStatus = '.1.3.6.1.4.1.8072.1.3.2.2.1.21'; # 4 = CreateAndGo +my $oid_nsExtendCommand = '.1.3.6.1.4.1.8072.1.3.2.2.1.2'; +my $oid_nsExtendStorage = '.1.3.6.1.4.1.8072.1.3.2.2.1.20'; # 2 = Volatile (what we want) +my $oid_nsExtendExecType = '.1.3.6.1.4.1.8072.1.3.2.2.1.6'; # 1 = exec, 2 = sub shell + +my $oid_nsExtendOutput1Line = '.1.3.6.1.4.1.8072.1.3.2.3.1.1'; +my $oid_nsExtendOutNumLines = '.1.3.6.1.4.1.8072.1.3.2.3.1.3'; +my $oid_nsExtendOutputFull = '.1.3.6.1.4.1.8072.1.3.2.3.1.2'; +my $oid_nsExtendResult = '.1.3.6.1.4.1.8072.1.3.2.3.1.4'; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "label:s" => { name => 'label' }, + "command:s" => { name => 'command' }, + "args:s" => { name => 'args' }, + "shell" => { name => 'shell' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{label})) { + $self->{output}->add_option_msg(short_msg => "Need to specify an label."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{command})) { + $self->{output}->add_option_msg(short_msg => "Need to specify a command."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{args})) { + $self->{output}->add_option_msg(short_msg => "Need to specify arguments (can be empty)."); + $self->{output}->option_exit(); + } +} + +sub get_instance { + my ($self, %options) = @_; + + # nsExtendStatus.LengthStr.CharacterInDecimal + my $instance = length($self->{option_results}->{label}); + foreach (split //, $self->{option_results}->{label}) { + $instance .= '.' . ord($_); + } + + return $instance; +} + +sub create_command { + my ($self, %options) = @_; + my $oids2set = {}; + + $oids2set->{$oid_nsExtendStatus . '.' . $options{instance}} = 4; + $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = $self->{option_results}->{args}; + $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = $self->{option_results}->{command}; + $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = defined($self->{option_results}->{shell}) ? 2 : 1; + $self->{snmp}->set(oids => $oids2set); +} + +sub update_command { + my ($self, %options) = @_; + my $shell = defined($self->{option_results}->{shell}) ? 2 : 1; + + # Cannot change values + if ($options{result}->{$oid_nsExtendStorage . '.' . $options{instance}} != 2) { + $self->{output}->add_option_msg(short_msg => "Command label '" . $self->{option_results}->{label} . "' is not volatile. So we can't manage it."); + $self->{output}->option_exit(); + } + + my $oids2set = {}; + if (!defined($options{result}->{$oid_nsExtendCommand . '.' . $options{instance}}) || + $options{result}->{$oid_nsExtendCommand . '.' . $options{instance}} ne $self->{option_results}->{command}) { + $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = $self->{option_results}->{command}; + } + if (!defined($options{result}->{$oid_nsExtendArgs . '.' . $options{instance}}) || + $options{result}->{$oid_nsExtendArgs . '.' . $options{instance}} ne $self->{option_results}->{args}) { + $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = $self->{option_results}->{args}; + } + if (!defined($options{result}->{$oid_nsExtendExecType . '.' . $options{instance}}) || + $options{result}->{$oid_nsExtendExecType . '.' . $options{instance}} ne $shell) { + $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = $shell; + } + + if (scalar(keys %$oids2set) > 0) { + $self->{snmp}->set(oids => $oids2set); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + # snmpset -On -c test -v 2c localhost \ + # '.1.3.6.1.4.1.8072.1.3.2.2.1.21.4.104.102.101.102' = 4 \ + # '.1.3.6.1.4.1.8072.1.3.2.2.1.2.4.104.102.101.102' = /bin/echo \ + # '.1.3.6.1.4.1.8072.1.3.2.2.1.3.4.104.102.101.102' = 'myplop' + # + + my $instance = $self->get_instance(); + $self->{snmp}->load(oids => [$oid_nsExtendArgs, $oid_nsExtendStatus, + $oid_nsExtendCommand, $oid_nsExtendStorage, $oid_nsExtendExecType], + instances => [$instance], + instance_regexp => '^(.+)$'); + my $result = $self->{snmp}->get_leef(); + + if (!defined($result->{$oid_nsExtendCommand . '.' . $instance})) { + $self->create_command(instance => $instance); + } else { + $self->update_command(result => $result, instance => $instance); + } + + $result = $self->{snmp}->get_leef(oids => [$oid_nsExtendOutputFull . '.' . $instance, + $oid_nsExtendResult . '.' . $instance], nothing_quit => 1); + + $self->{output}->output_add(severity => $self->{output}->get_litteral_status(status => $result->{$oid_nsExtendResult . '.' . $instance}), + short_msg => $result->{$oid_nsExtendOutputFull . '.' . $instance}); + $self->{output}->display(force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Execute command through SNMP. +Some prerequisites: +- 'net-snmp' and 'NET-SNMP-EXTEND-MIB' support ; +- a write account. + +=over 8 + +=item B<--label> + +Label which identify the command + +=item B<--command> + +Command executable. + +=item B<--args> + +Command arguments. + +=item B<--shell> + +Use a sub-shell to execute the command. + +=back + +=cut diff --git a/snmp_standard/mode/listinterfaces.pm b/snmp_standard/mode/listinterfaces.pm new file mode 100644 index 000000000..7750b2180 --- /dev/null +++ b/snmp_standard/mode/listinterfaces.pm @@ -0,0 +1,303 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::listinterfaces; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my @operstatus = ("up", "down", "testing", "unknown", "dormant", "notPresent", "lowerLayerDown"); +my %oids_iftable = ( + 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', + 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', + 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1' +); + +my $oid_adminstatus = '.1.3.6.1.2.1.2.2.1.7'; +my $oid_operstatus = '.1.3.6.1.2.1.2.2.1.8'; +my $oid_speed32 = '.1.3.6.1.2.1.2.2.1.5'; # in b/s +my $oid_speed64 = '.1.3.6.1.2.1.31.1.1.1.15'; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "name" => { name => 'use_name' }, + "interface:s" => { name => 'interface' }, + "speed:s" => { name => 'speed' }, + "filter-status:s" => { name => 'filter_status' }, + "use-adminstatus" => { name => 'use_adminstatus' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'ifname'}, + "oid-display:s" => { name => 'oid_display', default => 'ifname'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + }); + + $self->{interface_id_selected} = []; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); + if ($self->{option_results}->{oid_filter} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); + if ($self->{option_results}->{oid_display} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + my $result = $self->get_additional_information(); + + my $interfaces_display = ''; + my $interfaces_display_append = ''; + foreach (sort @{$self->{interface_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + + my $interface_speed = (defined($result->{$oid_speed64 . "." . $_}) && $result->{$oid_speed64 . "." . $_} ne '' ? ($result->{$oid_speed64 . "." . $_}) : (int($result->{$oid_speed32 . "." . $_} / 1000 / 1000))); + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + $interface_speed = $self->{option_results}->{speed}; + } + if (defined($self->{option_results}->{filter_status}) && $operstatus[$result->{$oid_operstatus . "." . $_} - 1] !~ /$self->{option_results}->{filter_status}/i) { + next; + } + if (defined($self->{option_results}->{use_adminstatus}) && $operstatus[$result->{$oid_adminstatus . "." . $_} - 1] ne 'up') { + next; + } + + $interfaces_display .= $interfaces_display_append . "name = $display_value [speed = $interface_speed, status = " . $operstatus[$result->{$oid_operstatus . "." . $_} - 1] . ", id = $_]"; + $interfaces_display_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List interfaces: ' . $interfaces_display); + $self->{output}->display(nolabel => 1); + $self->{output}->exit(); +} + +sub get_additional_information { + my ($self, %options) = @_; + + my $oids = [$oid_adminstatus, $oid_operstatus, $oid_speed32]; + if (!$self->{snmp}->is_snmpv1()) { + push @$oids, $oid_speed64; + } + + $self->{snmp}->load(oids => $oids, instances => $self->{interface_id_selected}); + return $self->{snmp}->get_leef(); +} + +sub get_display_value { + my ($self, %options) = @_; + my $value = $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $options{id}}; + + if (defined($self->{option_results}->{display_transform_src})) { + $self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst})); + eval "\$value =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}"; + } + return $value; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{datas} = {}; + $self->{datas}->{oid_filter} = $self->{option_results}->{oid_filter}; + $self->{datas}->{oid_display} = $self->{option_results}->{oid_display}; + my $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_filter}}); + my $total_interface = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $self->{datas}->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + $total_interface = $1; + } + + if (scalar(keys %{$self->{datas}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't get interfaces..."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { + $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_display}}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + } + } + + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{interface})) { + # get by ID + push @{$self->{interface_id_selected}}, $self->{option_results}->{interface}; + my $name = $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $self->{option_results}->{interface}}; + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No interface found for id '" . $self->{option_results}->{interface} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_interface; $i++) { + my $filter_name = $self->{datas}->{$self->{option_results}->{oid_filter} . "_" . $i}; + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{interface})) { + push @{$self->{interface_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/i) { + push @{$self->{interface_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/) { + push @{$self->{interface_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{interface}) { + push @{$self->{interface_id_selected}}, $i; + } + } + + if (scalar(@{$self->{interface_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{interface} . "'."); + $self->{output}->option_exit(); + } + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'total', 'status', 'interfaceid']); +} + +sub disco_show { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + my $result = $self->get_additional_information(); + foreach (sort @{$self->{interface_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + + my $interface_speed = (defined($result->{$oid_speed64 . "." . $_}) && $result->{$oid_speed64 . "." . $_} ne '' ? ($result->{$oid_speed64 . "." . $_}) : (int($result->{$oid_speed32 . "." . $_} / 1000 / 1000))); + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + $interface_speed = $self->{option_results}->{speed}; + } + if (defined($self->{option_results}->{filter_status}) && $operstatus[$result->{$oid_operstatus . "." . $_} - 1] !~ /$self->{option_results}->{filter_status}/i) { + next; + } + if (defined($self->{option_results}->{use_adminstatus}) && $operstatus[$result->{$oid_adminstatus . "." . $_} - 1] ne 'up') { + next; + } + + $self->{output}->add_disco_entry(name => $display_value, + total => $interface_speed, + status => $result->{$oid_operstatus . "." . $_}, + interfaceid => $_); + } +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--interface> + +Set the interface (number expected) ex: 1, 2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index. + +=item B<--regexp> + +Allows to use regexp to filter interfaces (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--speed> + +Set interface speed (in Mb). + +=item B<--filter-status> + +Display interfaces matching the filter (example: 'up'). + +=item B<--use-adminstatus> + +Display interfaces with AdminStatus 'up'. + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=back + +=cut diff --git a/snmp_standard/mode/liststorages.pm b/snmp_standard/mode/liststorages.pm new file mode 100644 index 000000000..4408c0cfe --- /dev/null +++ b/snmp_standard/mode/liststorages.pm @@ -0,0 +1,264 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::liststorages; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %oids_hrStorageTable = ( + 'hrstoragedescr' => '.1.3.6.1.2.1.25.2.3.1.3', + 'hrfsmountpoint' => '.1.3.6.1.2.1.25.3.8.1.2', + 'hrstoragetype' => '.1.3.6.1.2.1.25.2.3.1.2', +); + +my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; +my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; +my $oid_hrStorageType = '.1.3.6.1.2.1.25.2.3.1.2'; +my $oid_hrStorageFixedDisk = '.1.3.6.1.2.1.25.2.1.4'; +my $oid_hrStorageNetworkDisk = '.1.3.6.1.2.1.25.2.1.10'; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "storage:s" => { name => 'storage' }, + "name" => { name => 'use_name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'hrStorageDescr'}, + "oid-display:s" => { name => 'oid_display', default => 'hrStorageDescr'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + }); + + $self->{storage_id_selected} = []; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); + if ($self->{option_results}->{oid_filter} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); + if ($self->{option_results}->{oid_display} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + my $result = $self->get_additional_information(); + + my $storage_display = ''; + my $storage_display_append = ''; + foreach (sort @{$self->{storage_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + my $storage_type = $result->{$oid_hrStorageType . "." . $_}; + next if (!defined($storage_type) || ($storage_type ne $oid_hrStorageFixedDisk && $storage_type ne $oid_hrStorageNetworkDisk)); + + $storage_display .= $storage_display_append . "name = $display_value [size = " . $result->{$oid_hrStorageSize . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_} . "B, id = $_]"; + $storage_display_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List storage: ' . $storage_display); + $self->{output}->display(nolabel => 1); + $self->{output}->exit(); +} + +sub get_additional_information { + my ($self, %options) = @_; + + $self->{snmp}->load(oids => [$oid_hrStorageType, $oid_hrStorageAllocationUnits, $oid_hrStorageSize], instances => $self->{storage_id_selected}); + return $self->{snmp}->get_leef(); +} + +sub get_display_value { + my ($self, %options) = @_; + my $value = $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $options{id}}; + + if (defined($self->{option_results}->{display_transform_src})) { + $self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst})); + eval "\$value =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}"; + } + return $value; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{datas} = {}; + $self->{datas}->{oid_filter} = $self->{option_results}->{oid_filter}; + $self->{datas}->{oid_display} = $self->{option_results}->{oid_display}; + my $result = $self->{snmp}->get_table(oid => $oids_hrStorageTable{$self->{option_results}->{oid_filter}}); + my $total_storage = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $self->{datas}->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + $total_storage = $1; + } + + if (scalar(keys %{$self->{datas}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't get storages..."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { + $result = $self->{snmp}->get_table(oid => $oids_hrStorageTable{$self->{option_results}->{oid_display}}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + } + } + + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{storage})) { + # get by ID + push @{$self->{storage_id_selected}}, $self->{option_results}->{storage}; + my $name = $self->{datas}->{$self->{option_results}->{oid_display} . "_" . $self->{option_results}->{storage}}; + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No storage found for id '" . $self->{option_results}->{storage} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_storage; $i++) { + my $filter_name = $self->{datas}->{$self->{option_results}->{oid_filter} . "_" . $i}; + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{storage})) { + push @{$self->{storage_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{storage}/i) { + push @{$self->{storage_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{storage}/) { + push @{$self->{storage_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{storage}) { + push @{$self->{storage_id_selected}}, $i; + } + } + + if (scalar(@{$self->{storage_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No storage found for name '" . $self->{option_results}->{storage} . "'."); + $self->{output}->option_exit(); + } + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'total', 'storageid']); +} + +sub disco_show { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + my $result = $self->get_additional_information(); + foreach (sort @{$self->{storage_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + my $storage_type = $result->{$oid_hrStorageType . "." . $_}; + next if (!defined($storage_type) || ($storage_type ne $oid_hrStorageFixedDisk && $storage_type ne $oid_hrStorageNetworkDisk)); + + $self->{output}->add_disco_entry(name => $display_value, + total => $result->{$oid_hrStorageSize . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_}, + storageid => $_); + } +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--storage> + +Set the storage (number expected) ex: 1, 2,... (empty means 'check all storage'). + +=item B<--name> + +Allows to use storage name with option --storage instead of storage oid index. + +=item B<--regexp> + +Allows to use regexp to filter storage (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--oid-filter> + +Choose OID used to filter storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSRemoteMountPoint). + +=item B<--oid-display> + +Choose OID used to display storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSRemoteMountPoint). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=back + +=cut diff --git a/snmp_standard/mode/loadaverage.pm b/snmp_standard/mode/loadaverage.pm new file mode 100644 index 000000000..3fd28a90c --- /dev/null +++ b/snmp_standard/mode/loadaverage.pm @@ -0,0 +1,153 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::loadaverage; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', default => '' }, + "critical:s" => { name => 'critical', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + ($self->{warn1}, $self->{warn5}, $self->{warn15}) = split /,/, $self->{option_results}->{warning}; + ($self->{crit1}, $self->{crit5}, $self->{crit15}) = split /,/, $self->{option_results}->{critical}; + + if (($self->{perfdata}->threshold_validate(label => 'warn1', value => $self->{warn1})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (1min) threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn5', value => $self->{warn5})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (5min) threshold '" . $self->{warn5} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn15', value => $self->{warn15})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning (15min) threshold '" . $self->{warn15} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit1', value => $self->{crit1})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (1min) threshold '" . $self->{crit1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit5', value => $self->{crit5})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (5min) threshold '" . $self->{crit5} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit15', value => $self->{crit15})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical (15min) threshold '" . $self->{crit15} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_CpuLoad1m = '.1.3.6.1.4.1.2021.10.1.3.1'; + my $oid_CpuLoad5m = '.1.3.6.1.4.1.2021.10.1.3.2'; + my $oid_CpuLoad15m = '.1.3.6.1.4.1.2021.10.1.3.3'; + + my $result = $self->{snmp}->get_leef(oids => [$oid_CpuLoad1m, $oid_CpuLoad5m, $oid_CpuLoad15m]); + + my $exit1 = $self->{perfdata}->threshold_check(value => $result->{$oid_CpuLoad1m}, + threshold => [ { label => 'crit1', 'exit_litteral' => 'critical' }, { label => 'warn1', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $result->{$oid_CpuLoad5m}, + threshold => [ { label => 'crit5', 'exit_litteral' => 'critical' }, { label => 'warn5', exit_litteral => 'warning' } ]); + my $exit3 = $self->{perfdata}->threshold_check(value => $result->{$oid_CpuLoad15m}, + threshold => [ { label => 'crit15', 'exit_litteral' => 'critical' }, { label => 'warn15', exit_litteral => 'warning' } ]); + + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3 ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Load average: %s, %s, %s", $result->{$oid_CpuLoad1m}, $result->{$oid_CpuLoad5m}, $result->{$oid_CpuLoad15m})); + + $self->{output}->perfdata_add(label => 'load1', + value => $result->{$oid_CpuLoad1m}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn1'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit1'), + min => 0); + $self->{output}->perfdata_add(label => 'load5', + value => $result->{$oid_CpuLoad5m}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5'), + min => 0); + $self->{output}->perfdata_add(label => 'load15', + value => $result->{$oid_CpuLoad15m}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn15'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit15'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check system load-average. + +=over 8 + +=item B<--warning> + +Threshold warning (1min,5min,15min). + +=item B<--critical> + +Threshold critical (1min,5min,15min). + +=back + +=cut diff --git a/snmp_standard/mode/numericvalue.pm b/snmp_standard/mode/numericvalue.pm new file mode 100644 index 000000000..04c0089f7 --- /dev/null +++ b/snmp_standard/mode/numericvalue.pm @@ -0,0 +1,226 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::numericvalue; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "oid:s" => { name => 'oid' }, + "oid-type:s" => { name => 'oid_type', default => 'gauge' }, + "counter-per-seconds" => { name => 'counter_per_seconds' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "format:s" => { name => 'format', default => 'current value is %s' }, + "format-scale" => { name => 'format_scale' }, + "format-scale-unit:s" => { name => 'format_scale_unit', default => 'other'}, + "perfdata-unit:s" => { name => 'perfdata_unit', default => ''}, + "perfdata-name:s" => { name => 'perfdata_name', default => 'value'}, + "perfdata-max:s" => { name => 'perfdata_min', default => ''}, + "perfdata-max:s" => { name => 'perfdata_max', default => ''}, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{oid})) { + $self->{output}->add_option_msg(short_msg => "Need to specify an OID."); + $self->{output}->option_exit(); + } + if ($self->{option_results}->{oid_type} !~ /^gauge|counter$/i) { + $self->{output}->add_option_msg(short_msg => "Wrong --oid-type argument '" . $self->{option_results}->{oid_type} . "' ('gauge' or 'counter')."); + $self->{output}->option_exit(); + } + if ($self->{option_results}->{format_scale_unit} !~ /^other|network$/i) { + $self->{output}->add_option_msg(short_msg => "Wrong --format-scale-unit argument '" . $self->{option_results}->{format_scale_unit} . "' ('other' or 'network')."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_type} =~ /^counter$/i) { + $self->{statefile_cache}->check_options(%options); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + my $result = $self->{snmp}->get_leef(oids => [$self->{option_results}->{oid}], nothing_quit => 1); + my $value = $result->{$self->{option_results}->{oid}}; + + if ($self->{option_results}->{oid_type} =~ /^counter$/i) { + my $datas = {}; + + $self->{statefile_cache}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{mode} . '_' . md5_hex($self->{option_results}->{oid})); + my $old_timestamp = $self->{statefile_cache}->get(name => 'timestamp'); + my $old_value = $self->{statefile_cache}->get(name => 'value'); + + $datas->{timestamp} = time(); + $datas->{value} = $value; + $self->{statefile_cache}->write(data => $datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + $self->{output}->display(); + $self->{output}->exit(); + } + + $value = $value - $old_value; + if (defined($self->{option_results}->{counter_per_seconds})) { + my $delta_time = $datas->{timestamp} - $old_timestamp; + $delta_time = 1 if ($delta_time == 0); # at least 1 sec + $value = $value / $delta_time; + } + } + + my $exit = $self->{perfdata}->threshold_check(value => $value, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + if (defined($self->{option_results}->{format_scale})) { + my ($value_mod, $value_unit) = $self->{perfdata}->change_bytes(value => $value); + if ($self->{option_results}->{format_scale} =~ /^network$/i) { + ($value_mod, $value_unit) = $self->{perfdata}->change_bytes(value => $value, network => 1); + } + $self->{output}->output_add(severity => $exit, + short_msg => sprintf($self->{option_results}->{format}, $value_mod . $value_unit)); + } else { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf($self->{option_results}->{format}, $value)); + } + + $self->{output}->perfdata_add(label => $self->{option_results}->{perfdata_name}, unit => $self->{option_results}->{perfdata_unit}, + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => $self->{option_results}->{perfdata_min}, max => $self->{option_results}->{perfdata_max}); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check an SNMP numeric value: can be a Counter, Integer, Gauge, TimeTicks. +Use 'stringvalue' mode if you want to check: +- 'warning' value is 2, 4 and 5. +- 'critical' value is 1. +- 'ok' value is 10. + +=over 8 + +=item B<--oid> + +OID value to check (numeric format only). + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--oid-type> + +Type of the OID (Default: 'gauge'). +Can be 'counter' also. 'counter' will use a retention file. + +=item B<--counter-per-seconds> + +Convert counter value on a value per seconds (only with type 'counter'. + +=item B<--format> + +Output format (Default: 'current value is %s') + +=item B<--format-scale> + +Scale bytes value. We'll display value in output. + +=item B<--format-scale-type> + +Could be 'network' (value divide by 1000) or 'other' (divide by 1024) (Default: 'other') + +Output format (Default: 'current value is %s') + +=item B<--perfdata-unit> + +Perfdata unit in perfdata output (Default: '') + +=item B<--perfdata-name> + +Perfdata name in perfdata output (Default: 'value') + +=item B<--perfdata-min> + +Minimum value to add in perfdata output (Default: '') + +=item B<--perfdata-max> + +Maximum value to add in perfdata output (Default: '') + +=back + +=cut diff --git a/snmp_standard/mode/packeterrors.pm b/snmp_standard/mode/packeterrors.pm new file mode 100644 index 000000000..a19d78f90 --- /dev/null +++ b/snmp_standard/mode/packeterrors.pm @@ -0,0 +1,528 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::packeterrors; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +my @operstatus = ("up", "down", "testing", "unknown", "dormant", "notPresent", "lowerLayerDown"); +my %oids_iftable = ( + 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', + 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', + 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1' +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-in-discard:s" => { name => 'warning_in_discard' }, + "critical-in-discard:s" => { name => 'critical_in_discard' }, + "warning-out-discard:s" => { name => 'warning_out_discard' }, + "critical-out-discard:s" => { name => 'critical_out_discard' }, + "warning-in-error:s" => { name => 'warning_in_error' }, + "critical-in-error:s" => { name => 'critical_in_error' }, + "warning-out-error:s" => { name => 'warning_out_error' }, + "critical-out-error:s" => { name => 'critical_out_error' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + "name" => { name => 'use_name' }, + "interface:s" => { name => 'interface' }, + "skip" => { name => 'skip' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'ifname'}, + "oid-display:s" => { name => 'oid_display', default => 'ifname'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "show-cache" => { name => 'show_cache' }, + }); + + $self->{interface_id_selected} = []; + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + # 'discard' treshold + if (($self->{perfdata}->threshold_validate(label => 'warning-in-discard', value => $self->{option_results}->{warning_in_discard})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'in discard' threshold '" . $self->{option_results}->{warning_in_discard} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-in-discard', value => $self->{option_results}->{critical_in_discard})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'in discard' threshold '" . $self->{option_results}->{critical_in_discard} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning-out-discard', value => $self->{option_results}->{warning_out_discard})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'out discard' threshold '" . $self->{option_results}->{warning_out_disard} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-out-discard', value => $self->{option_results}->{critical_out_discard})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'out discard' threshold '" . $self->{option_results}->{critical_out_discard} . "'."); + $self->{output}->option_exit(); + } + + # 'errror' treshold + if (($self->{perfdata}->threshold_validate(label => 'warning-in-error', value => $self->{option_results}->{warning_in_error})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'in error' threshold '" . $self->{option_results}->{warning_in_error} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-in-error', value => $self->{option_results}->{critical_in_error})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'in error' threshold '" . $self->{option_results}->{critical_in_error} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning-out-error', value => $self->{option_results}->{warning_out_error})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'out error' threshold '" . $self->{option_results}->{warning_out_disard} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-out-error', value => $self->{option_results}->{critical_out_error})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'out error' threshold '" . $self->{option_results}->{critical_out_error} . "'."); + $self->{output}->option_exit(); + } + + $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); + if ($self->{option_results}->{oid_filter} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); + if ($self->{option_results}->{oid_display} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + $self->manage_selection(); + + my $oid_adminstatus = '.1.3.6.1.2.1.2.2.1.7'; + my $oid_operstatus = '.1.3.6.1.2.1.2.2.1.8'; + + # 32bits + my $oid_ifInUcastPkts = '.1.3.6.1.2.1.2.2.1.11'; + my $oid_ifInBroadcastPkts = '.1.3.6.1.2.1.31.1.1.1.3'; + my $oid_ifInMulticastPkts = '.1.3.6.1.2.1.31.1.1.1.2'; + my $oid_ifOutUcastPkts = '.1.3.6.1.2.1.2.2.1.17'; + my $oid_ifOutMulticastPkts = '.1.3.6.1.2.1.31.1.1.1.4'; + my $oid_ifOutBroadcastPkts = '.1.3.6.1.2.1.31.1.1.1.5'; + + # 64 bits + my $oid_ifHCInUcastPkts = '.1.3.6.1.2.1.31.1.1.1.7'; + my $oid_ifHCInMulticastPkts = '.1.3.6.1.2.1.31.1.1.1.8'; + my $oid_ifHCInBroadcastPkts = '.1.3.6.1.2.1.31.1.1.1.9'; + my $oid_ifHCOutUcastPkts = '.1.3.6.1.2.1.31.1.1.1.11'; + my $oid_ifHCOutMulticastPkts = '.1.3.6.1.2.1.31.1.1.1.12'; + my $oid_ifHCOutBroadcastPkts = '.1.3.6.1.2.1.31.1.1.1.13'; + + # 'discard' 'error' only 32 bits + my $oid_ifInDiscards = '.1.3.6.1.2.1.2.2.1.13'; + my $oid_ifInErrors = '.1.3.6.1.2.1.2.2.1.14'; + my $oid_ifOutDiscards = '.1.3.6.1.2.1.2.2.1.19'; + my $oid_ifOutErrors = '.1.3.6.1.2.1.2.2.1.20'; + + my $new_datas = {}; + $self->{statefile_value}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{interface}) ? md5_hex($self->{option_results}->{interface}) : md5_hex('all'))); + + foreach (@{$self->{interface_id_selected}}) { + $self->{snmp}->load(oids => [$oid_adminstatus . "." . $_, $oid_operstatus . "." . $_, + $oid_ifInUcastPkts . "." . $_, $oid_ifInBroadcastPkts . "." . $_, $oid_ifInMulticastPkts . "." . $_, + $oid_ifOutUcastPkts . "." . $_, $oid_ifOutMulticastPkts . "." . $_, $oid_ifOutBroadcastPkts . "." . $_, + $oid_ifInDiscards . "." . $_, $oid_ifInErrors . "." . $_, + $oid_ifOutDiscards . "." . $_, $oid_ifOutErrors . "." . $_]); + if (!$self->{snmp}->is_snmpv1()) { + $self->{snmp}->load(oids => [$oid_ifHCInUcastPkts . "." . $_, $oid_ifHCInMulticastPkts . "." . $_, $oid_ifHCInMulticastPkts . "." . $_, + $oid_ifHCOutUcastPkts . "." . $_, $oid_ifHCOutMulticastPkts . "." . $_, $oid_ifHCOutBroadcastPkts . "." . $_]); + } + } + + my $result = $self->{snmp}->get_leef(); + $new_datas->{last_timestamp} = time(); + my $old_timestamp; + if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All interfaces are ok.'); + } + + foreach (sort @{$self->{interface_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + + if ($operstatus[$result->{$oid_operstatus . "." . $_} - 1] ne "up") { + if (!defined($self->{option_results}->{skip}) && (!defined($result->{$oid_adminstatus . "." . $_}) || $operstatus[$result->{$oid_adminstatus . "." . $_} - 1] eq 'up') ) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Interface '" . $display_value . "' is not ready: " . $operstatus[$result->{$oid_operstatus . "." . $_} - 1]); + } else { + $self->{output}->output_add(long_msg => "Skip interface '" . $display_value . "'."); + } + next; + } + + ################# + # New values + ################# + my $old_mode = $self->{statefile_value}->get(name => 'mode_' . $_); + $new_datas->{'mode_' . $_} = '32'; + $new_datas->{'in_discard_' . $_} = $result->{$oid_ifInDiscards . "." . $_}; + $new_datas->{'in_error_' . $_} = $result->{$oid_ifInErrors . "." . $_}; + $new_datas->{'out_discard_' . $_} = $result->{$oid_ifOutDiscards . "." . $_}; + $new_datas->{'out_error_' . $_} = $result->{$oid_ifOutErrors . "." . $_}; + + $new_datas->{'in_ucast_' . $_} = $result->{$oid_ifInUcastPkts . "." . $_}; + $new_datas->{'in_bcast_' . $_} = defined($result->{$oid_ifInBroadcastPkts . "." . $_}) ? $result->{$oid_ifInBroadcastPkts . "." . $_} : 0; + $new_datas->{'in_mcast_' . $_} = defined($result->{$oid_ifInMulticastPkts . "." . $_}) ? $result->{$oid_ifInMulticastPkts . "." . $_} : 0; + $new_datas->{'out_ucast_' . $_} = $result->{$oid_ifOutUcastPkts . "." . $_}; + $new_datas->{'out_bcast_' . $_} = defined($result->{$oid_ifOutMulticastPkts . "." . $_}) ? $result->{$oid_ifOutMulticastPkts . "." . $_} : 0; + $new_datas->{'out_mcast_' . $_} = defined($result->{$oid_ifOutBroadcastPkts . "." . $_}) ? $result->{$oid_ifOutBroadcastPkts . "." . $_} : 0; + + if (defined($result->{$oid_ifHCInUcastPkts . "." . $_}) && $result->{$oid_ifHCInUcastPkts . "." . $_} ne '' && $result->{$oid_ifHCInUcastPkts . "." . $_} != 0) { + $new_datas->{'in_ucast_' . $_} = $result->{$oid_ifHCInUcastPkts . "." . $_}; + $new_datas->{'in_mcast_' . $_} = defined($result->{$oid_ifHCInMulticastPkts . "." . $_}) ? $result->{$oid_ifHCInMulticastPkts . "." . $_} : 0; + $new_datas->{'in_bcast_' . $_} = defined($result->{$oid_ifHCInBroadcastPkts . "." . $_}) ? $result->{$oid_ifHCInBroadcastPkts . "." . $_} : 0; + $new_datas->{'out_ucast_' . $_} = $result->{$oid_ifHCOutUcastPkts . "." . $_}; + $new_datas->{'out_mcast_' . $_} = defined($result->{$oid_ifHCOutMulticastPkts . "." . $_}) ? $result->{$oid_ifHCOutMulticastPkts . "." . $_} : 0; + $new_datas->{'out_bcast_' . $_} = defined($result->{$oid_ifHCOutBroadcastPkts . "." . $_}) ? $result->{$oid_ifHCOutBroadcastPkts . "." . $_} : 0; + $new_datas->{'mode_' . $_} = '64'; + } + + # We change mode. need to recreate a buffer + if (!defined($old_mode) || $new_datas->{'mode_' . $_} ne $old_mode) { + next; + } + + ################# + # Old values + ################# + my @getting = ('in_ucast', 'in_bcast', 'in_mcast', 'out_ucast', 'out_bcast', 'out_mcast', + 'in_discard', 'in_error', 'out_discard', 'out_error'); + my $old_datas = {}; + $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + foreach my $key (@getting) { + $old_datas->{$key} = $self->{statefile_value}->get(name => $key . '_' . $_); + if (!defined($old_datas->{$key}) || $new_datas->{$key . '_' . $_} < $old_datas->{$key}) { + # We set 0. Has reboot. + $old_datas->{$key} = 0; + } + } + + if (!defined($old_timestamp)) { + next; + } + my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; + if ($time_delta <= 0) { + # At least one second. two fast calls ;) + $time_delta = 1; + } + + ############ + + my $total_in_packets = ($new_datas->{'in_ucast_' . $_} - $old_datas->{in_ucast}) + ($new_datas->{'in_bcast_' . $_} - $old_datas->{in_bcast}) + ($new_datas->{'in_mcast_' . $_} - $old_datas->{in_mcast}); + my $total_out_packets = ($new_datas->{'out_ucast_' . $_} - $old_datas->{out_ucast}) + ($new_datas->{'out_bcast_' . $_} - $old_datas->{out_bcast}) + ($new_datas->{'out_mcast_' . $_} - $old_datas->{out_mcast}); + + my $in_discard_absolute_per_sec = ($new_datas->{'in_discard_' . $_} - $old_datas->{in_discard}) / $time_delta; + my $in_error_absolute_per_sec = ($new_datas->{'in_error_' . $_} - $old_datas->{in_error}) / $time_delta; + my $out_discard_absolute_per_sec = ($new_datas->{'out_discard_' . $_} - $old_datas->{out_discard}) / $time_delta; + my $out_error_absolute_per_sec = ($new_datas->{'out_error_' . $_} - $old_datas->{out_error}) / $time_delta; + my $in_discard_prct = ($total_in_packets == 0) ? 0 : ($new_datas->{'in_discard_' . $_} - $old_datas->{in_discard}) * 100 / $total_in_packets; + my $in_error_prct = ($total_in_packets == 0) ? 0 : ($new_datas->{'in_error_' . $_} - $old_datas->{in_error}) * 100 / $total_in_packets; + my $out_discard_prct = ($total_out_packets == 0) ? 0 : ($new_datas->{'out_discard_' . $_} - $old_datas->{out_discard}) * 100 / $total_out_packets; + my $out_error_prct = ($total_out_packets == 0) ? 0 : ($new_datas->{'out_error_' . $_} - $old_datas->{out_error}) * 100 / $total_out_packets; + + ########### + # Manage Output + ########### + my $exit1 = $self->{perfdata}->threshold_check(value => $in_discard_prct, threshold => [ { label => 'critical-in-discard', 'exit_litteral' => 'critical' }, { label => 'warning-in-discard', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $in_error_prct, threshold => [ { label => 'critical-in-error', 'exit_litteral' => 'critical' }, { label => 'warning-in-error', exit_litteral => 'warning' } ]); + my $exit3 = $self->{perfdata}->threshold_check(value => $out_discard_prct, threshold => [ { label => 'critical-out-discard', 'exit_litteral' => 'critical' }, { label => 'warning-out-discard', exit_litteral => 'warning' } ]); + my $exit4 = $self->{perfdata}->threshold_check(value => $out_error_prct, threshold => [ { label => 'critical-out-error', 'exit_litteral' => 'critical' }, { label => 'warning-out-error', exit_litteral => 'warning' } ]); + + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3, $exit4 ]); + $self->{output}->output_add(long_msg => sprintf("Interface '%s' Packets In Discard : %.2f %% (%d), In Error : %.2f %% (%d), Out Discard: %.2f %% (%d), Out Error: %.2f %% (%d)", $display_value, + $in_discard_prct, $new_datas->{'in_discard_' . $_} - $old_datas->{in_discard}, + $in_error_prct, $new_datas->{'in_error_' . $_} - $old_datas->{in_error}, + $out_discard_prct, $new_datas->{'out_discard_' . $_} - $old_datas->{out_discard}, + $out_error_prct, $new_datas->{'out_error_' . $_} - $old_datas->{out_error} + )); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{interface}) && !defined($self->{option_results}->{use_regexp}))) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Interface '%s' Packets In Discard : %.2f %% (%d), In Error : %.2f %% (%d), Out Discard: %.2f %% (%d), Out Error: %.2f %% (%d)", $display_value, + $in_discard_prct, $new_datas->{'in_discard_' . $_} - $old_datas->{in_discard}, + $in_error_prct, $new_datas->{'in_error_' . $_} - $old_datas->{in_error}, + $out_discard_prct, $new_datas->{'out_discard_' . $_} - $old_datas->{out_discard}, + $out_error_prct, $new_datas->{'out_error_' . $_} - $old_datas->{out_error} + )); + } + + my $extra_label = ''; + $extra_label = '_' . $display_value if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})); + $self->{output}->perfdata_add(label => 'packets_discard_in' . $extra_label, unit => '%', + value => sprintf("%.2f", $in_discard_prct), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in-discard'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in-discard'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => 'packets_error_in' . $extra_label, unit => '%', + value => sprintf("%.2f", $in_error_prct), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in-error'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in-error'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => 'packets_discard_out' . $extra_label, unit => '%', + value => sprintf("%.2f", $out_discard_prct), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out-discard'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out-discard'), + min => 0, max => 100); + $self->{output}->perfdata_add(label => 'packets_error_out' . $extra_label, unit => '%', + value => sprintf("%.2f", $out_error_prct), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out-error'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out-error'), + min => 0, max => 100); + } + + $self->{statefile_value}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_display_value { + my ($self, %options) = @_; + my $value = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $options{id}); + + if (defined($self->{option_results}->{display_transform_src})) { + $self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst})); + eval "\$value =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}"; + } + return $value; +} + +sub reload_cache { + my ($self) = @_; + my $datas = {}; + + $datas->{oid_filter} = $self->{option_results}->{oid_filter}; + $datas->{oid_display} = $self->{option_results}->{oid_display}; + my $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_filter}}); + my $last_num = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + $last_num = $1; + } + + if (scalar(keys %$datas) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { + $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_display}}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + } + } + + $datas->{total_interface} = $last_num; + $self->{statefile_cache}->write(data => $datas); +} + +sub manage_selection { + my ($self, %options) = @_; + + # init cache file + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{mode}); + if (defined($self->{option_results}->{show_cache})) { + $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); + $self->{output}->option_exit(); + } + + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + my $oid_display = $self->{statefile_cache}->get(name => 'oid_display'); + my $oid_filter = $self->{statefile_cache}->get(name => 'oid_filter'); + if ($has_cache_file == 0 || + ($self->{option_results}->{oid_display} !~ /^($oid_display|$oid_filter)$/i || $self->{option_results}->{oid_filter} !~ /^($oid_display|$oid_filter)$/i) || + (defined($timestamp_cache) && (time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(); + $self->{statefile_cache}->read(); + } + + my $total_interface = $self->{statefile_cache}->get(name => 'total_interface'); + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{interface})) { + # get by ID + push @{$self->{interface_id_selected}}, $self->{option_results}->{interface}; + my $name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $self->{option_results}->{interface}); + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No interface found for id '" . $self->{option_results}->{interface} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_interface; $i++) { + my $filter_name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_filter} . "_" . $i); + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{interface})) { + push @{$self->{interface_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/i) { + push @{$self->{interface_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/) { + push @{$self->{interface_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{interface}) { + push @{$self->{interface_id_selected}}, $i; + } + } + + if (scalar(@{$self->{interface_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{interface} . "' (maybe you should reload cache file)."); + $self->{output}->option_exit(); + } + } +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--warning-in-discard> + +Threshold warning in percent for 'in' discard packets. + +=item B<--critical-in-discard> + +Threshold critical in percent for 'in' discard packets. + +=item B<--warning-out-discard> + +Threshold warning in percent for 'out' discard packets. + +=item B<--critical-out-discard> + +Threshold critical in percent for 'out' discard packets. + +=item B<--warning-in-error> + +Threshold warning in percent for 'in' error packets. + +=item B<--critical-in-error> + +Threshold critical in percent for 'in' error packets. + +=item B<--warning-out-error> + +Threshold warning in percent for 'out' error packets. + +=item B<--critical-out-error> + +Threshold critical in percent for 'out' error packets. + +=item B<--interface> + +Set the interface (number expected) ex: 1, 2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index. + +=item B<--regexp> + +Allows to use regexp to filter interfaces (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--speed> + +Set interface speed (in Mb). + +=item B<--skip> + +Skip errors on interface status. + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/snmp_standard/mode/processcount.pm b/snmp_standard/mode/processcount.pm new file mode 100644 index 000000000..07f90e000 --- /dev/null +++ b/snmp_standard/mode/processcount.pm @@ -0,0 +1,217 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::processcount; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "process-name:s" => { name => 'process_name', }, + "regexp-name" => { name => 'regexp_name', }, + "process-path:s" => { name => 'process_path', }, + "regexp-path" => { name => 'regexp_path', }, + "process-args:s" => { name => 'process_args', }, + "regexp-args" => { name => 'regexp_args', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{process_name}) && + !defined($self->{option_results}->{process_path}) && + !defined($self->{option_results}->{process_args}) + ) { + $self->{output}->add_option_msg(short_msg => "Need to specify at least one argument '--process-*'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oids = { + name => '.1.3.6.1.2.1.25.4.2.1.2', # hrSWRunName + path => '.1.3.6.1.2.1.25.4.2.1.4', # hrSWRunPath + args => '.1.3.6.1.2.1.25.4.2.1.5', # hrSWRunParameters (Warning: it's truncated. (128 characters)) + }; + + my $oid_hrSWRunStatus = '.1.3.6.1.2.1.25.4.2.1.7'; + + my $oid2check_filter; + foreach (keys %$oids) { + if (defined($self->{option_results}->{'process_' . $_})) { + $oid2check_filter = $_; + last; + } + } + # Build other + my $mores_filters = {}; + my $more_oids = [$oid_hrSWRunStatus]; + foreach (keys %$oids) { + if ($_ ne $oid2check_filter && defined($self->{option_results}->{'process_' . $_})) { + push @{$more_oids}, $oids->{$_}; + $mores_filters->{$_} = 1; + } + } + + my $result = $self->{snmp}->get_table(oid => $oids->{$oid2check_filter}); + my $instances_keep = {}; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + my $val = $self->{option_results}->{'process_' . $oid2check_filter}; + + if ((defined($self->{option_results}->{'regexp_' . $oid2check_filter}) && $result->{$key} =~ /$val/) + || (!defined($self->{option_results}->{'regexp_' . $oid2check_filter}) && $result->{$key} eq $val)) { + $key =~ /\.([0-9]+)$/; + $instances_keep->{$1} = 1; + } + } + + if (scalar(keys %$instances_keep) > 0) { + $self->{snmp}->load(oids => $more_oids, instances => [keys %$instances_keep ]); + my $result2 = $self->{snmp}->get_leef(); + + foreach my $key (keys %$instances_keep) { + # 1 = running, 2 = runnable, 3 = notRunnable, 4 => invalid + if (!defined($result2->{$oid_hrSWRunStatus . "." . $key}) || $result2->{$oid_hrSWRunStatus . "." . $key} > 2) { + delete $instances_keep->{$key}; + next; + } + + my $long_value = '[ ' . $oid2check_filter . ' => ' . $result->{$oids->{$oid2check_filter} . '.' . $key} . ' ]'; + my $deleted = 0; + foreach (keys %$mores_filters) { + my $val = $self->{option_results}->{'process_' . $_}; + + if ((defined($self->{option_results}->{'regexp_' . $_}) && $result2->{$oids->{$_} . '.' . $key} !~ /$val/) + || (!defined($self->{option_results}->{'regexp_' . $_}) && $result2->{$oids->{$_} . '.' . $key} ne $val)) { + delete $instances_keep->{$key}; + $deleted = 1; + last; + } + + $long_value .= ' [ ' . $_ . ' => ' . $result2->{$oids->{$_} . '.' . $key} . ' ]'; + } + + if ($deleted == 0) { + $self->{output}->output_add(long_msg => 'Process: ' . $long_value); + } + } + } + + my $num_processes_match = scalar(keys(%$instances_keep)); + my $exit = $self->{perfdata}->threshold_check(value => $num_processes_match, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => "Number of current processes running: $num_processes_match"); + $self->{output}->perfdata_add(label => 'nbproc', + value => $num_processes_match, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check system number of processes. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--process-name> + +Check process name. + +=item B<--regexp-name> + +Allows to use regexp to filter process name (with option --process-name). + +=item B<--process-path> + +Check process path. + +=item B<--regexp-path> + +Allows to use regexp to filter process path (with option --process-path). + +=item B<--process-args> + +Check process args. + +=item B<--regexp-args> + +Allows to use regexp to filter process args (with option --process-args). + +=back + +=cut diff --git a/snmp_standard/mode/spanningtree.pm b/snmp_standard/mode/spanningtree.pm new file mode 100644 index 000000000..0c15842e0 --- /dev/null +++ b/snmp_standard/mode/spanningtree.pm @@ -0,0 +1,139 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::spanningtree; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %states = ( + 1 => ['disabled', 'OK'], + 2 => ['blocking', 'CRITICAL'], + 3 => ['listening', 'OK'], + 4 => ['learning', 'OK'], + 5 => ['forwarding', 'OK'], + 6 => ['broken', 'CRITICAL'], +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_dot1dStpPortEnable = '.1.3.6.1.2.1.17.2.15.1.4'; + my $oid_dot1dStpPortState = '.1.3.6.1.2.1.17.2.15.1.3'; + my $oid_dot1dBasePortIfIndex = '.1.3.6.1.2.1.17.1.4.1.2'; + my $oid_ifDesc = '.1.3.6.1.2.1.2.2.1.2'; + my $result = $self->{snmp}->get_table(oid => $oid_dot1dStpPortEnable, nothing_quit => 1); + + foreach my $oid (keys %$result) { + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + # '2' => disabled, we skip + if ($result->{$oid} == 2) { + $self->{output}->output_add(long_msg => sprintf("Skipping interface '%d': Stp port disabled", $instance)); + next; + } + + $self->{snmp}->load(oids => [$oid_dot1dStpPortState . "." . $instance, $oid_dot1dBasePortIfIndex . "." . $instance]); + } + + $result = $self->{snmp}->get_leef(nothing_quit => 1); + $self->{output}->output_add(severity => 'OK', + short_msg => 'Spanning Tree is ok on all interfaces'); + # Get description + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_dot1dBasePortIfIndex/); + $self->{snmp}->load(oids => [$oid_ifDesc . "." . $result->{$oid}]); + } + my $result_desc = $self->{snmp}->get_leef(); + + # Parsing ports + foreach my $oid (keys %$result) { + next if ($oid !~ /^$oid_dot1dStpPortState/); + $oid =~ /\.([0-9]+)$/; + my $instance = $1; + + my $stp_state = $result->{$oid}; + my $descr = $result_desc->{$oid_ifDesc . '.' . $result->{$oid_dot1dBasePortIfIndex . '.' . $instance}}; + + $self->{output}->output_add(long_msg => sprintf("Spanning Tree interface '%s' state is %s", $descr, + ${$states{$stp_state}}[0])); + if (${$states{$stp_state}}[1] ne 'OK') { + $self->{output}->output_add(severity => ${$states{$stp_state}}[1], + short_msg => sprintf("Spanning Tree interface '%s' state is %s", $descr, + ${$states{$stp_state}}[0])); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Spanning-Tree current state of ports (BRIDGE-MIB). + +=over 8 + +=back + +=cut + \ No newline at end of file diff --git a/snmp_standard/mode/storage.pm b/snmp_standard/mode/storage.pm new file mode 100644 index 000000000..3016f3bfc --- /dev/null +++ b/snmp_standard/mode/storage.pm @@ -0,0 +1,371 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::storage; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +my %oids_hrStorageTable = ( + 'hrstoragedescr' => '.1.3.6.1.2.1.25.2.3.1.3', + 'hrfsmountpoint' => '.1.3.6.1.2.1.25.3.8.1.2', + 'hrstoragetype' => '.1.3.6.1.2.1.25.2.3.1.2', +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + "name" => { name => 'use_name' }, + "storage:s" => { name => 'storage' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'hrStorageDescr'}, + "oid-display:s" => { name => 'oid_display', default => 'hrStorageDescr'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "show-cache" => { name => 'show_cache' }, + }); + + $self->{storage_id_selected} = []; + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); + if ($self->{option_results}->{oid_filter} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); + if ($self->{option_results}->{oid_display} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + $self->manage_selection(); + + my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; + my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; + my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; + my $oid_hrStorageType = '.1.3.6.1.2.1.25.2.3.1.2'; + my $oid_hrStorageFixedDisk = '.1.3.6.1.2.1.25.2.1.4'; + my $oid_hrStorageNetworkDisk = '.1.3.6.1.2.1.25.2.1.10'; + + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], instances => $self->{storage_id_selected}); + my $result = $self->{snmp}->get_leef(); + + if (!defined($self->{option_results}->{storage}) || defined($self->{option_results}->{use_regexp})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All storages are ok.'); + } + + my $num_disk_check = 0; + foreach (sort @{$self->{storage_id_selected}}) { + # Skipped disks + my $storage_type = $self->{statefile_cache}->get(name => "type_" . $_); + next if (!defined($storage_type) || ($storage_type ne $oid_hrStorageFixedDisk && $storage_type ne $oid_hrStorageNetworkDisk)); + + my $name_storage = $self->get_display_value(id => $_); + $num_disk_check++; + + # in bytes hrStorageAllocationUnits + my $total_size = $result->{$oid_hrStorageSize . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_}; + next if ($total_size == 0); + my $total_used = $result->{$oid_hrStorageUsed . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_}; + my $total_free = $total_size - $total_used; + my $prct_used = $total_used * 100 / $total_size; + my $prct_free = 100 - $prct_used; + + my ($exit, $threshold_value); + + $threshold_value = $total_used; + $threshold_value = $total_free if (defined($self->{option_results}->{free})); + if ($self->{option_results}->{units} eq '%') { + $threshold_value = $prct_used; + $threshold_value = $prct_free if (defined($self->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $total_used); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => ($total_size - $total_used)); + + $self->{output}->output_add(long_msg => sprintf("Storage '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{storage}) && !defined($self->{option_results}->{use_regexp}))) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Storage '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + } + + my $label = 'used'; + my $value_perf = $total_used; + if (defined($self->{option_results}->{free})) { + $label = 'free'; + $value_perf = $total_free; + } + my $extra_label = ''; + $extra_label = '_' . $name_storage if (!defined($self->{option_results}->{storage}) || defined($self->{option_results}->{use_regexp})); + my %total_options = (); + if ($self->{option_results}->{units} eq '%') { + $total_options{total} = $total_size; + $total_options{cast_int} = 1; + } + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'o', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), + min => 0, max => $total_size); + } + + if ($num_disk_check == 0) { + $self->{output}->add_option_msg(short_msg => "Not a disk with a good 'type'."); + $self->{output}->option_exit(); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub reload_cache { + my ($self) = @_; + my $datas = {}; + + $datas->{oid_filter} = $self->{option_results}->{oid_filter}; + $datas->{oid_display} = $self->{option_results}->{oid_display}; + my $result = $self->{snmp}->get_table(oid => $oids_hrStorageTable{$self->{option_results}->{oid_filter}}); + my $last_num = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + $last_num = $1; + } + + if (scalar(keys %$datas) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { + $result = $self->{snmp}->get_table(oid => $oids_hrStorageTable{$self->{option_results}->{oid_display}}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + } + } + + $result = $self->{snmp}->get_table(oid => $oids_hrStorageTable{hrstoragetype}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{"type_" . $1} = $result->{$key}; + } + + $datas->{total_storage} = $last_num; + $self->{statefile_cache}->write(data => $datas); +} + +sub manage_selection { + my ($self, %options) = @_; + + # init cache file + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{mode}); + if (defined($self->{option_results}->{show_cache})) { + $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); + $self->{output}->option_exit(); + } + + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + my $oid_display = $self->{statefile_cache}->get(name => 'oid_display'); + my $oid_filter = $self->{statefile_cache}->get(name => 'oid_filter'); + if ($has_cache_file == 0 || + ($self->{option_results}->{oid_display} !~ /^($oid_display|$oid_filter)$/i || $self->{option_results}->{oid_filter} !~ /^($oid_display|$oid_filter)$/i) || + (defined($timestamp_cache) && (time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(); + $self->{statefile_cache}->read(); + } + + my $total_storage = $self->{statefile_cache}->get(name => 'total_storage'); + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{storage})) { + # get by ID + push @{$self->{storage_id_selected}}, $self->{option_results}->{storage}; + my $name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $self->{option_results}->{storage}); + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No storage found for id '" . $self->{option_results}->{storage} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_storage; $i++) { + my $filter_name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_filter} . "_" . $i); + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{storage})) { + push @{$self->{storage_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{storage}/i) { + push @{$self->{storage_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{storage}/) { + push @{$self->{storage_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{storage}) { + push @{$self->{storage_id_selected}}, $i; + } + } + + if (scalar(@{$self->{storage_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No storage found for name '" . $self->{option_results}->{storage} . "' (maybe you should reload cache file)."); + $self->{output}->option_exit(); + } + } +} + +sub get_display_value { + my ($self, %options) = @_; + my $value = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $options{id}); + + if (defined($self->{option_results}->{display_transform_src})) { + $self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst})); + eval "\$value =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}"; + } + return $value; +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--storage> + +Set the storage (number expected) ex: 1, 2,... (empty means 'check all storage'). + +=item B<--name> + +Allows to use storage name with option --storage instead of storage oid index. + +=item B<--regexp> + +Allows to use regexp to filter storage (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSRemoteMountPoint). + +=item B<--oid-display> + +Choose OID used to display storage (default: hrStorageDescr) (values: hrStorageDescr, hrFSRemoteMountPoint). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=item B<--show-cache> + +Display cache storage datas. + +=back + +=cut diff --git a/snmp_standard/mode/stringvalue.pm b/snmp_standard/mode/stringvalue.pm new file mode 100644 index 000000000..9bf76791d --- /dev/null +++ b/snmp_standard/mode/stringvalue.pm @@ -0,0 +1,178 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::stringvalue; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "oid:s" => { name => 'oid' }, + "warning-regexp:s" => { name => 'warning_regexp' }, + "critical-regexp:s" => { name => 'critical_regexp' }, + "unknown-regexp:s" => { name => 'unknown_regexp' }, + "format:s" => { name => 'format', default => 'current value is %s' }, + "map-values:s" => { name => 'map_values' }, + "map-values-separator:s" => { name => 'map_values_separator', default => ',' }, + "regexp-map-values" => { name => 'use_regexp_map_values' }, + "regexp-isensitive" => { name => 'use_iregexp' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{oid})) { + $self->{output}->add_option_msg(short_msg => "Need to specify an OID."); + $self->{output}->option_exit(); + } + + $self->{map_values} = {}; + if (defined($self->{option_results}->{map_values})) { + foreach (split /$self->{option_results}->{map_values_separator}/, $self->{option_results}->{map_values}) { + my ($name, $map) = split /=>/; + $self->{map_values}->{centreon::plugins::misc::trim($name)} = centreon::plugins::misc::trim($map); + } + } +} + +sub check_regexp { + my ($self, %options) = @_; + + return 0 if (!defined($self->{option_results}->{$options{severity} . '_regexp'})); + my $regexp = $self->{option_results}->{$options{severity} . '_regexp'}; + + if (defined($self->{option_results}->{use_iregexp}) && $options{value} =~ /$regexp/i) { + $self->{exit_code} = $options{severity}; + return 1; + } elsif (!defined($self->{option_results}->{use_iregexp}) && $options{value} =~ /$regexp/) { + $self->{exit_code} = $options{severity}; + return 1; + } + + return 0; +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $result = $self->{snmp}->get_leef(oids => [$self->{option_results}->{oid}], nothing_quit => 1); + my $value_check = $result->{$self->{option_results}->{oid}}; + my $value_display = $value_check; + + if (defined($self->{option_results}->{map_values})) { + # If we don't find it. We keep the original value + $value_display = defined($self->{map_values}->{$value_check}) ? $self->{map_values}->{$value_check} : $value_check; + if (defined($self->{option_results}->{use_regexp_map_values})) { + $value_check = $value_display; + } + } + + $self->{exit_code} = 'ok'; + $self->check_regexp(severity => 'critical', value => $value_check) || + $self->check_regexp(severity => 'warning', value => $value_check) || + $self->check_regexp(severity => 'unknown', value => $value_check); + + $self->{output}->output_add(severity => $self->{exit_code}, + short_msg => sprintf($self->{option_results}->{format}, $value_display)); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check an SNMP string value (can be a String or an Integer). + +=over 8 + +=item B<--oid> + +OID value to check (numeric format only). + +=item B<--warning-regexp> + +Return Warning if the oid value match the regexp. + +=item B<--critical-regexp> + +Return Critical if the oid value match the regexp. + +=item B<--unknown-regexp> + +Return Unknown if the oid value match the regexp. + +=item B<--format> + +Output format (Default: 'current value is %s'). + +=item B<--map-values> + +Use to transform an integer value in most common case. +Example: --map-values='1=>ok,10=>fan failed,11=>psu recovery' + +=item B<--map-values-separator> + +Separator uses between values (default: coma). + +=item B<--regexp-map-values> + +Use the 'map values' to match in regexp (need --map-values option). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive. + +=back + +=cut diff --git a/snmp_standard/mode/traffic.pm b/snmp_standard/mode/traffic.pm new file mode 100644 index 000000000..eeb7751f8 --- /dev/null +++ b/snmp_standard/mode/traffic.pm @@ -0,0 +1,455 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::traffic; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +my @operstatus = ("up", "down", "testing", "unknown", "dormant", "notPresent", "lowerLayerDown"); +my %oids_iftable = ( + 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', + 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', + 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1' +); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-in:s" => { name => 'warning_in' }, + "critical-in:s" => { name => 'critical_in' }, + "warning-out:s" => { name => 'warning_out' }, + "critical-out:s" => { name => 'critical_out' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + "name" => { name => 'use_name' }, + "interface:s" => { name => 'interface' }, + "speed:s" => { name => 'speed' }, + "skip" => { name => 'skip' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'ifname'}, + "oid-display:s" => { name => 'oid_display', default => 'ifname'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "show-cache" => { name => 'show_cache' }, + }); + + $self->{interface_id_selected} = []; + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning-in', value => $self->{option_results}->{warning_in})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'in' threshold '" . $self->{option_results}->{warning_in} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-in', value => $self->{option_results}->{critical_in})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'in' threshold '" . $self->{option_results}->{critical_in} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warning-out', value => $self->{option_results}->{warning_out})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning 'out' threshold '" . $self->{option_results}->{warning_out} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-out', value => $self->{option_results}->{critical_out})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical 'out' threshold '" . $self->{option_results}->{critical_out} . "'."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); + if ($self->{option_results}->{oid_filter} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); + if ($self->{option_results}->{oid_display} !~ /^(ifdesc|ifalias|ifname)$/) { + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->check_options(%options); + $self->{statefile_value}->check_options(%options); +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + $self->{hostname} = $self->{snmp}->get_hostname(); + + $self->manage_selection(); + + my $oid_adminstatus = '.1.3.6.1.2.1.2.2.1.7'; + my $oid_operstatus = '.1.3.6.1.2.1.2.2.1.8'; + my $oid_speed32 = '.1.3.6.1.2.1.2.2.1.5'; # in b/s + my $oid_in32 = '.1.3.6.1.2.1.2.2.1.10'; # in B + my $oid_out32 = '.1.3.6.1.2.1.2.2.1.16'; # in B + my $oid_speed64 = '.1.3.6.1.2.1.31.1.1.1.15'; # need multiple by '1000000' + my $oid_in64 = '.1.3.6.1.2.1.31.1.1.1.6'; # in B + my $oid_out64 = '.1.3.6.1.2.1.31.1.1.1.10'; # in B + + my $new_datas = {}; + $self->{statefile_value}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{interface}) ? md5_hex($self->{option_results}->{interface}) : md5_hex('all'))); + + foreach (@{$self->{interface_id_selected}}) { + $self->{snmp}->load(oids => [$oid_adminstatus . "." . $_, $oid_operstatus . "." . $_, $oid_in32 . "." . $_, $oid_out32 . "." . $_]); + if (!defined($self->{option_results}->{speed}) || $self->{option_results}->{speed} eq '') { + $self->{snmp}->load(oids => [$oid_speed32 . "." . $_]); + } + if (!$self->{snmp}->is_snmpv1()) { + $self->{snmp}->load(oids => [$oid_in64 . "." . $_, $oid_out64 . "." . $_]); + if (!defined($self->{option_results}->{speed}) || $self->{option_results}->{speed} eq '') { + $self->{snmp}->load(oids => [$oid_speed64 . "." . $_]); + } + } + } + + my $result = $self->{snmp}->get_leef(); + $new_datas->{last_timestamp} = time(); + my $old_timestamp; + if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All traffic are ok'); + } + + foreach (sort @{$self->{interface_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + + # Manage interface speed + my $interface_speed; + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + $interface_speed = $self->{option_results}->{speed} * 1000000; + } else { + if ((!defined($result->{$oid_speed32 . "." . $_}) || $result->{$oid_speed32 . "." . $_} !~ /^[0-9]+$/) && + (!defined($result->{$oid_speed64 . "." . $_}) || $result->{$oid_speed64 . "." . $_} !~ /^[0-9]+$/)) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Interface '" . $display_value . "' Speed is null or incorrect. You should force the value with --speed option"); + next; + } + $interface_speed = (defined($result->{$oid_speed64 . "." . $_}) && $result->{$oid_speed64 . "." . $_} ne '' ? ($result->{$oid_speed64 . "." . $_} * 1000000) : ($result->{$oid_speed32 . "." . $_})); + if ($interface_speed == 0) { + next; + } + } + + + if ($operstatus[$result->{$oid_operstatus . "." . $_} - 1] ne "up") { + if (!defined($self->{option_results}->{skip}) && (!defined($result->{$oid_adminstatus . "." . $_}) || $operstatus[$result->{$oid_adminstatus . "." . $_} - 1] eq 'up') ) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Interface '" . $display_value . "' is not ready: " . $operstatus[$result->{$oid_operstatus . "." . $_} - 1]); + } else { + # Avoid getting "buffer creation..." alone + if (defined($self->{option_results}->{interface}) && !defined($self->{option_results}->{use_regexp})) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Interface '" . $display_value . "' is not up (normal state)"); + } + $self->{output}->output_add(long_msg => "Skip interface '" . $display_value . "'."); + } + next; + } + + my $old_mode = $self->{statefile_value}->get(name => 'mode_' . $_); + $new_datas->{'mode_' . $_} = '32'; + + $new_datas->{'in_' . $_} = $result->{$oid_in32 . "." . $_} * 8; + if (defined($result->{$oid_in64 . "." . $_}) && $result->{$oid_in64 . "." . $_} ne '' && $result->{$oid_in64 . "." . $_} != 0) { + $new_datas->{'in_' . $_} = $result->{$oid_in64 . "." . $_} * 8; + $new_datas->{'mode_' . $_} = '64'; + } + $new_datas->{'out_' . $_} = $result->{$oid_out32 . "." . $_} * 8; + if (defined($result->{$oid_out64 . "." . $_}) && $result->{$oid_out64 . "." . $_} ne '' && $result->{$oid_out64 . "." . $_} != 0) { + $new_datas->{'out_' . $_} = $result->{$oid_out64 . "." . $_} * 8; + $new_datas->{'mode_' . $_} = '64'; + } + + # We change mode. need to recreate a buffer + if (!defined($old_mode) || $new_datas->{'mode_' . $_} ne $old_mode) { + next; + } + + $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); + my $old_in = $self->{statefile_value}->get(name => 'in_' . $_); + my $old_out = $self->{statefile_value}->get(name => 'out_' . $_); + if (!defined($old_timestamp) || !defined($old_in) || !defined($old_out)) { + next; + } + if ($new_datas->{'in_' . $_} < $old_in) { + # We set 0. Has reboot. + $old_in = 0; + } + if ($new_datas->{'out_' . $_} < $old_out) { + # We set 0. Has reboot. + $old_out = 0; + } + + my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; + if ($time_delta <= 0) { + # At least one second. two fast calls ;) + $time_delta = 1; + } + my $in_absolute_per_sec = ($new_datas->{'in_' . $_} - $old_in) / $time_delta; + my $out_absolute_per_sec = ($new_datas->{'out_' . $_} - $old_out) / $time_delta; + my $in_prct = $in_absolute_per_sec * 100 / $interface_speed; + my $out_prct = $out_absolute_per_sec * 100 / $interface_speed; + + ########### + # Manage Output + ########### + my $exit1 = $self->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); + + my ($in_value, $in_unit) = $self->{perfdata}->change_bytes(value => $in_absolute_per_sec, network => 1); + my ($out_value, $out_unit) = $self->{perfdata}->change_bytes(value => $out_absolute_per_sec, network => 1); + my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + $self->{output}->output_add(long_msg => sprintf("Interface '%s' Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%) ", $display_value, + $in_value . $in_unit, $in_prct, + $out_value . $out_unit, $out_prct)); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{interface}) && !defined($self->{option_results}->{use_regexp}))) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Interface '%s' Traffic In : %s/s (%.2f %%), Out : %s/s (%.2f %%) ", $display_value, + $in_value . $in_unit, $in_prct, + $out_value . $out_unit, $out_prct)); + } + + my $extra_label = ''; + $extra_label = '_' . $display_value if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})); + $self->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $in_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in', total => $interface_speed), + min => 0, max => $interface_speed); + $self->{output}->perfdata_add(label => 'traffic_out' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $out_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), + min => 0, max => $interface_speed); + } + + $self->{statefile_value}->write(data => $new_datas); + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Buffer creation..."); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub get_display_value { + my ($self, %options) = @_; + my $value = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $options{id}); + + if (defined($self->{option_results}->{display_transform_src})) { + $self->{option_results}->{display_transform_dst} = '' if (!defined($self->{option_results}->{display_transform_dst})); + eval "\$value =~ s{$self->{option_results}->{display_transform_src}}{$self->{option_results}->{display_transform_dst}}"; + } + return $value; +} + +sub reload_cache { + my ($self) = @_; + my $datas = {}; + + $datas->{oid_filter} = $self->{option_results}->{oid_filter}; + $datas->{oid_display} = $self->{option_results}->{oid_display}; + my $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_filter}}); + my $last_num = 0; + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + $last_num = $1; + } + + if (scalar(keys %$datas) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { + $result = $self->{snmp}->get_table(oid => $oids_iftable{$self->{option_results}->{oid_display}}); + foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { + next if ($key !~ /\.([0-9]+)$/); + $datas->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$key}); + } + } + + $datas->{total_interface} = $last_num; + $self->{statefile_cache}->write(data => $datas); +} + +sub manage_selection { + my ($self, %options) = @_; + + # init cache file + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{mode}); + if (defined($self->{option_results}->{show_cache})) { + $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); + $self->{output}->option_exit(); + } + + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + my $oid_display = $self->{statefile_cache}->get(name => 'oid_display'); + my $oid_filter = $self->{statefile_cache}->get(name => 'oid_filter'); + if ($has_cache_file == 0 || + ($self->{option_results}->{oid_display} !~ /^($oid_display|$oid_filter)$/i || $self->{option_results}->{oid_filter} !~ /^($oid_display|$oid_filter)$/i) || + (defined($timestamp_cache) && (time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(); + $self->{statefile_cache}->read(); + } + + my $total_interface = $self->{statefile_cache}->get(name => 'total_interface'); + if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{interface})) { + # get by ID + push @{$self->{interface_id_selected}}, $self->{option_results}->{interface}; + my $name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_display} . "_" . $self->{option_results}->{interface}); + if (!defined($name)) { + $self->{output}->add_option_msg(short_msg => "No interface found for id '" . $self->{option_results}->{interface} . "'."); + $self->{output}->option_exit(); + } + } else { + for (my $i = 0; $i <= $total_interface; $i++) { + my $filter_name = $self->{statefile_cache}->get(name => $self->{option_results}->{oid_filter} . "_" . $i); + next if (!defined($filter_name)); + if (!defined($self->{option_results}->{interface})) { + push @{$self->{interface_id_selected}}, $i; + next; + } + if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/i) { + push @{$self->{interface_id_selected}}, $i; + } + if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/) { + push @{$self->{interface_id_selected}}, $i; + } + if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{interface}) { + push @{$self->{interface_id_selected}}, $i; + } + } + + if (scalar(@{$self->{interface_id_selected}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{interface} . "' (maybe you should reload cache file)."); + $self->{output}->option_exit(); + } + } +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--warning-in> + +Threshold warning in percent for 'in' traffic. + +=item B<--critical-in> + +Threshold critical in percent for 'in' traffic. + +=item B<--warning-out> + +Threshold warning in percent for 'out' traffic. + +=item B<--critical-out> + +Threshold critical in percent for 'out' traffic. + +=item B<--interface> + +Set the interface (number expected) ex: 1, 2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index. + +=item B<--regexp> + +Allows to use regexp to filter interfaces (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--speed> + +Set interface speed (in Mb). + +=item B<--skip> + +Skip errors on interface status. + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/snmp_standard/mode/uptime.pm b/snmp_standard/mode/uptime.pm new file mode 100644 index 000000000..b49190e49 --- /dev/null +++ b/snmp_standard/mode/uptime.pm @@ -0,0 +1,122 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::mode::uptime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use POSIX; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "seconds" => { name => 'seconds', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{warn1} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{snmp} = $options{snmp}; + + my $oid_hrSystemUptime = '.1.3.6.1.2.1.25.1.1.0'; + my $result = $self->{snmp}->get_leef(oids => [ $oid_hrSystemUptime ]); + + my $exit_code = $self->{perfdata}->threshold_check(value => floor($result->{$oid_hrSystemUptime} / 100), + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->perfdata_add(label => 'uptime', + value => floor($result->{$oid_hrSystemUptime} / 100), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("System uptime is: %s", + defined($self->{option_results}->{seconds}) ? floor($result->{$oid_hrSystemUptime} / 100) . " seconds" : floor($result->{$oid_hrSystemUptime} / 86400 / 100) . " days" )); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check system uptime. + +=over 8 + +=item B<--warning> + +Threshold warning in seconds. + +=item B<--critical> + +Threshold critical in seconds. + +=item B<--seconds> + +Display uptime in seconds. + +=back + +=cut diff --git a/snmp_standard/plugin.pm b/snmp_standard/plugin.pm new file mode 100644 index 000000000..267ac4655 --- /dev/null +++ b/snmp_standard/plugin.pm @@ -0,0 +1,66 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program 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. +# +# This program 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 program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package snmp_standard::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'numeric-value' => 'snmp_standard::mode::numericvalue', + 'string-value' => 'snmp_standard::mode::stringvalue', + 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check SNMP values (string, numeric or execute commands). + +=cut diff --git a/src/Centreon/SNMP/Utils.pm b/src/Centreon/SNMP/Utils.pm deleted file mode 100644 index 9b1366638..000000000 --- a/src/Centreon/SNMP/Utils.pm +++ /dev/null @@ -1,200 +0,0 @@ -################################################################################ -# Copyright 2005-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL -# SVN : $Id -# -#################################################################################### - -use strict; -use Net::SNMP qw(:snmp); -use warnings; - -package Centreon::SNMP::Utils; - -sub load_oids { - my ($exit_status, $oid_file) = @_; - eval 'require Config::IniFiles;'; - - if ($@) { - print "Could not load the Perl module 'Config::IniFiles' $@"; - exit($exit_status); - } - require Config::IniFiles; - - unless (-e $oid_file) { - print "Unknown - In centreon.pm :: $oid_file :: $!\n"; - exit($exit_status); - } - - my %centreon; - tie %centreon, 'Config::IniFiles', ( -file => $oid_file ); - return %centreon; -} - - -sub check_snmp_options { - my ($exit_status, $OPTION) = @_; - my %session_params; - - if (!defined($OPTION->{host})) { - print "Missing parameter -H (--host).\n"; - exit $exit_status; - } - - $OPTION->{'snmp-version'} =~ s/^v//; - if ($OPTION->{'snmp-version'} !~ /1|2c|2|3/) { - print "Unknown snmp version\n"; - exit $exit_status; - } - - if ($OPTION->{'snmp-version'} eq "3") { - %session_params = (-hostname => $OPTION->{host}, -version => $OPTION->{'snmp-version'}, -port => $OPTION->{'snmp-port'}); - - if (defined($OPTION->{'snmp-auth-password'}) && defined($OPTION->{'snmp-auth-key'})) { - print "Only option -k (--authkey) or -p (--password) is needed for snmp v3\n"; - exit $exit_status; - } - - if (!(defined($OPTION->{'snmp-auth-protocol'}) && (defined($OPTION->{'snmp-auth-password'}) || defined($OPTION->{'snmp-auth-key'})) && defined($OPTION->{'snmp-auth-user'}))) { - print "Missing parameter to open SNMPv3 session\n"; - exit $exit_status; - } - $OPTION->{'snmp-auth-protocol'} = lc($OPTION->{'snmp-auth-protocol'}); - if ($OPTION->{'snmp-auth-protocol'} ne "md5" && $OPTION->{'snmp-auth-protocol'} ne "sha") { - print "Wrong authentication protocol. Must be MD5 or SHA\n"; - exit $exit_status; - } - $session_params{-username} = $OPTION->{'snmp-auth-user'}; - $session_params{-authprotocol} = $OPTION->{'snmp-auth-protocol'}; - if (defined($OPTION->{'snmp-auth-password'})) { - $session_params{-authpassword} = $OPTION->{'snmp-auth-password'}; - } else { - $session_params{-authkey} = $OPTION->{'snmp-auth-key'}; - } - - if ((defined($OPTION->{'snmp-priv-password'}) || defined($OPTION->{'snmp-priv-key'})) && defined($OPTION->{'snmp-priv-protocol'})) { - $OPTION->{'snmp-priv-protocol'} = lc($OPTION->{'snmp-priv-protocol'}); - if ($OPTION->{'snmp-priv-protocol'} ne "des" && $OPTION->{'snmp-priv-protocol'} ne "aes" && $OPTION->{'snmp-priv-protocol'} ne "aes128") { - print "Wrong encryption protocol. Must be DES, AES or AES128\n"; - exit $exit_status; - } - - if (defined($OPTION->{'snmp-priv-password'}) && defined($OPTION->{'snmp-priv-key'})) { - print "Only option --privpassword or --privkey is needed for snmp v3\n"; - exit $exit_status; - } - - $session_params{-privprotocol} = $OPTION->{'snmp-priv-protocol'}; - if (defined($OPTION->{'snmp-priv-password'})) { - $session_params{-privpassword} = $OPTION->{'snmp-priv-password'}; - } else { - $session_params{-privkey} = $OPTION->{'snmp-priv-key'}; - } - } - } else { - %session_params = (-hostname => $OPTION->{'host'}, - -community => $OPTION->{'snmp-community'}, - -version => $OPTION->{'snmp-version'}, - -port => $OPTION->{'snmp-port'}); - } - - if (defined($OPTION->{'64-bits'})) { - if ($OPTION->{'snmp-version'} =~ /1/) { - print "Error : Usage : SNMP v2/v3 is required with option --64-bits\n"; - exit $exit_status; - } - - eval 'require bigint'; - if ($@) { - print "Could not load the Perl module 'bigint' $@"; - exit($exit_status); - } - require bigint; - } - - if (defined($OPTION->{snmptimeout}) && $OPTION->{snmptimeout} =~ /^[0-9]+$/) { - $session_params{-timeout} = $OPTION->{snmptimeout}; - } - - return (\%session_params); -} - -# Method to connect to the remote host -# This method take the hash table option as argument -sub connection { - my ($exit_status, $session_params) = @_; - my ($session, $error); - - ($session, $error) = Net::SNMP->session(%$session_params); - if (!defined($session)) { - print "UNKNOWN: SNMP Session : $error\n"; - exit $exit_status; - } - - $session->translate(Net::SNMP->TRANSLATE_NONE); - return $session; -} - -sub get_snmp_table { - my ($oid, $session, $exit_status, $OPTION) = @_; - my $result; - - if (defined($OPTION) && defined($OPTION->{'maxrepetitions'})) { - $result = $session->get_table(Baseoid => $oid, -maxrepetitions => $OPTION->{'maxrepetitions'}); - } else { - $result = $session->get_table(Baseoid => $oid); - } - if (!defined($result)) { - printf("SNMP TABLE ERROR : %s.\n", $session->error); - $session->close; - exit $exit_status; - } - return $result; -} - -sub get_snmp_leef { - my ($oids, $session, $exit_status, $extra_msg) = @_; - my $result = $session->get_request(-varbindlist => $oids); - if (!defined($result)) { - printf("SNMP REQUEST ERROR : %s.", $session->error); - if (defined($extra_msg)) { - print $extra_msg; - } - print "\n"; - $session->close; - exit $exit_status; - } - return $result; -} - -1; diff --git a/src/centreon.conf b/src/centreon.conf deleted file mode 100644 index 1e5cb4750..000000000 --- a/src/centreon.conf +++ /dev/null @@ -1,51 +0,0 @@ -[GLOBAL] -DIR_NAGIOS=@INSTALL_DIR_NAGIOS@/ -NAGIOS_PLUGINS=@NAGIOS_PLUGINS@/ -NAGIOS_ETC=@NAGIOS_ETC@/ - -[NT] -CPU=.1.3.6.1.2.1.25.3.3.1.2 -HD_USED=.1.3.6.1.2.1.25.2.3.1.6 -HD_NAME=.1.3.6.1.2.1.25.2.3.1.3 - -[CISCO] -NB_CONNECT=.1.3.6.1.4.1.9.9.147.1.2.2.2.1.5.40.6 - -[UNIX] -CPU_USER=.1.3.6.1.4.1.2021.11.50.0 -CPU_SYSTEM=.1.3.6.1.4.1.2021.11.52.0 -CPU_LOAD_1M =.1.3.6.1.4.1.2021.10.1.3.1 -CPU_LOAD_5M =.1.3.6.1.4.1.2021.10.1.3.2 -CPU_LOAD_15M =.1.3.6.1.4.1.2021.10.1.3.3 - -[DELL] -TEMP=.1.3.6.1.4.1.674.10892.1.700.20.1.6.1 - -[ALTEON] -VIRT=1.3.6.1.4.1.1872.2.1.8.2.7.1.3.1 -FRONT=1.3.6.1.4.1.1872.2.1.8.2.5.1.3.1 - -[MIB2] -SW_RUNNAME=.1.3.6.1.2.1.25.4.2.1.2 -SW_RUNINDEX=.1.3.6.1.2.1.25.4.2.1.1 -SW_RUNSTATUS=.1.3.6.1.2.1.25.4.2.1.7 -HR_STORAGE_DESCR=.1.3.6.1.2.1.25.2.3.1.3 -HR_STORAGE_ALLOCATION_UNITS=.1.3.6.1.2.1.25.2.3.1.4 -HR_STORAGE_SIZE=.1.3.6.1.2.1.25.2.3.1.5 -HR_STORAGE_USED=.1.3.6.1.2.1.25.2.3.1.6 -OBJECTID=.1.3.6.1.2.1.1.1.0 -UPTIME_WINDOWS=.1.3.6.1.2.1.1.3.0 -UPTIME_OTHER=.1.3.6.1.2.1.1.3.0 -IF_IN_OCTET=.1.3.6.1.2.1.2.2.1.10 -IF_OUT_OCTET=.1.3.6.1.2.1.2.2.1.16 -IF_SPEED=.1.3.6.1.2.1.2.2.1.5 -IF_OUT_OCTET_64_BITS=.1.3.6.1.2.1.31.1.1.1.10 -IF_IN_OCTET_64_BITS=.1.3.6.1.2.1.31.1.1.1.6 -IF_SPEED_64_BITS=.1.3.6.1.2.1.31.1.1.1.15 -IF_DESC=.1.3.6.1.2.1.2.2.1.2 -IF_IN_ERROR=.1.3.6.1.2.1.2.2.1.14 -IF_OUT_ERROR=.1.3.6.1.2.1.2.2.1.20 -IF_ADMINSTATUS=.1.3.6.1.2.1.2.2.1.7 -IF_OPERSTATUS=.1.3.6.1.2.1.2.2.1.8 -IF_ALIAS=.1.3.6.1.2.1.31.1.1.1.18 -IF_NAME=.1.3.6.1.2.1.31.1.1.1.1 diff --git a/src/check_centreon_MS_multiple_services b/src/check_centreon_MS_multiple_services deleted file mode 100644 index 1d3f9a361..000000000 --- a/src/check_centreon_MS_multiple_services +++ /dev/null @@ -1,222 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_p $opt_n $result @result %process_list); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); - -# Plugin var init - -my($proc, $proc_run); - -$PROGNAME = $0; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "n" => \$opt_n, "number" => \$opt_n, - "p=s" => \$opt_p, "process=s" => \$opt_p); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -my $process; -if(!$opt_p) { - print_usage(); - exit $ERRORS{'OK'}; -} elsif ($opt_p !~ /([-.A-Za-z0-9\,]+)/){ - print_usage(); - exit $ERRORS{'OK'}; -} -$process = $opt_p; -my @process_temp = split /\,/,$opt_p; -my (@proc,@status); -foreach (@process_temp) { - $status[scalar(@status)] = 0; - $proc[scalar(@proc)] = $_; -} -my $name = $0; - -# Plugin snmp requests -my $OID_SW_ServiceName = "1.3.6.1.4.1.77.1.2.3.1.1"; -my $OID_SW_ServiceInstallStatus = "1.3.6.1.4.1.77.1.2.3.1.2"; -my $OID_SW_ServiceStatus = "1.3.6.1.4.1.77.1.2.3.1.3"; - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -$result = Centreon::SNMP::Utils::get_snmp_table($OID_SW_ServiceName, $session, $ERRORS{'UNKNOWN'}, \%OPTION); -my %install_status = ( 1=>"Uninstalled", 2=> "Install-pending", 3=> "Uninstall-Pending", 4=>"Installed"); -my %defined_status = ( 1=>"Active", 2=>"Continue-Pending", 3=> "Pause-Pending", 4=> "Paused"); -foreach my $key (oid_lex_sort(keys %$result)) { - my $found = 0; - for(my $i = 0; $i < scalar(@proc) && !$found; $i++) { - my $value = substr($key, length($OID_SW_ServiceName)+1, length($key)); - if (lc $proc[$i] eq lc $result->{$key}) { - my $result2 = Centreon::SNMP::Utils::get_snmp_leef([$OID_SW_ServiceInstallStatus . "." . $value], $session, $ERRORS{'UNKNOWN'}); - if ((my $temp_installStatus_val = $result2->{$OID_SW_ServiceInstallStatus . "." . $value})) { - if ($temp_installStatus_val != 1 && $temp_installStatus_val != 3) { - $result2 = Centreon::SNMP::Utils::get_snmp_leef([$OID_SW_ServiceStatus . "." . $value], $session, $ERRORS{'UNKNOWN'}); - $status[$i] = $defined_status{$result2->{$OID_SW_ServiceStatus . "." . $value}}; - } else { - $status[$i] = $install_status{$temp_installStatus_val}; - } - } - $found = 1; - } - } -} - -my $final_status = "OK"; -my $active = ""; -my $inactive = ""; -my $unknown = ""; -# Plugin return code -for (my $i = 0; $i < scalar(@proc); $i++) { - if (defined($status[$i])) { - my $written = 0; - if ($final_status ne "CRITICAL" && $status[$i] eq "0") { - $status[$i] = "Unknown"; - $final_status = "WARNING"; - $written = 1; - $unknown .= $proc[$i]." - "; - } - if ($final_status ne "CRITICAL" && $status[$i] eq "Uninstall-Pending" || $status[$i] eq "Pause-Pending") { - $final_status = "WARNING"; - $written = 1; - $inactive .= $proc[$i]." - "; - } - if ($status[$i] && ($status[$i] eq "Uninstalled" || $status[$i] eq "paused")) { - $final_status = "CRITICAL"; - $written = 1; - $inactive .= $proc[$i]." - "; - } - if (!$written) { - $active .= $proc[$i]." - "; - } - } -} -my $msg = ""; -if ($inactive ne "") { - $msg .= "INACTIVE : $inactive "; -} -if ($unknown ne "") { - $msg .= "UNKNOWN : $unknown "; -} -if ($active ne "") { - $msg .= "ACTIVE : $active"; -} -$msg =~ s/\- $//; -print "$msg\n"; -exit $ERRORS{$final_status}; - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " --password snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -n (--number) Return the number of current running processes. \n"; - print " -p (--process) Set the process name ex: by default smbd\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_dummy b/src/check_centreon_dummy deleted file mode 100644 index deb179f01..000000000 --- a/src/check_centreon_dummy +++ /dev/null @@ -1,110 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2011 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Plugin init -# - -use strict; -use FindBin; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_h $opt_s $opt_o); - -################################################# -### Plugin var init -## -$PROGNAME = "$0"; - -sub print_help (); -sub print_usage (); - -Getopt::Long::Configure('bundling'); -GetOptions - ("h" => \$opt_h, "help" => \$opt_h, - "s=s" => \$opt_s, "status=s" => \$opt_s, - "o=s" => \$opt_o, "output=s" => \$opt_o); - - -################################################## -#### Verify Options -## - -if ($opt_h) { - print_help(); - exit 0; -} - -if (!defined($opt_s)) { - print_usage && exit 0; -} -if ($opt_s ne "0" && $opt_s ne "1" && $opt_s ne "2" && $opt_s ne "3") { - print_usage; - exit 0; -} -if (!$opt_o) { - $opt_o = "OK"; -} - -################################################# -## result -# - -$opt_o .= "\n"; -print $opt_o; -exit $opt_s; - -sub print_usage () { - print "Usage: $PROGNAME -s 2 -o 'This service is CRITICAL'\n"; - print " -s (--status) Value between 0 and 3 to return the Nagios status (Required)\n"; - print " 0 returns OK status\n"; - print " 1 returns WARNING status\n"; - print " 2 returns CRITICAL status\n"; - print " 3 returns UNKNOWN status\n"; - print " -o (--output) Output message that must be returned (Default: 'OK')\n"; - print " -h (--help) Usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2011 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} \ No newline at end of file diff --git a/src/check_centreon_ping b/src/check_centreon_ping deleted file mode 100644 index 7d8dba761..000000000 --- a/src/check_centreon_ping +++ /dev/null @@ -1,226 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2011 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL: http://svn.centreon.com/trunk/plugins-2.x/src/check_centreon_ping $ -# SVN : $Id: check_centreon_ping 12606 2011-10-14 16:11:39Z shotamchay $ -# -#################################################################################### -# -# Plugin init -# - -use strict; -use FindBin; -use lib "$FindBin::Bin"; -use lib "@NAGIOS_PLUGINS@"; -use utils qw($TIMEOUT %ERRORS &print_revision &support); - -if (eval "require centreon" ) { - use centreon qw(get_parameters); - use vars qw($VERSION %centreon); - %centreon = get_parameters(); -} else { - print "Unable to load centreon perl module\n"; - exit $ERRORS{'UNKNOWN'}; -} - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_H $opt_D $opt_w $opt_c $opt_n $opt_f $opt_i $rta_critical $rta_warning $pl_critical $pl_warning $opt_s); - - -# -# Plugin var init -# - -my $ping = `whereis -b ping`; -$ping =~ /^.*:\s(.*)$/; -$ping = $1; - -$PROGNAME = "$0"; -sub print_help (); -sub print_usage (); - -Getopt::Long::Configure('bundling'); -GetOptions - ("h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c, - "n=s" => \$opt_n, "number=s" => \$opt_n, - "H=s" => \$opt_H, "hostname=s" => \$opt_H, - "i=s" => \$opt_i); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -$opt_H = shift unless ($opt_H); -(print_usage() && exit $ERRORS{'OK'}) unless ($opt_H); - -($opt_c) || ($opt_c = shift) || ($opt_c = "500,40%"); -if ($opt_c =~ /([0-9]+),([0-9]+)%/) { - $rta_critical = $1; - $pl_critical = $2; -} - -($opt_w) || ($opt_w = shift) || ($opt_w = "200,20%"); -if ($opt_w =~ /([0-9]+),([0-9]+)%/) { - $rta_warning = $1; - $pl_warning = $2; -} -if (!$rta_warning || !$rta_critical || !$pl_warning || !$pl_critical) { - print "bad initialisation of Treshholds\n"; - exit $ERRORS{'OK'}; -} - -if ( ($rta_critical <= $rta_warning) || ($pl_critical <= $pl_warning) ) { - print "critical must be superior to warning\n"; - exit $ERRORS{'OK'}; -} - -($opt_n) || ($opt_n = shift) || ($opt_n = 1); -my $NbPing; -if ($opt_n =~ /([0-9]+)/){ - $NbPing = $1; -} else{ - print "Unknown ping number\n"; - exit $ERRORS{'UNKNOWN'}; -} - -my $start=time; - -# -# Plugin requests -# - -$opt_i = 1 if (!defined($opt_i) || !$opt_i); - -$_ = `$ping -n -c $NbPing -i $opt_i $opt_H 2>/dev/null`; -my $return = $? / 256; - -# -# Get Data From Ping Result -# - -if (!$_) { - print "no value returned by ping\n"; - exit $ERRORS{'UNKNOWN'}; -} - -my $ping_result = $_; -my @ping_result_array = split(/\n/,$ping_result); -my @ping_subresult1_array; -my @ping_subresult2_array; -my $rta = 0; -my $pl; -my $time_answer; - -if( ( $return != 0 ) || $ping_result_array[@ping_result_array -2 ] =~ /100% packet loss/) { - $rta = -1; - $time_answer = 0; -} else { - @ping_subresult1_array = split(/=/,$ping_result_array[@ping_result_array -1 ]); - @ping_subresult2_array = split(/,/,$ping_result_array[@ping_result_array -2 ]); - @ping_subresult1_array = split(/\//,$ping_subresult1_array[1]); - @ping_subresult2_array = split(/ /,$ping_subresult2_array[2]); - $rta = $ping_subresult1_array[1]; - $pl = $ping_subresult2_array[1]; - $time_answer = $ping_subresult1_array[1]; - $pl =~ /([0-9]+)\%/; - $pl = $1; -} - -# -# Plugin return code -# - -my $result_str = ""; - -if( $rta == -1 ) { - $ping_result_array[@ping_result_array - 2] =~ s/\%/percent/g; - if (length($ping_result_array[@ping_result_array - 5]) && $ping_result_array[@ping_result_array - 5] !~ m/pipe/g) { - print "PING CRITICAL - ".$ping_result_array[@ping_result_array - 5]."|time=0 ok=0\n"; - } elsif (length($ping_result_array[@ping_result_array - 1]) != 0 && $ping_result_array[@ping_result_array - 1] !~ m/pipe/g) { - print "PING CRITICAL - ".$ping_result_array[@ping_result_array - 1]."|time=0 ok=0\n"; - } elsif (length($ping_result_array[@ping_result_array - 4]) && $ping_result_array[@ping_result_array - 4] !~ m/pipe/g) { - print "PING CRITICAL - ".$ping_result_array[@ping_result_array - 4]."|time=0 ok=0\n"; - } elsif (length($ping_result_array[@ping_result_array - 1]) !~ m/pipe/g) { - print "PING CRITICAL - ".$ping_result_array[@ping_result_array - 1]."|time=0 ok=0\n"; - } else { - print "PING CRITICAL - ".$ping_result_array[@ping_result_array - 3]."|time=0 ok=0\n"; - } - exit $ERRORS{'CRITICAL'}; -} elsif ( ($pl >= $pl_critical) || ($rta >= $rta_critical) ) { - $ping_result_array[@ping_result_array -1 ] =~ s/\%/percent/g; - my @tab = split(/,/,$ping_result_array[@ping_result_array -1 ]); - print "PING CRITICAL - ". $tab[0] ."|time=".$time_answer."ms;$rta_warning;$rta_critical;0; ok=1\n"; - exit $ERRORS{'CRITICAL'}; -} elsif ( ($pl >= $pl_warning) || ($rta >= $rta_warning) ) { - $ping_result_array[@ping_result_array -1 ] =~ s/\%/percent/g; - my @tab = split(/,/,$ping_result_array[@ping_result_array -1 ]); - print "PING WARNING - ".$tab[0]."|time=".$time_answer."ms;$rta_warning;$rta_critical;0; ok=1\n"; - exit $ERRORS{'WARNING'}; -} else { - $ping_result_array[@ping_result_array -1 ] =~ s/\%/percent/g; - my @tab = split(/,/,$ping_result_array[@ping_result_array -1 ]); - print "PING OK - ".$tab[0]."|time=".$time_answer."ms;$rta_warning;$rta_critical;0; ok=1\n"; - exit $ERRORS{'OK'}; -} - -sub print_usage () { - print "Usage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (Required)\n"; - print " -w (--warning) Threshold pair (Default: 200,20%)\n"; - print " -c (--critical) Threshold pair (Default: 500,40%)\n"; - print " -n (--number) Number of ICMP ECHO packets to send (Default: 1)\n"; - print " -i Interval between ping (Default: 1s)\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) Usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2011 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_TcpConn b/src/check_centreon_snmp_TcpConn deleted file mode 100644 index 29be70a7b..000000000 --- a/src/check_centreon_snmp_TcpConn +++ /dev/null @@ -1,167 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Plugin init - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_h $opt_V $opt_p $opt_c $opt_w); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); - -my $Revision = 1.2.1; - -$PROGNAME = "ckeck_TcpConn"; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "p=i" => \$opt_p, "port=s" => \$opt_p, - "c=s" => \$opt_c, "w=s" => \$opt_w -); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.0'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); - -$opt_p = shift unless ($opt_p); -(print_usage() && exit $ERRORS{'OK'}) unless ($opt_p); - -my $name = $0; -$name =~ s/\.pl.*//g; -my $day = 0; - -#=== create a SNMP session ==== -# 1.3.6.1.4.1.232.1.2.2.1.1.6 -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -my $OID_TCP_PORT = ".1.3.6.1.2.1.6.13.1.3"; - -my $result = Centreon::SNMP::Utils::get_snmp_table($OID_TCP_PORT, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -my $cpt = 0; -foreach my $key (oid_lex_sort(keys %$result)) { - if ($result->{$key} == $opt_p) { - $cpt++; - } -} - -if (!defined($opt_w)){$opt_w = 20;} -if (!defined($opt_c)){$opt_c = 30;} - -print "Number of connections on port $opt_p : $cpt |nb_conn=$cpt\n"; -if ($cpt >= $opt_w && $cpt < $opt_c){ - exit $ERRORS{'WARNING'}; -} elsif ($cpt >= $opt_c){ - exit $ERRORS{'CRITICAL'}; -} else { - exit $ERRORS{'OK'}; -} - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " --password snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -p (--port) port you want to check - (required)\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_cpu b/src/check_centreon_snmp_cpu deleted file mode 100644 index 77e15bd87..000000000 --- a/src/check_centreon_snmp_cpu +++ /dev/null @@ -1,190 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_c $opt_w $opt_D $snmp @critical @warning $opt_l); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); - -my %centreon = Centreon::SNMP::Utils::load_oids($ERRORS{'UNKNOWN'}, "@NAGIOS_PLUGINS@/centreon.conf"); -# Plugin var init - -my($return_code); - -$PROGNAME = "$0"; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "p|authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c, - "l" => \$opt_l); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.3 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -$opt_l = 0 if (!defined($opt_l)); - -$opt_c = 95 if (!defined($opt_c) || !$opt_c); -$opt_w = 90 if (!defined($opt_w) || !$opt_w); - -my $name = $0; -$name =~ s/\.pl.*//g; - -# Plugin snmp requests - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -my $OID_CPU = ".1.3.6.1.2.1.25.3.3.1.2"; - -# Get all datas -my $result = Centreon::SNMP::Utils::get_snmp_table($OID_CPU, $session, $ERRORS{'UNKNOWN'}, \%OPTION, " Error getting CPU percentage."); - -# Get all values and computes average cpu. -my $cpu = 0; -my $i = 0; -my @cpulist; -foreach my $key ( oid_lex_sort(keys %$result)) { - my @oid_list = split (/\./,$key); - my $index = pop (@oid_list); - $cpulist[$i] = $$result{$key}; - $cpu += $$result{$key}; - $i++; -} -undef($result); - -$cpu /= $i; - -# Plugin return code -my $status = "OK"; -if ($cpu >= $opt_c) { - $status = "CRITICAL"; -} elsif ($cpu >= $opt_w) { - $status = "WARNING"; -} - -my $str = "CPU utilization percentage : ".$cpu."%|avg=".$cpu."%;$opt_w;$opt_c;0;100"; -if ($opt_l == 0) { - for ($i = 0; defined($cpulist[$i]); $i++){ - $str .= " cpu$i=".$cpulist[$i]."%"; - } -} - -# Display Ouptut -print $str."\n"; -exit $ERRORS{$status}; - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print "This Plugin is design for return CPU percent on windows Serveurs (1 min Average)\n"; - print "\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " -p (--password) snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -c (--critical) Three critical tresholds (defaults : 95)\n"; - print " -w (--warning) Three warning tresholds (defaults : 90)\n"; - print " -l Display only cpu average\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_loadaverage b/src/check_centreon_snmp_loadaverage deleted file mode 100644 index 1e9a28272..000000000 --- a/src/check_centreon_snmp_loadaverage +++ /dev/null @@ -1,183 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_c $opt_w $opt_D @critical @warning); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); -my %centreon = Centreon::SNMP::Utils::load_oids($ERRORS{'UNKNOWN'}, "@NAGIOS_PLUGINS@/centreon.conf"); - -# Plugin var init - -$PROGNAME = "$0"; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "p|authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -if ($opt_c && $opt_c =~ /^([0-9\.]+),([0-9\.]+),([0-9\.]+)$/) { - @critical = ($1,$2,$3); -} elsif (!defined($opt_c) && !$opt_c){ - @critical = ('2', '4', '6'); -} else { - print "Specify three critical treshold separated with a coma\n"; - exit $ERRORS{'OK'}; -} - -if ($opt_w && $opt_w =~ /^([0-9\.]+),([0-9\.]+),([0-9\.]+)$/) { - @warning = ($1,$2,$3); -} elsif (!defined($opt_w) && !$opt_w) { - @warning = ('1', '3', '5'); -} else { - print "Specify three warning treshold separated with a coma\n"; - exit $ERRORS{'UNKNOWN'}; -} - -for (my $i = 0; $i < scalar(@warning); $i++) { - if ($warning[$i] >= $critical[$i]) { - print "Critical tresholds must be superior to warning tresholds.\n"; - exit $ERRORS{'UNKNOWN'}; - } -} - -my $name = $0; -$name =~ s/\.pl.*//g; - -# Plugin snmp requests -my $OID_CPULOAD_1 = $centreon{UNIX}{CPU_LOAD_1M}; -my $OID_CPULOAD_5 = $centreon{UNIX}{CPU_LOAD_5M}; -my $OID_CPULOAD_15 =$centreon{UNIX}{CPU_LOAD_15M}; - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -my $result = Centreon::SNMP::Utils::get_snmp_leef([$OID_CPULOAD_1, $OID_CPULOAD_5, $OID_CPULOAD_15], $session, $ERRORS{'UNKNOWN'}); -my $un = $result->{$OID_CPULOAD_1}; -my $cinq = $result->{$OID_CPULOAD_5}; -my $quinze = $result->{$OID_CPULOAD_15}; - -# Plugin return code -my $status = "OK"; - -$status = "WARNING" if ($warning[0] <= $un || $warning[1] <= $cinq || $warning[2] <= $quinze); -$status = "CRITICAL" if ($critical[0] <= $un || $critical[1] <= $cinq || $critical[2] <= $quinze); - -# Print output -print "Load average: ".$un.", ".$cinq.", ".$quinze.".|load1=".$un." load5=".$cinq." load15=".$quinze."\n"; -exit $ERRORS{$status}; - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " -p (--password) snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -c (--critical) Three critical tresholds (defaults : 2,4,6)\n"; - print " -w (--warning) Three warning tresholds (defaults : 1,3,5)\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_memory b/src/check_centreon_snmp_memory deleted file mode 100644 index 5061345b6..000000000 --- a/src/check_centreon_snmp_memory +++ /dev/null @@ -1,280 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_w $opt_c $opt_s); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); -my %centreon = Centreon::SNMP::Utils::load_oids($ERRORS{'UNKNOWN'}, "@NAGIOS_PLUGINS@/centreon.conf"); - -## -## Plugin var init -## - -my ($hrStorageDescr, $hrStorageAllocationUnits, $hrStorageSize, $hrStorageUsed); -my ($AllocationUnits, $Size, $Used); -my ($tot, $used, $pourcent, $return_code); - -$PROGNAME = "$0"; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, - "disable-swap" => undef -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "p|authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - "S" => \$OPTION{'disable-swap'}, - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c, - "s=s" => \$opt_s, "swap=s" => \$opt_s); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); - -($opt_c) || ($opt_c = shift) || ($opt_c = 95); -my $critical = $1 if ($opt_c =~ /([0-9]+)/); - -($opt_w) || ($opt_w = shift) || ($opt_w = 80); -my $warning = $1 if ($opt_w =~ /([0-9]+)/); -if ($critical <= $warning){ - print "(--crit) must be superior to (--warn)"; - print_usage(); - exit $ERRORS{'OK'}; -} - -my $swap_limit; -if ($opt_s) { - ($opt_s) || ($opt_s = shift) || ($opt_s = 10); - $swap_limit = $1 if ($opt_s =~ /([0-9]+)/); -} - -my $start=time; -my $name = $0; - -## Plugin snmp requests - -# my $OID_hrStorageDescr = $centreon{MIB2}{HR_STORAGE_DESCR}; -# my $OID_hrStorageAllocationUnits =$centreon{MIB2}{HR_STORAGE_ALLOCATION_UNITS}; -# my $OID_hrStorageSize =$centreon{MIB2}{HR_STORAGE_SIZE}; -# my $OID_hrStorageUsed =$centreon{MIB2}{HR_STORAGE_USED}; - -# create a SNMP session -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - - -#################### -#### snmp request -## - -my $OID_descr_storage = ".1.3.6.1.2.1.25.2.3.1.3"; #"1.3.6.1.2.1.25.2.3.1.1"; -my $result = Centreon::SNMP::Utils::get_snmp_table($OID_descr_storage, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -my ($virt_alloc, my $virt_used, my $virt_size); - -my $indexV = 0; -my $indexR = 0; -my $indexC = 0; - -foreach my $key (oid_lex_sort(keys %$result)) { - if ($result->{$key} =~ m/Swap|Virtual/) { - my @cpt = split /\./,$key; - $indexV = $cpt[scalar(@cpt) - 1];; - } - if ($result->{$key} =~ m/Real|Physical/) { - my @cpt = split /\./,$key; - $indexR = $cpt[scalar(@cpt)-1]; - } - if ($result->{$key} =~ m/Cached/) { - my @cpt = split /\./,$key; - $indexC = $cpt[scalar(@cpt)-1]; - } -} -if ($indexV == 0 || $indexR == 0) { - printf("ERROR: cannot find ram information"); - exit $ERRORS{'UNKNOWN'}; -} -my $OID_hrStorage_used = ".1.3.6.1.2.1.25.2.3.1.6"; -my $OID_Swap_storage_used = ".1.3.6.1.2.1.25.2.3.1.6.".$indexV; -my $OID_RealM_storage_used = ".1.3.6.1.2.1.25.2.3.1.6.".$indexR; - - -my $used_mem = Centreon::SNMP::Utils::get_snmp_table($OID_hrStorage_used, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -my $OID_hrStorage_size = ".1.3.6.1.2.1.25.2.3.1.5"; -my $OID_Swap_storage_size = ".1.3.6.1.2.1.25.2.3.1.5.".$indexV; -my $OID_RealM_storage_size = ".1.3.6.1.2.1.25.2.3.1.5.".$indexR; -my $OID_Cache_storage_size = ".1.3.6.1.2.1.25.2.3.1.5.".$indexC; - -my $total_mem = Centreon::SNMP::Utils::get_snmp_table($OID_hrStorage_size, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -my $OID_storage_allocationUnits = ".1.3.6.1.2.1.25.2.3.1.4"; -my $OID_Swap_storage_allocationUnits = ".1.3.6.1.2.1.25.2.3.1.4.".$indexV; -my $OID_RealM_storage_allocationUnits = ".1.3.6.1.2.1.25.2.3.1.4.".$indexR; -my $OID_Cache_storage_allocationUnits = ".1.3.6.1.2.1.25.2.3.1.4.".$indexC; -my $alloc_units = Centreon::SNMP::Utils::get_snmp_table($OID_storage_allocationUnits, $session, $ERRORS{'UNKNOWN'}, \%OPTION); -my $swap_used = $used_mem->{$OID_Swap_storage_used} * $alloc_units->{$OID_Swap_storage_allocationUnits}; -my $realM_used = $used_mem->{$OID_RealM_storage_used} * $alloc_units->{$OID_RealM_storage_allocationUnits}; - -my $cache_used = 0; - -if (defined $indexC > 0) { - if (defined($total_mem->{$OID_Cache_storage_size}) && defined($alloc_units->{$OID_Cache_storage_allocationUnits})) { - $cache_used = $total_mem->{$OID_Cache_storage_size} * $alloc_units->{$OID_Cache_storage_allocationUnits}; - } -} - -my $swap_size = $total_mem->{$OID_Swap_storage_size} * $alloc_units->{$OID_Swap_storage_allocationUnits}; -my $realM_size = $total_mem->{$OID_RealM_storage_size} * $alloc_units->{$OID_RealM_storage_allocationUnits}; -my ($total_memory_used, $total_memory_size); -if (defined($OPTION{'disable-swap'})) { - $total_memory_used = $realM_used - $cache_used; - $total_memory_size = $realM_size; -} else { - $total_memory_used = $swap_used + $realM_used - $cache_used; - $total_memory_size = $swap_size + $realM_size; -} - -# percentage of total, physical and swap memory used -if ($swap_size eq "0"){ - $swap_size = 1; -} - -my $percent_used = ($total_memory_used/$total_memory_size)*100; -my $percent_swap_used = ($swap_used/$swap_size) * 100; -my $percent_realM_used = ($realM_used/$realM_size) * 100; -$percent_swap_used =~ s/\.[0-9]+//; -$percent_used =~ s/\.[0-9]+//; -$percent_realM_used =~ s/\.[0-9]+//; - -# return - -if (($opt_s) && ($opt_s =~ /([0-9]+)/)) { - if (($percent_realM_used >= 99) && ($percent_swap_used > $swap_limit)) { - print "Swap threshold (".$opt_s."%) excedeed : total memory used : ".$percent_used."%, ram used : ".$percent_realM_used."%, swap used : ".$percent_swap_used."% | used=".$total_memory_used."o size=".$total_memory_size."o\n"; - exit $ERRORS{'CRITICAL'}; - } -} - -if ($percent_used >= $opt_c){ - print "Threshold (".$opt_c."%) excedeed : total memory used : ".$percent_used."%, ram used : ".$percent_realM_used."%, swap used : ".$percent_swap_used."% | used=".$total_memory_used."o size=".$total_memory_size."o\n"; - exit $ERRORS{'CRITICAL'}; -} elsif ($percent_used >= $opt_w){ - print "Threshold (".$opt_w."%) excedeed : total memory used : ".$percent_used."%, ram used : ".$percent_realM_used."%, swap used ".$percent_swap_used."% | used=".$total_memory_used."o size=".$total_memory_size."o\n"; - exit $ERRORS{'WARNING'}; -} else { - print "Total memory used : ".$percent_used."% ram used : ".$percent_realM_used."%, swap used ".$percent_swap_used."% | used=".$total_memory_used."o size=".$total_memory_size."o\n"; - exit $ERRORS{'OK'}; -} - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " -p (--password) snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; - print " -c (--critical) percentage of memory used at which a critical message will be generated\n"; - print " -w (--warning) percentage of memory used at which a warning message will be generated\n"; - print " -s (--swap) limit of swap memory can reach before the service turns critical, while phyical memory is near 100%\n"; - print " -S Do not add swap size in total memory size, perfdata will show ram size corresponding physical size installed\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_multiple_process b/src/check_centreon_snmp_multiple_process deleted file mode 100644 index 61ea2b33c..000000000 --- a/src/check_centreon_snmp_multiple_process +++ /dev/null @@ -1,229 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_d $opt_h $opt_p $result @result %process_list); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); - -my %centreon = Centreon::SNMP::Utils::load_oids($ERRORS{'UNKNOWN'}, "@NAGIOS_PLUGINS@/centreon.conf"); - -# Plugin var init - -my($proc, $proc_run); - -$PROGNAME = $0; -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "p=s" => \$opt_p, "process=s" => \$opt_p, - "d" => \$opt_d, "debug" => \$opt_d); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); - -my $process; -if(!$opt_p) { - print_usage(); - exit $ERRORS{'OK'}; -} elsif ($opt_p !~ /([-.A-Za-z0-9\,]+)/){ - print_usage(); - exit $ERRORS{'OK'}; -} -$process = $opt_p; -my @process_temp = split /\,/,$opt_p; -my (@proc,@status,@parameters); -foreach (@process_temp) { - my @tab = split /\:/,$_; - $status[scalar(@proc)] = 0; - $proc[scalar(@proc)] = $tab[0]; - $parameters[scalar(@parameters)] = $tab[1]; -} -my $name = $0; - -# Plugin snmp requests -my $OID_SW_RunName = $centreon{MIB2}{SW_RUNNAME}; -my $OID_SW_RunParameters = $centreon{MIB2}{SW_RUNPARAMETERS}; -my $OID_SW_RunIndex =$centreon{MIB2}{SW_RUNINDEX}; -my $OID_SW_RunStatus =$centreon{MIB2}{SW_RUNSTATUS}; - -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); -$result = Centreon::SNMP::Utils::get_snmp_table($OID_SW_RunName, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -my %defined_status = (0=>"NotPresent", 1=>"Running", 2=> "Runnable", 3=> "NotRunnable", 4=>"Invalid"); -foreach my $key (oid_lex_sort(keys %$result)) { - my $found = 0; - for(my $i = 0; $i < scalar(@proc) && !$found; $i++) { - my @oid_list = split (/\./,$key); - my $value = pop(@oid_list); - if (lc $proc[$i] eq lc $result->{$key}) { - my $result2 = Centreon::SNMP::Utils::get_snmp_leef([$OID_SW_RunStatus . "." . $value], $session, $ERRORS{'UNKNOWN'}); - my $temp_status_val = $result2->{$OID_SW_RunStatus . "." . $value}; - if (defined ($parameters[$i]) && $parameters[$i] ne "") { - $result2 = Centreon::SNMP::Utils::get_snmp_leef([$OID_SW_RunParameters . "." . $value], $session, $ERRORS{'UNKNOWN'}); - if (lc $parameters[$i] eq lc $result2->{$OID_SW_RunParameters . "." . $value}) { - $status[$i] = $temp_status_val; - $found = 1; - } - } else { - $status[$i] = $temp_status_val; - $found = 1; - } - } - } -} - -my $final_status = "OK"; -my $msg = ""; -my $notPresent = ""; -my $critical =""; -my $OK = ""; -# Plugin return code -my $unKnown = ""; -#$msg =~ s/\-$//; -for (my $i = 0; $i < scalar(@proc); $i++) { - if (defined($status[$i])) { - if ($status[$i] != 1 && $status[$i] != 2) { - if ($status[$i] == 0) { - $final_status = "CRITICAL"; - $notPresent .= $proc[$i]." - "; - } - if ($status[$i]) { - $final_status = "CRITICAL"; - $critical .= $proc[$i]." - "; - } - } else { - $OK .= $proc[$i]." - "; - } - } else { - $unKnown .= $proc[$i]." - "; - } -} -if ($critical ne "") { - $msg = "CRITICAL : $critical"; -} -if ($notPresent ne "") { - $msg .= "NOT-PRESENT : $notPresent"; -} -if ($OK ne "" && $opt_d) { - $msg .= "OK : $OK"; -} -if ($msg eq "" ) { - $msg = "All process OK"; -} -$msg =~ s/\- $//; -print "$msg\n"; -exit $ERRORS{$final_status}; - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " --password snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -p (--process) Set the process name ex: by default smbd\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_packetErrors b/src/check_centreon_snmp_packetErrors deleted file mode 100644 index f4fcb3762..000000000 --- a/src/check_centreon_snmp_packetErrors +++ /dev/null @@ -1,265 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Plugin init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_w $opt_c); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); -my $centplugins_path = "@CENTPLUGINS_TMP@"; - -# -# Plugin var init -# -$PROGNAME = "$0"; - -my ($row, @flg_created, @last_check_time, @last_in_errors, @last_out_errors, $result_in, $result_out, @nb_out_errors, @nb_in_errors, $update_time, $db_file); - -sub print_help (); -sub print_usage (); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "p|authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -################################################## -##### Verify Options -## - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); - -($opt_c) || ($opt_c = shift) || ($opt_c = 100); -my $critical = $1 if ($opt_c =~ /([0-9]+)/); - -($opt_w) || ($opt_w = shift) || ($opt_w = 80); -my $warning = $1 if ($opt_w =~ /([0-9]+)/); - -if ($critical <= $warning){ - print "(--crit) must be superior to (--warn)"; - print_usage(); - exit $ERRORS{'OK'}; -} - -my $start = time; - -################################################# -##### Plugin snmp requests -## - -my $OID_IN_ERRORS = ".1.3.6.1.2.1.2.2.1.14"; -my $OID_OUT_ERRORS = ".1.3.6.1.2.1.2.2.1.20"; -my $OID_IF_DESC = ".1.3.6.1.2.1.2.2.1.2"; - - -# create a SNMP session -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -####### Get IN ERRORS -$result_in = Centreon::SNMP::Utils::get_snmp_table($OID_IN_ERRORS, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -# loop for each interface -foreach my $err (oid_lex_sort(keys %$result_in)) { - $nb_in_errors[scalar(@nb_in_errors)] = $result_in->{$err}; -} -# ####### Get OUT ERRORS - -$result_out = Centreon::SNMP::Utils::get_snmp_table($OID_OUT_ERRORS, $session, $ERRORS{'UNKNOWN'}, \%OPTION); -foreach my $err (oid_lex_sort(keys %$result_out)) { - $nb_out_errors[scalar(@nb_out_errors)] = $result_out->{$err}; -} - -# ####### Get Interface descriptions for output -my @desc_tab; -my $if_description = Centreon::SNMP::Utils::get_snmp_table($OID_IF_DESC, $session, $ERRORS{'UNKNOWN'}, \%OPTION); -foreach my $desc (oid_lex_sort(keys %$if_description)) { - $desc_tab[scalar(@desc_tab)] = $if_description->{$desc} if ($if_description->{$desc} !~ m/StackSub/i); -} - - -# ############################################# -# ##### read and write in buffer file -# ## - -for (my $i = 0; $i < scalar(@nb_in_errors); $i++) { - if (-e $centplugins_path . "/packet_errors_if".$i."_" . $OPTION{'host'} . ".tmp") { - open(FILE,"<" . $centplugins_path . "/packet_errors_if".$i."_" . $OPTION{'host'} . ".tmp"); - while($row = ){ - my @last_values = split(":",$row); - $last_check_time[$i] = $last_values[0]; - $last_in_errors[$i] = $last_values[1]; - $last_out_errors[$i] = $last_values[2]; - $flg_created[$i] = 1; - } - close(FILE); - } else { - $flg_created[$i] = 0; - } - - $update_time = time; - unless (open(FILE,">". $centplugins_path . "/packet_errors_if".$i."_" . $OPTION{'host'} . ".tmp")){ - print "Unknown - $centplugins_path/packet_errors_if".$i."_" . $OPTION{'host'} . ".tmp!\n"; - exit $ERRORS{"UNKNOWN"}; - } - print FILE "$update_time:$nb_in_errors[$i]:$nb_out_errors[$i]"; - close(FILE); - if ($flg_created[$i] eq 0){ - print "First execution : Buffer in creation.... \n"; - } -} - -# ############################################# -# ##### return result -# ## -my $status = "OK"; -my @msg; -my $diff_test = 0; -for (my $i = 0; $i < scalar(@nb_in_errors); $i++) { - my $interface = $i+1; - if ($flg_created[$i]) { - if (($nb_in_errors[$i] - $last_in_errors[$i] >= $critical) or ($nb_out_errors[$i] - $last_out_errors[$i] >= $critical)){ - $msg[$i] = $desc_tab[$i] . ":critical "; - $status = "CRITICAL"; - } - if (($nb_in_errors[$i] - $last_in_errors[$i] >= $warning) or ($nb_out_errors[$i] - $last_out_errors[$i] >= $warning)){ - if (!defined($msg[$i])) { - $msg[$i] = $desc_tab[$i] . ":warning "; - } - if ($status ne "CRITICAL") { - $status = "WARNING"; - } - } - $diff_test = 1; - } -} - -if (!$diff_test) { - exit($ERRORS{'UNKNOWN'}); -} -my $output = ""; -for (my $i = 0; $i < scalar (@msg); $i++) { - if (defined($msg[$i])) { - $output .= $msg[$i]; - } -} -if ($output ne ""){ - print $output."\n"; -} else { - print "Status OK on all interfaces\n"; -} -exit($ERRORS{$status}); - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " -p (--password) snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -w (--warn) Signal strength at which a warning message will be generated\n"; - print " (default 80)\n"; - print " -c (--crit) Signal strength at which a critical message will be generated\n"; - print " (default 100)\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} - -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_process b/src/check_centreon_snmp_process deleted file mode 100644 index 43163b66e..000000000 --- a/src/check_centreon_snmp_process +++ /dev/null @@ -1,210 +0,0 @@ -#! /usr/bin/perl -w -################################################################################ -# Copyright 2004-2013 MERETHIS -# Centreon is developped by : Julien Mathis and Romain Le Merlus under -# GPL Licence 2.0. -# -# This program 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. -# -# This program 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 program; if not, see . -# -# Linking this program statically or dynamically with other modules is making a -# combined work based on this program. Thus, the terms and conditions of the GNU -# General Public License cover the whole combination. -# -# As a special exception, the copyright holders of this program give MERETHIS -# permission to link this program with independent modules to produce an executable, -# regardless of the license terms of these independent modules, and to copy and -# distribute the resulting executable under terms of MERETHIS choice, provided that -# MERETHIS also meet, for each linked independent module, the terms and conditions -# of the license of that module. An independent module is a module which is not -# derived from this program. If you modify this program, you may extend this -# exception to your version of the program, but you are not obliged to do so. If you -# do not wish to do so, delete this exception statement from your version. -# -# For more information : contact@centreon.com -# -# SVN : $URL$ -# SVN : $Id$ -# -#################################################################################### -# -# Script init -# - -use strict; -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; - -use vars qw($PROGNAME); -use Getopt::Long; -use vars qw($opt_V $opt_h $opt_p $opt_n $opt_w $opt_c $result @result %process_list %STATUS); - -my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3); - -my %centreon = Centreon::SNMP::Utils::load_oids($ERRORS{'UNKNOWN'}, "@NAGIOS_PLUGINS@/centreon.conf"); - -# Plugin var init - -my($proc, $proc_run); - -$PROGNAME = $0; -sub print_help (); -sub print_usage (); - -%STATUS=(1=>'running',2=>'runnable',3=>'notRunnable',4=>'invalid'); - -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef -); - -Getopt::Long::Configure('bundling'); -GetOptions - ( - "H|hostname|host=s" => \$OPTION{'host'}, - "C|community=s" => \$OPTION{'snmp-community'}, - "v|snmp|snmp-version=s" => \$OPTION{'snmp-version'}, - "P|snmpport|snmp-port=i" => \$OPTION{'snmp-port'}, - "u|username=s" => \$OPTION{'snmp-auth-user'}, - "authpassword|password=s" => \$OPTION{'snmp-auth-password'}, - "k|authkey=s" => \$OPTION{'snmp-auth-key'}, - "authprotocol=s" => \$OPTION{'snmp-auth-protocol'}, - "privpassword=s" => \$OPTION{'snmp-priv-password'}, - "privkey=s" => \$OPTION{'snmp-priv-key'}, - "privprotocol=s" => \$OPTION{'snmp-priv-protocol'}, - "maxrepetitions=s" => \$OPTION{'maxrepetitions'}, - "snmp-timeout=i" => \$OPTION{'snmptimeout'}, - "64-bits" => \$OPTION{'64-bits'}, - - "h" => \$opt_h, "help" => \$opt_h, - "V" => \$opt_V, "version" => \$opt_V, - "n" => \$opt_n, "number" => \$opt_n, - "p=s" => \$opt_p, "process=s" => \$opt_p, - "w=s" => \$opt_w, "warning=s" => \$opt_w, - "c=s" => \$opt_c, "critical=s" => \$opt_c); - -if ($opt_V) { - print_revision($PROGNAME,'$Revision: 1.2 $'); - exit $ERRORS{'OK'}; -} - -if ($opt_h) { - print_help(); - exit $ERRORS{'OK'}; -} - -my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION); - -if ($opt_n && (!$opt_c || !$opt_w)) { - print_usage(); - exit $ERRORS{'OK'}; -} - -my $process; -if(!$opt_p) { - print_usage(); - exit $ERRORS{'OK'}; -} elsif ($opt_p !~ /([-.A-Za-z0-9]+)/){ - print_usage(); - exit $ERRORS{'OK'}; -} -$process = $opt_p; - -my $name = $0; -$name =~ s/\.pl.*//g; - -# Plugin snmp requests -my $OID_SW_RunName = $centreon{MIB2}{SW_RUNNAME}; -my $OID_SW_RunIndex =$centreon{MIB2}{SW_RUNINDEX}; -my $OID_SW_RunStatus =$centreon{MIB2}{SW_RUNSTATUS}; - -my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params); - -$result = Centreon::SNMP::Utils::get_snmp_table($OID_SW_RunName, $session, $ERRORS{'UNKNOWN'}, \%OPTION); - -$proc = 0; -foreach my $key (oid_lex_sort(keys %$result)) { - my @oid_list = split (/\./,$key); - $process_list{$$result{$key}} = pop (@oid_list) ; - if (defined($opt_p) && $opt_p ne ""){ - $proc++ if ($$result{$key} eq $opt_p); - } else { - $proc++; - } -} - -if (!($opt_n)) { - if ($process_list{$process}) { - $result = Centreon::SNMP::Utils::get_snmp_leef([$OID_SW_RunStatus . "." . $process_list{$process}], $session, $ERRORS{'UNKNOWN'}); - $proc_run = $result->{$OID_SW_RunStatus . "." . $process_list{$process} }; - } -} - -# Plugin return code -my $status; -if ($opt_n){ - $status = 'OK'; - if ($proc >= $opt_w){ - $status = 'WARNING'; - } - if ($proc >= $opt_c){ - $status = 'CRITICAL'; - } - print "Number of current processes: $proc|nbproc=$proc\n"; - exit $ERRORS{$status}; -} else { - if ($proc_run){ - print "Process OK - $process: $STATUS{$proc_run}\n"; - exit $ERRORS{'OK'}; - } else { - print "Process CRITICAL - $process not in 'running' state\n"; - exit $ERRORS{'CRITICAL'}; - } -} - -sub print_usage () { - print "\nUsage:\n"; - print "$PROGNAME\n"; - print " -H (--hostname) Hostname to query (required)\n"; - print " -C (--community) SNMP read community (defaults to public)\n"; - print " used with SNMP v1 and v2c\n"; - print " -v (--snmp-version) 1 for SNMP v1 (default)\n"; - print " 2 for SNMP v2c\n"; - print " 3 for SNMP v3\n"; - print " -P (--snmp-port) SNMP port (default: 161)\n"; - print " -k (--authkey) snmp V3 key\n"; - print " -u (--username) snmp V3 username \n"; - print " -p (--password) snmp V3 password\n"; - print " --authprotocol protocol MD5/SHA (v3)\n"; - print " --privprotocol encryption system (DES/AES)(v3) \n"; - print " --privpassword passphrase (v3) \n"; - print " --64-bits Use 64 bits OID\n"; - print " --maxrepetitions To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n"; - print " Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n"; - print " --snmp-timeout SNMP Timeout\n"; - print " -n (--number) Return the number of current running processes. \n"; - print " -w (--warning) Number of process that will cause a warning (only required with -n option)\n"; - print " -c (--critical) Number of process that will cause an error (only required with -n option)\n"; - print " -p (--process) Set the process name ex: by default smbd (required)\n"; - print " -V (--version) Plugin version\n"; - print " -h (--help) usage help\n"; -} -sub print_help () { - print "##############################################\n"; - print "# Copyright (c) 2004-2013 Centreon #\n"; - print "# Bugs to http://forge.centreon.com/ #\n"; - print "##############################################\n"; - print_usage(); - print "\n"; -} diff --git a/src/check_centreon_snmp_process_detailed b/src/check_centreon_snmp_process_detailed deleted file mode 100644 index 9824778c2..000000000 --- a/src/check_centreon_snmp_process_detailed +++ /dev/null @@ -1,516 +0,0 @@ -#!/usr/bin/perl -w -###################### check_snmp_process ##################### -# Version : 1.2.1 -# Date : Dec 12 2004 -# Author : Patrick Proy (patrick at proy.org) -# Help : http://www.manubulon.com/nagios/ -# Licence : GPL - http://www.fsf.org/licenses/gpl.txt -# TODO : put $o_delta as an option -############################################################### -# -# help : ./check_snmp_process -h - -########### check_centreon_snmp_process_detailed ############## -# Version : 1.2.2 -# Date : Jun 20 2007 -# Author : Sugumaran Mathavarajan - msugumaran@merethis.com -# Company : Merethis -# Licence : GPL - http://www.fsf.org/licenses/gpl.txt -# TODO : put $o_delta as an option -############################################################### -# -# help : ./check_snmp_process -h - -############### BASE DIRECTORY FOR TEMP FILE ######## -my $o_base_dir="/tmp/tmp_Nagios_proc."; -my $file_history=200; # number of data to keep in files. -my $delta_of_time_to_make_average=300; # 5minutes by default - -use strict; -use Getopt::Long; - -# Nagios specific - -use lib "@NAGIOS_PLUGINS@"; -use utils qw(%ERRORS); - -# centreon specific -require "@NAGIOS_PLUGINS@/Centreon/SNMP/Utils.pm"; -my %OPTION = ( - "host" => undef, - "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161, - "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5", - "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES", - "maxrepetitions" => undef, "snmptimeout" => undef, - "64-bits" => undef, -); -my $session_params; - -# SNMP Datas -my $process_table= '1.3.6.1.2.1.25.4.2.1'; -my $index_table = '1.3.6.1.2.1.25.4.2.1.1'; -my $run_name_table = '1.3.6.1.2.1.25.4.2.1.2'; -my $run_path_table = '1.3.6.1.2.1.25.4.2.1.4'; -my $proc_mem_table = '1.3.6.1.2.1.25.5.1.1.2'; # Kbytes -my $proc_cpu_table = '1.3.6.1.2.1.25.5.1.1.1'; # Centi sec of CPU -my $proc_run_state = '1.3.6.1.2.1.25.4.2.1.7'; - -# Globals - -my $Version='1.2.1'; - -my $o_descr = undef; # description filter -my $o_warn = 0; # warning limit -my @o_warnL= undef; # warning limits (min,max) -my $o_crit= 0; # critical limit -my @o_critL= undef; # critical limits (min,max) -my $o_help= undef; # wan't some help ? -my $o_verb= undef; # verbose mode -my $o_version= undef; # print version -my $o_noreg= undef; # Do not use Regexp for name -my $o_path= undef; # check path instead of name -my $o_inverse= undef; # checks max instead of min number of process -# Memory & CPU -my $o_mem= undef; # checks memory (max) -my @o_memL= undef; # warn and crit level for mem -my $o_mem_avg= undef; # cheks memory average -my $o_cpu= undef; # checks CPU usage -my @o_cpuL= undef; # warn and crit level for cpu -my $o_delta= $delta_of_time_to_make_average; # delta time for CPU check -# Oreon specific -my $o_g= undef; -my $o_S= undef; -my $start= undef; -my $ServiceId= undef; - -# functions - -sub p_version { print "check_snmp_process version : $Version\n"; } - -sub print_usage { - print "Usage: $0 [-v] -H -C | (-l login -x passwd) [-p ] -n [-w [,] -c [,max_proc] ] [-m, -a -u, ] [-t ] [-f ] [-r] [-V]\n"; -} - -sub isnotnum { # Return true if arg is not a number - my $num = shift; - if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} - return 1; -} - -sub read_file { - # Input : File, items_number - # Returns : array of value : [line][item] - my ($traffic_file,$items_number)=@_; - my ($ligne,$n_rows)=(undef,0); - my (@last_values,@file_values,$i); - open(FILE,"<".$traffic_file) || return (1,0,0); - - while($ligne = ) { - chomp($ligne); - @file_values = split(":",$ligne); - #verb("@file_values"); - if ($#file_values >= ($items_number-1)) { - # check if there is enough data, else ignore line - for ( $i=0 ; $i< $items_number ; $i++ ) { - $last_values[$n_rows][$i]=$file_values[$i]; - } - $n_rows++; - } - } - close FILE; - if ($n_rows != 0) { - return (0,$n_rows,@last_values); - } else { - return (1,0,0); - } -} - -sub write_file { - # Input : file , rows, items, array of value : [line][item] - # Returns : 0 / OK, 1 / error - my ($file_out,$rows,$item,@file_values)=@_; - my $start_line= ($rows > $file_history) ? $rows - $file_history : 0; - if ( open(FILE2,">".$file_out) ) { - for (my $i=$start_line;$i<$rows;$i++) { - for (my $j=0;$j<$item;$j++) { - print FILE2 $file_values[$i][$j]; - if ($j != ($item -1)) { - print FILE2 ":" - }; - } - print FILE2 "\n"; - } - close FILE2; - return 0; - } else { - return 1; - } -} - -sub help { - print "\nSNMP Process Monitor for Nagios version ",$Version,"\n"; - print "(c)2004 to my cat Ratoune - Author: Patrick Proy\n\n"; - print_usage(); - print < 100% : 100%=1 CPU --t, --timeout=INTEGER - timeout for SNMP in seconds (Default: 5) --V, --version - prints version number - -Note : - CPU usage is in % of one cpu, so maximum can be 100% * number of CPU - example : - Browse process list :