diff --git a/apps/vmware/connector/lib/common.pm b/apps/vmware/connector/lib/common.pm new file mode 100644 index 000000000..644c0b585 --- /dev/null +++ b/apps/vmware/connector/lib/common.pm @@ -0,0 +1,86 @@ +############################################################################### +# Copyright 2005-2014 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 timeelapsedutable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting timeelapsedutable 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 +# Author : Simon BOMM +# +#################################################################################### + +package apps::vmware::connector::lib::common; + +use strict; +use warnings; +use JSON; +use ZMQ::LibZMQ3; + +sub connector_response { + my ($self, %options) = @_; + + if (!defined($options{response})) { + $self->{output}->add_option_msg(short_msg => "Cannot read response: $!"); + $self->{output}->option_exit(); + } + + my $data = zmq_msg_data($options{response}); + if ($data !~ /^RESPSERVER (.*)/msi) { + $self->{output}->add_option_msg(short_msg => "Response not formatted: $data"); + $self->{output}->option_exit(); + } + + my $json = $1; + my $result; + + eval { + $result = JSON->new->utf8->decode($json); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json result: $@"); + $self->{output}->option_exit(); + } + + foreach my $output (@{$result->{plugin}->{outputs}}) { + if ($output->{type} == 1) { + $self->{output}->output_add(severity => $output->{exit}, + short_msg => $output->{msg}); + } elsif ($output->{type} == 2) { + $self->{output}->output_add(long_msg => $output->{msg}); + } + } + + foreach my $perf (@{$result->{plugin}->{perfdatas}}) { + $self->{output}->perfdata_add(label => $perf->{label}, unit => $perf->{unit}, + value => $perf->{value}, + warning => $perf->{warning}, + critical => $perf->{critical}, + min => $perf->{min}, max => $perf->{max}); + } +} + +1; diff --git a/apps/vmware/connector/mode/cpuhost.pm b/apps/vmware/connector/mode/cpuhost.pm new file mode 100644 index 000000000..860b33f69 --- /dev/null +++ b/apps/vmware/connector/mode/cpuhost.pm @@ -0,0 +1,202 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::cpuhost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + 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->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'cpuhost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check ESX cpu usage. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/apps/vmware/connector/mode/getmap.pm b/apps/vmware/connector/mode/getmap.pm new file mode 100644 index 000000000..cc1f0fc53 --- /dev/null +++ b/apps/vmware/connector/mode/getmap.pm @@ -0,0 +1,179 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::getmap; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "vm-no" => { name => 'vm_no' }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'getmap'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +List ESX hosts and Virtual machines. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to list. +If not set, we list all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--vm-no> + +Don't list virtual machines. + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=back + +=cut diff --git a/apps/vmware/connector/mode/healthhost.pm b/apps/vmware/connector/mode/healthhost.pm new file mode 100644 index 000000000..a2c813472 --- /dev/null +++ b/apps/vmware/connector/mode/healthhost.pm @@ -0,0 +1,189 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::healthhost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "storage-status" => { name => 'storage_status' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'healthhost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check health of ESX hosts. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--storage-status> + +Check storage(s) status. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=back + +=cut diff --git a/apps/vmware/connector/mode/listdatastores.pm b/apps/vmware/connector/mode/listdatastores.pm new file mode 100644 index 000000000..f88d3622d --- /dev/null +++ b/apps/vmware/connector/mode/listdatastores.pm @@ -0,0 +1,191 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::listdatastores; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "datastore-name:s" => { name => 'datastore_name' }, + "filter" => { name => 'filter' }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'listdatastores'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + # We need to remove xml output + if (defined($self->{output}->{option_results}->{output_xml})) { + delete $self->{output}->{option_results}->{output_xml}; + } + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'accessible']); +} + +sub disco_show { + my ($self, %options) = @_; + + # We ask to use XML output from the connector + $self->{json_send}->{disco_show} = 1; + $self->run(); +} + +1; + +__END__ + +=head1 MODE + +List datastores. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--datastore-name> + +datastore name to list. + +=item B<--filter> + +Datastore name is a regexp. + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=back + +=cut diff --git a/apps/vmware/connector/mode/listnichost.pm b/apps/vmware/connector/mode/listnichost.pm new file mode 100644 index 000000000..72afe2d56 --- /dev/null +++ b/apps/vmware/connector/mode/listnichost.pm @@ -0,0 +1,192 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::listnichost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{esx_hostname}) || + $self->{option_results}->{esx_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --esx-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'listnichost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + # We need to remove xml output + if (defined($self->{output}->{option_results}->{output_xml})) { + delete $self->{output}->{option_results}->{output_xml}; + } + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'status', 'vswitch']); +} + +sub disco_show { + my ($self, %options) = @_; + + # We ask to use XML output from the connector + $self->{json_send}->{disco_show} = 1; + $self->run(); +} + +1; + +__END__ + +=head1 MODE + +List ESX interfaces. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check (required). + +=item B<--timeout> + +Set global execution timeout (Default: 50). + +=back + +=cut diff --git a/apps/vmware/connector/mode/maintenancehost.pm b/apps/vmware/connector/mode/maintenancehost.pm new file mode 100644 index 000000000..0da576bd4 --- /dev/null +++ b/apps/vmware/connector/mode/maintenancehost.pm @@ -0,0 +1,198 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::maintenancehost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "maintenance-alert:s" => { name => 'maintenance_alert', default => '^(?!(false))' }, + "maintenance-status:s" => { name => 'maintenance_status', default => 'critical' }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $self->{option_results}->{maintenance_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong maintenance-status status option '" . $self->{option_results}->{maintenance_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'maintenancehost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check maintenance mode of ESX hosts. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=item B<--maintenance-alert> + +Alert if maintenance mode value matches (default: '^(?!(false))'). + +=item B<--maintenance-status> + +Maintenance alert status (default: 'critical'). + +=back + +=cut diff --git a/apps/vmware/connector/mode/memoryhost.pm b/apps/vmware/connector/mode/memoryhost.pm new file mode 100644 index 000000000..d61e6335b --- /dev/null +++ b/apps/vmware/connector/mode/memoryhost.pm @@ -0,0 +1,202 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::memoryhost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + 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->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'memhost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check ESX memory usage. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/apps/vmware/connector/mode/statconnectors.pm b/apps/vmware/connector/mode/statconnectors.pm new file mode 100644 index 000000000..686157adf --- /dev/null +++ b/apps/vmware/connector/mode/statconnectors.pm @@ -0,0 +1,158 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::statconnectors; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'stats'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Get number of requests for each connectors (information from daemon. Not VMWare). + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=back + +=cut diff --git a/apps/vmware/connector/mode/statushost.pm b/apps/vmware/connector/mode/statushost.pm new file mode 100644 index 000000000..ae2bfb2bb --- /dev/null +++ b/apps/vmware/connector/mode/statushost.pm @@ -0,0 +1,185 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::statushost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "caca" => { name => 'caca' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + if ($self->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'statushost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check ESX global status. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=back + +=cut diff --git a/apps/vmware/connector/mode/swaphost.pm b/apps/vmware/connector/mode/swaphost.pm new file mode 100644 index 000000000..ac2b55f0c --- /dev/null +++ b/apps/vmware/connector/mode/swaphost.pm @@ -0,0 +1,202 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::swaphost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + 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->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'swaphost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check ESX swap rate usage. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=item B<--warning> + +Threshold warning in bytes per seconds. + +=item B<--critical> + +Threshold critical in bytes per seconds. + +=back + +=cut diff --git a/apps/vmware/connector/mode/uptimehost.pm b/apps/vmware/connector/mode/uptimehost.pm new file mode 100644 index 000000000..c2ece2de6 --- /dev/null +++ b/apps/vmware/connector/mode/uptimehost.pm @@ -0,0 +1,202 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::mode::uptimehost; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::vmware::connector::lib::common; +use ZMQ::LibZMQ3; +use ZMQ::Constants qw(:all); +use UUID; + +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 => + { + "connector-hostname:s" => { name => 'connector_hostname' }, + "connector-port:s" => { name => 'connector_port', default => 5700 }, + "container:s" => { name => 'container', default => 'default' }, + "esx-hostname:s" => { name => 'esx_hostname' }, + "filter" => { name => 'filter' }, + "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "timeout:s" => { name => 'timeout', default => 50 }, + }); + $self->{json_send} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{connector_hostname}) || + $self->{option_results}->{connector_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + $self->{timeout} = $self->{option_results}->{timeout}; + } else { + $self->{timeout} = 50; + } + + 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->{output}->is_litteral_status(status => $self->{option_results}->{disconnect_status}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong disconnect-status status option '" . $self->{option_results}->{disconnect_status} . "'."); + $self->{output}->option_exit(); + } +} + +sub build_request { + my ($self, %options) = @_; + + $self->{json_send}->{identity} = 'client-' . unpack('H*', $options{uuid}); + $self->{json_send}->{command} = 'uptimehost'; + foreach (keys %{$self->{option_results}}) { + $self->{json_send}->{$_} = $self->{option_results}->{$_}; + } +} + +sub run { + my ($self, %options) = @_; + + my $uuid; + my $context = zmq_init(); + $self->{requester} = zmq_socket($context, ZMQ_DEALER); + if (!defined($self->{requester})) { + $self->{output}->add_option_msg(short_msg => "Cannot create socket: $!"); + $self->{output}->option_exit(); + } + + my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; + UUID::generate($uuid); + zmq_setsockopt($self->{requester}, ZMQ_IDENTITY, "client-" . $uuid); + zmq_setsockopt($self->{requester}, ZMQ_LINGER, 0); # we discard + zmq_connect($self->{requester}, 'tcp://' . $self->{option_results}->{connector_hostname} . ':' . $self->{option_results}->{connector_port}); + + $self->build_request(uuid => $uuid); + + zmq_sendmsg($self->{requester}, "REQCLIENT " . JSON->new->utf8->encode($self->{json_send}), ZMQ_NOBLOCK); + + my @poll = ( + { + socket => $self->{requester}, + events => ZMQ_POLLIN, + callback => sub { + my $response = zmq_recvmsg($self->{requester}); + zmq_close($self->{requester}); + apps::vmware::connector::lib::common::connector_response($self, response => $response); + $self->{output}->display(); + $self->{output}->exit(); + }, + }, + ); + + zmq_poll(\@poll, $self->{timeout} * 1000); + zmq_close($self->{requester}); + + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot get response (timeout received)")); + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check ESX swap rate usage. + +=over 8 + +=item B<--connector-hostname> + +Connector hostname (required). + +=item B<--connector-port> + +Connector port (default: 5700). + +=item B<--container> + +Container to use (it depends of the connector configuration). + +=item B<--esx-hostname> + +ESX hostname to check. +If not set, we check all ESX. + +=item B<--filter> + +ESX hostname is a regexp. + +=item B<--disconnect-status> + +Status if ESX host disconnected (default: 'unknown'). + +=item B<--timeout> + +Set global execution timeout (Default: 50) + +=item B<--warning> + +Threshold warning in seconds. + +=item B<--critical> + +Threshold critical in seconds. + +=back + +=cut diff --git a/apps/vmware/connector/plugin.pm b/apps/vmware/connector/plugin.pm new file mode 100644 index 000000000..5ab099790 --- /dev/null +++ b/apps/vmware/connector/plugin.pm @@ -0,0 +1,74 @@ +################################################################################ +# Copyright 2005-2014 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 apps::vmware::connector::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +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-host' => 'apps::vmware::connector::mode::cpuhost', + 'getmap' => 'apps::vmware::connector::mode::getmap', + 'health-host' => 'apps::vmware::connector::mode::healthhost', + 'list-datastores' => 'apps::vmware::connector::mode::listdatastores', + 'list-nichost' => 'apps::vmware::connector::mode::listnichost', + 'maintenance-host' => 'apps::vmware::connector::mode::maintenancehost', + 'memory-host' => 'apps::vmware::connector::mode::memoryhost', + 'stat-connectors' => 'apps::vmware::connector::mode::statconnectors', + 'status-host' => 'apps::vmware::connector::mode::statushost', + 'swap-host' => 'apps::vmware::connector::mode::swaphost', + 'uptime-host' => 'apps::vmware::connector::mode::uptimehost', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check VMWare with centreon-esxd connector. + +=cut diff --git a/centreon/common/smcli/custom/custom.pm b/centreon/common/smcli/custom/custom.pm index e78d75b1c..e198b3bf1 100644 --- a/centreon/common/smcli/custom/custom.pm +++ b/centreon/common/smcli/custom/custom.pm @@ -1,5 +1,5 @@ ################################################################################ -# Copyright 2005-2013 MERETHIS +# Copyright 2005-2014 MERETHIS # Centreon is developped by : Julien Mathis and Romain Le Merlus under # GPL Licence 2.0. # @@ -33,7 +33,7 @@ # #################################################################################### -package centreon::common::emc::navisphere::custom::custom; +package centreon::common::smcli::custom::custom; use strict; use warnings; @@ -69,6 +69,7 @@ sub new { "hostname2:s@" => { name => 'hostname2' }, "password:s@" => { name => 'password' }, "timeout:s@" => { name => 'timeout' }, + "show-output:s" => { name => 'show_output' }, }); } $options{options}->add_help(package => __PACKAGE__, sections => 'SMCLI OPTIONS', once => 1); @@ -114,7 +115,7 @@ sub build_command { $self->{cmd} = ''; $self->{cmd} .= $self->{option_results}->{smcli_path} . '/' if (defined($self->{option_results}->{smcli_path})); - $self->{cmd} .= $self->{option_results}->{smcli_path_command}; + $self->{cmd} .= $self->{option_results}->{smcli_command}; if (defined($self->{special_arg}) && $self->{special_arg} ne '') { $self->{cmd} .= ' ' . $self->{special_arg}; @@ -143,7 +144,7 @@ sub check_options { $self->{hostname2} = (defined($self->{option_results}->{hostname2})) ? shift(@{$self->{option_results}->{hostname2}}) : undef; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : undef; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 30; - $self->{extra_options} = (defined($self->{option_results}->{extra_options})) ? shift(@{$self->{option_results}->{extra_options}}) : '-quick'; + $self->{extra_options} = (defined($self->{option_results}->{extra_options})) ? shift(@{$self->{option_results}->{extra_options}}) : '-quick -S'; $self->{special_arg} = (defined($self->{option_results}->{special_arg})) ? shift(@{$self->{option_results}->{special_arg}}) : undef; $self->{sudo} = $self->{option_results}->{sudo}; @@ -168,13 +169,22 @@ sub execute_command { # Need to set timeout over command. $self->{option_results}->{timeout} = $self->{timeout}; - return centreon::plugins::misc::execute(output => $self->{output}, + my ($response, $exit_code) = centreon::plugins::misc::execute(output => $self->{output}, options => $self->{option_results}, sudo => $self->{sudo}, command => $self->{cmd}, command_path => undef, - command_options => undef + command_options => undef, + no_quit => 1 ); + if ($exit_code != 0) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Command execution error (verbose mode for more details)"); + $self->{output}->output_add(long_msg => $response); + $self->{output}->display(); + $self->{output}->exit(); + } + return $response; } 1; @@ -195,7 +205,7 @@ my smcli manage =item B<--smcli-path> -Specify smcli path (default: none) +Specify smcli path (default: for dell '/opt/dell/mdstoragemanager/client', for ibm '/opt/IBM_DS/client') =item B<--smcli-command> @@ -203,7 +213,7 @@ Specify navicli command (default: 'SMcli'). =item B<--extra-option> -Set SMcli extras options (Default: '-quick'). +Set SMcli extras options (Default: '-quick -S'). =item B<--sudo> diff --git a/centreon/common/smcli/mode/healthstatus.pm b/centreon/common/smcli/mode/healthstatus.pm new file mode 100644 index 000000000..c0d8897e5 --- /dev/null +++ b/centreon/common/smcli/mode/healthstatus.pm @@ -0,0 +1,100 @@ +################################################################################ +# Copyright 2005-2014 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::common::smcli::mode::healthstatus; + +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 => + { + "storage-command:s" => { name => 'storage_command', }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + my $smcli = $options{custom}; + + my $response = $smcli->execute_command(cmd => $self->{option_results}->{storage_command}); + # IBM smcli: Storage Subsystem health status = optimal. + # Dell smcli: Storage array health status = optimal. + + my $match_ok_regexp = 'health status.*optimal'; + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("storage health status is optimal")); + if ($response !~ /$match_ok_regexp/msi) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Some failures have been found (verbose mode for more details)")); + $self->{output}->output_add(long_msg => $response); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check health status + +=over 8 + +=item B<--storage-command> + +By default for Dell MD: 'show storageArray healthstatus;' +By default for IBM DS: 'show storageSubsystem healthstatus;' + +=back + +=cut diff --git a/centreon/plugins/mode.pm b/centreon/plugins/mode.pm index cc4a895cd..e4a83b1a1 100644 --- a/centreon/plugins/mode.pm +++ b/centreon/plugins/mode.pm @@ -55,7 +55,7 @@ sub new { sub init { my ($self, %options) = @_; - # options{default} = [ {option_name => '', option_value => '' }, ] + # options{default} = { mode_xxx => { option_name => option_value }, } %{$self->{option_results}} = %{$options{option_results}}; # Manage default value diff --git a/centreon/plugins/options.pm b/centreon/plugins/options.pm index 52743ffd0..531100cea 100644 --- a/centreon/plugins/options.pm +++ b/centreon/plugins/options.pm @@ -40,6 +40,7 @@ use Pod::Find qw(pod_where); use Getopt::Long; Getopt::Long::Configure("pass_through"); Getopt::Long::Configure('bundling'); +Getopt::Long::Configure('no_auto_abbrev'); use strict; use warnings; diff --git a/database/postgres/mode/vacuum.pm b/database/postgres/mode/vacuum.pm new file mode 100644 index 000000000..754adc888 --- /dev/null +++ b/database/postgres/mode/vacuum.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 Delance +# +#################################################################################### + +package database::postgres::mode::vacuum; + +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{sql} = sqlmode object + $self->{sql} = $options{sql}; + + # Ensures a DB has been specified + # otherwise we endup in default system table (postgres) + # and the check does not support this behaviour (empty pg_stat_user_table => no need to check) + # FIXME this check should be performed in check_options() but these settings are not available at the moment + my $data_source = $self->{sql}->{data_source}; + if ($data_source =~ /.*;database=(.*)/) { + if ($1 eq 'postgres') { + $self->{output}->add_option_msg(short_msg => "Cannot use system 'postgres' database ; you must use a real database."); + $self->{output}->option_exit(); + } + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify database argument."); + $self->{output}->option_exit(); + } + + $self->{sql}->connect(); + + my $target_fields = undef; + + # Autovacuum feature has only been impleted starting PG 8.2 + # (options needed http://www.postgresql.org/docs/8.2/static/runtime-config-autovacuum.html, no need starting 8.3) + if ($self->{sql}->is_version_minimum(version => '8.2.0')) { + $target_fields = 'greatest(last_autovacuum,last_vacuum)'; + } else { + $target_fields = 'last_vacuum'; + } + + my $query = sprintf("SELECT ROUND(EXTRACT(EPOCH from (select min (now() - %s) + from pg_stat_user_tables where %s is not null)))", $target_fields, $target_fields); + $self->{sql}->query(query => $query); + + my $result = $self->{sql}->fetchrow_array(); + + if (defined($result)) { + + 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("Most recent vacuum dates back from %d seconds", $result)); + + $self->{output}->perfdata_add(label => 'last_vacuum', + value => $result, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); + } else { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'No vacuum performed on this BD yet.'); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check a vacuum (manual or auto) command has been performed on at least one of the tables of the associated DB + +=over 8 + +=item B<--warning> + +Threshold warning in seconds, maximum time interval since last vacuum. + +=item B<--critical> + +Threshold critical in seconds, maximum time interval since last vacuum. + +=back + +=cut diff --git a/database/postgres/plugin.pm b/database/postgres/plugin.pm index 5f51df5a3..6ee72bb65 100644 --- a/database/postgres/plugin.pm +++ b/database/postgres/plugin.pm @@ -55,6 +55,7 @@ sub new { 'list-databases' => 'database::postgres::mode::listdatabases', 'query-time' => 'database::postgres::mode::querytime', 'timesync' => 'database::postgres::mode::timesync', + 'vacuum' => 'database::postgres::mode::vacuum', ); $self->{sql_modes}{psqlcmd} = 'database::postgres::psqlcmd'; return $self; diff --git a/storage/dell/MD3000/cli/plugin.pm b/storage/dell/MD3000/cli/plugin.pm new file mode 100644 index 000000000..f58f6d1f0 --- /dev/null +++ b/storage/dell/MD3000/cli/plugin.pm @@ -0,0 +1,78 @@ +################################################################################ +# Copyright 2005-2014 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 storage::dell::MD3000::cli::plugin; + +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}} = ( + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); + $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; + $self->{default} = { 'health-status' => { storage_command => 'show storageArray healthstatus;', + smcli_path => '/opt/dell/mdstoragemanager/client' }, }; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Dell MD3000 series. + +=over 8 + +=back + +=cut diff --git a/storage/ibm/DS3000/cli/plugin.pm b/storage/ibm/DS3000/cli/plugin.pm new file mode 100644 index 000000000..8b0e8f68b --- /dev/null +++ b/storage/ibm/DS3000/cli/plugin.pm @@ -0,0 +1,78 @@ +################################################################################ +# Copyright 2005-2014 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 storage::ibm::DS3000::cli::plugin; + +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}} = ( + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); + $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; + $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', + smcli_path => '/opt/IBM_DS/client' }, }; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM DS3000 series. + +=over 8 + +=back + +=cut diff --git a/storage/ibm/DS4000/cli/plugin.pm b/storage/ibm/DS4000/cli/plugin.pm new file mode 100644 index 000000000..1882b8ec8 --- /dev/null +++ b/storage/ibm/DS4000/cli/plugin.pm @@ -0,0 +1,78 @@ +################################################################################ +# Copyright 2005-2014 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 storage::ibm::DS3000::cli::plugin; + +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}} = ( + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); + $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; + $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', + smcli_path => '/opt/IBM_DS/client' }, }; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM DS4000 series. + +=over 8 + +=back + +=cut diff --git a/storage/ibm/DS5000/cli/plugin.pm b/storage/ibm/DS5000/cli/plugin.pm new file mode 100644 index 000000000..fa17286d2 --- /dev/null +++ b/storage/ibm/DS5000/cli/plugin.pm @@ -0,0 +1,78 @@ +################################################################################ +# Copyright 2005-2014 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 storage::ibm::DS3000::cli::plugin; + +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}} = ( + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); + $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; + $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', + smcli_path => '/opt/IBM_DS/client' }, }; + + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM DS5000 series. + +=over 8 + +=back + +=cut