From 9459872f1767853736b47355e1600fa7fed1d795 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Mon, 19 Jun 2017 13:31:01 +0200 Subject: [PATCH] add vtl quadstor plugin --- apps/backup/quadstor/local/mode/listvtl.pm | 176 ++++++++ .../quadstor/local/mode/vtldiskusage.pm | 340 ++++++++++++++++ .../quadstor/local/mode/vtljobstatus.pm | 375 ++++++++++++++++++ .../quadstor/local/mode/vtltapeusage.pm | 357 +++++++++++++++++ apps/backup/quadstor/local/plugin.pm | 51 +++ .../video/appeartv/snmp/mode/alarms.pm | 8 +- .../ibm/mgmt_cards/imm/snmp/mode/eventlog.pm | 8 +- 7 files changed, 1301 insertions(+), 14 deletions(-) create mode 100644 apps/backup/quadstor/local/mode/listvtl.pm create mode 100644 apps/backup/quadstor/local/mode/vtldiskusage.pm create mode 100644 apps/backup/quadstor/local/mode/vtljobstatus.pm create mode 100644 apps/backup/quadstor/local/mode/vtltapeusage.pm create mode 100644 apps/backup/quadstor/local/plugin.pm diff --git a/apps/backup/quadstor/local/mode/listvtl.pm b/apps/backup/quadstor/local/mode/listvtl.pm new file mode 100644 index 000000000..48b95cc23 --- /dev/null +++ b/apps/backup/quadstor/local/mode/listvtl.pm @@ -0,0 +1,176 @@ +# +# Copyright 2017 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 apps::backup::quadstor::local::mode::listvtl; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'vtconfig' }, + "command-path:s" => { name => 'command_path', default => '/quadstorvtl/bin' }, + "command-options:s" => { name => 'command_options', default => '-l' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + + foreach (sort keys %{$self->{vtl}}) { + $self->{output}->output_add(long_msg => "'" . $_ . "' [type = " . $self->{vtl}->{$_}->{type} . "]"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List VTL:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (sort keys %{$self->{vtl}}) { + $self->{output}->add_disco_entry(name => $_, + active => $self->{vtl}->{$_}->{type} + ); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + + #Name DevType Type + #BV00002 VTL IBM IBM System Storage TS3100 + $self->{vtl} = {}; + my @lines = split /\n/, $stdout; + shift @lines; + foreach (@lines) { + next if (! /^(\S+)\s+(\S+)/); + + my ($name, $type) = ($1, $2); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping vtl '" . $name . "': no matching filter"); + next; + } + + $self->{vtl}->{$name} = { type => $type }; + } +} + +1; + +__END__ + +=head1 MODE + +List VTL. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'vtconfig'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: '/quadstorvtl/bin'). + +=item B<--command-options> + +Command options (Default: '-l'). + +=item B<--filter-name> + +Filter vtl name (can be a regexp). + +=back + +=cut diff --git a/apps/backup/quadstor/local/mode/vtldiskusage.pm b/apps/backup/quadstor/local/mode/vtldiskusage.pm new file mode 100644 index 000000000..752d44dcd --- /dev/null +++ b/apps/backup/quadstor/local/mode/vtldiskusage.pm @@ -0,0 +1,340 @@ +# +# Copyright 2017 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 apps::backup::quadstor::local::mode::vtldiskusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disks are ok' } + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'usage', set => { + key_values => [ { name => 'total' }, { name => 'used' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => + { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'bdconfig' }, + "command-path:s" => { name => 'command_path', default => '/quadstorvtl/bin' }, + "command-options:s" => { name => 'command_options', default => '-l -c' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /active/i' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + $self->{disk} = {}; + #ID Vendor Model SerialNumber Name Pool Size Used Status + #1 Msft Virtual /dev/sdb Default 1024.00 21.28 Active + #3 Msft Virtual /dev/sdc Default 1024.00 21.03 Active + #2 Msft Virtual /dev/sdd Default 1024.00 44.53 Active + #4 Msft Virtual /dev/sde Default 1024.00 165.06 Active + + my @lines = split /\n/, $stdout; + shift @lines; + foreach (@lines) { + next if (! /(\S+)\s+\S+\s+([0-9\.]+)\s+([0-9\.]+)\s+(\S+)\s*$/); + my ($name, $size, $used, $status) = ($1, $2, $3, $4); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping disk '" . $name . "': no matching filter"); + next; + } + + $self->{disk}->{$name} = { + display => $name, + total => $size * 1024 * 1024 * 1024, + used => $used * 1024 * 1024 * 1024, + status => $status, + }; + } + + if (scalar(keys %{$self->{disk}}) == 0) { + $self->{output}->add_option_msg(short_msg => "No disk found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check vtl disk usage. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'bdconfig'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: '/quadstorvtl/bin'). + +=item B<--command-options> + +Command options (Default: '-l -c'). + +=item B<--filter-name> + +Filter tape name. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=item B<--free> + +Thresholds are on free tape left. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /active/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage'. + +=back + +=cut diff --git a/apps/backup/quadstor/local/mode/vtljobstatus.pm b/apps/backup/quadstor/local/mode/vtljobstatus.pm new file mode 100644 index 000000000..abfbead27 --- /dev/null +++ b/apps/backup/quadstor/local/mode/vtljobstatus.pm @@ -0,0 +1,375 @@ +# +# Copyright 2017 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 apps::backup::quadstor::local::mode::vtljobstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + my $msg = 'status : ' . $self->{result_values}->{status}; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_long_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_long}) && $instance_mode->{option_results}->{critical_long} ne '' && + eval "$instance_mode->{option_results}->{critical_long}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_long}) && $instance_mode->{option_results}->{warning_long} ne '' && + eval "$instance_mode->{option_results}->{warning_long}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_long_output { + my ($self, %options) = @_; + my $msg = 'elapsed time : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); + + return $msg; +} + +sub custom_long_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{elapsed} = $options{new_datas}->{$self->{instance} . '_elapsed'}; + + return 0; +} + +my $last_status_frozen; + +sub custom_frozen_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_frozen}) && $instance_mode->{option_results}->{critical_frozen} ne '' && + eval "$instance_mode->{option_results}->{critical_frozen}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_frozen}) && $instance_mode->{option_results}->{warning_frozen} ne '' && + eval "$instance_mode->{option_results}->{warning_frozen}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + $last_status_frozen = $status; + return $status; +} + +sub custom_frozen_output { + my ($self, %options) = @_; + my $msg = 'frozen : no'; + + if (!$self->{output}->is_status(value => $last_status_frozen, compare => 'ok', litteral => 1)) { + $msg = 'frozen: yes'; + } + return $msg; +} + +sub custom_frozen_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{elapsed} = $options{new_datas}->{$self->{instance} . '_elapsed'}; + $self->{result_values}->{kb} = $options{new_datas}->{$self->{instance} . '_kb'} - $options{old_datas}->{$self->{instance} . '_kb'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'jobs', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + group => [ { name => 'job', cb_prefix_output => 'prefix_job_output', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{job} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'long', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' }, { name => 'elapsed' } ], + closure_custom_calc => $self->can('custom_long_calc'), + closure_custom_output => $self->can('custom_long_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_long_threshold'), + } + }, + { label => 'frozen', threshold => 0, set => { + key_values => [ { name => 'kb', diff => 1 }, { name => 'status' }, { name => 'display' }, { name => 'elapsed' } ], + closure_custom_calc => $self->can('custom_frozen_calc'), + closure_custom_output => $self->can('custom_frozen_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_frozen_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'impexp' }, + "command-path:s" => { name => 'command_path', default => '/quadstorvtl/bin' }, + "command-options:s" => { name => 'command_options', default => '-l' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /error/i' }, + "warning-long:s" => { name => 'warning_long' }, + "critical-long:s" => { name => 'critical_long' }, + "warning-frozen:s" => { name => 'warning_frozen' }, + "critical-frozen:s" => { name => 'critical_frozen' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return "job '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'warning_long', 'critical_long', 'warning_frozen', 'critical_frozen')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "quadstor_" . $self->{mode} . '_' . (defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me') . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + $self->{jobs}->{global} = { job => {} }; + #JobID Type Source State Transfer Elapsed + #252 Import 701831L2 Error 36.00 GB 572 + #253 Export 701849L2 Completed 19.43 GB 262 + #254 Export 701850L2 Completed 16.05 GB 1072 + #255 Export 701854L2 Completed 6.31 GB 142 + my $current_time = time(); + my @lines = split /\n/, $stdout; + shift @lines; + foreach (@lines) { + next if (! /^(\d+)\s+\S+\s+(\S+)\s+(\S+)\s+([0-9\.]+)\s+\S+\s+(\d+)/); + + my ($job_id, $job_source, $job_state, $job_kb, $job_elapsed) = + ($1, $2, $3, $4, $5); + + my $name = $job_source . '.' . $job_id; + $self->{jobs}->{global}->{job}->{$name} = { + display => $name, + status => $job_state, + kb => $job_kb * 1024, + elapsed => $job_elapsed + }; + } + + if (scalar(keys %{$self->{jobs}->{global}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No job found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check job status. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'impexp'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: '/quadstorvtl/bin'). + +=item B<--command-options> + +Command options (Default: '-l'). + +=item B<--warning-status> + +Set warning threshold for status (Default: none) +Can used special variables like: %{display}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /error/i'). +Can used special variables like: %{display}, %{status} + +=item B<--warning-long> + +Set warning threshold for long jobs (Default: none) +Can used special variables like: %{display}, %{status}, %{elapsed} + +=item B<--critical-long> + +Set critical threshold for long jobs (Default: none). +Can used special variables like: %{display}, %{status}, %{elapsed} + +=item B<--warning-frozen> + +Set warning threshold for frozen jobs (Default: none) +Can used special variables like: %{display}, %{status}, %{elapsed}, %{kb} + +=item B<--critical-frozen> + +Set critical threshold for frozen jobs (Default: none). +Can used special variables like: %{display}, %{status}, %{elapsed}, %{kb} + +=back + +=cut diff --git a/apps/backup/quadstor/local/mode/vtltapeusage.pm b/apps/backup/quadstor/local/mode/vtltapeusage.pm new file mode 100644 index 000000000..51792aaa6 --- /dev/null +++ b/apps/backup/quadstor/local/mode/vtltapeusage.pm @@ -0,0 +1,357 @@ +# +# Copyright 2017 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 apps::backup::quadstor::local::mode::vtltapeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_used_prct'}; + + $self->{result_values}->{used} = $self->{result_values}->{total} * $self->{result_values}->{prct_used} / 100; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tape', type => 1, cb_prefix_output => 'prefix_tape_output', message_multiple => 'All tapes are ok' } + ]; + + $self->{maps_counters}->{tape} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'usage', set => { + key_values => [ { name => 'total' }, { name => 'used_prct' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => + { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'vcconfig' }, + "command-path:s" => { name => 'command_path', default => '/quadstorvtl/bin' }, + "command-options:s" => { name => 'command_options', default => '-l -v %{vtl_name}' }, + "vtl-name:s" => { name => 'vtl_name' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /active/i' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{vtl_name}) || $self->{option_results}->{vtl_name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set vtl-name option."); + $self->{output}->option_exit(); + } + + $self->{option_results}->{command_options} =~ s/%\{vtl_name\}/$self->{option_results}->{vtl_name}/; + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_tape_output { + my ($self, %options) = @_; + + return "Tape '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + $self->{tape} = {}; + #Pool Label Element Address Vtype WORM Size Used% Status + #Default 701862L2 Unknown 0 LTO 2 200GB No 200 99 Vaulted + #Default 701899L2 Slot 1180 LTO 2 200GB No 200 0 Active + #Default 701900L2 Slot 1181 LTO 2 200GB No 200 0 Active + #Default 701901L2 Slot 1182 LTO 2 200GB No 200 0 Active + #Default 701902L2 Slot 1183 LTO 2 200GB No 200 0 Active + #Default 701903L2 Slot 1184 LTO 2 200GB No 200 0 Active + #Default 701904L2 Slot 1185 LTO 2 200GB No 200 0 Active + + my @lines = split /\n/, $stdout; + shift @lines; + foreach (@lines) { + next if (! /([0-9\.]+)\s+([0-9\.]+)\s+(\S+)\s*$/); + my ($size, $used_prct, $status) = ($1, $2, $3); + next if (! /^\S+\s+(\S+)\s+\S+\s+(\S+)/); + my $name = $1 . '.' . $2; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping vtl '" . $name . "': no matching filter"); + next; + } + + $self->{tape}->{$name} = { + display => $name, + total => $size * 1024 * 1024 * 1024, + used_prct => $used_prct, + status => $status, + }; + } + + if (scalar(keys %{$self->{tape}}) == 0) { + $self->{output}->add_option_msg(short_msg => "No tape found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check vtl tape usage. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'vcconfig'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: '/quadstorvtl/bin'). + +=item B<--command-options> + +Command options (Default: '-l -v %{vtl_name}'). + +=item B<--vtl-name> + +Set VTL name (Required). + +=item B<--filter-name> + +Filter tape name. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=item B<--free> + +Thresholds are on free tape left. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /active/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage'. + +=back + +=cut diff --git a/apps/backup/quadstor/local/plugin.pm b/apps/backup/quadstor/local/plugin.pm new file mode 100644 index 000000000..b505c206a --- /dev/null +++ b/apps/backup/quadstor/local/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2017 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 apps::backup::quadstor::local::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; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'list-vtl' => 'apps::backup::quadstor::local::mode::listvtl', + 'vtl-disk-usage' => 'apps::backup::quadstor::local::mode::vtldiskusage', + 'vtl-job-status' => 'apps::backup::quadstor::local::mode::vtljobstatus', + 'vtl-tape-usage' => 'apps::backup::quadstor::local::mode::vtltapeusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Quadstor through local commands (the plugin can use SSH). + +=cut diff --git a/hardware/devices/video/appeartv/snmp/mode/alarms.pm b/hardware/devices/video/appeartv/snmp/mode/alarms.pm index 57e668894..1a5febdc7 100644 --- a/hardware/devices/video/appeartv/snmp/mode/alarms.pm +++ b/hardware/devices/video/appeartv/snmp/mode/alarms.pm @@ -77,7 +77,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'alarms', type => 2, cb_long_output => 'alarms_long_output', message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] } ]; @@ -94,12 +94,6 @@ sub set_counters { ]; } -sub policy_long_output { - my ($self, %options) = @_; - - return "checking alarms"; -} - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); diff --git a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm index b98a50844..066c4e8b8 100644 --- a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm +++ b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/eventlog.pm @@ -76,7 +76,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'alarms', type => 2, cb_long_output => 'alarms_long_output', message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] } ]; @@ -93,12 +93,6 @@ sub set_counters { ]; } -sub policy_long_output { - my ($self, %options) = @_; - - return "checking alarms"; -} - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options);