From 366e5cca067a5e67d5a8868e6f8a7cb1c514465a Mon Sep 17 00:00:00 2001 From: Sims24 Date: Mon, 14 Sep 2015 11:27:37 +0200 Subject: [PATCH] Add EMC/Xtremio first checks --- .../emc/xtremio/restapi/custom/xtremioapi.pm | 231 ++++++++++++++++++ .../emc/xtremio/restapi/mode/clusterhealth.pm | 219 +++++++++++++++++ .../emc/xtremio/restapi/mode/ssdendurance.pm | 152 ++++++++++++ storage/emc/xtremio/restapi/mode/ssdiops.pm | 208 ++++++++++++++++ storage/emc/xtremio/restapi/mode/xenvscpu.pm | 153 ++++++++++++ .../emc/xtremio/restapi/mode/xenvsstate.pm | 190 ++++++++++++++ storage/emc/xtremio/restapi/plugin.pm | 58 +++++ 7 files changed, 1211 insertions(+) create mode 100644 storage/emc/xtremio/restapi/custom/xtremioapi.pm create mode 100644 storage/emc/xtremio/restapi/mode/clusterhealth.pm create mode 100644 storage/emc/xtremio/restapi/mode/ssdendurance.pm create mode 100644 storage/emc/xtremio/restapi/mode/ssdiops.pm create mode 100644 storage/emc/xtremio/restapi/mode/xenvscpu.pm create mode 100644 storage/emc/xtremio/restapi/mode/xenvsstate.pm create mode 100644 storage/emc/xtremio/restapi/plugin.pm diff --git a/storage/emc/xtremio/restapi/custom/xtremioapi.pm b/storage/emc/xtremio/restapi/custom/xtremioapi.pm new file mode 100644 index 000000000..b766cb827 --- /dev/null +++ b/storage/emc/xtremio/restapi/custom/xtremioapi.pm @@ -0,0 +1,231 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::custom::xtremioapi; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; + +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', }, + "xtremio-username:s@" => { name => 'xtremio_username', }, + "xtremio-password:s@" => { name => 'xtremio_password', }, + "proxyurl:s@" => { name => 'proxyurl', }, + "timeout:s@" => { name => 'timeout', }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(output => $self->{output}); + + 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->{xtremio_username} = (defined($self->{option_results}->{xtremio_username})) ? shift(@{$self->{option_results}->{xtremio_username}}) : ''; + $self->{xtremio_password} = (defined($self->{option_results}->{xtremio_password})) ? shift(@{$self->{option_results}->{xtremio_password}}) : ''; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; + $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->{xtremio_username}) || !defined($self->{xtremio_password})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --xtremio-username and --xtremio-password options."); + $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->{xtremio_username}.':'.$self->{xtremio_password}.'@'.$self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = 443; + $self->{option_results}->{proto} = 'https'; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_items { + my ($self, %options) = @_; + + $self->settings(); + + if (defined($options{obj}) && $options{obj} ne '') { + $options{url} .= $options{obj} . '/'; + } + + my $response = $self->{http}->request(url_path => $options{url}); + my $decoded; + eval { + $decoded = decode_json($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + my @items; + foreach my $context (@{$decoded->{$options{obj}}}) { + push @items,$context->{name}; + } + + return @items; +} + +sub get_details { + my ($self, %options) = @_; + + $self->settings(); + + if ((defined($options{obj}) && $options{obj} ne '') && (defined($options{name}) && $options{name} ne '')) { + $options{url} .= $options{obj} . '/?name=' . $options{name} ; + } + + my $response = $self->{http}->request(url_path => $options{url}); + my $decoded; + eval { + $decoded = decode_json($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + return $decoded->{content}; + +} + +1; + +__END__ + +=head1 NAME + +XREMIO REST API + +=head1 SYNOPSIS + +Xtremio Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Xtremio hostname. + +=item B<--xtremio-username> + +Xtremio username. + +=item B<--xtremio-password> + +Xtremio password. + +=item B<--proxyurl> + +Proxy URL if any + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/storage/emc/xtremio/restapi/mode/clusterhealth.pm b/storage/emc/xtremio/restapi/mode/clusterhealth.pm new file mode 100644 index 000000000..a626c9520 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/clusterhealth.pm @@ -0,0 +1,219 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::clusterhealth; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $thresholds = { + 'consistency-state' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'free-ud-ssd-space-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'shared-memory-efficiency-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'free-ud-ssd-space-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'vaai-tp-limit-crossing' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'shared-memory-in-use-ratio-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'sys-health-state' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + if (scalar(@values) < 3) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if (!defined $thresholds->{$section}) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; + } + + +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'clusters'); + + my @sensors = ('consistency-state','shared-memory-efficiency-level','free-ud-ssd-space-level', + 'vaai-tp-limit-crossing', 'shared-memory-in-use-ratio-level', 'sys-health-state'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'Health is OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'cluster', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'clusters', + name => $item); + + foreach my $sensor (@sensors) { + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' state is '%s'", + $sensor, $details->{$sensor})); + + my $exit = $self->get_severity(section => $sensor, value => $details->{$sensor}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Sensor '%s' state is '%s'", + $sensor, $details->{$sensor})); + } + + } + + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { + $status = $_->{status}; + return $status; + } + } + } + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + + +1; + +__END__ + +=head1 MODE + +Check cluster health indicators ('consistency-state','shared-memory-efficiency-level','free-ud-ssd-space-level', 'vaai-tp-limit-crossing', 'shared-memory-in-use-ratio-level', 'sys-health-state'); + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=cluster,CLUSTER-NAME + +=item B<--threshold-overload> + +Overload a specific threshold, e.g --threshold-overload="consistency-state,Xtremio,CRITICAL,healthy" + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/ssdendurance.pm b/storage/emc/xtremio/restapi/mode/ssdendurance.pm new file mode 100644 index 000000000..d1ae7499a --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/ssdendurance.pm @@ -0,0 +1,152 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::ssdendurance; + +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.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + 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) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'ssds'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All SSDs Endurance are OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'ssds', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'ssds', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("SSD '%s' endurance remaining is %i%%", + $item, $details->{'percent-endurance-remaining'})); + + + my $exit = $self->{perfdata}->threshold_check(value => $details->{'percent-endurance-remaining'}, + threshold => [ { label => 'warning', 'exit_litteral' => 'warning' }, { label => 'critical', exit_litteral => 'critical' } ]); + + $self->{output}->perfdata_add(label => $item."_endurance", + value => $details->{'percent-endurance-remaining'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + if ($exit ne 'ok') { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("SSD '%s' endurance is %i%%", + $item, $details->{'percent-endurance-remaining'})); + } + + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check SSDs endurance level (100% is the best value) + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=ssds,SSD-NAME-NUMBER + +=item B<--warning> + +Warning trigger for SSD endurance + +=item B<--critical> + +Critical trigger for SSD endurance + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/ssdiops.pm b/storage/emc/xtremio/restapi/mode/ssdiops.pm new file mode 100644 index 000000000..5faaf70b8 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/ssdiops.pm @@ -0,0 +1,208 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::ssdiops; + +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.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "warning-read:s" => { name => 'warning_read' }, + "critical-read:s" => { name => 'critical_read' }, + "warning-write:s" => { name => 'warning_write' }, + "critical-write:s" => { name => 'critical_write' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + 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->{perfdata}->threshold_validate(label => 'warning-read', value => $self->{option_results}->{warning_read})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-read threshold '" . $self->{option_results}->{warning_read} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-read', value => $self->{option_results}->{critical_read})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-read threshold '" . $self->{option_results}->{critical_read} . "'."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning-write', value => $self->{option_results}->{warning_write})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-write threshold '" . $self->{option_results}->{warning_write} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-write', value => $self->{option_results}->{critical_write})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-write threshold '" . $self->{option_results}->{critical_write} . "'."); + $self->{output}->option_exit(); + } + + +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'ssds'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All SSDs Iops are OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'ssds', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'ssds', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("SSD '%s' IOPS : Global=%i Read=%i Write=%i", + $item, $details->{'iops'}, $details->{'rd-iops'}, $details->{'wr-iops'})); + + my $exit1 = $self->{perfdata}->threshold_check(value => $details->{'iops'}, + threshold => [ { label => 'warning', 'exit_litteral' => 'warning' }, { label => 'critical', exit_litteral => 'critical' } ]); + my $exit2 = $self->{perfdata}->threshold_check(value => $details->{'rd-iops'}, + threshold => [ { label => 'warning-read', 'exit_litteral' => 'warning' }, { label => 'critical-read', exit_litteral => 'critical' } ]); + my $exit3 = $self->{perfdata}->threshold_check(value => $details->{'wr-iops'}, + threshold => [ { label => 'warning-write', 'exit_litteral' => 'warning' }, { label => 'critical-write', exit_litteral => 'critical' } ]); + + my $exit = $self->{output}->get_most_critical(status => [$exit1, $exit2, $exit3]); + + $self->{output}->perfdata_add(label => $item."_iops", + value => $details->{'iops'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + $self->{output}->perfdata_add(label => $item."_rd-iops", + value => $details->{'rd-iops'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_read'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_read'), + min => 0, max => 100); + + $self->{output}->perfdata_add(label => $item."_wr-iops", + value => $details->{'wr-iops'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_write'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_write'), + min => 0, max => 100); + + if ($exit ne 'ok') { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("SSD '%s' IOPS : Global=%i Read=%i Write=%i", + $item, $details->{'iops'}, $details->{'rd-iops'}, $details->{'wr-iops'})); + } + + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check IOPS (Global, Read, Write) on each SSDs + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=ssds,SSDS-Number + +=item B<--warning> + +Warning value on global IOPS + +=item B<--critical> + +Critical value on global IOPS + +=item B<--warning-read> + +Warning value on read IOPS + +=item B<--critical-read> + +Critical value on read IOPS + +=item B<--warning-write> + +Warning value on write IOPS + +=item B<--critical-write> + +Critical value on write IOPS + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/xenvscpu.pm b/storage/emc/xtremio/restapi/mode/xenvscpu.pm new file mode 100644 index 000000000..3c8454ad4 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/xenvscpu.pm @@ -0,0 +1,153 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::xenvscpu; + +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.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + 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) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'xenvs'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All Xenvs CPU Usage are OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'cpu', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'xenvs', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("Xenvs '%s' CPU Usage is %i%%", + $item, + $details->{'cpu-usage'})); + + + my $exit = $self->{perfdata}->threshold_check(value => $details->{'cpu-usage'}, threshold => [ { label => 'warning', 'exit_litteral' => 'warning' }, { label => 'critical', exit_litteral => 'critical' } ]); + + $self->{output}->perfdata_add(label => 'cpu_'.$item, + value => $details->{'cpu-usage'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + if ($exit ne 'ok') { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Xenvs '%s' cpu-Usage is %i%%", + $item, + $details->{'cpu-usage'})); + } + + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check Xenvs CPU usage + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=cpu,XENVS-NAME-NUMBER + +=item B<--warning> + +Value to trigger a warning alarm on CPU usage + +=item B<--critical> + +Value to trigger a critical alarm on CPU usage + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/xenvsstate.pm b/storage/emc/xtremio/restapi/mode/xenvsstate.pm new file mode 100644 index 000000000..9942f4650 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/xenvsstate.pm @@ -0,0 +1,190 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::xenvsstate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $thresholds = { + xenvs_state => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + if (scalar(@values) < 3) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if (!defined $thresholds->{$section}) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; + } + +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'xenvs'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All Xenvs states are active'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'state', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'xenvs', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("Xenvs '%s' state is '%s'", + $item, + $details->{'xenv-state'})); + + my $exit = $self->get_severity(section => 'xenvs_state', instance => $item, value => $details->{'xenv-state'}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Xenvs '%s' state is '%s'", + $item, $details->{'xenv-state'})); + } + + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { + $status = $_->{status}; + return $status; + } + } + } + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +1; + +__END__ + +=head1 MODE + +Check Xenvs state + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=device,cluster-1_xxxx + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='xenvs_state,CRITICAL,^(?!(ok)$)' + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/plugin.pm b/storage/emc/xtremio/restapi/plugin.pm new file mode 100644 index 000000000..55e37a12a --- /dev/null +++ b/storage/emc/xtremio/restapi/plugin.pm @@ -0,0 +1,58 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::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} = '1.0'; + %{$self->{modes}} = ( + 'xenvs-cpu' => 'storage::emc::xtremio::restapi::mode::xenvscpu', + 'xenvs-state' => 'storage::emc::xtremio::restapi::mode::xenvsstate', + 'ssds-endurance' => 'storage::emc::xtremio::restapi::mode::ssdendurance', + 'ssds-iops' => 'storage::emc::xtremio::restapi::mode::ssdiops', + 'cluster-health' => 'storage::emc::xtremio::restapi::mode::clusterhealth', + ); + + $self->{custom_modes}{xtremioapi} = 'storage::emc::xtremio::restapi::custom::xtremioapi'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check EMC Xtremio through HTTP/REST API.