WIP: can begin mode code
This commit is contained in:
Quentin Garnier 2014-07-24 17:37:33 +02:00
parent 99c5599277
commit c18bf9104f
5 changed files with 613 additions and 0 deletions

View File

@ -68,6 +68,12 @@ sub connect {
$req = HTTP::Request->new( GET => $self->{option_results}->{proto}. "://" . $self->{option_results}->{hostname} . $self->{option_results}->{url_path});
}
if (defined($options{headers})) {
foreach my $key (keys %{$options{headers}}) {
$req->header($key => $options{headers}->{$key});
}
}
if (defined($self->{option_results}->{credentials}) && defined($self->{option_results}->{ntlm})) {
$ua->credentials($self->{option_results}->{hostname} . ':' . $self->{option_results}->{port}, '', $self->{option_results}->{username}, $self->{option_results}->{password});
} elsif (defined($self->{option_results}->{credentials})) {

View File

@ -0,0 +1,286 @@
################################################################################
# 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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
package storage::hp::p2000::xmlapi::custom;
use strict;
use warnings;
use centreon::plugins::misc;
use centreon::plugins::httplib;
use XML::XPath;
use Digest::MD5 qw(md5_hex);
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
# $options{options} = options object
# $options{output} = output object
# $options{exit_value} = integer
# $options{noptions} = integer
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments =>
{
"hostname:s@" => { name => 'hostname', },
"port:s@" => { name => 'port', },
"proto:s@" => { name => 'proto', },
"urlpath:s@" => { name => 'url_path', },
"proxyurl:s@" => { name => 'proxyurl', },
"username:s@" => { name => 'username', },
"password:s@" => { name => 'password', },
"timeout:s@" => { name => 'timeout', },
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'P2000 OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{mode} = $options{mode};
$self->{session_id} = '';
$self->{logon} = 0;
return $self;
}
# Method to manage multiples
sub set_options {
my ($self, %options) = @_;
# options{options_result}
$self->{option_results} = $options{option_results};
}
# Method to manage multiples
sub set_defaults {
my ($self, %options) = @_;
# options{default}
# Manage default value
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
foreach my $opt (keys %{$options{default}->{$_}[$i]}) {
if (!defined($self->{option_results}->{$opt}[$i])) {
$self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt};
}
}
}
}
}
}
sub check_options {
my ($self, %options) = @_;
# return 1 = ok still hostname
# return 0 = no hostname left
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : undef;
$self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : undef;
$self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : undef;
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 30;
$self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : undef;
$self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http';
$self->{url_path} = (defined($self->{option_results}->{url_path})) ? shift(@{$self->{option_results}->{url_path}}) : '/api/';
$self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef;
if (!defined($self->{hostname})) {
$self->{output}->add_option_msg(short_msg => "Need to specify hostname option.");
$self->{output}->option_exit();
}
if (!defined($self->{username}) || !defined($self->{password})) {
$self->{output}->add_option_msg(short_msg => 'Need to specify username or/and password option.');
$self->{output}->option_exit();
}
if (!defined($self->{hostname}) ||
scalar(@{$self->{option_results}->{hostname}}) == 0) {
return 0;
}
return 1;
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{hostname} = $self->{hostname};
$self->{option_results}->{username} = $self->{username};
$self->{option_results}->{password} = $self->{password};
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{port} = $self->{port};
$self->{option_results}->{proto} = $self->{proto};
$self->{option_results}->{url_path} = $self->{url_path};
$self->{option_results}->{proxyurl} = $self->{proxyurl};
}
sub check_login {
my ($self, %options) = @_;
my ($xpath, $nodeset);
eval {
$xpath = XML::XPath->new(xml => $options{content});
$nodeset = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='return-code']");
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot parse login response: $@");
$self->{output}->option_exit();
}
if (scalar($nodeset->get_nodelist) == 0) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Cannot find login response.');
$self->{output}->display();
$self->{output}->exit();
}
foreach my $node ($nodeset->get_nodelist()) {
if ($node->string_value != 1) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Login authentification failed (return-code: ' . $node->string_value . ').');
$self->{output}->display();
$self->{output}->exit();
}
}
$nodeset = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='response']");
my @nodes = $nodeset->get_nodelist();
my $node = shift(@nodes);
$self->{session_id} = $node->string_value;
$self->{logon} = 1;
}
sub DESTROY {
my $self = shift;
if ($self->{logon} == 1) {
$self->{option_results}->{url_path} = $self->{url_path} . 'exit';
centreon::plugins::httplib::connect($self,
headers => {dataType => 'api', sessionKey => $self->{session_id} });
}
}
##############
# Specific methods
##############
sub login {
my ($self, %options) = @_;
$self->build_options_for_httplib();
# Login First
my $md5_hash = md5_hex($self->{username} . '_' . $self->{password});
$self->{option_results}->{url_path} = $self->{url_path} . 'login/' . $md5_hash;
my $response = centreon::plugins::httplib::connect($self);
$self->check_login(content => $response);
# test disk
$self->{option_results}->{url_path} = $self->{url_path} . 'show/disks';
$response = centreon::plugins::httplib::connect($self,
headers => {dataType => 'api', sessionKey => $self->{session_id} });
use Data::Dumper;
print Data::Dumper::Dumper($response);
$self->{option_results}->{url_path} = $self->{url_path} . 'show/sensor-status';
$response = centreon::plugins::httplib::connect($self,
headers => {dataType => 'api', sessionKey => $self->{session_id} });
use Data::Dumper;
print Data::Dumper::Dumper($response);
}
1;
__END__
=head1 NAME
MSA p2000
=head1 SYNOPSIS
my p2000 xml api manage
=head1 P2000 OPTIONS
=over 8
=item B<--hostname>
HP p2000 Hostname.
=item B<--port>
Port used
=item B<--proxyurl>
Proxy URL if any
=item B<--proto>
Specify https if needed
=item B<--urlpath>
Set path to xml api (Default: '/api/')
=item B<--username>
Username to connect.
=item B<--password>
Password to connect.
=item B<--timeout>
Set HTTP timeout
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,79 @@
################################################################################
# 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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
package storage::hp::p2000::xmlapi::mode::components::disk;
use strict;
use warnings;
my %conditions = (
1 => ['^Not Ready$' => 'WARNING'],
2 => ['^(?!(Present|Valid)$)' => 'CRITICAL'],
);
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking batteries");
$self->{components}->{battery} = {name => 'battery', total => 0, skip => 0};
return if ($self->check_exclude(section => 'battery'));
# SPS means = Standby Power Supply
# Enclosure SPE SPS A State: Present
while ($self->{response} =~ /^(?:Bus\s+(\d+)\s+){0,1}Enclosure\s+(\S+)\s+(SPS)\s+(\S+)\s+State:\s+(.*)$/mgi) {
my ($state, $instance) = ($5, "$2.$3.$4");
if (defined($1)) {
$instance = "$1.$2.$3.$4";
}
next if ($self->check_exclude(section => 'battery', instance => $instance));
$self->{components}->{battery}->{total}++;
$self->{output}->output_add(long_msg => sprintf("Battery '%s' state is %s.",
$instance, $state)
);
foreach (keys %conditions) {
if ($state =~ /${$conditions{$_}}[0]/i) {
$self->{output}->output_add(severity => ${$conditions{$_}}[1],
short_msg => sprintf("Battery '%s' state is %s",
$instance, $state));
last;
}
}
}
}
1;

View File

@ -0,0 +1,166 @@
################################################################################
# Copyright 2005-2013 MERETHIS
# Centreon is developped by : Julien Mathis and Romain Le Merlus under
# GPL Licence 2.0.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation ; either version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
package storage::hp::p2000::xmlapi::mode::health;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use centreon::plugins::misc;
use storage::hp::p2000::xmlapi::mode::components::disk;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"exclude:s" => { name => 'exclude' },
"component:s" => { name => 'component', default => 'all' },
"no-component:s" => { name => 'no_component' },
});
$self->{components} = {};
$self->{no_components} = undef;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (defined($self->{option_results}->{no_component})) {
if ($self->{option_results}->{no_component} ne '') {
$self->{no_components} = $self->{option_results}->{no_component};
} else {
$self->{no_components} = 'critical';
}
}
}
sub component {
my ($self, %options) = @_;
if ($self->{option_results}->{component} eq 'all') {
storage::hp::p2000::xmlapi::mode::components::disk::check($self);
} elsif ($self->{option_results}->{component} eq 'disk') {
storage::hp::p2000::xmlapi::mode::components::disk::check($self);
} else {
$self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'.");
$self->{output}->option_exit();
}
my $total_components = 0;
my $display_by_component = '';
my $display_by_component_append = '';
foreach my $comp (sort(keys %{$self->{components}})) {
# Skipping short msg when no components
next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0);
$total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
$display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name};
$display_by_component_append = ', ';
}
$self->{output}->output_add(severity => 'OK',
short_msg => sprintf("All %s components [%s] are ok.",
$total_components,
$display_by_component)
);
if (defined($self->{option_results}->{no_component}) && $total_components == 0) {
$self->{output}->output_add(severity => $self->{no_components},
short_msg => 'No components are checked.');
}
}
sub run {
my ($self, %options) = @_;
$self->{p2000} = $options{custom};
$self->{p2000}->login();
$self->component();
$self->{output}->display();
$self->{output}->exit();
}
sub check_exclude {
my ($self, %options) = @_;
if (defined($options{instance})) {
if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) {
$self->{components}->{$options{section}}->{skip}++;
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance."));
return 1;
}
} elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) {
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section."));
return 1;
}
return 0;
}
1;
__END__
=head1 MODE
Check health status of storage.
=over 8
=item B<--component>
Which component to check (Default: 'all').
Can be: 'disk', 'xxx'.
=item B<--exclude>
Exclude some parts (comma seperated list) (Example: --exclude=fan,lcc)
Can also exclude specific instance: --exclude=fan#1.2#,lcc
=item B<--no-component>
Return an error if no compenents are checked.
If total (with skipped) is 0. (Default: 'critical' returns).
=back
=cut

View File

@ -0,0 +1,76 @@
################################################################################
# Copyright 2005-2013 MERETHIS
# Centreon is developped by : Julien Mathis and Romain Le Merlus under
# GPL Licence 2.0.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation ; either version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
package storage::hp::p2000::xmlapi::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' => 'storage::hp::p2000::xmlapi::mode::health',
);
$self->{custom_modes}{p2000xml} = 'storage::hp::p2000::xmlapi::custom';
return $self;
}
sub init {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check HP MSA p2000 with XmlApi.
=over 8
=back
=cut