diff --git a/centreon-plugins/.github/issue_template.md b/centreon-plugins/.github/issue_template.md new file mode 100644 index 000000000..9be725cf8 --- /dev/null +++ b/centreon-plugins/.github/issue_template.md @@ -0,0 +1,27 @@ + +Please follow information shown below according your issue. For all issues, thank you to describe it in English. +If some informations are confidentials, please send it directly by email to qgarnier@centreon.com and sbomm@centreon.com + +## Bug/Question + +If you are reporting a bug/question, make sure that we do not have any duplicates already open. You +can ensure this by searching the issue list for this repository. If there is a duplicate, please +close your issue and add a comment to the existing issue instead. + +Otherwise, open your issue and provide all informations you can. + +## New plugins and modes + +To develop a plugin/mode, we need following informations: +* SNMP: MIBs files and full snmpwalk of entreprise branch (snmpwalk -ObentU -v 2c -c public address .1.3.6.1.4.1 > equipment.snmpwalk) +* HTTP API (SOAP, Rest/Json, XML-RPC): the documentation and some curls examples +* CLI: command line examples +* SQL: requests +* JMX: mbean names and attributes + +If you can't provide informations, we'll close the ticket. The issue can be reopened if informations are provided. +All developments are open-source. We can't give a date for the development. If it's a priority, send us an email about it (qgarnier@centreon.com and sbomm@centreon.com) +and we'll put you in touch with our company. + +Thanks for using centreon-plugins! + diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm b/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm new file mode 100644 index 000000000..9b81362df --- /dev/null +++ b/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm @@ -0,0 +1,133 @@ +# +# 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::hyperv::2012::local::mode::listnodevms; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::common::powershell::hyperv::2012::listnodevms; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps', }, + "ps-exec-only" => { name => 'ps_exec_only', }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::hyperv::2012::listnodevms::get_powershell(no_ps => $self->{option_results}->{no_ps}); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => 'List Virtual Machines:'); + centreon::common::powershell::hyperv::2012::listnodevms::list($self, stdout => $stdout); + } + + $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', 'state', 'status', 'is_clustered', 'note']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::hyperv::2012::listnodevms::get_powershell(no_ps => $self->{option_results}->{no_ps}); + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + centreon::common::powershell::hyperv::2012::listnodevms::disco_show($self, stdout => $stdout); +} + +1; + +__END__ + +=head1 MODE + +List virtual machines on hyper-v node. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=back + +=cut \ No newline at end of file diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm b/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm index 4aab7d77c..4b77656d8 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm @@ -31,25 +31,38 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All VM snapshots are ok' }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All VM snapshots are ok', skipped_code => { -10 => 1 } }, ]; $self->{maps_counters}->{vm} = [ { label => 'snapshot', set => { key_values => [ { name => 'snapshot' }, { name => 'display' }], - closure_custom_output => $self->can('custom_vm_output'), + closure_custom_output => $self->can('custom_snapshot_output'), + closure_custom_perfdata => sub { return 0; }, + } + }, + { label => 'backing', set => { + key_values => [ { name => 'backing' }, { name => 'display' }], + closure_custom_output => $self->can('custom_backing_output'), closure_custom_perfdata => sub { return 0; }, } }, ]; } -sub custom_vm_output { +sub custom_snapshot_output { my ($self, %options) = @_; my $msg = 'checkpoint started since : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{snapshot_absolute}); return $msg; } +sub custom_backing_output { + my ($self, %options) = @_; + my $msg = 'backing started since : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{backing_absolute}); + + return $msg; +} + sub prefix_vm_output { my ($self, %options) = @_; @@ -96,18 +109,18 @@ sub manage_selection { } #[name= ISC1-SV04404 ][state= Running ][note= ] - #[checkpointCreationTime= 1475502921.28734 ] - #[checkpointCreationTime= 1475503073.81975 ] + #[checkpointCreationTime= 1475502921.28734 ][type= snapshot] + #[checkpointCreationTime= 1475503073.81975 ][type= backing] $self->{vm} = {}; - my $id = 1; + my ($id, $time) = (1, time()); while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[state=\s*(.*?)\s*\]\[note=\s*(.*?)\s*\](.*?)(?=\[name=|\z)/msig) { my ($name, $status, $note, $content) = ($1, $2, $3, $4); - my $chkpt = -1; - while ($content =~ /\[checkpointCreationTime=s*(.*?)\s*\]/msig) { - $chkpt = $1 if ($chkpt == -1 || $chkpt > $1); + my %chkpt = (backing => -1, snapshot => -1); + while ($content =~ /\[checkpointCreationTime=\s*(.*?)\s*\]\[type=\s*(.*?)\s*\]/msig) { + $chkpt{$2} = $1 if ($chkpt{$2} == -1 || $chkpt{$2} > $1); } - next if ($chkpt == -1); + next if ($chkpt{backing} == -1 && $chkpt{snapshot} == -1); if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && $name !~ /$self->{option_results}->{filter_vm}/i) { @@ -125,7 +138,9 @@ sub manage_selection { next; } - $self->{vm}->{$id} = { display => $name, snapshot => time() - $chkpt }; + $self->{vm}->{$id} = { display => $name, + snapshot => $chkpt{snapshot} > 0 ? $time - $chkpt{snapshot} : undef, + backing => $chkpt{backing} > 0 ? $time - $chkpt{backing} : undef }; $id++; } } @@ -180,12 +195,12 @@ Filter by VM notes (can be a regexp). =item B<--warning-*> Threshold warning. -Can be: 'snapshot' (in seconds). +Can be: 'snapshot' (in seconds), 'backing' (in seconds). =item B<--critical-*> Threshold critical. -Can be: 'snapshot' (in seconds). +Can be: 'snapshot' (in seconds), 'backing' (in seconds). =back diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm index dfc96d8e0..0dcb5342f 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm @@ -66,6 +66,11 @@ sub custom_status_calc { $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; $self->{result_values}->{vmaddition} = $options{new_datas}->{$self->{instance} . '_vmaddition'}; + $self->{result_values}->{operatingsystemshutdownenabled} = $options{new_datas}->{$self->{instance} . '_operatingsystemshutdownenabled'}; + $self->{result_values}->{timesynchronizationenabled} = $options{new_datas}->{$self->{instance} . '_timesynchronizationenabled'}; + $self->{result_values}->{dataexchangeenabled} = $options{new_datas}->{$self->{instance} . '_dataexchangeenabled'}; + $self->{result_values}->{heartbeatenabled} = $options{new_datas}->{$self->{instance} . '_heartbeatenabled'}; + $self->{result_values}->{backupenabled} = $options{new_datas}->{$self->{instance} . '_backupenabled'}; return 0; } @@ -77,7 +82,9 @@ sub set_counters { ]; $self->{maps_counters}->{vm} = [ { label => 'snapshot', set => { - key_values => [ { name => 'vm' }, { name => 'status' }, { name => 'vmaddition' } ], + key_values => [ { name => 'vm' }, { name => 'status' }, { name => 'vmaddition' }, + { name => 'operatingsystemshutdownenabled' }, { name => 'timesynchronizationenabled' }, + { name => 'dataexchangeenabled' }, { name => 'heartbeatenabled' }, { name => 'backupenabled' } ], closure_custom_calc => $self->can('custom_status_calc'), closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, @@ -171,16 +178,20 @@ sub manage_selection { $self->{output}->exit(); } - #[name= test1 ][description= Test Descr - - pp - - aa ][status= Running ][cloud= ][hostgrouppath= All Hosts\CORP\test1 ]][VMAddition= 6.3.9600.16384 ] - #[name= test2 ][description= ][status= HostNotResponding ][cloud= ][hostgrouppath= All Hosts\CORP\test2 ]][VMAddition= Not Detected ] - #[name= test3 ][description= ][status= HostNotResponding ][cloud= ][hostgrouppath= All Hosts\CORP\test3 ]][VMAddition= Not Detected ] - #[name= test4 ][description= ][status= HostNotResponding ][cloud= ][hostgrouppath= All Hosts\CORP\test4 ]][VMAddition= Not Detected ] + #[VM= test1 ][Description= Test Descr - - pp - - aa ][Status= Running ][Cloud= ][HostGroup= All Hosts\CORP\test1 ][VMAddition= 6.3.9600.16384 ] + #[VM= test2 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test2 ][VMAddition= Not Detected ] + #[VM= test3 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test3 ][VMAddition= Not Detected ] + #[VM= test4 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test4 ][VMAddition= Not Detected ] $self->{vm} = {}; my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[description=\s*(.*?)\s*\]\[status=\s*(.*?)\s*\]\[cloud=\s*(.*?)\s*\]\[hostgrouppath=\s*(.*?)\s*\]\[VMAddition=\s*(.*?)\s*\]/msig) { - my %values = (vm => $1, description => $2, status => $3, cloud => $4, hostgroup => $5, vmaddition => $6); - + my @lines = split /\n/, $stdout; + foreach my $line (@lines) { + my %values; + while ($line =~ /\[(.*?)=\s*(.*?)\s*\]/g) { + $values{lc($1)} = $2; + } + $values{hostgroup} =~ s/\\/\//g; my $filtered = 0; foreach (('vm', 'description', 'status', 'hostgroup')) { diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm index 44d2e0573..5d8bdbda9 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm @@ -129,7 +129,7 @@ sub manage_selection { my $content = $6; my $chkpt = -1; - while ($content =~ /\[checkpointAddedTime=s*(.*?)\s*\]/msig) { + while ($content =~ /\[checkpointAddedTime=\s*(.*?)\s*\]/msig) { $chkpt = $1 if ($chkpt == -1 || $chkpt > $1); } next if ($chkpt == -1); diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm index 6563b126a..4161a6fcb 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm @@ -188,7 +188,8 @@ sub manage_selection { } } - $self->{vm}->{$id} = { display => $values{vm}, vm => $values{vm}, status => $values{status}, hostgroup => $values{hostgroup} }; + $self->{vm}->{$id} = { display => $values{vm}, vm => $values{vm}, status => $values{status}, hostgroup => $values{hostgroup} } + if ($filtered == 0); $id++; } diff --git a/centreon-plugins/apps/hyperv/2012/local/plugin.pm b/centreon-plugins/apps/hyperv/2012/local/plugin.pm index 31eb8492c..f6091e374 100644 --- a/centreon-plugins/apps/hyperv/2012/local/plugin.pm +++ b/centreon-plugins/apps/hyperv/2012/local/plugin.pm @@ -31,13 +31,14 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'scvmm-integration-service' => 'apps::hyperv::2012::local::mode::scvmmintegrationservice', - 'scvmm-snapshot' => 'apps::hyperv::2012::local::mode::scvmmsnapshot', - 'scvmm-vm-status' => 'apps::hyperv::2012::local::mode::scvmmvmstatus', + 'list-node-vms' => 'apps::hyperv::2012::local::mode::listnodevms', 'node-integration-service' => 'apps::hyperv::2012::local::mode::nodeintegrationservice', 'node-replication' => 'apps::hyperv::2012::local::mode::nodereplication', 'node-snapshot' => 'apps::hyperv::2012::local::mode::nodesnapshot', 'node-vm-status' => 'apps::hyperv::2012::local::mode::nodevmstatus', + 'scvmm-integration-service' => 'apps::hyperv::2012::local::mode::scvmmintegrationservice', + 'scvmm-snapshot' => 'apps::hyperv::2012::local::mode::scvmmsnapshot', + 'scvmm-vm-status' => 'apps::hyperv::2012::local::mode::scvmmvmstatus', ); return $self; diff --git a/centreon-plugins/apps/pacemaker/local/mode/clustat.pm b/centreon-plugins/apps/pacemaker/local/mode/clustat.pm new file mode 100644 index 000000000..b26984e79 --- /dev/null +++ b/centreon-plugins/apps/pacemaker/local/mode/clustat.pm @@ -0,0 +1,267 @@ +# +# Copyright 2016 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::pacemaker::local::mode::clustat; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use XML::Simple; + +my $instance_mode; + +my %map_node_state = ( + 0 => 'down', + 1 => 'up', + 2 => 'clean' +); + +sub custom_state_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_state_output { + my ($self, %options) = @_; + + my $msg = sprintf("state is '%s'", $self->{result_values}->{state}); + return $msg; +} + +sub custom_state_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All nodes are ok' }, + { name => 'groups', type => 1, cb_prefix_output => 'prefix_group_output', message_multiple => 'All groups/resources are ok' } + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'node', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_state_calc'), + closure_custom_output => $self->can('custom_state_output'), + closure_custom_threshold_check => $self->can('custom_state_threshold'), + closure_custom_perfdata => sub { return 0; }, + } + }, + ]; + $self->{maps_counters}->{groups} = [ + { label => 'group', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_state_calc'), + closure_custom_output => $self->can('custom_state_output'), + closure_custom_threshold_check => $self->can('custom_state_threshold'), + closure_custom_perfdata => sub { return 0; }, + } + }, + ]; +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node: '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_group_output { + my ($self, %options) = @_; + + return "Resource group: '" . $options{instance_value}->{display} . "' "; +} + +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 => 'clustat' }, + "command-path:s" => { name => 'command_path', default => '/usr/sbin' }, + "command-options:s" => { name => 'command_options', default => ' -x 2>&1' }, + "warning-group:s" => { name => 'warning_group' }, + "critical-group:s" => { name => 'critical_group' }, + "warning-node:s" => { name => 'warning_node' }, + "critical-node:s" => { name => 'critical_node' }, + "filter-node:s" => { name => 'filter_node', default => '%{state} !~ /up|clean/' }, + "filter-groups:s" => { name => 'filter_groups', default => '%{state} !~ /starting|started/' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + + $self->change_macros(); + +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_group', 'critical_group', 'warning_node', 'critical_node')) { + 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}); + + my $clustat_hash = XMLin($stdout); + + foreach my $node (keys %{$clustat_hash->{nodes}->{node}}) { + if (defined($self->{option_results}->{filter_node}) && $self->{option_results}->{filter_node} ne '' && + $node !~ /$self->{option_results}->{filter_node}/) { + $self->{output}->output_add(long_msg => "skipping peer '" . $node . "': no matching filter.", debug => 1); + next; + } + $self->{nodes}->{$node} = { state => $map_node_state{$clustat_hash->{nodes}->{node}->{$node}->{state}}, + display => $node }; + } + + foreach my $group_name (keys %{$clustat_hash->{groups}->{group}}) { + if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' && + $group_name !~ /$self->{option_results}->{filter_group}/) { + $self->{output}->output_add(long_msg => "skipping peer '" . $group_name . "': no matching filter.", debug => 1); + next; + } + $self->{groups}->{$group_name} = { state => $clustat_hash->{groups}->{group}->{$group_name}->{state_str}, + display => $group_name }; + } + +} + +1; + +__END__ + +=head1 MODE + +Check Cluster Resource Manager (need 'clustat' command). +Should be executed on a cluster node. + +=over 8 + +=item B<--warning-*> + +Can be ('group','node') +Warning threshold for status. + +=item B<--critical-*> + +Can be ('group','node') +Critical threshold for status. (Default: --critical-node '%{state} !~ /up|clean/' --critical-group '%{state} !~ /started|starting/') + +=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: 'crm_mon'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: '/usr/sbin'). + +=item B<--command-options> + +Command options (Default: ' -x 2>&1'). + +=back + +=cut diff --git a/centreon-plugins/apps/pacemaker/local/plugin.pm b/centreon-plugins/apps/pacemaker/local/plugin.pm index 5977b892b..96f165665 100644 --- a/centreon-plugins/apps/pacemaker/local/plugin.pm +++ b/centreon-plugins/apps/pacemaker/local/plugin.pm @@ -33,6 +33,7 @@ sub new { %{$self->{modes}} = ( 'crm' => 'apps::pacemaker::local::mode::crm', 'constraints' => 'apps::pacemaker::local::mode::constraints', + 'clustat' => 'apps::pacemaker::local::mode::clustat', ); return $self; diff --git a/centreon-plugins/apps/varnish/local/mode/backend.pm b/centreon-plugins/apps/varnish/local/mode/backend.pm index 48e227506..5b34647a4 100644 --- a/centreon-plugins/apps/varnish/local/mode/backend.pm +++ b/centreon-plugins/apps/varnish/local/mode/backend.pm @@ -1,5 +1,5 @@ # -# Copyright 2017 Centreon (http://www.centreon.com/) +# Copyright 2016 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -20,80 +20,115 @@ package apps::varnish::local::mode::backend; -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; use Digest::MD5 qw(md5_hex); +use JSON; -my $maps_counters = { - backend_conn => { thresholds => { - warning_conn => { label => 'warning-conn', exit_value => 'warning' }, - critical_conn => { label => 'critical-conn', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. success: %.2f', - factor => 1, unit => '', - }, - backend_unhealthy => { thresholds => { - warning_unhealthy => { label => 'warning-unhealthy', exit_value => 'warning' }, - critical_unhealthy => { label => 'critical-unhealthy', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. not attempted: %.2f', - factor => 1, unit => '', - }, - backend_busy => { thresholds => { - warning_busy => { label => 'warning-busy', exit_value => 'warning' }, - critical_busy => { label => 'critical-busy', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. too many: %.2f', - factor => 1, unit => '', - }, - backend_fail => { thresholds => { - warning_fail => { label => 'warning-fail', exit_value => 'warning' }, - critical_fail => { label => 'critical-fail', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. failures: %.2f', - factor => 1, unit => '', - }, - backend_reuse => { thresholds => { - warning_reuse => { label => 'warning-reuse', exit_value => 'warning' }, - critical_reuse => { label => 'critical-reuse', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. reuses: %.2f', - factor => 1, unit => '', - }, - backend_toolate => { thresholds => { - warning_toolate => { label => 'warning-toolate', exit_value => 'warning' }, - critical_toolate => { label => 'critical-toolate', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. was closed: %.2f', - factor => 1, unit => '', - }, - backend_recycle => { thresholds => { - warning_recycle => { label => 'warning-recycle', exit_value => 'warning' }, - critical_recycle => { label => 'critical-recycle', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. recycles: %.2f', - factor => 1, unit => '', - }, - backend_retry => { thresholds => { - warning_retry => { label => 'warning-retry', exit_value => 'warning' }, - critical_retry => { label => 'critical-retry', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. retry: %.2f', - factor => 1, unit => '', - }, - backend_req => { thresholds => { - warning_req => { label => 'warning-req', exit_value => 'warning' }, - critical_req => { label => 'critical-req', exit_value => 'critical' }, - }, - output_msg => 'Backend requests made: %.2f', - factor => 1, unit => '', - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'backend', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{backend} = [ + { label => 'conn', set => { + key_values => [ { name => 'backend_conn', diff => 1 } ], + output_template => 'Backend con: %.2f/s', output_error_template => "Backend con: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_conn', value => 'backend_conn_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'unhealthy', set => { + key_values => [ { name => 'backend_unhealthy', diff => 1 } ], + output_template => 'Backend unhealthy: %.2f/s', output_error_template => "Backend unhealthy: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_unhealthy', value => 'backend_unhealthy_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'busy', set => { + key_values => [ { name => 'backend_busy', diff => 1 } ], + output_template => 'Backend busy: %.2f/s', output_error_template => "Backend busy: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_miss', value => 'backend_miss_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'fail', set => { + key_values => [ { name => 'backend_fail', diff => 1 } ], + output_template => 'Backend fail: %.2f/s', output_error_template => "Backend fail: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_fail', value => 'backend_fail_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'reuse', set => { + key_values => [ { name => 'backend_reuse', diff => 1 } ], + output_template => 'Backend reuse: %.2f/s', output_error_template => "Backend reuse: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_reuse', value => 'backend_reuse_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'recycle', set => { + key_values => [ { name => 'backend_recycle', diff => 1 } ], + output_template => 'Backend recycle: %.2f/s', output_error_template => "Backend recycle: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_recycle', value => 'backend_recycle_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'retry', set => { + key_values => [ { name => 'backend_retry', diff => 1 } ], + output_template => 'Backend retry: %.2f/s', output_error_template => "Backend retry: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_retry', value => 'backend_retry_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'recycle', set => { + key_values => [ { name => 'backend_recycle', diff => 1 } ], + output_template => 'Backend recycle: %.2f/s', output_error_template => "Backend recycle: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_recycle', value => 'backend_recycle_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'request', set => { + key_values => [ { name => 'backend_req', diff => 1 } ], + output_template => 'Backend requests: %.2f/s', output_error_template => "Backend requests: %s", + per_second => 1, + perfdatas => [ + { label => 'backend_req', value => 'backend_req_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + ], +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; @@ -108,39 +143,13 @@ sub new { "sudo" => { name => 'sudo' }, "command:s" => { name => 'command', default => 'varnishstat' }, "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; }; -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { +sub manage_selection { my ($self, %options) = @_; my $stdout = centreon::plugins::misc::execute(output => $self->{output}, @@ -148,86 +157,23 @@ sub getdata { 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->{option_results}->{command_options2}); - #print $stdout; + command_options => $self->{option_results}->{command_options}); - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text +# "MAIN.backend_hit": {"type": "MAIN", "value": 18437, "flag": "a", "description": "Cache hits"}, +# "MAIN.backend_hitpass": {"type": "MAIN", "value": 3488, "flag": "a", "description": "Cache hits for pass"}, +# "MAIN.backend_miss": {"type": "MAIN", "value": 5782, "flag": "a", "description": "Cache misses"}, + my $json_data = decode_json($stdout); - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /backend/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + $self->{backend}->{$counter} = $value; } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); }; @@ -267,7 +213,7 @@ Parameter for Binary File (Default: ' -1 ') =item B<--warning-*> -Warning Threshold for: +Warning Threshold for: conn => Backend conn. success, unhealthy => Backend conn. not attempted, busy => Backend conn. too many, @@ -276,11 +222,11 @@ reuse => Backend conn. reuses, toolate => Backend conn. was closed, recycle => Backend conn. recycles, retry => Backend conn. retry, -req => Backend requests made +request => Backend requests made =item B<--critical-*> -Critical Threshold for: +Critical Threshold for: conn => Backend conn. success, unhealthy => Backend conn. not attempted, busy => Backend conn. too many, @@ -289,8 +235,8 @@ reuse => Backend conn. reuses, toolate => Backend conn. was closed, recycle => Backend conn. recycles, retry => Backend conn. retry, -req => Backend requests made +request => Backend requests made =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/varnish/local/mode/cache.pm b/centreon-plugins/apps/varnish/local/mode/cache.pm index ad04ec8d3..9582f4c06 100644 --- a/centreon-plugins/apps/varnish/local/mode/cache.pm +++ b/centreon-plugins/apps/varnish/local/mode/cache.pm @@ -1,5 +1,5 @@ # -# Copyright 2017 Centreon (http://www.centreon.com/) +# Copyright 2016 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -20,38 +20,55 @@ package apps::varnish::local::mode::cache; -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; use Digest::MD5 qw(md5_hex); +use JSON; -my $maps_counters = { - cache_hit => { thresholds => { - warning_hit => { label => 'warning-hit', exit_value => 'warning' }, - critical_hit => { label => 'critical-hit', exit_value => 'critical' }, - }, - output_msg => 'Cache Hits: %.2f', - factor => 1, unit => '', - }, - cache_hitpass => { thresholds => { - warning_hitpass => { label => 'warning-hitpass', exit_value => 'warning' }, - critical_hitpass => { label => 'critical-hitpass', exit_value => 'critical' }, - }, - output_msg => 'Cache Hits for pass: %.2f', - factor => 1, unit => '', - }, - cache_miss => { thresholds => { - warning_miss => { label => 'warning-miss', exit_value => 'warning' }, - critical_miss => { label => 'critical-miss', exit_value => 'critical' }, - }, - output_msg => 'Cache misses: %.2f', - factor => 1, unit => '', - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cache', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{cache} = [ + { label => 'hit', set => { + key_values => [ { name => 'cache_hit', diff => 1 } ], + output_template => 'Cache hit: %.2f/s', output_error_template => "Cache hit: %s", + per_second => 1, + perfdatas => [ + { label => 'cache_hit', value => 'cache_hit_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'hitpass', set => { + key_values => [ { name => 'cache_hitpass', diff => 1 } ], + output_template => 'Cache hitpass : %.2f/s', output_error_template => "Cache hitpass : %s", + per_second => 1, + perfdatas => [ + { label => 'cache_hitpass', value => 'cache_hitpass_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'miss', set => { + key_values => [ { name => 'cache_miss', diff => 1 } ], + output_template => 'Cache miss : %.2f/s', output_error_template => "Cache miss : %s", + per_second => 1, + perfdatas => [ + { label => 'cache_miss', value => 'cache_miss_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + ], +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; @@ -66,45 +83,13 @@ sub new { "sudo" => { name => 'sudo' }, "command:s" => { name => 'command', default => 'varnishstat' }, "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; }; -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -#my $stdout = ' -#cache_hit 69941 0.00 Cache hits -#cache_hitpass 10 0.00 Cache hits for pass -#cache_miss 16746 0.00 Cache misses -#'; - -sub getdata { +sub manage_selection { my ($self, %options) = @_; my $stdout = centreon::plugins::misc::execute(output => $self->{output}, @@ -112,86 +97,23 @@ sub getdata { 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->{option_results}->{command_options2}); - #print $stdout; + command_options => $self->{option_results}->{command_options}); - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text +# "MAIN.cache_hit": {"type": "MAIN", "value": 18437, "flag": "a", "description": "Cache hits"}, +# "MAIN.cache_hitpass": {"type": "MAIN", "value": 3488, "flag": "a", "description": "Cache hits for pass"}, +# "MAIN.cache_miss": {"type": "MAIN", "value": 5782, "flag": "a", "description": "Cache misses"}, + my $json_data = decode_json($stdout); - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /cache/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + $self->{cache}->{$counter} = $value; } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); }; @@ -227,7 +149,7 @@ Directory Path to Varnishstat Binary File (Default: /usr/bin) =item B<--command-options> -Parameter for Binary File (Default: ' -1 ') +Parameter for Binary File (Default: ' -1 -j 2>&1') =item B<--warning-*> @@ -245,4 +167,4 @@ miss => Cache Misses =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/varnish/local/mode/clients.pm b/centreon-plugins/apps/varnish/local/mode/clients.pm new file mode 100644 index 000000000..e9b701143 --- /dev/null +++ b/centreon-plugins/apps/varnish/local/mode/clients.pm @@ -0,0 +1,187 @@ +# +# Copyright 2016 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::varnish::local::mode::clients; + +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use JSON; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'clients', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{clients} = [ + { label => 'request', set => { + key_values => [ { name => 'client_req' , diff => 1 } ], + output_template => 'Client request (Total): %.2f', output_error_template => "Client request: %s", + per_second => 1, + perfdatas => [ + { label => 'client_req', value => 'client_req_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'request-400', set => { + key_values => [ { name => 'client_req_400' , diff => 1 } ], + output_template => 'Client request (HTTP/400): %.2f', output_error_template => "Client request (HTTP/400): %s", + per_second => 1, + perfdatas => [ + { label => 'client_req_400', value => 'client_req_400_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'request-411', set => { + key_values => [ { name => 'client_req_411' , diff => 1 } ], + output_template => 'Client request (HTTP/411): %.2f', output_error_template => "Client request (HTTP/411): %s", + per_second => 1, + perfdatas => [ + { label => 'client_req_411', value => 'client_req_411_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'request-413', set => { + key_values => [ { name => 'client_req_413' , diff => 1 } ], + output_template => 'Client request (HTTP/413): %.2f', output_error_template => "Client request (HTTP/413): %s", + per_second => 1, + perfdatas => [ + { label => 'client_req_413', value => 'client_req_413_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'request-417', set => { + key_values => [ { name => 'client_req_417' , diff => 1 } ], + output_template => 'Client request (HTTP/417): %.2f', output_error_template => "Client request (HTTP/417): %s", + per_second => 1, + perfdatas => [ + { label => 'client_req_417', value => 'client_req_417_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + ], +} + +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 => 'varnishstat' }, + "command-path:s" => { name => 'command_path', default => '/usr/bin' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, + }); + + return $self; +}; + +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}); + +# "MAIN.client_req_400": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 400 errors"}, +# "MAIN.client_req_411": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 411 errors"}, +# "MAIN.client_req_413": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 413 errors"}, +# "MAIN.client_req_417": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 417 errors"}, +# "MAIN.client_req": {"type": "MAIN", "value": 13597, "flag": "a", "description": "Good client requests received"}, + + my $json_data = decode_json($stdout); + + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /^([A-Z])+\.client_.*/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + $self->{clients}->{$counter} = $value; + } +}; + + +1; + +__END__ + +=head1 MODE + +Check client requests with varnishstat command (Varnish v4 required) + +=over 8 + +=item B<--remote> + +If you dont run this script locally, if you wanna use it remote, you can run it remotely with '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<--command> + +Varnishstat Binary Filename (Default: varnishstat) + +=item B<--command-path> + +Directory Path to Varnishstat Binary File (Default: /usr/bin) + +=item B<--command-options> + +Parameter for Binary File (Default: ' -1 -j 2>&1') + +=item B<--warning-*> +Warning threshold per second. +Can be: (request,request-400,request-411,request-413,request-417) + +=item B<--critical-*> +Critical threshold per second : +Can be: (request,request-400,request-411,request-413,request-417) + +=back + +=cut diff --git a/centreon-plugins/apps/varnish/local/mode/sessions.pm b/centreon-plugins/apps/varnish/local/mode/sessions.pm index 29105c824..46224d2aa 100644 --- a/centreon-plugins/apps/varnish/local/mode/sessions.pm +++ b/centreon-plugins/apps/varnish/local/mode/sessions.pm @@ -1,5 +1,5 @@ # -# Copyright 2017 Centreon (http://www.centreon.com/) +# Copyright 2016 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -20,52 +20,135 @@ package apps::varnish::local::mode::sessions; -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; use Digest::MD5 qw(md5_hex); +use JSON; -my $maps_counters = { - sess_closed => { thresholds => { - warning_closed => { label => 'warning-closed', exit_value => 'warning' }, - critical_closed => { label => 'critical-closed', exit_value => 'critical' }, - }, - output_msg => 'Session Closed: %.2f', - factor => 1, unit => '', - }, - sess_pipeline => { thresholds => { - warning_pipeline => { label => 'warning-pipeline', exit_value => 'warning' }, - critical_pipeline => { label => 'critical-pipeline', exit_value => 'critical' }, - }, - output_msg => 'Session Pipeline: %.2f', - factor => 1, unit => '', - }, - sess_readahead => { thresholds => { - warning_readahead => { label => 'warning-readahead', exit_value => 'warning' }, - critical_readahead => { label => 'critical-readahead', exit_value => 'critical' }, - }, - output_msg => 'Session Read Ahead: %.2f', - factor => 1, unit => '', - }, - sess_linger => { thresholds => { - warning_linger => { label => 'warning-linger', exit_value => 'warning' }, - critical_linger => { label => 'critical-linger', exit_value => 'critical' }, - }, - output_msg => 'Session Linger: %.2f', - factor => 1, unit => '', - }, - sess_herd => { thresholds => { - warning_herd => { label => 'warning-herd', exit_value => 'warning' }, - critical_herd => { label => 'critical-herd', exit_value => 'critical' }, - }, - output_msg => 'Session herd: %.2f', - factor => 1, unit => '', - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'sessions', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{sessions} = [ + { label => 'accepted', set => { + key_values => [ { name => 'sess_conn', diff => 1 } ], + output_template => 'Session accepted: %.2f/s', output_error_template => "Session accepted: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_conn', value => 'sess_conn_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'dropped', set => { + key_values => [ { name => 'sess_drop', diff => 1 } ], + output_template => 'Session dropped: %.2f/s', output_error_template => "Session dropped: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_drop', value => 'sess_drop_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'failed', set => { + key_values => [ { name => 'sess_fail', diff => 1 } ], + output_template => 'Session fail: %.2f/s', output_error_template => "Session fail: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_fail', value => 'sess_fail_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'pipeoverflow', set => { + key_values => [ { name => 'sess_pipe_overflow', diff => 1 } ], + output_template => 'Sessions pipe overflow: %.2f/s', output_error_template => "Sessions pipe overflow: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_pipe_overflow', value => 'sess_pipe_overflow_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'queued', set => { + key_values => [ { name => 'sess_queued' , diff => 1 } ], + output_template => 'Session queued: %.2f/s', output_error_template => "Session queued: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_queued', value => 'sess_queued_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'dropped', set => { + key_values => [ { name => 'sess_dropped' , diff => 1 } ], + output_template => 'Session dropped: %.2f/s', output_error_template => "Session dropped: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_dropped', value => 'sess_dropped_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'readahead', set => { + key_values => [ { name => 'sess_readahead' , diff => 1 } ], + output_template => 'Session readahead: %.2f/s', output_error_template => "Session readahead: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_readahead', value => 'sess_readahead_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'closed', set => { + key_values => [ { name => 'sess_closed' , diff => 1 } ], + output_template => 'Session closed: %.2f/s', output_error_template => "Session closed: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_closed', value => 'sess_closed_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'herd', set => { + key_values => [ { name => 'sess_herd' , diff => 1 } ], + output_template => 'Session herd: %.2f/s', output_error_template => "Session herd: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_herd', value => 'sess_herd_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'linger', set => { + key_values => [ { name => 'sess_linger' , diff => 1 } ], + output_template => 'Session linger: %.2f/s', output_error_template => "Session linger: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_linger', value => 'sess_linger_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'pipeline', set => { + key_values => [ { name => 'sess_pipeline' , diff => 1 } ], + output_template => 'Session pipeline: %.2f/s', output_error_template => "Session pipeline: %s", + per_second => 1, + perfdatas => [ + { label => 'sess_pipeline', value => 'sess_pipeline_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + ], +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; @@ -80,39 +163,13 @@ sub new { "sudo" => { name => 'sudo' }, "command:s" => { name => 'command', default => 'varnishstat' }, "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; }; -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { +sub manage_selection { my ($self, %options) = @_; my $stdout = centreon::plugins::misc::execute(output => $self->{output}, @@ -120,86 +177,31 @@ sub getdata { 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->{option_results}->{command_options2}); - #print $stdout; + command_options => $self->{option_results}->{command_options}); - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text +# "MAIN.sess_conn": {"type": "MAIN", "value": 13598, "flag": "c", "description": "Sessions accepted"}, +# "MAIN.sess_drop": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions dropped"}, +# "MAIN.sess_fail": {"type": "MAIN", "value": 0, "flag": "c", "description": "Session accept failures"}, +# "MAIN.sess_pipe_overflow": {"type": "MAIN", "value": 0, "flag": "c", "description": "Session pipe overflow"}, +# "MAIN.sess_queued": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions queued for thread"}, +# "MAIN.sess_dropped": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions dropped for thread"}, +# "MAIN.sess_closed": {"type": "MAIN", "value": 13211, "flag": "a", "description": "Session Closed"}, +# "MAIN.sess_pipeline": {"type": "MAIN", "value": 0, "flag": "a", "description": "Session Pipeline"}, +# "MAIN.sess_readahead": {"type": "MAIN", "value": 0, "flag": "a", "description": "Session Read Ahead"}, +# "MAIN.sess_herd": {"type": "MAIN", "value": 26, "flag": "a", "description": "Session herd"}, - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; + my $json_data = decode_json($stdout); -sub run { - my ($self, %options) = @_; + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /^([A-Z])+\.sess_.*/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + $self->{sessions}->{$counter} = $value; } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); }; @@ -235,26 +237,16 @@ Directory Path to Varnishstat Binary File (Default: /usr/bin) =item B<--command-options> -Parameter for Binary File (Default: ' -1 ') +Parameter for Binary File (Default: ' -1 -j 2>&1') =item B<--warning-*> - -Warning Threshold for: -closed => Session Closed, -pipeline => Session Pipeline, -readahead => Session Read Ahead, -linger => Session Linger, -herd => Session herd +Warning Threshold per second. +Can be (accepted,closed,queued,failed,pipeline,readahead,linger,herd,dropped,pipeoverflow) =item B<--critical-*> - -Critical Threshold for: -closed => Session Closed, -pipeline => Session Pipeline, -readahead => Session Read Ahead, -linger => Session Linger, -herd => Session herd +Critical Threshold per second for: +Can be (accepted,closed,queued,failed,pipeline,readahead,linger,herd,dropped,pipeoverflow) =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/varnish/local/mode/shm.pm b/centreon-plugins/apps/varnish/local/mode/shm.pm index 873470d64..28e510120 100644 --- a/centreon-plugins/apps/varnish/local/mode/shm.pm +++ b/centreon-plugins/apps/varnish/local/mode/shm.pm @@ -1,5 +1,5 @@ # -# Copyright 2017 Centreon (http://www.centreon.com/) +# Copyright 2016 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -20,52 +20,75 @@ package apps::varnish::local::mode::shm; -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; use Digest::MD5 qw(md5_hex); +use JSON; -my $maps_counters = { - shm_records => { thresholds => { - warning_records => { label => 'warning-records', exit_value => 'warning' }, - critical_records => { label => 'critical-records', exit_value => 'critical' }, - }, - output_msg => 'SHM records: %.2f', - factor => 1, unit => '', - }, - shm_writes => { thresholds => { - warning_writes => { label => 'warning-writes', exit_value => 'warning' }, - critical_writes => { label => 'critical-writes', exit_value => 'critical' }, - }, - output_msg => 'SHM writes: %.2f', - factor => 1, unit => '', - }, - shm_flushes => { thresholds => { - warning_flushes => { label => 'warning-flushes', exit_value => 'warning' }, - critical_flushes => { label => 'critical-flushes', exit_value => 'critical' }, - }, - output_msg => 'SHM flushes due to overflow: %.2f', - factor => 1, unit => '', - }, - shm_cont => { thresholds => { - warning_cont => { label => 'warning-cont', exit_value => 'warning' }, - critical_cont => { label => 'critical-cont', exit_value => 'critical' }, - }, - output_msg => 'SHM MTX contention: %.2f', - factor => 1, unit => '', - }, - shm_cycles => { thresholds => { - warning_cycles => { label => 'warning-cycles', exit_value => 'warning' }, - critical_cycles => { label => 'critical-cycles', exit_value => 'critical' }, - }, - output_msg => 'SHM cycles through buffer: %.2f', - factor => 1, unit => '', - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'shm', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{shm} = [ + { label => 'records', set => { + key_values => [ { name => 'shm_records', diff => 1 } ], + output_template => 'SHM Records: %.2f/s', output_error_template => "SHM Records: %s", + per_second => 1, + perfdatas => [ + { label => 'shm_records', value => 'shm_records_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'writes', set => { + key_values => [ { name => 'shm_writes', diff => 1 } ], + output_template => 'SHM Writes: %.2f/s', output_error_template => "SHM Writes: %s", + per_second => 1, + perfdatas => [ + { label => 'shm_writes', value => 'shm_writes_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'flushes', set => { + key_values => [ { name => 'shm_flushes', diff => 1 } ], + output_template => 'SHM Flushes: %.2f/s', output_error_template => "SHM Flushes: %s", + per_second => 1, + perfdatas => [ + { label => 'shm_flushes', value => 'shm_flushes_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'cont', set => { + key_values => [ { name => 'shm_cont', diff => 1 } ], + output_template => 'SHM Contention: %.2f/s', output_error_template => "SHM Contention: %s", + per_second => 1, + perfdatas => [ + { label => 'shm_cont', value => 'shm_cont_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'cycles', set => { + key_values => [ { name => 'shm_cycles', diff => 1 } ], + output_template => 'SHM Cycles: %.2f/s', output_error_template => "SHM Cycles: %s", + per_second => 1, + perfdatas => [ + { label => 'shm_cycles', value => 'shm_cycles_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + ], +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; @@ -80,39 +103,13 @@ sub new { "sudo" => { name => 'sudo' }, "command:s" => { name => 'command', default => 'varnishstat' }, "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; }; -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { +sub manage_selection { my ($self, %options) = @_; my $stdout = centreon::plugins::misc::execute(output => $self->{output}, @@ -120,89 +117,28 @@ sub getdata { 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->{option_results}->{command_options2}); - #print $stdout; + command_options => $self->{option_results}->{command_options}); - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text +# "MAIN.shm_records": {"type": "MAIN", "value": 6992776, "flag": "a", "description": "SHM records"}, +# "MAIN.shm_writes": {"type": "MAIN", "value": 3947244, "flag": "a", "description": "SHM writes"}, +# "MAIN.shm_flushes": {"type": "MAIN", "value": 12354, "flag": "a", "description": "SHM flushes due to overflow"}, +# "MAIN.shm_cont": {"type": "MAIN", "value": 564, "flag": "a", "description": "SHM MTX contention"}, +# "MAIN.shm_cycles": {"type": "MAIN", "value": 3, "flag": "a", "description": "SHM cycles through buffer"}, - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; + my $json_data = decode_json($stdout); + + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /shm/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + $self->{shm}->{$counter} = $value; + } }; -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - 1; __END__ @@ -235,11 +171,11 @@ Directory Path to Varnishstat Binary File (Default: /usr/bin) =item B<--command-options> -Parameter for Binary File (Default: ' -1 ') +Parameter for Binary File (Default: ' -1 -j 2>&1') =item B<--warning-*> -Warning Threshold for: +Warning Threshold for: records => SHM records, writes => SHM writes, flushes => SHM flushes due to overflow, @@ -248,7 +184,7 @@ cycles => SHM cycles through buffer =item B<--critical-*> -Critical Threshold for: +Critical Threshold for: records => SHM records, writes => SHM writes, flushes => SHM flushes due to overflow, @@ -257,4 +193,4 @@ cycles => SHM cycles through buffer =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/varnish/local/mode/threads.pm b/centreon-plugins/apps/varnish/local/mode/threads.pm new file mode 100644 index 000000000..c867f9509 --- /dev/null +++ b/centreon-plugins/apps/varnish/local/mode/threads.pm @@ -0,0 +1,203 @@ +# +# Copyright 2016 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::varnish::local::mode::threads; + +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use JSON; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'threads', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{threads} = [ + { label => 'total', set => { + key_values => [ { name => 'threads' } ], + output_template => 'Total Threads: %d', output_error_template => "Total Threads: %s", + perfdatas => [ + { label => 'total', value => 'threads_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'created', set => { + key_values => [ { name => 'threads_created', diff => 1 } ], + output_template => 'Thread created: %.2f/s', output_error_template => "Thread created: %s", + per_second => 1, + perfdatas => [ + { label => 'created', value => 'threads_created_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'limited', set => { + key_values => [ { name => 'threads_limited', diff => 1 } ], + output_template => 'Thread limited: %.2f/s', output_error_template => "Thread limited: %s", + per_second => 1, + perfdatas => [ + { label => 'limited', value => 'threads_limited_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'destroyed', set => { + key_values => [ { name => 'threads_destroyed', diff => 1 } ], + output_template => 'Thread destroyed: %.2f/s', output_error_template => "Thread destroyed: %s", + per_second => 1, + perfdatas => [ + { label => 'destroyed', value => 'threads_destroyed_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'failed', set => { + key_values => [ { name => 'threads_failed', diff => 1 } ], + output_template => 'Threads fail: %.2f/s', output_error_template => "Threads fail: %s", + per_second => 1, + perfdatas => [ + { label => 'failed', value => 'threads_failed_per_second', template => '%.2f', + min => 0 }, + ], + } + }, + { label => 'queue', set => { + key_values => [ { name => 'thread_queue_len' } ], + output_template => 'Thread queue lenght: %d', output_error_template => "Thread queue lenght: %d", + perfdatas => [ + { label => 'queue_lenght', value => 'thread_queue_len_absolute', template => '%d', + min => 0 }, + ], + } + }, + ], +} + +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 => 'varnishstat' }, + "command-path:s" => { name => 'command_path', default => '/usr/bin' }, + "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, + }); + + return $self; +}; + +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}); + +# "MAIN.threads_limited": {"type": "MAIN", "value": 0, "flag": "c", "description": "Threads hit max"}, +# "MAIN.threads_created": {"type": "MAIN", "value": 100, "flag": "c", "description": "Threads created"}, +# "MAIN.threads_destroyed": {"type": "MAIN", "value": 0, "flag": "c", "description": "Threads destroyed"}, +# "MAIN.threads_failed": {"type": "MAIN", "value": 0, "flag": "c", "description": "Thread creation failed"}, +# "MAIN.thread_queue_len": {"type": "MAIN", "value": 0, "flag": "g", "description": "Length of session queue"}, + + my $json_data = decode_json($stdout); + + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + foreach my $counter (keys %{$json_data}) { + next if ($counter !~ /^([A-Z])+\.thread.*/); + my $value = $json_data->{$counter}->{value}; + $counter =~ s/^([A-Z])+\.//; + print "$counter ===> $value \n"; + $self->{threads}->{$counter} = $value; + } +}; + + +1; + +__END__ + +=head1 MODE + +Check Varnish 4 Cache with varnishstat Command + +=over 8 + +=item B<--remote> + +If you dont run this script locally, if you wanna use it remote, you can run it remotely with '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<--command> + +Varnishstat Binary Filename (Default: varnishstat) + +=item B<--command-path> + +Directory Path to Varnishstat Binary File (Default: /usr/bin) + +=item B<--command-options> + +Parameter for Binary File (Default: ' -1 -j 2>&1') + +=item B<--warning-*> + +Warning Threshold for threads. +Can be: + (created, destroyed, limited, failed) [per sec] + (total, queue lenght) [absolute] + +=item B<--critical-*> + +Warning Threshold for threads. +Can be: + (created, destroyed, limited, failed) [per sec] + (total, queue lenght) [absolute] + +=back + +=cut + diff --git a/centreon-plugins/apps/varnish/local/plugin.pm b/centreon-plugins/apps/varnish/local/plugin.pm index 097e198bf..d646541d2 100644 --- a/centreon-plugins/apps/varnish/local/plugin.pm +++ b/centreon-plugins/apps/varnish/local/plugin.pm @@ -32,6 +32,7 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( 'connections' => 'apps::varnish::local::mode::connections', + 'clients' => 'apps::varnish::local::mode::clients', 'cache' => 'apps::varnish::local::mode::cache', 'backend' => 'apps::varnish::local::mode::backend', 'sessions' => 'apps::varnish::local::mode::sessions', @@ -48,6 +49,7 @@ sub new { 'sms' => 'apps::varnish::local::mode::sms', 'hcb' => 'apps::varnish::local::mode::hcb', 'esi' => 'apps::varnish::local::mode::esi', + 'threads' => 'apps::varnish::local::mode::threads', ); return $self; diff --git a/centreon-plugins/apps/video/openheadend/snmp/mode/nodeusage.pm b/centreon-plugins/apps/video/openheadend/snmp/mode/nodeusage.pm new file mode 100644 index 000000000..a39ec6a14 --- /dev/null +++ b/centreon-plugins/apps/video/openheadend/snmp/mode/nodeusage.pm @@ -0,0 +1,228 @@ +# +# 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::video::openheadend::snmp::mode::nodeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 = 'dependancy status : ' . $self->{result_values}->{dep_status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{dep_status} = $options{new_datas}->{$self->{instance} . '_nodeDepStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'node', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All nodes are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{node} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'nodeDepStatus' }, { 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 => 'bitrate', set => { + key_values => [ { name => 'nodeBitrate' }, { name => 'display' } ], + output_template => 'bitRate : %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'bitrate', value => 'nodeBitrate_absolute', template => '%d', + unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{dep_status} =~ /false/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $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; + } + } +} + +my %map_type = (1 => 'net', 2 => 'dvb', 3 => 'file', 4 => 'circular-file', + 5 => 'directory', 6 => 'asi-rx', 7 => 'rtsp', 8 => 'jpeg', + 9 => 'video', 10 => 'audio', 11 => 'video-rx', 12 => 'extract' +); +my %map_status = (1 => 'true', 2 => 'false'); +my $mapping = { + nodeType => { oid => '.1.3.6.1.4.1.35902.1.4.1.1.3', map => \%map_type }, + nodeDepStatus => { oid => '.1.3.6.1.4.1.35902.1.4.1.1.5', map => \%map_status }, + nodeName => { oid => '.1.3.6.1.4.1.35902.1.4.1.1.7' }, + nodeBitrate => { oid => '.1.3.6.1.4.1.35902.1.4.2.1.9' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{node} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{nodeType}->{oid} }, + { oid => $mapping->{nodeDepStatus}->{oid} }, + { oid => $mapping->{nodeName}->{oid} }, + { oid => $mapping->{nodeBitrate}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{nodeName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{nodeName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{nodeName} . "': no matching filter.", debug => 1); + next; + } + + $result->{nodeBitrate} = !defined($result->{nodeBitrate}) || $result->{nodeBitrate} == 0 ? undef : $result->{nodeBitrate}; + $self->{node}->{$instance} = { + display => $result->{nodeName}, + %$result + }; + } + + if (scalar(keys %{$self->{node}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No node found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check node usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{dep_status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{dep_status} =~ /false/i'). +Can used special variables like: %{dep_status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'bitrate'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'bitrate'. + +=back + +=cut diff --git a/centreon-plugins/apps/video/openheadend/snmp/mode/operationstatus.pm b/centreon-plugins/apps/video/openheadend/snmp/mode/operationstatus.pm new file mode 100644 index 000000000..36c0163ef --- /dev/null +++ b/centreon-plugins/apps/video/openheadend/snmp/mode/operationstatus.pm @@ -0,0 +1,215 @@ +# +# 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::video::openheadend::snmp::mode::operationstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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}->{dep_status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_operationOpStatus'}; + $self->{result_values}->{dep_status} = $options{new_datas}->{$self->{instance} . '_operationDepStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'operation', type => 1, cb_prefix_output => 'prefix_operation_output', message_multiple => 'All operations are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{operation} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'operationOpStatus' }, { name => 'operationDepStatus' }, { 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'), + } + }, + ]; +} + +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 => + { + "filter-id:s" => { name => 'filter_id' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /false/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_operation_output { + my ($self, %options) = @_; + + return "Operation '" . $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; + } + } +} + +my %map_type = (1 => 'demux', 2 => 'monitor-pid', 3 => 'monitor-type', + 4 => 'playout-file', 5 => 'playout-circular-file', 6 => 'monitor-sid', + 7 => 'playout-directory', 8 => 'hint', 9 => 'transcode-avc', 10 => 'transcode-mp2', + 11 => 'transcode-aac', 12 => 'transmit-input', 13 => 'transmit-output', + 14 => 'transcode-a52', 15 => 'grid-input', 16 => 'grid-acquire-mono', + 17 => 'grid-acquire-stereo', 18 => 'acquire-mono', 19 => 'acquire-stereo', + 20 => 'mux-input', 21 => 'remap-pid', 22 => 'remap-sid', + 23 => 'mosaic', 24 => 'hint-scte35', +); +my %map_status = (1 => 'true', 2 => 'false'); +my $mapping = { + operationType => { oid => '.1.3.6.1.4.1.35902.1.6.1.1.3', map => \%map_type }, + operationDepStatus => { oid => '.1.3.6.1.4.1.35902.1.6.1.1.5', map => \%map_status }, + operationOpStatus => { oid => '.1.3.6.1.4.1.35902.1.6.1.1.7', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{operation} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{operationType}->{oid} }, + { oid => $mapping->{operationDepStatus}->{oid} }, + { oid => $mapping->{operationOpStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{operationOpStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $instance !~ /$self->{option_results}->{filter_id}/) { + $self->{output}->output_add(long_msg => "skipping '" . $instance . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $result->{operationType} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{operationType} . "': no matching filter.", debug => 1); + next; + } + + $self->{operation}->{$instance} = { + display => $instance, + %$result + }; + } + + if (scalar(keys %{$self->{operation}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No operation found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check operation status. + +=over 8 + +=item B<--filter-id> + +Filter by operation ID (can be a regexp). + +=item B<--filter-type> + +Filter by operation type (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{dep_status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{dep_status} =~ /false/i'). +Can used special variables like: %{status}, %{dep_status}, %{display} + +=back + +=cut diff --git a/centreon-plugins/apps/video/openheadend/snmp/plugin.pm b/centreon-plugins/apps/video/openheadend/snmp/plugin.pm new file mode 100644 index 000000000..9681d37e6 --- /dev/null +++ b/centreon-plugins/apps/video/openheadend/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# 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::video::openheadend::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'node-usage' => 'apps::video::openheadend::snmp::mode::nodeusage', + 'operation-status' => 'apps::video::openheadend::snmp::mode::operationstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check OpenHeadend in SNMP. + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/custom/api.pm b/centreon-plugins/apps/video/zixi/restapi/custom/api.pm new file mode 100644 index 000000000..ede50ee12 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/custom/api.pm @@ -0,0 +1,209 @@ +# +# 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::video::zixi::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => '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->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : 4444; + $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http'; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{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->{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}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{username} = $self->{username}; + $self->{option_results}->{password} = $self->{password}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get { + my ($self, %options) = @_; + + $self->settings(); + + my $response = $self->{http}->request(url_path => $options{path}, + critical_status => '', warning_status => ''); + my $content; + eval { + $content = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (defined($content->{errmsg})) { + $self->{output}->add_option_msg(short_msg => "Cannot get data: " . $content->{errmsg}); + $self->{output}->option_exit(); + } + + return $content; +} + +1; + +__END__ + +=head1 NAME + +Zixi REST API + +=head1 SYNOPSIS + +Zixi Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Zixi hostname. + +=item B<--port> + +Port used (Default: 4444) + +=item B<--proto> + +Specify https if needed (Default: 'http') + +=item B<--username> + +Zixi username. + +=item B<--password> + +Zixi password. + +=item B<--proxyurl> + +Proxy URL if any + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterinputusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterinputusage.pm new file mode 100644 index 000000000..755669d8a --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterinputusage.pm @@ -0,0 +1,241 @@ +# +# 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::video::zixi::restapi::mode::broadcasterinputusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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} . ' [error: ' . $self->{result_values}->{error} . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{source} = $options{new_datas}->{$self->{instance} . '_source'}; + $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'input', type => 1, cb_prefix_output => 'prefix_input_output', message_multiple => 'All inputs are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{input} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'source' }, { name => 'error' } ], + 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 => 'traffic-in', set => { + key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'source' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'traffic_in_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'source_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'traffic_out', diff => 1 }, { name => 'source' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'traffic_out_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'source_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-source:s" => { name => 'filter_source' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_input_output { + my ($self, %options) = @_; + + return "Input '" . $options{instance_value}->{source} . "' "; +} + +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; + } + } +} + +my %mapping_input_status = (0 => 'none', 1 => 'unknown', + 2 => 'resolve error', 3 => 'timeout', 4 => 'network error', 5 => 'protocol error', + 6 => 'server is full', 7 => 'connection rejected', 8 => 'authentication error', 9 => 'license error', + 10 => 'end of file', 11 => 'flood error', 12 => 'redirect', 13 => 'stopped', + 14 => 'limit', 15 => 'not found', 16 => 'not supported', 17 => 'local file system error', + 18 => 'remote file system error', 19 => 'stream replaced', 20 => 'p2p abort', + 21 => 'compression error', 22 => 'source collision error', 23 => 'adaptive', + 24 => 'tcp connection error', 25 => 'rtmp connection error', 26 => 'rtmp handshake error', + 27 => 'tcp connection closed', 28 => 'rtmp stream error', 29 => 'rtmp publish error', + 30 => 'rtmp stream closed', 31 => 'rtmp play error', 32 => 'rtmp protocol error', + 33 => 'rtmp analyze timeout', 34 => 'busy', 35 => 'encryption error', + 36 => 'transcoder error', 37 => 'error in invocation a transcoder subprocess', + 38 => 'error communicating with a transcoder subprocess', 39 => 'error in RTMP Akamai authentication', + 40 => 'maximum outputs for the source reached', 41 => 'generic error', + 42 => 'zero bitrate warning', 43 => 'low bitrate warning', 44 => 'multicast join failed', +); + +sub manage_selection { + my ($self, %options) = @_; + + $self->{input} = {}; + my $result = $options{custom}->get(path => '/zixi/streams.json?complete=1'); + + foreach my $entry (@{$result->{streams}}) { + if (defined($self->{option_results}->{filter_source}) && $self->{option_results}->{filter_source} ne '' && + $entry->{source} !~ /$self->{option_results}->{filter_source}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{source} . "': no matching filter.", debug => 1); + next; + } + + $self->{input}->{$entry->{id}} = { + source => $entry->{source}, + status => $entry->{status}, + error => $mapping_input_status{$entry->{error_code}}, + traffic_in => $entry->{stats}->{net_recv}->{bytes} * 8, + traffic_out => $entry->{stats}->{net_send}->{bytes} * 8, + }; + } + + if (scalar(keys %{$self->{input}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No input found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "zixi_" . $self->{mode} . '_' . $options{custom}->{hostname} . '_' . $options{custom}->{port} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check input usage. + +=over 8 + +=item B<--filter-source> + +Filter source (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in', 'traffic-out'. + +=item B<--warning-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{source}, %{status}, %{error}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i'). +Can used special variables like: %{source}, %{status}, %{error}. + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm new file mode 100644 index 000000000..720c193d6 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm @@ -0,0 +1,303 @@ +# +# 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::video::zixi::restapi::mode::broadcasterlicenseusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 $info = $self->{result_values}->{info} eq '' ? '-' : $self->{result_values}->{info}; + my $error = $self->{result_values}->{error} eq '' ? '-' : $self->{result_values}->{error}; + my $msg = 'information : ' . $info . ' [error: ' . $error . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{info} = $options{new_datas}->{$self->{instance} . '_info'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; + + 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 ($self->{result_values}->{total} =~ /[0-9]/ && $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, + 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} =~ /[0-9]/ ? $self->{result_values}->{total} : undef); +} + +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 ($self->{result_values}->{total} =~ /[0-9]/ && $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 $msg = sprintf("Total: %s Used: %s (%s) Free: %s (%s)", + $self->{result_values}->{total}, + $self->{result_values}->{used}, + defined($self->{result_values}->{prct_used}) ? sprintf("%.2f%%", $self->{result_values}->{prct_used}) : '-', + defined($self->{result_values}->{free}) ? $self->{result_values}->{free} : '-', + defined($self->{result_values}->{prct_free}) ? sprintf("%.2f%%", $self->{result_values}->{prct_free}) : '-'); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + return -10 if ($options{new_datas}->{$self->{instance} . '_info'} =~ /disabled/i || + $options{new_datas}->{$self->{instance} . '_used'} eq '' || + ($options{new_datas}->{$self->{instance} . '_used'} =~ /^0$/ && $options{new_datas}->{$self->{instance} . '_limit'} =~ /^0$/)); + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_limit'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_name'}; + + # Can be 'unlimited' + if ($self->{result_values}->{total} =~ /[0-9]/) { + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + if ($self->{result_values}->{free} < 0) { + $self->{result_values}->{free} = 0; + $self->{result_values}->{prct_free} = 0; + } + } + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'license', type => 1, cb_prefix_output => 'prefix_license_output', message_multiple => 'All licenses are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{license} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'info' }, { name => 'name' }, { name => 'error' } ], + 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 => 'used' }, { name => 'limit' }, { name => 'name' }, { name => 'info' } ], + 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'), + } + }, + { label => 'days', set => { + key_values => [ { name => 'days' } ], + output_template => '%d days remaining before expiration', + closure_custom_perfdata => sub { return 0; }, + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'."); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_license_output { + my ($self, %options) = @_; + + return "License '" . $options{instance_value}->{name} . "' "; +} + +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) = @_; + + $self->{license} = {}; + my $result = $options{custom}->get(path => '/licensing_info'); + + my $current_time = time(); + foreach my $entry (@{$result->{lics}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{name} . "': no matching filter.", debug => 1); + next; + } + + # Format 09-dec-2017. Can be also 'permanent' (so dont care) + my $days_remaining; + if ($entry->{exp} =~ /\d+-\S+-\d+/) { + my $create_time = Date::Parse::str2time($entry->{exp}); + $days_remaining = ($create_time - $current_time) / 86400; + } + + $self->{license}->{$entry->{name}} = { %{$entry}, days => $days_remaining }; + } + + if (scalar(keys %{$self->{license}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No license found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check license usage. + +=over 8 + +=item B<--filter-source> + +Filter source (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage', 'days'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage', 'days'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=item B<--free> + +Thresholds are on free license left. + +=item B<--warning-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{name}, %{error}, %{info}. + +=item B<--critical-status> + +Set critical threshold for status (Default: -). +Can used special variables like: %{name}, %{error}, %{info}. + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm new file mode 100644 index 000000000..9973a7637 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/broadcasteroutputusage.pm @@ -0,0 +1,252 @@ +# +# 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::video::zixi::restapi::mode::broadcasteroutputusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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} . ' [error: ' . $self->{result_values}->{error} . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'output_stream', type => 1, cb_prefix_output => 'prefix_output_output', message_multiple => 'All outputs are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{output_stream} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'name' }, { name => 'error' } ], + 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 => 'traffic-in', set => { + key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'name' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'traffic_in_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'traffic_out', diff => 1 }, { name => 'name' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'traffic_out_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'dropped-in', set => { + key_values => [ { name => 'dropped_in', diff => 1 }, { name => 'name' } ], + output_template => 'Packets Dropped In : %s', + perfdatas => [ + { label => 'dropped_in', value => 'dropped_in_absolute', template => '%.2f', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_output_output { + my ($self, %options) = @_; + + return "Output '" . $options{instance_value}->{name} . "' "; +} + +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; + } + } +} + +my %mapping_output_status = (0 => 'none', 1 => 'unknown', + 2 => 'resolve error', 3 => 'timeout', 4 => 'network error', 5 => 'protocol error', + 6 => 'server is full', 7 => 'connection rejected', 8 => 'authentication error', 9 => 'license error', + 10 => 'end of file', 11 => 'flood error', 12 => 'redirect', 13 => 'stopped', + 14 => 'limit', 15 => 'not found', 16 => 'not supported', 17 => 'local file system error', + 18 => 'remote file system error', 19 => 'stream replaced', 20 => 'p2p abort', + 21 => 'compression error', 22 => 'source collision error', 23 => 'adaptive', + 24 => 'tcp connection error', 25 => 'rtmp connection error', 26 => 'rtmp handshake error', + 27 => 'tcp connection closed', 28 => 'rtmp stream error', 29 => 'rtmp publish error', + 30 => 'rtmp stream closed', 31 => 'rtmp play error', 32 => 'rtmp protocol error', + 33 => 'rtmp analyze timeout', 34 => 'busy', 35 => 'encryption error', + 36 => 'transcoder error', 37 => 'error in invocation a transcoder subprocess', + 38 => 'error communicating with a transcoder subprocess', 39 => 'error in RTMP Akamai authentication', + 40 => 'maximum outputs for the source reached', 41 => 'generic error', + 42 => 'zero bitrate warning', 43 => 'low bitrate warning', 44 => 'multicast join failed', +); + +sub manage_selection { + my ($self, %options) = @_; + + $self->{output_stream} = {}; + my $result = $options{custom}->get(path => '/zixi/outputs.json?complete=1'); + + foreach my $entry (@{$result->{outputs}}) { + my $name = $entry->{name} . '/' . $entry->{requested_stream_id}; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{output_stream}->{$entry->{id}} = { + name => $name, + status => $entry->{status}, + error => $mapping_output_status{$entry->{error_code}}, + traffic_in => $entry->{stats}->{net_recv}->{bytes} * 8, + traffic_out => $entry->{stats}->{net_send}->{bytes} * 8, + dropped_in => $entry->{stats}->{net_recv}->{dropped}, + }; + } + + if (scalar(keys %{$self->{output_stream}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No output found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "zixi_" . $self->{mode} . '_' . $options{custom}->{hostname} . '_' . $options{custom}->{port} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check output usage. + +=over 8 + +=item B<--filter-name> + +Filter name (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in', 'traffic-out', 'dropped-in'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in', 'traffic-out', 'dropped-in'. + +=item B<--warning-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{name}, %{status}, %{error}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i'). +Can used special variables like: %{name}, %{status}, %{error}. + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/broadcastersystemusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/broadcastersystemusage.pm new file mode 100644 index 000000000..75bef28f9 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/broadcastersystemusage.pm @@ -0,0 +1,113 @@ +# +# 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::video::zixi::restapi::mode::broadcastersystemusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'cpu-load', set => { + key_values => [ { name => 'cpu_load' } ], + output_template => 'Cpu Load : %.2f %%', + perfdatas => [ + { label => 'cpu_load', value => 'cpu_load_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'memory-usage', set => { + key_values => [ { name => 'memory_used' } ], + output_template => 'Memory Used : %.2f %%', + perfdatas => [ + { label => 'memory_used', value => 'memory_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'disk-usage', set => { + key_values => [ { name => 'disk_used' } ], + output_template => 'Disk Used : %.2f %%', + perfdatas => [ + { label => 'disk_used', value => 'disk_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => '/sys_load.json'); + $self->{global} = { disk_used => $result->{disk_space}, cpu_load => $result->{cpu_load}, memory_used => $result->{memory_use} }; +} + +1; + +__END__ + +=head1 MODE + +Check system usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^disk-usage$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'disk-usage' (%), 'memory-usage' (%), 'cpu-load' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'disk-usage' (%), 'memory-usage' (%), 'cpu-load' (%). + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/feederinputusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/feederinputusage.pm new file mode 100644 index 000000000..559a86cd4 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/feederinputusage.pm @@ -0,0 +1,212 @@ +# +# 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::video::zixi::restapi::mode::feederinputusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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 = 'active : ' . $self->{result_values}->{active} . ' [error: ' . ($self->{result_values}->{error} ne '' ? $self->{result_values}->{error} : '-') . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'input', type => 1, cb_prefix_output => 'prefix_input_output', message_multiple => 'All inputs are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{input} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'active' }, { name => 'name' }, { name => 'error' } ], + 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 => 'traffic-in', set => { + key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'name' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'traffic_in_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_input_output { + my ($self, %options) = @_; + + return "Input '" . $options{instance_value}->{name} . "' "; +} + +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) = @_; + + $self->{input} = {}; + my $result = $options{custom}->get(path => '/inputs_data'); + foreach my $entry (@{$result->{inputs}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{source} . "': no matching filter.", debug => 1); + next; + } + + $self->{input}->{$entry->{name}} = { + name => $entry->{name}, + active => $entry->{active} == 0 ? 'false' : 'true', + error => $entry->{error}, + traffic_in => $entry->{bytes} * 8, + }; + } + + if (scalar(keys %{$self->{input}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No input found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "zixi_" . $self->{mode} . '_' . $options{custom}->{hostname} . '_' . $options{custom}->{port} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check feeder input usage. + +=over 8 + +=item B<--filter-name> + +Filter name (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in'. + +=item B<--warning-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{name}, %{active}, %{error}. + +=item B<--critical-status> + +Set critical threshold for status (Default: -). +Can used special variables like: %{name}, %{active}, %{error}. + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/mode/feederoutputusage.pm b/centreon-plugins/apps/video/zixi/restapi/mode/feederoutputusage.pm new file mode 100644 index 000000000..a4fc8339a --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/mode/feederoutputusage.pm @@ -0,0 +1,211 @@ +# +# 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::video::zixi::restapi::mode::feederoutputusage; + +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 = 'active : ' . $self->{result_values}->{active} . ' [error: ' . ($self->{result_values}->{error} ne '' ? $self->{result_values}->{error} : '-') . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; + $self->{result_values}->{con_stat} = $options{new_datas}->{$self->{instance} . '_con_stat'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'output_stream', type => 1, cb_prefix_output => 'prefix_output_output', message_multiple => 'All outputs are ok' }, + ]; + + $self->{maps_counters}->{output_stream} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'active' }, { name => 'name' }, { name => 'error' }, { name => 'con_stat' } ], + 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 => 'current-bitrate', set => { + key_values => [ { name => 'bitrate' }, { name => 'name' } ], + output_change_bytes => 2, + output_template => 'Current Bitrate : %s %s/s', + perfdatas => [ + { label => 'current_bitrate', value => 'bitrate_absolute', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_output_output { + my ($self, %options) = @_; + + return "Output '" . $options{instance_value}->{name} . "' "; +} + +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) = @_; + + $self->{output_stream} = {}; + my $result = $options{custom}->get(path => '/outs'); + foreach my $entry (@{$result->{outs}}) { + $entry->{name} = centreon::plugins::misc::trim($entry->{name}); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{source} . "': no matching filter.", debug => 1); + next; + } + + $self->{output_stream}->{$entry->{name}} = { + name => $entry->{name}, + active => $entry->{active} == 0 ? 'false' : 'true', + error => $entry->{error}, + con_stat => $entry->{con_stat}, + bitrate => $entry->{bitrate}, + }; + } + + if (scalar(keys %{$self->{output_stream}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No output found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check feeder output usage. + +=over 8 + +=item B<--filter-source> + +Filter source (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'current-birate'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-birate'. + +=item B<--warning-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{name}, %{active}, %{error}, %{con_stat}. + +=item B<--critical-status> + +Set critical threshold for status (Default: -). +Can used special variables like: %{name}, %{active}, %{error}, %{con_stat}. + +=back + +=cut diff --git a/centreon-plugins/apps/video/zixi/restapi/plugin.pm b/centreon-plugins/apps/video/zixi/restapi/plugin.pm new file mode 100644 index 000000000..feaa65522 --- /dev/null +++ b/centreon-plugins/apps/video/zixi/restapi/plugin.pm @@ -0,0 +1,54 @@ +# +# 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::video::zixi::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'broadcaster-input-usage' => 'apps::video::zixi::restapi::mode::broadcasterinputusage', + 'broadcaster-license-usage' => 'apps::video::zixi::restapi::mode::broadcasterlicenseusage', + 'broadcaster-output-usage' => 'apps::video::zixi::restapi::mode::broadcasteroutputusage', + 'broadcaster-system-usage' => 'apps::video::zixi::restapi::mode::broadcastersystemusage', + 'feeder-input-usage' => 'apps::video::zixi::restapi::mode::feederinputusage', + 'feeder-output-usage' => 'apps::video::zixi::restapi::mode::feederoutputusage', + ); + + $self->{custom_modes}{api} = 'apps::video::zixi::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Zixi through HTTP/REST API. + +=cut diff --git a/centreon-plugins/apps/vmware/connector/custom/connector.pm b/centreon-plugins/apps/vmware/connector/custom/connector.pm index b54f96a85..6b39120ba 100644 --- a/centreon-plugins/apps/vmware/connector/custom/connector.pm +++ b/centreon-plugins/apps/vmware/connector/custom/connector.pm @@ -23,7 +23,7 @@ package apps::vmware::connector::custom::connector; use strict; use warnings; use JSON; -use ZMQ::LibZMQ3; +use ZMQ::LibZMQ4; use ZMQ::Constants qw(:all); use UUID; @@ -309,4 +309,4 @@ Can shift the time. We the following option you can average X counters values (d B. -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/cisco/standard/snmp/mode/components/sensor.pm b/centreon-plugins/centreon/common/cisco/standard/snmp/mode/components/sensor.pm index 5190a05d4..26d33e60a 100644 --- a/centreon-plugins/centreon/common/cisco/standard/snmp/mode/components/sensor.pm +++ b/centreon-plugins/centreon/common/cisco/standard/snmp/mode/components/sensor.pm @@ -129,11 +129,11 @@ sub get_default_warning_threshold { my $value = $result->{entSensorThresholdValue} * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision}))); if ($result->{entSensorThresholdRelation} eq 'greaterOrEqual') { - $high_th = $value - 0.01; + $high_th = $value - (1 * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision})))); } elsif ($result->{entSensorThresholdRelation} eq 'greaterThan') { $high_th = $value; } elsif ($result->{entSensorThresholdRelation} eq 'lessOrEqual') { - $low_th = $value + 0.01; + $low_th = $value + (1 * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision})))); } elsif ($result->{entSensorThresholdRelation} eq 'lessThan') { $low_th = $value; } @@ -157,11 +157,11 @@ sub get_default_critical_threshold { my $value = $result->{entSensorThresholdValue} * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision}))); if ($result->{entSensorThresholdRelation} eq 'greaterOrEqual') { - $high_th = $value - 0.01; + $high_th = $value - (1 * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision})))); } elsif ($result->{entSensorThresholdRelation} eq 'greaterThan') { $high_th = $value; } elsif ($result->{entSensorThresholdRelation} eq 'lessOrEqual') { - $low_th = $value + 0.01; + $low_th = $value + (1 * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision})))); } elsif ($result->{entSensorThresholdRelation} eq 'lessThan') { $low_th = $value; } diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm new file mode 100644 index 000000000..42ee95da4 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm @@ -0,0 +1,101 @@ +# +# 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 centreon::common::powershell::hyperv::2012::listnodevms; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + $vms = Get-VM + + Foreach ($vm in $vms) { + $note = $vm.Notes -replace "\r","" + $note = $note -replace "\n"," - " + Write-Host "[name=" $vm.VMName "][state=" $vm.State "][status=" $vm.Status "][IsClustered=" $vm.IsClustered "][note=" $note "]" + } +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + + +sub list { + my ($self, %options) = @_; + + # Following output: + #[name= XXXX1 ][state= Running ][status= Operating normally ][IsClustered= True ][note= ] + #... + + foreach my $line (split /\n/, $options{stdout}) { + next if ($line !~ /^\[name=(.*?)\]\[state=(.*?)\]\[status=(.*?)\]\[IsClustered=(.*?)\]\[note=(.*?)\]/); + my ($name, $state, $status, $IsClustered, $note) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2), + centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5)); + + $self->{output}->output_add(long_msg => "'" . $name . "' [state = $state, status = " . $status . ']'); + } +} + +sub disco_show { + my ($self, %options) = @_; + + # Following output: + #[name= XXXX1 ][state= Running ][status= Operating normally ][IsClustered= True ][note= ] + #... + + foreach my $line (split /\n/, $options{stdout}) { + next if ($line !~ /^\[name=(.*?)\]\[state=(.*?)\]\[status=(.*?)\]\[IsClustered=(.*?)\]\[note=(.*?)\]/); + my ($name, $state, $status, $IsClustered, $note) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2), + centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5)); + + $self->{output}->add_disco_entry(name => $name, + state => $state, + status => $status, is_clustered => $IsClustered, note => $note); + } +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get hyper-v informations. + +=cut \ No newline at end of file diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm index 0134855fe..837e81511 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm @@ -51,7 +51,7 @@ Try { if ($i -eq 0) { Write-Host "[name=" $vm.VMName "][state=" $vm.State "][note=" $note "]" } - Write-Host "[checkpointCreationTime=" (get-date -date $snap.CreationTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "]" + Write-Host "[checkpointCreationTime=" (get-date -date $snap.CreationTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "][type= snapshot]" $i=1 } } @@ -64,7 +64,7 @@ Try { if ($i -eq 0) { Write-Host "[name=" $vm.VMName "][state=" $vm.State "][note=" $note "]" } - Write-Host "[checkpointCreationTime=" (get-date -date $parent.LastWriteTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "]" + Write-Host "[checkpointCreationTime=" (get-date -date $parent.LastWriteTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "][type= backing]" $i=1 } } diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm index ee35b6557..9dc351d30 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm @@ -49,7 +49,17 @@ Try { Foreach ($vm in $vms) { $desc = $vm.description -replace "\r","" $desc = $desc -replace "\n"," - " - Write-Host "[name=" $vm.Name "][description=" $desc "][status=" $vm.Status "][cloud=" $vm.Cloud "][hostgrouppath=" $vm.HostGroupPath "]][VMAddition=" $vm.VMAddition "]" + Write-Host ("[VM={0}]" -f $vm.Name) -NoNewline + Write-Host ("[Description={0}]" -f $desc) -NoNewline + Write-Host ("[Status={0}]" -f $vm.Status) -NoNewline + Write-Host ("[Cloud={0}]" -f $vm.Cloud) -NoNewline + Write-Host ("[HostGroup={0}]" -f $vm.HostGroupPath) -NoNewline + Write-Host ("[VMAddition={0}]" -f $vm.VMAddition) -NoNewline + Write-Host ("[OperatingSystemShutdownEnabled={0}]" -f $vm.OperatingSystemShutdownEnabled) -NoNewline + Write-Host ("[TimeSynchronizationEnabled={0}]" -f $vm.TimeSynchronizationEnabled) -NoNewline + Write-Host ("[DataExchangeEnabled={0}]" -f $vm.DataExchangeEnabled) -NoNewline + Write-Host ("[HeartbeatEnabled={0}]" -f $vm.HeartbeatEnabled) -NoNewline + Write-Host ("[BackupEnabled={0}]" -f $vm.BackupEnabled) } } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/plugins/output.pm b/centreon-plugins/centreon/plugins/output.pm index 02563f022..8585c9ab5 100644 --- a/centreon-plugins/centreon/plugins/output.pm +++ b/centreon-plugins/centreon/plugins/output.pm @@ -45,6 +45,7 @@ sub new { "opt-exit:s" => { name => 'opt_exit', default => 'unknown' }, "output-xml" => { name => 'output_xml' }, "output-json" => { name => 'output_json' }, + "output-file:s" => { name => 'output_file' }, "disco-format" => { name => 'disco_format' }, "disco-show" => { name => 'disco_show' }, }); @@ -439,6 +440,12 @@ sub display { my $force_long_output = (defined($options{force_long_output}) && $options{force_long_output} == 1) ? 1 : 0; $force_long_output = 1 if (defined($self->{option_results}->{debug})); + if (defined($self->{option_results}->{output_file})) { + if (!open (STDOUT, '>', $self->{option_results}->{output_file})) { + $self->output_add(severity => 'UNKNOWN', + short_msg => "cannot open file '" . $self->{option_results}->{output_file} . "': $!"); + } + } if (defined($self->{option_results}->{output_xml})) { $self->create_xml_document(); if ($self->{is_output_xml}) { @@ -798,6 +805,10 @@ Display output in XML Format. Display output in JSON Format. +=item B<--output-file> + +Write output in file (can be used with json and xml options) + =item B<--disco-format> Display discovery arguments (if the mode manages it). diff --git a/centreon-plugins/centreon/plugins/script.pm b/centreon-plugins/centreon/plugins/script.pm index e5f3ead05..dbcfd9359 100644 --- a/centreon-plugins/centreon/plugins/script.pm +++ b/centreon-plugins/centreon/plugins/script.pm @@ -30,7 +30,7 @@ use Pod::Find qw(pod_where); my %handlers = (DIE => {}); -my $global_version = 20170329; +my $global_version = 20170613; my $alternative_fatpacker = 0; sub new { @@ -132,7 +132,7 @@ sub convert_args { if ($self->{convert_args} =~ /^(.+?),(.*)/) { my ($search, $replace) = ($1, $2); - for (my $i = 0; $i < $#ARGV; $i++) { + for (my $i = 0; $i <= $#ARGV; $i++) { eval "\$ARGV[\$i] =~ s/$search/$replace/g"; } } diff --git a/centreon-plugins/centreon/plugins/snmp.pm b/centreon-plugins/centreon/plugins/snmp.pm index 1f825da95..786481d9d 100644 --- a/centreon-plugins/centreon/plugins/snmp.pm +++ b/centreon-plugins/centreon/plugins/snmp.pm @@ -73,6 +73,7 @@ sub new { # Dont load MIB $SNMP::auto_init_mib = 0; + $ENV{MIBS} = ''; # For snmpv v1 - get request retries when you have "NoSuchName" $self->{RetryNoSuch} = 1; # Dont try to translate OID (we keep value) diff --git a/centreon-plugins/centreon/plugins/templates/counter.pm b/centreon-plugins/centreon/plugins/templates/counter.pm index e146610e6..fb6454bd5 100644 --- a/centreon-plugins/centreon/plugins/templates/counter.pm +++ b/centreon-plugins/centreon/plugins/templates/counter.pm @@ -330,6 +330,12 @@ sub run_group { short_msg => "$total_problems problem(s) detected"); } } + + if (defined($options{config}->{display_counter_problem})) { + $self->{output}->perfdata_add(label => $options{config}->{display_counter_problem}->{label}, unit => $options{config}->{display_counter_problem}->{unit}, + value => $total_problems, + min => $options{config}->{display_counter_problem}->{min}, max => $options{config}->{display_counter_problem}->{max}); + } } sub run { diff --git a/centreon-plugins/changelog b/centreon-plugins/changelog index 66556790a..933270b82 100644 --- a/centreon-plugins/changelog +++ b/centreon-plugins/changelog @@ -1,3 +1,29 @@ +2017-06-13 Quentin Garnier + * Plugin added: HP Eva CLI + * Plugin added: Acme Packet SNMP + * Plugin added: A10 AX SNMP + * Plugin added: OpenHeadend SNMP + * Plugin added: Zixi Rest API + * Plugin added: Various Evertz SNMP + * Plugin added: Qsan Nas SNMP + * Plugin added: Citrix SDX SNMP + * Plugin added: IBM TS2900 SNMP + * Plugin added: Fortinet Fortimanager SNMP + * Mode added: [pacemaker] clustat + * Break: path change for Alcatel Omniswitch SNMP + +2017-05-19 Quentin Garnier + * Plugin added: Alteon SNMP + * Plugin added: Nutanix SNMP + * Plugin added: Citrix Cloudbridge SNMP + * Plugin added: Protocol Modbus + * Plugin added: Notification HighSMS + * Plugin added: Jmeter Scenario + * Plugin added: AppearTV SNMP + * Plugin added: QSan NAS SNMP + * Mode added: [linux] systemd services + * Break: path change for Alcatel Omniswitch + 2017-03-29 Quentin Garnier * Plugin added: Watchguard SNMP * Plugin added: Intelligence Interactive SNMP @@ -201,4 +227,4 @@ * Fix: [elasticsearch] Crash without some values in command line (#243) 2015-11-26 Quentin Garnier - * initial release \ No newline at end of file + * initial release diff --git a/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm b/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm new file mode 100644 index 000000000..8130475cf --- /dev/null +++ b/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm @@ -0,0 +1,225 @@ +# +# 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 hardware::devices::video::appeartv::snmp::mode::alarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::statefile; + +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 = sprintf("alarm [severity: %s] [source: %s] [text: %s] %s", $self->{result_values}->{severity}, + $self->{result_values}->{source}, $self->{result_values}->{text}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{source} = $options{new_datas}->{$self->{instance} . '_msgSourceName'}; + $self->{result_values}->{text} = $options{new_datas}->{$self->{instance} . '_msgText'}; + $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_msgSeverity'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_msgGenerationTime'}; + return 0; +} + + +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 }, + group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{alarm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'msgSourceName' }, { name => 'msgText' }, { name => 'since' }, { name => 'msgSeverity' }, { name => 'msgGenerationTime' } ], + 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'), + } + }, + ]; +} + +sub policy_long_output { + my ($self, %options) = @_; + + return "checking alarms"; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /minor|warning/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' }, + "memory" => { name => 'memory' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'."); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->check_options(%options); + } +} + +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; + } + } +} + +my %map_severity = (0 => 'indeterminate', 1 => 'critical', 2 => 'major', 3 => 'minor', + 4 => 'warning', 5 => 'cleared', 6 => 'notify'); + +my $mapping = { + msgSourceName => { oid => '.1.3.6.1.4.1.23916.3.1.4.1.3' }, + msgText => { oid => '.1.3.6.1.4.1.23916.3.1.4.1.4' }, + msgGenerationTime => { oid => '.1.3.6.1.4.1.23916.3.1.4.1.6' }, # 2016-12-16 14:49:18 + msgSeverity => { oid => '.1.3.6.1.4.1.23916.3.1.4.1.13', map => \%map_severity }, +}; + +my $oid_clusVolumeEntry = '.1.3.6.1.4.1.9804.3.1.1.2.12.97.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{alarms}->{global} = { alarm => {} }; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{msgSourceName}->{oid} }, + { oid => $mapping->{msgText}->{oid} }, + { oid => $mapping->{msgGenerationTime}->{oid} }, + { oid => $mapping->{msgSeverity}->{oid} }, + ], nothing_quit => 1, return_type => 1); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => "cache_appeartv_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port(). '_' . $self->{mode}); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{msgSeverity}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + my $create_time = Date::Parse::str2time($result->{msgGenerationTime}); + if (!defined($create_time)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't Parse date '" . $result->{msgGenerationTime} . "'"); + next; + } + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time); + + my $diff_time = $current_time - $create_time; + + $self->{alarms}->{global}->{alarm}->{$i} = { %$result, since => $diff_time }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check alarms. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') +Can used special variables like: %{severity}, %{text}, %{source}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). +Can used special variables like: %{severity}, %{text}, %{source}, %{since} + +=item B<--memory> + +Only check new alarms. + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/hardware/devices/video/appeartv/snmp/plugin.pm b/centreon-plugins/hardware/devices/video/appeartv/snmp/plugin.pm new file mode 100644 index 000000000..8ceffe6ba --- /dev/null +++ b/centreon-plugins/hardware/devices/video/appeartv/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 hardware::devices::video::appeartv::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'alarms' => 'hardware::devices::video::appeartv::snmp::mode::alarms', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check AppeartTV in SNMP. + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/mode/cpu.pm b/centreon-plugins/network/a10/ax/snmp/mode/cpu.pm new file mode 100644 index 000000000..732a8689e --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/cpu.pm @@ -0,0 +1,124 @@ +# +# 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 network::a10::ax::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok' }, + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'cpu-30s', set => { + key_values => [ { name => 'cpu_30s' }, { name => 'display' } ], + output_template => '30s : %s %%', + perfdatas => [ + { label => 'cpu_30s', value => 'cpu_30s_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-1m', set => { + key_values => [ { name => 'cpu_1m' }, { name => 'display' } ], + output_template => '1m : %s %%', + perfdatas => [ + { label => 'cpu_1m', value => 'cpu_1m_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +my $oid_axSysCpuUsageValueAtPeriod = '.1.3.6.1.4.1.22610.2.4.1.3.6.1.3'; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_table(oid => $oid_axSysCpuUsageValueAtPeriod, + nothing_quit => 1); + + $self->{cpu} = {}; + foreach my $oid (keys %$results) { + $oid =~ /\.(\d*?)\.\d*?$/; + next if (defined($self->{cpu}->{$1})); + my $instance = $1; + + $self->{cpu}->{$instance} = { display => $instance, + cpu_1m => $results->{$oid_axSysCpuUsageValueAtPeriod . '.' . $instance . '.5'}, + cpu_30s => $results->{$oid_axSysCpuUsageValueAtPeriod . '.' . $instance . '.4'} + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example : --filter-counters='^cpu-1m$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'cpu-30s' (%), 'cpu-1m' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'cpu-30s' (%), 'cpu-1m' (%). + +=back + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/mode/disk.pm b/centreon-plugins/network/a10/ax/snmp/mode/disk.pm new file mode 100644 index 000000000..8d9b6058a --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/disk.pm @@ -0,0 +1,134 @@ +# +# 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 network::a10::ax::snmp::mode::disk; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, 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("Disk 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}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; + $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 => 0 } + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'usage', set => { + key_values => [ { name => 'free' }, { name => 'total' } ], + 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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_axSysDiskFreeSpace = '.1.3.6.1.4.1.22610.2.4.1.4.2.0'; # in MB + my $oid_axSysDiskTotalSpace = '.1.3.6.1.4.1.22610.2.4.1.4.1.0'; # in MB + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_axSysDiskFreeSpace, $oid_axSysDiskTotalSpace], + nothing_quit => 1); + $self->{disk} = { free => $snmp_result->{$oid_axSysDiskFreeSpace} * 1024 * 1024, total => $snmp_result->{$oid_axSysDiskTotalSpace} * 1024 * 1024 }; + +} + +1; + +__END__ + +=head1 MODE + +Check disk usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/mode/globalstats.pm b/centreon-plugins/network/a10/ax/snmp/mode/globalstats.pm new file mode 100644 index 000000000..bf48dfb23 --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/globalstats.pm @@ -0,0 +1,127 @@ +# +# 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 network::a10::ax::snmp::mode::globalstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'current-connections', set => { + key_values => [ { name => 'current_connections' } ], + output_template => 'Current Connections : %s', + perfdatas => [ + { label => 'current_connections', value => 'current_connections_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'total-connections', set => { + key_values => [ { name => 'total_connections', diff => 1 } ], + output_template => 'Total Connections : %s', + perfdatas => [ + { label => 'total_connections', value => 'total_connections_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'total-ssl-connections', set => { + key_values => [ { name => 'total_ssl_connections', diff => 1 } ], + output_template => 'Total SSL Connections : %s', + perfdatas => [ + { label => 'total_ssl_connections', value => 'total_ssl_connections_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_axAppGlobalTotalCurrentConnections = '.1.3.6.1.4.1.22610.2.4.3.1.2.1.0'; + my $oid_axAppGlobalTotalNewConnections = '.1.3.6.1.4.1.22610.2.4.3.1.2.2.0'; + my $oid_axAppGlobalTotalSSLConnections = '.1.3.6.1.4.1.22610.2.4.3.1.2.6.0'; + my $result = $options{snmp}->get_leef(oids => [ + $oid_axAppGlobalTotalCurrentConnections, $oid_axAppGlobalTotalNewConnections, + $oid_axAppGlobalTotalSSLConnections, + ], + nothing_quit => 1); + $self->{global} = { current_connections => $result->{$oid_axAppGlobalTotalCurrentConnections}, + total_connections => $result->{$oid_axAppGlobalTotalNewConnections}, + total_ssl_connections => $result->{$oid_axAppGlobalTotalSSLConnections}, + }; + + $self->{cache_name} = "a10_ax_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check global statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^current-connections$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'current-connections', 'total-connections'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-connections', 'total-connections'. + +=back + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/mode/hardware.pm b/centreon-plugins/network/a10/ax/snmp/mode/hardware.pm new file mode 100644 index 000000000..4997475c7 --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/hardware.pm @@ -0,0 +1,260 @@ +# +# 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 network::a10::ax::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['off', 'CRITICAL'], + ['on', 'OK'], + ['unknown', 'UNKNOWN'], + ], + fan => [ + ['failed', 'CRITICAL'], + ['okFixedHigh', 'OK'], + ['okLowMed', 'OK'], + ['okMedMed', 'OK'], + ['okMedHigh', 'OK'], + ['notReady', 'WARNING'], + ['unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'network::a10::ax::snmp::mode::components'; + $self->{components_module} = ['psu', 'fan', 'temperature']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + my $oid_axSysHwInfo = '.1.3.6.1.4.1.22610.2.4.1.5'; + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_table(oid => $oid_axSysHwInfo); +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'psu', 'fan', 'temperature'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=psu,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='psu,OK,off' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut + +package network::a10::ax::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_status = (0 => 'failed', 4 => 'okFixedHigh', + 5 => 'okLowMed', 6 => 'okMedMed', 7 => 'okMedHigh', + -2 => 'notReady', -1 => 'unknown' +); + +my $mapping = { + axFanName => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.9.1.2' }, + axFanStatus => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.9.1.3', map => \%map_fan_status }, + axFanSpeed => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.9.1.4' }, +}; + +sub load { } + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}})) { + next if ($oid !~ /^$mapping->{axFanStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]", + $result->{axFanName}, $result->{axFanStatus}, $instance, $result->{axFanSpeed})); + my $exit = $self->get_severity(section => 'fan', value => $result->{axFanStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("fan '%s' status is '%s'", $result->{axFanName}, $result->{axFanStatus})); + } + + if ($result->{axFanSpeed} > 0) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{axFanSpeed}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("fan '%s' speed is %s rpm", $result->{axFanName}, $result->{axFanSpeed})); + } + $self->{output}->perfdata_add(label => $result->{axFanName}, unit => 'rpm', + value => $result->{axFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); + } + } +} + +1; + +package network::a10::ax::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = (0 => 'off', 1 => 'on', -1 => 'unknown'); + +my $mapping_psu = { + axSysLowerPowerSupplyStatus => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.7', map => \%map_psu_status }, + axSysUpperPowerSupplyStatus => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.8', map => \%map_psu_status }, +}; + +sub load {} + +sub check_psu { + my ($self, %options) = @_; + + return if (!defined($options{status})); + return if ($self->check_filter(section => 'psu', instance => $options{instance})); + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $options{instance}, $options{status}, $options{instance})); + my $exit = $self->get_severity(section => 'psu', value => $options{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("power supply '%s' status is '%s'", $options{instance}, $options{status})); + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my $result = $self->{snmp}->map_instance(mapping => $mapping_psu, results => $self->{results}, instance => '0'); + + check_psu($self, status => $result->{axSysLowerPowerSupplyStatus}, instance => 1); + check_psu($self, status => $result->{axSysUpperPowerSupplyStatus}, instance => 2); +} + +1; + +package network::a10::ax::snmp::mode::components::temperature; + +use strict; +use warnings; + +my $mapping_temp = { + axSysHwPhySystemTemp => { oid => '.1.3.6.1.4.1.22610.2.4.1.5.1' }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperature"); + $self->{components}->{temperature} = {name => 'temperature', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my $result = $self->{snmp}->map_instance(mapping => $mapping_temp, results => $self->{results}, instance => '0'); + + return if (!defined($result->{axSysHwPhySystemTemp})); + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("physical temperature is %s C [instance = %s]", + $result->{axSysHwPhySystemTemp}, '0')); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => '0', value => $result->{axSysHwPhySystemTemp}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("physical temperature is %s C", $result->{axSysHwPhySystemTemp})); + } + $self->{output}->perfdata_add(label => 'temperature_physical', unit => 'C', + value => $result->{axSysHwPhySystemTemp}, + warning => $warn, + critical => $crit + ); +} + +1; diff --git a/centreon-plugins/network/a10/ax/snmp/mode/listvservers.pm b/centreon-plugins/network/a10/ax/snmp/mode/listvservers.pm new file mode 100644 index 000000000..6a5d9d63b --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/listvservers.pm @@ -0,0 +1,127 @@ +# +# 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 network::a10::ax::snmp::mode::listvservers; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + $self->{vserver} = {}; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_status = (1 => 'up', 2 => 'down', 3 => 'disabled'); +my $mapping = { + axVirtualServerStatName => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.2' }, + axVirtualServerStatStatus => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.10', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $mapping->{axVirtualServerStatName}->{oid} }, + { oid => $mapping->{axVirtualServerStatStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{axVirtualServerStatName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $result->{axVirtualServerStatName} =~ s/\\//g; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{axVirtualServerStatName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{axVirtualServerStatName} . "': no matching filter.", debug => 1); + next; + } + + $self->{vserver}->{$instance} = { + name => $result->{axVirtualServerStatName}, status => $result->{axVirtualServerStatStatus} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vserver}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{vserver}->{$instance}->{name} . + "] [status = " . $self->{vserver}->{$instance}->{status} . ']' + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List virtual servers:'); + $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', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vserver}}) { + $self->{output}->add_disco_entry(name => $self->{vserver}->{$instance}->{name}, + status => $self->{vserver}->{$instance}->{status}); + } +} + +1; + +__END__ + +=head1 MODE + +List virtual servers. + +=over 8 + +=item B<--filter-name> + +Filter by virtual server name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/network/a10/ax/snmp/mode/memory.pm b/centreon-plugins/network/a10/ax/snmp/mode/memory.pm new file mode 100644 index 000000000..c7946b527 --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/memory.pm @@ -0,0 +1,135 @@ +# +# 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 network::a10::ax::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, 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("Memory 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}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_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}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + 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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_axSysMemoryUsage = '.1.3.6.1.4.1.22610.2.4.1.2.2.0'; # in KB + my $oid_axSysMemoryTotal = '.1.3.6.1.4.1.22610.2.4.1.2.1.0'; # in KB + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_axSysMemoryUsage, $oid_axSysMemoryTotal], + nothing_quit => 1); + + $self->{memory} = { used => $snmp_result->{$oid_axSysMemoryUsage} * 1024, total => $snmp_result->{$oid_axSysMemoryTotal} * 1024 }; + +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/mode/vserverusage.pm b/centreon-plugins/network/a10/ax/snmp/mode/vserverusage.pm new file mode 100644 index 000000000..dce59c28e --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/mode/vserverusage.pm @@ -0,0 +1,267 @@ +# +# 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 network::a10::ax::snmp::mode::vserverusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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} . '_axVirtualServerStatStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vserver', type => 1, cb_prefix_output => 'prefix_vserver_output', message_multiple => 'All virtual servers are ok' } + ]; + + $self->{maps_counters}->{vserver} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'axVirtualServerStatStatus' }, { 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 => 'current-con', set => { + key_values => [ { name => 'axVirtualServerStatCurConns' }, { name => 'display' } ], + output_template => 'Current Connections : %s', + perfdatas => [ + { label => 'current_connections', value => 'axVirtualServerStatCurConns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-con', set => { + key_values => [ { name => 'axVirtualServerStatTotConns', diff => 1 }, { name => 'display' } ], + output_template => 'Total Connections : %s', + perfdatas => [ + { label => 'total_connections', value => 'axVirtualServerStatTotConns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'axVirtualServerStatBytesIn', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'axVirtualServerStatBytesIn_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'axVirtualServerStatBytesOut', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'axVirtualServerStatBytesOut_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_vserver_output { + my ($self, %options) = @_; + + return "Virtual Server '" . $options{instance_value}->{display} . "' "; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /down/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +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; + } + } +} + +my %map_status = ( + 1 => 'up', 2 => 'down', 3 => 'disabled', +); +my $oid_axVirtualServerStatName = '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.2'; +my $mapping = { + axVirtualServerStatBytesIn => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.4' }, + axVirtualServerStatBytesOut => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.6' }, + axVirtualServerStatTotConns => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.8' }, + axVirtualServerStatCurConns => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.9' }, + axVirtualServerStatStatus => { oid => '.1.3.6.1.4.1.22610.2.4.3.4.2.1.1.10', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + my $snmp_result = $options{snmp}->get_table(oid => $oid_axVirtualServerStatName, nothing_quit => 1); + $self->{vserver} = {}; + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_axVirtualServerStatName\.(.*)$/; + my $instance = $1; + $snmp_result->{$oid} =~ s/\\//g; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping virtual server '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + $self->{vserver}->{$instance} = { display => $snmp_result->{$oid} }; + } + + $options{snmp}->load(oids => [$mapping->{axVirtualServerStatBytesIn}->{oid}, $mapping->{axVirtualServerStatBytesOut}->{oid}, + $mapping->{axVirtualServerStatTotConns}->{oid}, $mapping->{axVirtualServerStatCurConns}->{oid}, + $mapping->{axVirtualServerStatStatus}->{oid} + ], + instances => [keys %{$self->{vserver}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{vserver}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + foreach my $name (('axVirtualServerStatBytesIn', 'axVirtualServerStatBytesOut')) { + $result->{$name} *= 8; + } + + foreach my $name (keys %$mapping) { + $self->{vserver}->{$_}->{$name} = $result->{$name}; + } + } + + if (scalar(keys %{$self->{vserver}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No virtual server found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "a10_ax_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check virtual server usage. + +=over 8 + +=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} =~ /down/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'current-con', 'total-con', 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-con', 'total-con', 'traffic-in', 'traffic-out'. + +=item B<--filter-name> + +Filter by virtual server name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/a10/ax/snmp/plugin.pm b/centreon-plugins/network/a10/ax/snmp/plugin.pm new file mode 100644 index 000000000..df5602f0f --- /dev/null +++ b/centreon-plugins/network/a10/ax/snmp/plugin.pm @@ -0,0 +1,56 @@ +# +# 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 network::a10::ax::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::a10::ax::snmp::mode::cpu', + 'disk' => 'network::a10::ax::snmp::mode::disk', + 'global-stats' => 'network::a10::ax::snmp::mode::globalstats', + 'hardware' => 'network::a10::ax::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-vservers' => 'network::a10::ax::snmp::mode::listvservers', + 'memory' => 'network::a10::ax::snmp::mode::memory', + 'vserver-usage' => 'network::a10::ax::snmp::mode::vserverusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check A10 AX in SNMP. + +=cut diff --git a/centreon-plugins/network/acmepacket/snmp/mode/components/fan.pm b/centreon-plugins/network/acmepacket/snmp/mode/components/fan.pm new file mode 100644 index 000000000..df2001712 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/components/fan.pm @@ -0,0 +1,79 @@ +# +# 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 network::acmepacket::snmp::mode::components::fan; + +use strict; +use warnings; +use network::acmepacket::snmp::mode::components::resources qw($map_status); + +my $mapping = { + apEnvMonFanStatusDescr => { oid => '.1.3.6.1.4.1.9148.3.3.1.4.1.1.3' }, + apEnvMonFanStatusValue => { oid => '.1.3.6.1.4.1.9148.3.3.1.4.1.1.4' }, + apEnvMonFanState => { oid => '.1.3.6.1.4.1.9148.3.3.1.4.1.1.5', map => $map_status }, +}; +my $oid_apEnvMonFanStatusEntry = '.1.3.6.1.4.1.9148.3.3.1.4.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_apEnvMonFanStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_apEnvMonFanStatusEntry}})) { + next if ($oid !~ /^$mapping->{apEnvMonFanState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_apEnvMonFanStatusEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + next if ($result->{apEnvMonFanState} =~ /notPresent/i && + $self->absent_problem(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]", + $result->{apEnvMonFanStatusDescr}, $result->{apEnvMonFanState}, $instance, defined($result->{apEnvMonFanStatusValue}) ? $result->{apEnvMonFanStatusValue} : 'unknown')); + $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{apEnvMonFanState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' status is '%s'", $result->{apEnvMonFanStatusDescr}, $result->{apEnvMonFanState})); + } + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{apEnvMonFanStatusValue}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is '%s' %%", $result->{apEnvMonFanStatusDescr}, $result->{apEnvMonFanStatusValue})); + } + $self->{output}->perfdata_add(label => 'fan_' . $result->{apEnvMonFanStatusDescr}, unit => '%', + value => $result->{apEnvMonFanStatusValue}, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); + } +} + +1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/components/psu.pm b/centreon-plugins/network/acmepacket/snmp/mode/components/psu.pm new file mode 100644 index 000000000..8690ff67d --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/components/psu.pm @@ -0,0 +1,66 @@ +# +# 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 network::acmepacket::snmp::mode::components::psu; + +use strict; +use warnings; +use network::acmepacket::snmp::mode::components::resources qw($map_status); + +my $mapping = { + apEnvMonPowerSupplyStatusDescr => { oid => '.1.3.6.1.4.1.9148.3.3.1.5.1.1.3' }, + apEnvMonPowerSupplyState => { oid => '.1.3.6.1.4.1.9148.3.3.1.5.1.1.4', map => $map_status }, +}; +my $oid_apEnvMonPowerSupplyStatusEntry = '.1.3.6.1.4.1.9148.3.3.1.5.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_apEnvMonPowerSupplyStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_apEnvMonPowerSupplyStatusEntry}})) { + next if ($oid !~ /^$mapping->{apEnvMonPowerSupplyState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_apEnvMonPowerSupplyStatusEntry}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + next if ($result->{apEnvMonPowerSupplyState} =~ /notPresent/i && + $self->absent_problem(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $result->{apEnvMonPowerSupplyStatusDescr}, $result->{apEnvMonPowerSupplyState}, $instance)); + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{apEnvMonPowerSupplyState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $result->{apEnvMonPowerSupplyStatusDescr}, $result->{apEnvMonPowerSupplyState})); + } + } +} + +1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/components/resources.pm b/centreon-plugins/network/acmepacket/snmp/mode/components/resources.pm new file mode 100644 index 000000000..8a6a4522a --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/components/resources.pm @@ -0,0 +1,38 @@ +# +# 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 network::acmepacket::snmp::mode::components::resources; + +use strict; +use warnings; +use Exporter; + +our $map_status; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw($map_status); + +$map_status = { 1 => 'initial', 2 => 'normal', + 3 => 'minor', 4 => 'major', 5 => 'critical', + 6 => 'shutdown', 7 => 'notPresent', + 8 => 'notFunctioning', 9 => 'unknown' +}; + +1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/components/temperature.pm b/centreon-plugins/network/acmepacket/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..cca566b47 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/components/temperature.pm @@ -0,0 +1,80 @@ +# +# 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 network::acmepacket::snmp::mode::components::temperature; + +use strict; +use warnings; +use network::acmepacket::snmp::mode::components::resources qw($map_status); + +my $mapping = { + apEnvMonTemperatureStatusDescr => { oid => '.1.3.6.1.4.1.9148.3.3.1.3.1.1.3' }, + apEnvMonTemperatureStatusValue => { oid => '.1.3.6.1.4.1.9148.3.3.1.3.1.1.4' }, + apEnvMonTemperatureState => { oid => '.1.3.6.1.4.1.9148.3.3.1.3.1.1.5', map => $map_status }, +}; +my $oid_apEnvMonTemperatureStatusEntry = '.1.3.6.1.4.1.9148.3.3.1.3.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_apEnvMonTemperatureStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_apEnvMonTemperatureStatusEntry}})) { + next if ($oid !~ /^$mapping->{apEnvMonTemperatureState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_apEnvMonTemperatureStatusEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + next if ($result->{apEnvMonTemperatureState} =~ /notPresent/i && + $self->absent_problem(section => 'temperature', instance => $instance)); + + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, value = %s]", + $result->{apEnvMonTemperatureStatusDescr}, $result->{apEnvMonTemperatureState}, $instance, + $result->{apEnvMonTemperatureStatusValue})); + $exit = $self->get_severity(label => 'default', section => 'temperature', value => $result->{apEnvMonTemperatureState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $result->{apEnvMonTemperatureStatusDescr}, $result->{apEnvMonTemperatureState})); + } + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{apEnvMonTemperatureStatusValue}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is '%s' C", $result->{apEnvMonTemperatureStatusDescr}, $result->{apEnvMonTemperatureStatusValue})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $result->{apEnvMonTemperatureStatusDescr}, unit => 'C', + value => $result->{apEnvMonTemperatureStatusValue}, + warning => $warn, + critical => $crit + ); + } +} + +1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/components/voltage.pm b/centreon-plugins/network/acmepacket/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..465640971 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/components/voltage.pm @@ -0,0 +1,81 @@ +# +# 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 network::acmepacket::snmp::mode::components::voltage; + +use strict; +use warnings; +use network::acmepacket::snmp::mode::components::resources qw($map_status); + +my $mapping = { + apEnvMonVoltageStatusDescr => { oid => '.1.3.6.1.4.1.9148.3.3.1.2.1.1.3' }, + apEnvMonVoltageStatusValue => { oid => '.1.3.6.1.4.1.9148.3.3.1.2.1.1.4' }, + apEnvMonVoltageState => { oid => '.1.3.6.1.4.1.9148.3.3.1.2.1.1.5', map => $map_status }, +}; +my $oid_apEnvMonVoltageStatusEntry = '.1.3.6.1.4.1.9148.3.3.1.2.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_apEnvMonVoltageStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_apEnvMonVoltageStatusEntry}})) { + next if ($oid !~ /^$mapping->{apEnvMonVoltageState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_apEnvMonVoltageStatusEntry}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance)); + next if ($result->{apEnvMonVoltageState} =~ /notPresent/i && + $self->absent_problem(section => 'voltage', instance => $instance)); + + $result->{apEnvMonVoltageStatusValue} = sprintf("%.3f", $result->{apEnvMonVoltageStatusValue}); + $self->{components}->{voltage}->{total}++; + $self->{output}->output_add(long_msg => sprintf("voltage '%s' status is '%s' [instance = %s, value = %s]", + $result->{apEnvMonVoltageStatusDescr}, $result->{apEnvMonVoltageState}, $instance, + $result->{apEnvMonVoltageStatusValue})); + $exit = $self->get_severity(label => 'default', section => 'voltage', value => $result->{apEnvMonVoltageState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' status is '%s'", $result->{apEnvMonVoltageStatusDescr}, $result->{apEnvMonVoltageState})); + } + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{apEnvMonVoltageStatusValue}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' is '%s' V", $result->{apEnvMonVoltageStatusDescr}, $result->{apEnvMonVoltageStatusValue})); + } + $self->{output}->perfdata_add(label => 'voltage_' . $result->{apEnvMonVoltageStatusDescr}, unit => 'V', + value => $result->{apEnvMonVoltageStatusValue}, + warning => $warn, + critical => $crit + ); + } +} + +1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/hardware.pm b/centreon-plugins/network/acmepacket/snmp/mode/hardware.pm new file mode 100644 index 000000000..dd815edb2 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/hardware.pm @@ -0,0 +1,121 @@ +# +# 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 network::acmepacket::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(voltage|temperature|fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(voltage|temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + $self->{thresholds} = { + default => [ + ['initial', 'OK'], + ['normal', 'OK'], + ['minor', 'WARNING'], + ['major', 'CRITICAL'], + ['critical', 'CRITICAL'], + ['shutdown', 'CRITICAL'], + ['notPresent', 'OK'], + ['notFunctioning', 'CRITICAL'], + ['unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'network::acmepacket::snmp::mode::components'; + $self->{components_module} = ['voltage', 'temperature', 'fan', 'psu']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'voltage', 'temperature', 'fan', 'psu'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1 + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) (comma seperated list) +Can be specific or global: --absent-problem=psu,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='psu,CRITICAL,^(?!(normal|initial)$)' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/network/acmepacket/snmp/mode/listrealm.pm b/centreon-plugins/network/acmepacket/snmp/mode/listrealm.pm new file mode 100644 index 000000000..5234b20f3 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/listrealm.pm @@ -0,0 +1,112 @@ +# +# 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 network::acmepacket::snmp::mode::listrealm; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $oid_apSigRealmStatsRealmName = '.1.3.6.1.4.1.9148.3.2.1.2.4.1.2'; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $self->{snmp}->get_table(oid => $oid_apSigRealmStatsRealmName, nothing_quit => 1); + $self->{realm} = {}; + foreach my $oid (keys %{$snmp_result}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping service class '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + $self->{realm}->{$snmp_result->{$oid}} = { name => $snmp_result->{$oid} }; + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{realm}}) { + $self->{output}->output_add(long_msg => "'" . $name . "'"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List Realm:'); + $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']); +} + +sub disco_show { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{realm}}) { + $self->{output}->add_disco_entry(name => $name); + } +} + +1; + +__END__ + +=head1 MODE + +List realm. + +=over 8 + +=item B<--filter-name> + +Filter by realm name. + +=back + +=cut + diff --git a/centreon-plugins/network/acmepacket/snmp/mode/listsip.pm b/centreon-plugins/network/acmepacket/snmp/mode/listsip.pm new file mode 100644 index 000000000..502cb530e --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/listsip.pm @@ -0,0 +1,129 @@ +# +# 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 network::acmepacket::snmp::mode::listsip; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + $self->{sip} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_status = ( + 0 => 'disabled', 1 => 'outOfService', + 2 => 'standby', 3 => 'inService', + 4 => 'constraintsViolation', 5 => 'inServiceTimedOut', + 6 => 'oosprovisionedresponse', +); +my $mapping = { + apSipSAStatsSessionAgentHostname => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.2' }, + apSipSAStatsSessionAgentStatus => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.22', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{apSipSAStatsSessionAgentHostname}->{oid} }, + { oid => $mapping->{apSipSAStatsSessionAgentStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{apSipSAStatsSessionAgentHostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{apSipSAStatsSessionAgentHostname} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{apSipSAStatsSessionAgentHostname} . "': no matching filter.", debug => 1); + next; + } + + $self->{sip}->{$instance} = { name => $result->{apSipSAStatsSessionAgentHostname}, status => $result->{apSipSAStatsSessionAgentStatus} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{sip}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{sip}->{$instance}->{name} . "] [status = '" . $self->{sip}->{$instance}->{status} . "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List SIPs:'); + $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', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{sip}}) { + $self->{output}->add_disco_entry(name => $self->{sip}->{$instance}->{name}, status => $self->{sip}->{$instance}->{status}); + } +} + +1; + +__END__ + +=head1 MODE + +List SIPs. + +=over 8 + +=item B<--filter-name> + +Filter by SIP name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/network/acmepacket/snmp/mode/realmusage.pm b/centreon-plugins/network/acmepacket/snmp/mode/realmusage.pm new file mode 100644 index 000000000..3e2b0048f --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/realmusage.pm @@ -0,0 +1,216 @@ +# +# 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 network::acmepacket::snmp::mode::realmusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'realm', type => 1, cb_prefix_output => 'prefix_realm_output', message_multiple => 'All realms are ok' } + ]; + + $self->{maps_counters}->{realm} = [ + { label => 'current-in-sessions', set => { + key_values => [ { name => 'apSigRealmStatsCurrentActiveSessionsInbound' }, { name => 'display' } ], + output_template => 'Current Inbound Sessions : %s', + perfdatas => [ + { label => 'current_inbound_sessions', value => 'apSigRealmStatsCurrentActiveSessionsInbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'current-in-sessions-rate', set => { + key_values => [ { name => 'apSigRealmStatsCurrentSessionRateInbound' }, { name => 'display' } ], + output_template => 'Current Inbound Sessions Rate : %s/s', + perfdatas => [ + { label => 'current_inbound_sessions_rate', value => 'apSigRealmStatsCurrentSessionRateInbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-in-sessions', set => { + key_values => [ { name => 'apSigRealmStatsTotalSessionsInbound', diff => 1 }, { name => 'display' } ], + output_template => 'Total Inbound Sessions : %s', + perfdatas => [ + { label => 'total_inbound_sessions', value => 'apSigRealmStatsTotalSessionsInbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'current-out-sessions', set => { + key_values => [ { name => 'apSigRealmStatsCurrentActiveSessionsOutbound' }, { name => 'display' } ], + output_template => 'Current Outbound Sessions : %s', + perfdatas => [ + { label => 'current_outbound_sessions', value => 'apSigRealmStatsCurrentActiveSessionsOutbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'current-out-sessions-rate', set => { + key_values => [ { name => 'apSigRealmStatsCurrentSessionRateOutbound' }, { name => 'display' } ], + output_template => 'Current Outbound Sessions Rate : %s/s', + perfdatas => [ + { label => 'current_outbound_sessions_rate', value => 'apSigRealmStatsCurrentSessionRateOutbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-out-sessions', set => { + key_values => [ { name => 'apSigRealmStatsTotalSessionsOutbound', diff => 1 }, { name => 'display' } ], + output_template => 'Total Outbound Sessions : %s', + perfdatas => [ + { label => 'total_outbound_sessions', value => 'apSigRealmStatsTotalSessionsOutbound_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'avg-qos-rfactor', set => { + key_values => [ { name => 'apSigRealmStatsAverageQoSRFactor' }, { name => 'display' } ], + output_template => 'Average QoS RFactor : %s', + perfdatas => [ + { label => 'avg_qos_rfactor', value => 'apSigRealmStatsAverageQoSRFactor_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-rfactor', set => { + key_values => [ { name => 'apSigRealmStatsTotalMajorRFactorExceeded', diff => 1 }, { name => 'display' } ], + output_template => 'Total Rfactor Exceeded : %s', + perfdatas => [ + { label => 'total_rfactor', value => 'apSigRealmStatsTotalMajorRFactorExceededabsolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_realm_output { + my ($self, %options) = @_; + + return "Realm '" . $options{instance_value}->{display} . "' "; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +my $oid_apSigRealmStatsRealmName = '.1.3.6.1.4.1.9148.3.2.1.2.4.1.2'; +my $mapping = { + apSigRealmStatsCurrentActiveSessionsInbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.3' }, + apSigRealmStatsCurrentSessionRateInbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.4' }, + apSigRealmStatsCurrentActiveSessionsOutbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.5' }, + apSigRealmStatsCurrentSessionRateOutbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.6' }, + apSigRealmStatsTotalSessionsInbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.7' }, + apSigRealmStatsTotalSessionsOutbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.11' }, + apSigRealmStatsAverageQoSRFactor => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.24' }, + apSigRealmStatsTotalMajorRFactorExceeded => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.4.1.27' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_apSigRealmStatsRealmName, nothing_quit => 1); + $self->{realm} = {}; + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping realm '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + $self->{realm}->{$instance} = { display => $snmp_result->{$oid} }; + } + $options{snmp}->load(oids => [$mapping->{apSigRealmStatsCurrentActiveSessionsInbound}->{oid}, $mapping->{apSigRealmStatsCurrentSessionRateInbound}->{oid}, + $mapping->{apSigRealmStatsCurrentActiveSessionsOutbound}->{oid}, $mapping->{apSigRealmStatsCurrentSessionRateOutbound}->{oid}, + $mapping->{apSigRealmStatsTotalSessionsInbound}->{oid}, $mapping->{apSigRealmStatsTotalSessionsOutbound}->{oid}, + $mapping->{apSigRealmStatsAverageQoSRFactor}->{oid}, $mapping->{apSigRealmStatsTotalMajorRFactorExceeded}->{oid} + ], + instances => [keys %{$self->{realm}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{realm}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + foreach my $name (keys %$mapping) { + $self->{realm}->{$_}->{$name} = $result->{$name}; + } + } + + if (scalar(keys %{$self->{realm}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No realm found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "acmepacket_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check realm usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'current-in-sessions', 'current-in-sessions-rate', 'total-in-sessions', +'current-out-sessions', 'current-out-sessions-rate', 'total-out-session', +'avg-qos-rfactor', 'total-rfactor'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-in-sessions', 'current-in-sessions-rate', 'total-in-sessions', +'current-out-sessions', 'current-out-sessions-rate', 'total-out-session', +'avg-qos-rfactor', 'total-rfactor'. + +=item B<--filter-name> + +Filter by realm name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/acmepacket/snmp/mode/sipusage.pm b/centreon-plugins/network/acmepacket/snmp/mode/sipusage.pm new file mode 100644 index 000000000..72212ffed --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/sipusage.pm @@ -0,0 +1,258 @@ +# +# 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 network::acmepacket::snmp::mode::sipusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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} . '_apSipSAStatsSessionAgentStatus'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'sip', type => 1, cb_prefix_output => 'prefix_sip_output', message_multiple => 'All SIPs are ok' } + ]; + + $self->{maps_counters}->{sip} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'apSipSAStatsSessionAgentStatus' } ], + 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 => 'in-sessions-rate', set => { + key_values => [ { name => 'apSipSAStatsTotalSessionsInbound', diff => 1 }, { name => 'display' } ], + output_template => 'Inbound Sessions Rate : %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'inbound_sessions_rate', value => 'apSipSAStatsTotalSessionsInbound_per_second', template => '%.2f', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'out-sessions-rate', set => { + key_values => [ { name => 'apSipSAStatsTotalSessionsOutbound', diff => 1 }, { name => 'display' } ], + output_template => 'Outbound Sessions Rate : %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'outbound_sessions_rate', value => 'apSipSAStatsTotalSessionsOutbound_per_second', template => '%.2f', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'latency', set => { + key_values => [ { name => 'apSipSAStatsAverageLatency' }, { name => 'display' } ], + output_template => 'Average Latency : %s ms', + perfdatas => [ + { label => 'avg_latency', value => 'apSipSAStatsAverageLatency_absolute', template => '%s', + unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'asr', set => { + key_values => [ { name => 'apSipSAStatsPeriodASR' }, { name => 'display' } ], + output_template => 'Answer-to-seizure Ratio : %s %%', + perfdatas => [ + { label => 'asr', value => 'apSipSAStatsPeriodASR_absolute', template => '%s', + unit => '%', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_sip_output { + my ($self, %options) = @_; + + return "SIP '" . $options{instance_value}->{display} . "' "; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /outOfService|constraintsViolation|inServiceTimedOut/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +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; + } + } +} + +my %map_status = ( + 0 => 'disabled', 1 => 'outOfService', + 2 => 'standby', 3 => 'inService', + 4 => 'constraintsViolation', 5 => 'inServiceTimedOut', + 6 => 'oosprovisionedresponse', +); +my $oid_apSipSAStatsSessionAgentHostname = '.1.3.6.1.4.1.9148.3.2.1.2.2.1.2'; +my $mapping = { + apSipSAStatsTotalSessionsInbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.8' }, + apSipSAStatsTotalSessionsOutbound => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.12' }, + apSipSAStatsPeriodASR => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.19' }, + apSipSAStatsAverageLatency => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.20' }, + apSipSAStatsSessionAgentStatus => { oid => '.1.3.6.1.4.1.9148.3.2.1.2.2.1.22', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_apSipSAStatsSessionAgentHostname, nothing_quit => 1); + $self->{sip} = {}; + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping SIP '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + $self->{sip}->{$instance} = { display => $snmp_result->{$oid} }; + } + $options{snmp}->load(oids => [$mapping->{apSipSAStatsTotalSessionsInbound}->{oid}, $mapping->{apSipSAStatsTotalSessionsOutbound}->{oid}, + $mapping->{apSipSAStatsPeriodASR}->{oid}, $mapping->{apSipSAStatsAverageLatency}->{oid}, + $mapping->{apSipSAStatsSessionAgentStatus}->{oid} + ], + instances => [keys %{$self->{sip}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{sip}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + foreach my $name (keys %$mapping) { + $self->{sip}->{$_}->{$name} = $result->{$name}; + } + } + + if (scalar(keys %{$self->{sip}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No SIP found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "acmepacket_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check SIP usage. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: -). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /outOfService|constraintsViolation|inServiceTimedOut/i'). +Can used special variables like: %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'in-sessions-rate', 'out-sessions-rate', 'latency', 'asr'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'in-sessions-rate', 'out-sessions-rate', 'latency', 'asr'. + +=item B<--filter-name> + +Filter by SIP name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm b/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm new file mode 100644 index 000000000..0b4ca3711 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm @@ -0,0 +1,158 @@ +# +# 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 network::acmepacket::snmp::mode::systemusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'health-score', set => { + key_values => [ { name => 'health_score' } ], + output_template => 'Health Score : %.2f %%', + perfdatas => [ + { label => 'health_score', value => 'health_score_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'cpu-load', set => { + key_values => [ { name => 'cpu_load' } ], + output_template => 'Cpu Load : %.2f %%', + perfdatas => [ + { label => 'cpu_load', value => 'cpu_load_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'memory-usage', set => { + key_values => [ { name => 'memory_used' } ], + output_template => 'Memory Used : %.2f %%', + perfdatas => [ + { label => 'memory_used', value => 'memory_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'license-usage', set => { + key_values => [ { name => 'license_used' } ], + output_template => 'License Used : %.2f %%', + perfdatas => [ + { label => 'license_used', value => 'license_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'current-sessions', set => { + key_values => [ { name => 'current_sessions' } ], + output_template => 'Current Sessions : %s', + perfdatas => [ + { label => 'current_sessions', value => 'current_sessions_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'current-calls', set => { + key_values => [ { name => 'current_calls' } ], + output_template => 'Current Calls : %s/s', + perfdatas => [ + { label => 'current_calls', value => 'current_calls_absolute', template => '%s', + unit => '/s', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_apSysCPUUtil = '.1.3.6.1.4.1.9148.3.2.1.1.1.0'; + my $oid_apSysMemoryUtil = '.1.3.6.1.4.1.9148.3.2.1.1.2.0'; + my $oid_apSysHealthScore = '.1.3.6.1.4.1.9148.3.2.1.1.3.0'; + my $oid_apSysGlobalConSess = '.1.3.6.1.4.1.9148.3.2.1.1.5.0'; + my $oid_apSysGlobalCPS = '.1.3.6.1.4.1.9148.3.2.1.1.6.0'; + my $oid_apSysLicenseCapacity = '.1.3.6.1.4.1.9148.3.2.1.1.10.0'; + my $result = $options{snmp}->get_leef(oids => [ + $oid_apSysCPUUtil, $oid_apSysMemoryUtil, $oid_apSysHealthScore, + $oid_apSysLicenseCapacity, $oid_apSysGlobalConSess, $oid_apSysGlobalCPS + ], + nothing_quit => 1); + $self->{global} = { cpu_load => $result->{$oid_apSysCPUUtil}, + memory_used => $result->{$oid_apSysMemoryUtil}, + license_used => $result->{$oid_apSysLicenseCapacity}, + health_score => $result->{$oid_apSysHealthScore}, + current_sessions => $result->{$oid_apSysGlobalConSess}, + current_calls => $result->{$oid_apSysGlobalCPS}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check system usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^memory-usage$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'license-usage' (%), 'memory-usage' (%), 'cpu-load' (%), +'health-score' (%), 'current-sessions', 'current-calls'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'license-usage' (%), 'memory-usage' (%), 'cpu-load' (%), +'health-score' (%), 'current-sessions', 'current-calls'. + +=back + +=cut diff --git a/centreon-plugins/network/acmepacket/snmp/plugin.pm b/centreon-plugins/network/acmepacket/snmp/plugin.pm new file mode 100644 index 000000000..c74613272 --- /dev/null +++ b/centreon-plugins/network/acmepacket/snmp/plugin.pm @@ -0,0 +1,55 @@ +# +# 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 network::acmepacket::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'network::acmepacket::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-realm' => 'network::acmepacket::snmp::mode::listrealm', + 'list-sip' => 'network::acmepacket::snmp::mode::listsip', + 'realm-usage' => 'network::acmepacket::snmp::mode::realmusage', + 'sip-usage' => 'network::acmepacket::snmp::mode::sipusage', + 'system-usage' => 'network::acmepacket::snmp::mode::systemusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Acme Packet equipments (Oracle SBC) in SNMP. + +=cut diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/backplane.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/backplane.pm index 4d167a861..303e9c3fe 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/backplane.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/backplane.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'backplane.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'backplane.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("backplane '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/chassis.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/chassis.pm index 2918e5867..aabd448e5 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/chassis.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/chassis.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'chassis.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'chassis.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("chassis '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/container.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/container.pm index 883b6a749..03b411a5d 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/container.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/container.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'container.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'container.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("container '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/fan.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/fan.pm index e575a5668..9800a772b 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/fan.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/fan.pm @@ -75,7 +75,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'fan.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'fan.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("fan '%s/%s/%s' operational status is %s", @@ -89,9 +89,9 @@ sub check { my ($phys_index, $loc_index) = ($1, $2); my $status = $self->{results}->{$oids{alaChasEntPhysFanStatus}}->{$key}; my $descr = defined($self->{results}->{entity}->{$oids{entPhysicalDescr} . '.' . $phys_index}) ? - $self->{results}->{$oids{entPhysicalDescr}}->{$oids{entPhysicalDescr} . '.' . $phys_index} : 'unknown'; + $self->{results}->{entity}->{$oids{entPhysicalDescr} . '.' . $phys_index} : 'unknown'; my $name = defined($self->{results}->{entity}->{$oids{entPhysicalName} . '.' . $phys_index}) ? - $self->{results}->{$oids{entPhysicalName}}->{$oids{entPhysicalName} . '.' . $phys_index} : 'unknown'; + $self->{results}->{entity}->{$oids{entPhysicalName} . '.' . $phys_index} : 'unknown'; next if ($self->check_filter(section => 'fan', instance => $phys_index . '.' . $loc_index)); $self->{components}->{fan}->{total}++; @@ -110,4 +110,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/module.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/module.pm index ff631571c..4786112e8 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/module.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/module.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'module.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'module.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("module '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/other.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/other.pm index cdb704a9d..e2d48cac0 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/other.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/other.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'other.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'other.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("other '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/port.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/port.pm index d8ad20bc3..870936d07 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/port.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/port.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'port.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'port.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("port '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/psu.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/psu.pm index 04921e1fa..cd87e14d5 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/psu.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/psu.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'psu.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'psu.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("power supply '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/sensor.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/sensor.pm index 5a6a1f5f2..23bcddfa8 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/sensor.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/sensor.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'sensor.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'sensor.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("sensor '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/stack.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/stack.pm index 5b24ec8d6..4bd8f39db 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/stack.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/stack.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'stack.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'stack.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("stack '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/unknown.pm b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/unknown.pm index fe18d7a17..197ea2517 100644 --- a/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/unknown.pm +++ b/centreon-plugins/network/alcatel/omniswitch/snmp/mode/components/unknown.pm @@ -69,7 +69,7 @@ sub check { next; } - $exit = $self->get_severity(label => 'oper', section => 'unknown.oper', value => $result->{chasEntPhysAdminStatus}); + $exit = $self->get_severity(label => 'oper', section => 'unknown.oper', value => $result->{chasEntPhysOperStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("unknown '%s/%s/%s' operational status is %s", @@ -79,4 +79,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/alcatel/oxe/snmp/mode/pbxrole.pm b/centreon-plugins/network/alcatel/oxe/snmp/mode/pbxrole.pm index 0de48fbf0..564568d32 100644 --- a/centreon-plugins/network/alcatel/oxe/snmp/mode/pbxrole.pm +++ b/centreon-plugins/network/alcatel/oxe/snmp/mode/pbxrole.pm @@ -129,7 +129,7 @@ Check PBX Role. Set to overload default threshold values (syntax: section,status,regexp) It used before default thresholds (order stays). -Example: --threshold-overload='state,CRITICAL,^(?!(main)$)' +Example: --threshold-overload='role,CRITICAL,^(?!(main)$)' =back diff --git a/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm b/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm index 547cac179..8d2d5cf1b 100644 --- a/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm +++ b/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm @@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use Digest::MD5 qw(md5_hex); my $instance_mode; @@ -84,12 +85,39 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_status_threshold'), } }, + { label => 'avg-calls', set => { + key_values => [ { name => 'acPMTrunkUtilizationAverage' }, { name => 'display' } ], + output_template => 'Average calls : %s', + perfdatas => [ + { label => 'avg_calls', value => 'acPMTrunkUtilizationAverage_absolute', template => '%d', + min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'max-calls', set => { + key_values => [ { name => 'acPMTrunkUtilizationMax' }, { name => 'display' } ], + output_template => 'Max calls : %s', + perfdatas => [ + { label => 'max_calls', value => 'acPMTrunkUtilizationMax_absolute', template => '%d', + min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'count-calls', set => { + key_values => [ { name => 'acPMTrunkUtilizationTotal', diff => 1 }, { name => 'display' } ], + output_template => 'Count calls : %s', + perfdatas => [ + { label => 'count_calls', value => 'acPMTrunkUtilizationTotal_absolute', template => '%d', + min => 0, unit => 'calls', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; @@ -132,39 +160,58 @@ my %map_dchannel = (0 => 'dChannelEstablished', 1 => 'dChannelNotEstablished', 1 my %map_deactivate = (0 => 'notAvailable', 1 => 'deActivated', 2 => 'activated'); my $mapping = { - acTrunkStatusDChannel => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.6', map => \%map_dchannel }, - acTrunkStatusAlarm => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.7', map => \%map_alarm }, - acTrunkDeactivate => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.11', map => \%map_deactivate }, - acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' }, + status => { + acTrunkStatusDChannel => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.6', map => \%map_dchannel }, + acTrunkStatusAlarm => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.7', map => \%map_alarm }, + acTrunkDeactivate => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.11', map => \%map_deactivate }, + acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' }, + }, + usage => { + acPMTrunkUtilizationAverage => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.4' }, + acPMTrunkUtilizationMax => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.5' }, + acPMTrunkUtilizationTotal => { oid => '.1.3.6.1.4.1.5003.10.10.2.21.1.12' }, + } }; -my $oid_acTrunkStatusEntry = '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1'; sub manage_selection { my ($self, %options) = @_; $self->{trunk} = {}; - my $snmp_result = $options{snmp}->get_multiple_table(oids => [ - { oid => $mapping->{acTrunkName}->{oid} }, - { oid => $mapping->{acTrunkDeactivate}->{oid} }, - { oid => $oid_acTrunkStatusEntry }, - ], nothing_quit => 1, return_type => 1); + my $oids = []; + foreach (keys %{$mapping}) { + foreach my $name (keys %{$mapping->{$_}}) { + push @{$oids}, { oid => $mapping->{$_}->{$name}->{oid} }; + } + } + my $snmp_result = $options{snmp}->get_multiple_table(oids => $oids, nothing_quit => 1); - foreach my $oid (keys %{$snmp_result}) { - next if ($oid !~ /^$mapping->{acTrunkStatusAlarm}->{oid}\.(.*)$/); + my $datas = { status => {}, usage => {} }; + foreach (keys %{$mapping}) { + foreach my $name (keys %{$mapping->{$_}}) { + $datas->{$_} = { %{$datas->{$_}}, %{$snmp_result->{ $mapping->{$_}->{$name}->{oid} }} }; + } + } + foreach (keys %{$snmp_result->{ $mapping->{status}->{acTrunkStatusAlarm}->{oid} }}) { + /\.(\d+)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{status}, results => $datas->{status}, instance => $instance); + my $result2 = $options{snmp}->map_instance(mapping => $mapping->{usage}, results => $datas->{usage}, instance => $instance . '.0'); $self->{trunk}->{$instance} = { display => defined($result->{acTrunkName}) && $result->{acTrunkName} ne '' ? $result->{acTrunkName} : $instance, alarm => $result->{acTrunkStatusAlarm}, state => $result->{acTrunkDeactivate}, - dchannel => $result->{acTrunkStatusDChannel} }; + dchannel => $result->{acTrunkStatusDChannel}, + %$result2 }; } if (scalar(keys %{$self->{trunk}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No trunk found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "audiocodes_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -173,7 +220,7 @@ __END__ =head1 MODE -Check vpn status. +Check trunk status. =over 8 @@ -187,6 +234,17 @@ Can used special variables like: %{display}, %{alarm}, %{dchannel}, %{state} Set critical threshold for status (Default: '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i'). Can used special variables like: %{display}, %{alarm}, %{dchannel}, %{state} +=item B<--warning-*> + +Threshold warning. +Can be: 'avg-calls', 'max-calls', 'count-calls'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'avg-calls', 'max-calls', 'count-calls'. + + =back =cut diff --git a/centreon-plugins/network/citrix/sdx/snmp/mode/diskusage.pm b/centreon-plugins/network/citrix/sdx/snmp/mode/diskusage.pm new file mode 100644 index 000000000..44d126b47 --- /dev/null +++ b/centreon-plugins/network/citrix/sdx/snmp/mode/diskusage.pm @@ -0,0 +1,249 @@ +# +# 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 network::citrix::sdx::snmp::mode::diskusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +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 => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ], + 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'), + } + }, + { label => 'read-iops', set => { + key_values => [ { name => 'diskTotalBlocksRead', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", + perfdatas => [ + { label => 'read_iops', value => 'diskTotalBlocksRead_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-iops', set => { + key_values => [ { name => 'diskTotalBlocksWritten', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", + perfdatas => [ + { label => 'write_iops', value => 'diskTotalBlocksWritten_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + diskName => { oid => '.1.3.6.1.4.1.5951.6.2.1000.3.1.1' }, + diskTotalBlocksRead => { oid => '.1.3.6.1.4.1.5951.6.2.1000.3.1.7' }, + diskTotalBlocksWritten => { oid => '.1.3.6.1.4.1.5951.6.2.1000.3.1.8' }, + diskUtilized => { oid => '.1.3.6.1.4.1.5951.6.2.1000.3.1.9' }, + diskSize => { oid => '.1.3.6.1.4.1.5951.6.2.1000.3.1.10' }, +}; + +my $oid_diskEntry = '.1.3.6.1.4.1.5951.6.2.1000.3.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{disk} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_diskEntry, + nothing_quit => 1); + + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{diskName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{diskName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{diskName} . "': no matching filter.", debug => 1); + next; + } + + $self->{disk}->{$instance} = { + display => $result->{diskName}, + total => $result->{diskSize}, + used => $result->{diskUtilized}, + %$result + }; + } + + if (scalar(keys %{$self->{disk}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No disk found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "citrix_sdx_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check disks. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^usage$' + +=item B<--filter-name> + +Filter disk name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'read-iops', 'write-iops', 'usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'read-iops', 'write-iops', 'usage'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=back + +=cut diff --git a/centreon-plugins/network/citrix/sdx/snmp/mode/hardware.pm b/centreon-plugins/network/citrix/sdx/snmp/mode/hardware.pm new file mode 100644 index 000000000..bc870247a --- /dev/null +++ b/centreon-plugins/network/citrix/sdx/snmp/mode/hardware.pm @@ -0,0 +1,184 @@ +# +# 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 network::citrix::sdx::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(hardware|software)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['OK', 'OK'], + ['ERROR', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::citrix::sdx::snmp::mode::components'; + $self->{components_module} = ['hardware', 'software']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'hardware', 'software'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=hardware,name + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='hardware,WARNING,ERROR' + +=back + +=cut + +package network::citrix::sdx::snmp::mode::components::hardware; + +use strict; +use warnings; + +my $mapping_hw = { + hardwareResourceName => { oid => '.1.3.6.1.4.1.5951.6.2.1000.1.1.1' }, + hardwareResourceStatus => { oid => '.1.3.6.1.4.1.5951.6.2.1000.1.1.7' }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping_hw->{hardwareResourceName}->{oid} }, + { oid => $mapping_hw->{hardwareResourceStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking hardware"); + $self->{components}->{hardware} = {name => 'hardware', total => 0, skip => 0}; + return if ($self->check_filter(section => 'hardware')); + + my $datas = { %{$self->{results}->{ $mapping_hw->{hardwareResourceStatus}->{oid} }}, %{$self->{results}->{ $mapping_hw->{hardwareResourceName}->{oid} }} }; + foreach ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping_hw->{hardwareResourceStatus}->{oid} }})) { + /^$mapping_hw->{hardwareResourceStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping_hw, results => $datas, instance => $instance); + + next if ($self->check_filter(section => 'hardware', instance => $result->{hardwareResourceName})); + + $self->{components}->{hardware}->{total}++; + $self->{output}->output_add(long_msg => sprintf("hardware '%s' status is '%s' [instance = %s]", + $result->{hardwareResourceName}, $result->{hardwareResourceStatus}, $result->{hardwareResourceName})); + my $exit = $self->get_severity(label => 'default', section => 'hardware', value => $result->{hardwareResourceStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Hardware '%s' status is '%s'", $result->{hardwareResourceName}, $result->{hardwareResourceStatus})); + } + } +} + +1; + +package network::citrix::sdx::snmp::mode::components::software; + +use strict; +use warnings; + +my $mapping_soft = { + softwareResourceName => { oid => '.1.3.6.1.4.1.5951.6.2.1000.2.1.1' }, + softwareResourceStatus => { oid => '.1.3.6.1.4.1.5951.6.2.1000.2.1.7' }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping_soft->{softwareResourceName}->{oid} }, + { oid => $mapping_soft->{softwareResourceStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking software"); + $self->{components}->{software} = {name => 'software', total => 0, skip => 0}; + return if ($self->check_filter(section => 'software')); + + my $datas = { %{$self->{results}->{ $mapping_soft->{softwareResourceStatus}->{oid} }}, %{$self->{results}->{ $mapping_soft->{softwareResourceName}->{oid} }} }; + foreach ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping_soft->{softwareResourceStatus}->{oid} }})) { + /^$mapping_soft->{softwareResourceStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping_soft, results => $datas, instance => $instance); + + next if ($self->check_filter(section => 'software', instance => $result->{softwareResourceName})); + + $self->{components}->{software}->{total}++; + $self->{output}->output_add(long_msg => sprintf("software '%s' status is '%s' [instance = %s]", + $result->{softwareResourceName}, $result->{softwareResourceStatus}, $result->{softwareResourceName})); + my $exit = $self->get_severity(label => 'default', section => 'software', value => $result->{softwareResourceStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Software '%s' status is '%s'", $result->{softwareResourceName}, $result->{softwareResourceStatus})); + } + } +} + +1; diff --git a/centreon-plugins/network/citrix/sdx/snmp/mode/srusage.pm b/centreon-plugins/network/citrix/sdx/snmp/mode/srusage.pm new file mode 100644 index 000000000..8f8dd8bb3 --- /dev/null +++ b/centreon-plugins/network/citrix/sdx/snmp/mode/srusage.pm @@ -0,0 +1,293 @@ +# +# 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 network::citrix::sdx::snmp::mode::srusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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} . '_srStatus'}; + $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 => 'sr', type => 1, cb_prefix_output => 'prefix_sr_output', message_multiple => 'All storage repositories are ok' } + ]; + + $self->{maps_counters}->{sr} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'srStatus' }, { 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 => 'display' }, { name => 'used' }, { name => 'total' } ], + 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 => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /good/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_sr_output { + my ($self, %options) = @_; + + return "Storage repository '" . $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; + } + } +} + +my $mapping = { + srName => { oid => '.1.3.6.1.4.1.5951.6.2.1000.4.1.1' }, + srUtilized => { oid => '.1.3.6.1.4.1.5951.6.2.1000.4.1.5' }, + srSize => { oid => '.1.3.6.1.4.1.5951.6.2.1000.4.1.6' }, + srStatus => { oid => '.1.3.6.1.4.1.5951.6.2.1000.4.1.7' }, +}; + +my $oid_srEntry = '.1.3.6.1.4.1.5951.6.2.1000.4.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{sr} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_srEntry, + nothing_quit => 1); + + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{srName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{srName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{srName} . "': no matching filter.", debug => 1); + next; + } + + $self->{sr}->{$instance} = { + display => $result->{srName}, + total => $result->{srSize}, + used => $result->{srUtilized}, + %$result + }; + } + + if (scalar(keys %{$self->{sr}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No storage repository found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage repositories. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^read|write$' + +=item B<--filter-name> + +Filter storage repository name (can be a regexp). + +=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} !~ /good/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=back + +=cut diff --git a/centreon-plugins/network/citrix/sdx/snmp/mode/xenusage.pm b/centreon-plugins/network/citrix/sdx/snmp/mode/xenusage.pm new file mode 100644 index 000000000..799cd13c4 --- /dev/null +++ b/centreon-plugins/network/citrix/sdx/snmp/mode/xenusage.pm @@ -0,0 +1,232 @@ +# +# 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 network::citrix::sdx::snmp::mode::xenusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'memory_used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'memory_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("Memory 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} . '_mem_total'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_mem_free'}; + $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; + $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 => 'xen', type => 1, cb_prefix_output => 'prefix_xen_output', message_multiple => 'All xen hypervisors are ok' } + ]; + + $self->{maps_counters}->{xen} = [ + { label => 'memory-usage', set => { + key_values => [ { name => 'display' }, { name => 'mem_free' }, { name => 'mem_total' } ], + 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'), + } + }, + { label => 'cpu-usage', set => { + key_values => [ { name => 'xenCpuUsage' }, { name => 'display' } ], + output_template => 'CPU Usage : %.2f %%', output_error_template => "CPU Usage : %s", + perfdatas => [ + { label => 'cpu_usage', value => 'xenCpuUsage_absolute', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Xen '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + xenHostname => { oid => '.1.3.6.1.4.1.5951.6.3.1.1.3' }, + xenCpuUsage => { oid => '.1.3.6.1.4.1.5951.6.3.1.1.8' }, + xenMemoryTotal => { oid => '.1.3.6.1.4.1.5951.6.3.1.1.9' }, + xenMemoryFree => { oid => '.1.3.6.1.4.1.5951.6.3.1.1.10' }, +}; + +my $oid_xenEntry = '.1.3.6.1.4.1.5951.6.3.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{xen} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_xenEntry, + nothing_quit => 1); + + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{xenHostname}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{xenHostname} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{xenHostname} . "': no matching filter.", debug => 1); + next; + } + + $self->{xen}->{$instance} = { + display => $result->{xenHostname}, + mem_total => $result->{xenMemoryTotal} * 1024 * 1024, + mem_free => $result->{xenMemoryFree} * 1024 * 1024, + %$result + }; + } + + if (scalar(keys %{$self->{xen}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No xen hypervisor found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check xen hypervisors. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^memory-usage$' + +=item B<--filter-name> + +Filter xen name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'cpu-usage', 'memory-usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'cpu-usage', 'memory-usage'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=back + +=cut diff --git a/centreon-plugins/network/citrix/sdx/snmp/plugin.pm b/centreon-plugins/network/citrix/sdx/snmp/plugin.pm new file mode 100644 index 000000000..d019c49c1 --- /dev/null +++ b/centreon-plugins/network/citrix/sdx/snmp/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 network::citrix::sdx::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'disk-usage' => 'network::citrix::sdx::snmp::mode::diskusage', + 'hardware' => 'network::citrix::sdx::snmp::mode::hardware', + 'sr-usage' => 'network::citrix::sdx::snmp::mode::srusage', + 'xen-usage' => 'network::citrix::sdx::snmp::mode::xenusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Citrix SDX in SNMP. + +=cut diff --git a/centreon-plugins/network/evertz/AEA47721/snmp/mode/streamstatus.pm b/centreon-plugins/network/evertz/AEA47721/snmp/mode/streamstatus.pm new file mode 100644 index 000000000..6a8aae4c3 --- /dev/null +++ b/centreon-plugins/network/evertz/AEA47721/snmp/mode/streamstatus.pm @@ -0,0 +1,231 @@ +# +# 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 network::evertz::AEA47721::snmp::mode::streamstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'video', type => 1, cb_prefix_output => 'prefix_video_output', message_multiple => 'All videos are ok' }, + { name => 'audio', type => 1, cb_prefix_output => 'prefix_audio_output', message_multiple => 'All audios are ok' }, + ]; + + $self->{maps_counters}->{video} = [ + { label => 'video-status', threshold => 0, set => { + key_values => [ { name => 'videoInputStatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'Status', name_status => 'videoInputStatus' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + $self->{maps_counters}->{audio} = [ + { label => 'audio-status', threshold => 0, set => { + key_values => [ { name => 'videoInputGroupStatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'Status', name_status => 'videoInputGroupStatus' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $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 = $self->{result_values}->{output_label} . ' : ' . $self->{result_values}->{status}; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{output_label} = $options{extra_options}->{output_label}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{name_status}}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-audio-status:s" => { name => 'warning_audio_status', default => '' }, + "critical-audio-status:s" => { name => 'critical_audio_status', default => '%{status} =~ /loss/i' }, + "warning-video-status:s" => { name => 'warning_video_status', default => '' }, + "critical-video-status:s" => { name => 'critical_video_status', default => '%{status} =~ /loss|unknown/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_audio_status', 'critical_audio_status', 'warning_video_status', 'critical_video_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub prefix_video_output { + my ($self, %options) = @_; + + return "Video '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_audio_output { + my ($self, %options) = @_; + + return "Audio '" . $options{instance_value}->{display} . "' "; +} + +my %map_video_input_status = (1 => 'loss', 2 => 'unknown', 3 => 'p270', 4 => 'n270', 5 => 'sdtiP270', + 6 => 'sdtiN270', 7 => 'std1080ix60', 8 => 'std1080ix5994', 9 => 'std1080ix50', 10 => 'std1035ix60', + 11 => 'std1035ix5994', 12 => 'std1080ix48', 13 => 'std1080ix4796', 14 => 'std1080px24', + 15 => 'std1080px2398', 16 => 'std1080px25', 17 => 'std1080px30', 18 => 'std1080px2997', + 19 => 'std720px60', 20 => 'std720px5994', +); +my %map_video_input_group_status = (1 => 'free', 2 => 'used', 3 => 'clean', 4 => 'loss'); + +my $mapping = { + videoInputStatus => { oid => '.1.3.6.1.4.1.6827.10.138.4.1.1.1', map => \%map_video_input_status }, +}; +my $mapping2 = { + videoInputGroupStatus => { oid => '.1.3.6.1.4.1.6827.10.138.4.2.1.2', map => \%map_video_input_group_status }, +}; + +my $oid_monitorEntry = '.1.3.6.1.4.1.6827.10.138.4.1.1'; +my $oid_audioMonitorEntry = '.1.3.6.1.4.1.6827.10.138.4.2.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_monitorEntry }, + { oid => $oid_audioMonitorEntry }, + ], + nothing_quit => 1); + $self->{video} = {}; + foreach my $oid (keys %{$snmp_result->{ $oid_monitorEntry }}) { + next if ($oid !~ /^$mapping->{videoInputStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{ $oid_monitorEntry }, instance => $instance); + + $self->{video}->{$instance} = { + display => $instance, %$result + }; + } + + $self->{audio} = {}; + foreach my $oid (keys %{$snmp_result->{ $oid_audioMonitorEntry }}) { + next if ($oid !~ /^$mapping2->{videoInputGroupStatus}->{oid}\.(.*?)\.(.*?)$/); + my ($audio_group_id, $instance) = ($1, $2); + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{ $oid_audioMonitorEntry }, instance => $audio_group_id . '.' . $instance); + + $self->{audio}->{$audio_group_id . '.' . $instance} = { + display => $instance . '.' . $audio_group_id, %$result + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check video/audio stream status. + +=over 8 + +=item B<--warning-audio-status> + +Set warning threshold for device status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-audio-status> + +Set critical threshold for device status (Default: '%{status} =~ /loss/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-video-status> + +Set warning threshold for device connection status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-video-status> + +Set critical threshold for device connection status (Default: '%{status} =~ /loss|unknown/i'). +Can used special variables like: %{status}, %{display} + +=back + +=cut diff --git a/centreon-plugins/network/evertz/AEA47721/snmp/plugin.pm b/centreon-plugins/network/evertz/AEA47721/snmp/plugin.pm new file mode 100644 index 000000000..87148cc2a --- /dev/null +++ b/centreon-plugins/network/evertz/AEA47721/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 network::evertz::AEA47721::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'stream-status' => 'network::evertz::AEA47721::snmp::mode::streamstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Audio Embedder Card in SNMP. + +=cut diff --git a/centreon-plugins/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm b/centreon-plugins/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm new file mode 100644 index 000000000..134f4e0e7 --- /dev/null +++ b/centreon-plugins/network/evertz/DA6HDL7700/snmp/mode/videostatus.pm @@ -0,0 +1,181 @@ +# +# 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 network::evertz::DA6HDL7700::snmp::mode::videostatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'video', type => 1, cb_prefix_output => 'prefix_video_output', message_multiple => 'All videos are ok' }, + ]; + + $self->{maps_counters}->{video} = [ + { label => 'video-status', threshold => 0, set => { + key_values => [ { name => 'videoLocked' }, { name => 'detectedVideoStandard' }, { 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'), + } + }, + ]; +} + +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]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $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 = 'is : ' . $self->{result_values}->{video_locked}; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{video_locked} = $options{new_datas}->{$self->{instance} . '_videoLocked'}; + $self->{result_values}->{detected_video_standard} = $options{new_datas}->{$self->{instance} . '_detectedVideoStandard'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-video-status:s" => { name => 'warning_video_status', default => '' }, + "critical-video-status:s" => { name => 'critical_video_status', default => '%{video_locked} =~ /notLocked/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_video_status', 'critical_video_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub prefix_video_output { + my ($self, %options) = @_; + + return "Video '" . $options{instance_value}->{display} . "' "; +} + +my %map_video_standard = (1 => 'vs15G', 2 => 'vs540M', 3 => 'vs360M', + 4 => 'vs270M', 5 => 'vs177M', 6 => 'vs143', 7 => 'none' +); +my %map_video_locked = (1 => 'locked', 2 => 'notlocked'); + +my $mapping = { + videoLocked => { oid => '.1.3.6.1.4.1.6827.10.131.4.1.1.1', map => \%map_video_locked }, + detectedVideoStandard => { oid => '.1.3.6.1.4.1.6827.10.131.4.1.1.2', map => \%map_video_standard }, +}; + +my $oid_videoMonitorEntry = '.1.3.6.1.4.1.6827.10.131.4.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_videoMonitorEntry, + nothing_quit => 1); + $self->{video} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{videoLocked}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{video}->{$instance} = { + display => $instance, %$result + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check video stream status. + +=over 8 + +=item B<--warning-video-status> + +Set warning threshold for device connection status. +Can used special variables like: %{video_locked}, %{display} + +=item B<--critical-video-status> + +Set critical threshold for device connection status (Default: '%{video_locked} =~ /notLocked/i'). +Can used special variables like: %{video_locked}, %{display} + +=back + +=cut diff --git a/centreon-plugins/network/evertz/DA6HDL7700/snmp/plugin.pm b/centreon-plugins/network/evertz/DA6HDL7700/snmp/plugin.pm new file mode 100644 index 000000000..42e83ea5e --- /dev/null +++ b/centreon-plugins/network/evertz/DA6HDL7700/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 network::evertz::DA6HDL7700::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'video-status' => 'network::evertz::DA6HDL7700::snmp::mode::videostatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Reclocking Distribution Amplifier Card in SNMP. + +=cut diff --git a/centreon-plugins/network/evertz/FC7800/snmp/mode/hardware.pm b/centreon-plugins/network/evertz/FC7800/snmp/mode/hardware.pm new file mode 100644 index 000000000..9e7612fa1 --- /dev/null +++ b/centreon-plugins/network/evertz/FC7800/snmp/mode/hardware.pm @@ -0,0 +1,188 @@ +# +# 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 network::evertz::FC7800::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(psu|frameline)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['false', 'CRITICAL'], + ['true', 'OK'], + ['notAvailable', 'UNKNOWN'], + ], + frameline => [ + ['false', 'OK'], + ['true', 'CRITICAL'], + ['notAvailable', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'network::evertz::FC7800::snmp::mode::components'; + $self->{components_module} = ['frameline', 'psu']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_leef(oids => $self->{request}); +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'psu', 'frameline'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=psu,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='psu,OK,notAvailable' + +=back + +=cut + +package network::evertz::FC7800::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = (1 => 'false', 2 => 'true', 3 => 'notAvailable'); + +my $mapping_psu = { + powerSupply1Status => { oid => '.1.3.6.1.4.1.6827.10.232.4.3', map => \%map_psu_status }, + powerSupply2Status => { oid => '.1.3.6.1.4.1.6827.10.232.4.4', map => \%map_psu_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, $mapping_psu->{powerSupply1Status}->{oid} . '.0', $mapping_psu->{powerSupply2Status}->{oid} . '.0'; +} + +sub check_psu { + my ($self, %options) = @_; + + return if (!defined($options{status})); + return if ($self->check_filter(section => 'psu', instance => $options{instance})); + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $options{instance}, $options{status}, $options{instance})); + my $exit = $self->get_severity(section => 'psu', value => $options{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $options{instance}, $options{status})); + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking poer supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my $result = $self->{snmp}->map_instance(mapping => $mapping_psu, results => $self->{results}, instance => '0'); + + check_psu($self, status => $result->{powerSupply1Status}, instance => 1); + check_psu($self, status => $result->{powerSupply2Status}, instance => 2); +} + +1; + +package network::evertz::FC7800::snmp::mode::components::frameline; + +use strict; +use warnings; + +my %map_frameline_status = (1 => 'false', 2 => 'true', 3 => 'notAvailable'); + +my $mapping_frameline = { + frameStatusLine => { oid => '.1.3.6.1.4.1.6827.10.232.4.2', map => \%map_frameline_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, $mapping_frameline->{frameStatusLine}->{oid} . '.0'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking frame line"); + $self->{components}->{frameline} = {name => 'frameline', total => 0, skip => 0}; + return if ($self->check_filter(section => 'frameline')); + + my $result = $self->{snmp}->map_instance(mapping => $mapping_frameline, results => $self->{results}, instance => '0'); + + return if (!defined($result->{frameStatusLine})); + $self->{components}->{frameline}->{total}++; + $self->{output}->output_add(long_msg => sprintf("frame line status is '%s' [instance = %s]", + $result->{frameStatusLine}, '0')); + my $exit = $self->get_severity(section => 'frameline', value => $result->{frameStatusLine}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Frame line status is '%s'", $result->{frameStatusLine})); + } +} + +1; diff --git a/centreon-plugins/network/evertz/FC7800/snmp/plugin.pm b/centreon-plugins/network/evertz/FC7800/snmp/plugin.pm new file mode 100644 index 000000000..18987093c --- /dev/null +++ b/centreon-plugins/network/evertz/FC7800/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 network::evertz::FC7800::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'network::evertz::FC7800::snmp::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check 7800 Frame Controller in SNMP. + +=cut diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/listnodes.pm b/centreon-plugins/network/f5/bigip/snmp/mode/listnodes.pm index a06d6c607..ca6a5fa00 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/listnodes.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/listnodes.pm @@ -25,7 +25,8 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -my $oid_ltmNodeAddrStatusAvailState = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.3'; +my $oid_ltmNodeAddrName = '.1.3.6.1.4.1.3375.2.2.4.1.2.1.17'; # old +my $oid_ltmNodeAddrStatusName = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.7'; # new sub new { my ($class, %options) = @_; @@ -35,11 +36,8 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, + "filter-name:s" => { name => 'filter_name' }, }); - $self->{node_id_selected} = []; - return $self; } @@ -51,30 +49,22 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_ltmNodeAddrStatusAvailState, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { - next if ($oid !~ /^$oid_ltmNodeAddrStatusAvailState\.(.*)$/); - my $instance = $1; - - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{node_id_selected}}, $instance; + my $snmp_result = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_ltmNodeAddrName }, { oid => $oid_ltmNodeAddrStatusName } ], nothing_quit => 1); + + my ($branch_name) = ($oid_ltmNodeAddrStatusName); + if (!defined($snmp_result->{$oid_ltmNodeAddrStatusName}) || scalar(keys %{$snmp_result->{$oid_ltmNodeAddrStatusName}}) == 0) { + ($branch_name) = ($oid_ltmNodeAddrName); + } + + $self->{node} = {}; + foreach my $oid (keys %{$snmp_result->{$branch_name}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$branch_name}->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping service class '" . $snmp_result->{$branch_name}->{$oid} . "'.", debug => 1); next; } - my $name = $instance; - # prefix by '1.4' - $name =~ s/^1\.4\.//; - if (!defined($self->{option_results}->{use_regexp}) && $name eq $self->{option_results}->{name}) { - push @{$self->{node_id_selected}}, $instance; - next; - } - if (defined($self->{option_results}->{use_regexp}) && $name =~ /$self->{option_results}->{name}/) { - push @{$self->{node_id_selected}}, $instance; - next; - } - - $self->{output}->output_add(long_msg => "Skipping node '" . $name . "': no matching filter name", debug => 1); + $self->{node}->{$snmp_result->{$branch_name}->{$oid}} = { name => $snmp_result->{$branch_name}->{$oid} }; } } @@ -83,11 +73,7 @@ sub run { $self->{snmp} = $options{snmp}; $self->manage_selection(); - foreach my $instance (sort @{$self->{node_id_selected}}) { - my $name = $instance; - # prefix by '1.4' - $name =~ s/^1\.4\.//; - + foreach my $name (sort keys %{$self->{node}}) { $self->{output}->output_add(long_msg => "'" . $name . "'"); } @@ -107,12 +93,8 @@ sub disco_show { my ($self, %options) = @_; $self->{snmp} = $options{snmp}; - $self->manage_selection(disco => 1); - foreach my $instance (sort @{$self->{node_id_selected}}) { - my $name = $instance; - # prefix by '1.4' - $name =~ s/^1\.4\.//; - + $self->manage_selection(); + foreach my $name (sort keys %{$self->{node}}) { $self->{output}->add_disco_entry(name => $name); } } @@ -123,19 +105,14 @@ __END__ =head1 MODE -List F-5 Nodes. +List nodes. =over 8 -=item B<--name> +=item B<--filter-name> -Set the node name. - -=item B<--regexp> - -Allows to use regexp to filter node name (with option --name). +Filter by node name. =back =cut - \ No newline at end of file diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm b/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm index 145891fb3..818a3b831 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm @@ -66,6 +66,15 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_threshold_output'), } }, + { label => 'current-server-connections', set => { + key_values => [ { name => 'ltmNodeAddrStatServerCurConns' }, { name => 'Name' } ], + output_template => 'Current Server Connections : %s', output_error_template => "Current Server Connections : %s", + perfdatas => [ + { label => 'current_server_connections', value => 'ltmNodeAddrStatServerCurConns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'Name_absolute' }, + ], + } + }, ]; } @@ -152,9 +161,9 @@ my %map_node_enabled = ( # New OIDS my $mapping = { new => { - AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.3', map => \%map_node_status }, - EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.4', map => \%map_node_enabled }, - StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.6' }, + AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.3', map => \%map_node_status }, + EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.4', map => \%map_node_enabled }, + StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.6' }, }, old => { AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.13', map => \%map_node_status }, @@ -162,44 +171,59 @@ my $mapping = { StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.16' }, }, }; -my $oid_ltmNodeAddrStatusEntry = '.1.3.6.1.4.1.3375.2.2.4.3.2.1'; # new -my $oid_ltmNodeAddrEntry = '.1.3.6.1.4.1.3375.2.2.4.1.2.1'; # old +my $mapping2 = { + ltmNodeAddrStatServerCurConns => { oid => '.1.3.6.1.4.1.3375.2.2.4.2.3.1.9' }, +}; +my $oid_ltmNodeAddrName = '.1.3.6.1.4.1.3375.2.2.4.1.2.1.17'; # old +my $oid_ltmNodeAddrStatusName = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.7'; # new sub manage_selection { my ($self, %options) = @_; - $self->{results} = $options{snmp}->get_multiple_table(oids => [ - { oid => $oid_ltmNodeAddrEntry, start => $mapping->{old}->{AvailState}->{oid} }, - { oid => $oid_ltmNodeAddrStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ltmNodeAddrName }, + { oid => $oid_ltmNodeAddrStatusName }, ], , nothing_quit => 1); - my ($branch, $map) = ($oid_ltmNodeAddrStatusEntry, 'new'); - if (!defined($self->{results}->{$oid_ltmNodeAddrStatusEntry}) || scalar(keys %{$self->{results}->{$oid_ltmNodeAddrStatusEntry}}) == 0) { - ($branch, $map) = ($oid_ltmNodeAddrEntry, 'old'); + my ($branch_name, $map) = ($oid_ltmNodeAddrStatusName, 'new'); + if (!defined($snmp_result->{$oid_ltmNodeAddrStatusName}) || scalar(keys %{$snmp_result->{$oid_ltmNodeAddrStatusName}}) == 0) { + ($branch_name, $map) = ($oid_ltmNodeAddrName, 'old'); } $self->{node} = {}; - foreach my $oid (keys %{$self->{results}->{$branch}}) { - next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); + foreach my $oid (keys %{$snmp_result->{$branch_name}}) { + $oid =~ /^$branch_name\.(.*)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); - - $result->{Name} = $instance; - # prefix by '1.4' - $result->{Name} =~ s/^1\.4\.//; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $result->{Name} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': no matching filter name."); + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping node '" . $snmp_result->{$oid} . "'.", debug => 1); next; } - if ($result->{EnabledState} !~ /enabled/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': state is '$result->{EnabledState}'."); - next; - } - $result->{StatusReason} = '-' if (!defined($result->{StatusReason}) || $result->{StatusReason} eq ''); - $self->{node}->{$instance} = { %$result }; + $self->{node}->{$instance} = { Name => $snmp_result->{$branch_name}->{$oid} }; + } + + $options{snmp}->load(oids => [$mapping->{$map}->{AvailState}->{oid}, $mapping->{$map}->{EnabledState}->{oid}, + $mapping->{$map}->{StatusReason}->{oid}, $mapping2->{ltmNodeAddrStatServerCurConns}->{oid} + ], + instances => [keys %{$self->{node}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{node}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $snmp_result, instance => $_); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); + + if ($result->{EnabledState} !~ /enabled/) { + $self->{output}->output_add(long_msg => "skipping '" . $self->{node}->{$_}->{Name} . "': state is '$result->{EnabledState}'.", debug => 1); + delete $self->{node}->{$_}; + next; + } + $self->{node}->{$_}->{ltmNodeAddrStatServerCurConns} = $result2->{ltmNodeAddrStatServerCurConns}; + $result->{StatusReason} = '-' if (!defined($result->{StatusReason}) || $result->{StatusReason} eq ''); + foreach my $name (keys %{$mapping->{$map}}) { + $self->{node}->{$_}->{$name} = $result->{$name}; + } } if (scalar(keys %{$self->{node}}) <= 0) { @@ -228,6 +252,16 @@ Set to overload default threshold values (syntax: section,status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='node,CRITICAL,^(?!(green)$)' +=item B<--warning-*> + +Threshold warning. +Can be: 'current-server-connections'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-server-connections'. + =back =cut diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/poolstatus.pm b/centreon-plugins/network/f5/bigip/snmp/mode/poolstatus.pm index 00cced8e7..91cc81830 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/poolstatus.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/poolstatus.pm @@ -66,6 +66,15 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_threshold_output'), } }, + { label => 'current-server-connections', set => { + key_values => [ { name => 'ltmPoolStatServerCurConns' }, { name => 'Name' } ], + output_template => 'Current Server Connections : %s', output_error_template => "Current Server Connections : %s", + perfdatas => [ + { label => 'current_server_connections', value => 'ltmPoolStatServerCurConns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'Name_absolute' }, + ], + } + }, ]; } @@ -162,45 +171,65 @@ my $mapping = { StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.5.1.2.1.21' }, }, }; -my $oid_ltmPoolStatusEntry = '.1.3.6.1.4.1.3375.2.2.5.5.2.1'; # new -my $oid_ltmPoolEntry = '.1.3.6.1.4.1.3375.2.2.5.1.2.1'; # old +my $mapping2 = { + ltmPoolStatServerCurConns => { oid => '.1.3.6.1.4.1.3375.2.2.5.2.3.1.8' }, +}; sub manage_selection { my ($self, %options) = @_; - - $self->{results} = $options{snmp}->get_multiple_table(oids => [ - { oid => $oid_ltmPoolEntry, start => $mapping->{old}->{AvailState}->{oid} }, - { oid => $oid_ltmPoolStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{new}->{AvailState}->{oid} }, + { oid => $mapping->{old}->{AvailState}->{oid} }, ], , nothing_quit => 1); - my ($branch, $map) = ($oid_ltmPoolStatusEntry, 'new'); - if (!defined($self->{results}->{$oid_ltmPoolStatusEntry}) || scalar(keys %{$self->{results}->{$oid_ltmPoolStatusEntry}}) == 0) { - ($branch, $map) = ($oid_ltmPoolEntry, 'old'); + my ($branch_name, $map) = ($mapping->{new}->{AvailState}->{oid}, 'new'); + if (!defined($snmp_result->{$mapping->{new}->{AvailState}->{oid}}) || scalar(keys %{$snmp_result->{$mapping->{new}->{AvailState}->{oid}}}) == 0) { + ($branch_name, $map) = ($mapping->{old}->{AvailState}->{oid}, 'old'); } $self->{pool} = {}; - foreach my $oid (keys %{$self->{results}->{$branch}}) { - next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); + foreach my $oid (keys %{$snmp_result->{$branch_name}}) { + $oid =~ /^$branch_name\.(.*)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $snmp_result->{$branch_name}, instance => $instance); $result->{Name} = ''; foreach (split /\./, $instance) { $result->{Name} .= chr if ($_ >= 32 && $_ <= 126); } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{Name} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': no matching filter name."); + $self->{output}->output_add(long_msg => "skipping pool '" . $result->{Name} . "'.", debug => 1); next; } - if ($result->{EnabledState} !~ /enabled/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': state is '$result->{EnabledState}'."); - next; - } - $result->{StatusReason} = '-' if (!defined($result->{StatusReason}) || $result->{StatusReason} eq ''); - $self->{pool}->{$instance} = { %$result }; + $self->{pool}->{$instance} = { Name => $result->{Name}, AvailState => $result->{AvailState} }; + } + + $options{snmp}->load(oids => [$mapping->{$map}->{EnabledState}->{oid}, + $mapping->{$map}->{StatusReason}->{oid}, $mapping2->{ltmPoolStatServerCurConns}->{oid} + ], + instances => [keys %{$self->{pool}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{pool}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $snmp_result, instance => $_); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); + + delete $result->{AvailState}; + if ($result->{EnabledState} !~ /enabled/) { + $self->{output}->output_add(long_msg => "skipping '" . $self->{pool}->{$_}->{Name} . "': state is '$result->{EnabledState}'.", debug => 1); + delete $self->{pool}->{$_}; + next; + } + $self->{pool}->{$_}->{ltmPoolStatServerCurConns} = $result2->{ltmPoolStatServerCurConns}; + $result->{StatusReason} = '-' if (!defined($result->{StatusReason}) || $result->{StatusReason} eq ''); + foreach my $name (keys %$result) { + $self->{pool}->{$_}->{$name} = $result->{$name}; + } } if (scalar(keys %{$self->{pool}}) <= 0) { @@ -229,6 +258,16 @@ Set to overload default threshold values (syntax: section,status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='pool,CRITICAL,^(?!(green)$)' +=item B<--warning-*> + +Threshold warning. +Can be: 'current-server-connections'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current-server-connections'. + =back =cut diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm b/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm index 6f578df83..9f915b3e9 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm @@ -90,6 +90,24 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, + { label => 'cpu-1m', set => { + key_values => [ { name => 'sysTmmStatTmUsageRatio1m' }, { name => 'display' } ], + output_template => 'CPU Usage 1min : %s %%', output_error_template => "CPU Usage 1min : %s", + perfdatas => [ + { label => 'cpu_1m', value => 'sysTmmStatTmUsageRatio1m_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-5m', set => { + key_values => [ { name => 'sysTmmStatTmUsageRatio5m' }, { name => 'display' } ], + output_template => 'CPU Usage 5min : %s %%', output_error_template => "CPU Usage 5min : %s", + perfdatas => [ + { label => 'cpu_5m', value => 'sysTmmStatTmUsageRatio5m_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, { label => 'current-client-connections', set => { key_values => [ { name => 'sysTmmStatClientCurConns' }, { name => 'display' } ], output_template => 'Current Client Connections : %s', output_error_template => "Current Client Connections : %s", @@ -157,6 +175,8 @@ my $mapping = { sysTmmStatServerCurConns => { oid => '.1.3.6.1.4.1.3375.2.1.8.2.3.1.19' }, sysTmmStatMemoryTotal => { oid => '.1.3.6.1.4.1.3375.2.1.8.2.3.1.31' }, # B sysTmmStatMemoryUsed => { oid => '.1.3.6.1.4.1.3375.2.1.8.2.3.1.32' }, # B + sysTmmStatTmUsageRatio1m => { oid => '.1.3.6.1.4.1.3375.2.1.8.2.3.1.38' }, + sysTmmStatTmUsageRatio5m => { oid => '.1.3.6.1.4.1.3375.2.1.8.2.3.1.39' }, }; my $oid_sysTmmStatEntry = '.1.3.6.1.4.1.3375.2.1.8.2.3.1'; @@ -221,13 +241,13 @@ Filter by TMM name (regexp can be used). =item B<--warning-*> Threshold warning. -Can be: 'memory-usage' (%), 'total-client-connections', 'current-client-connections', +Can be: 'cpu1m', 'cpu5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', 'total-server-connections', 'current-server-connections'. =item B<--critical-*> Threshold critical. -Can be: 'memory-usage' (%), 'total-client-connections', 'current-client-connections', +Can be: 'cpu1m', 'cpu5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', 'total-server-connections', 'current-server-connections'. =back diff --git a/centreon-plugins/network/fortinet/fortimanager/snmp/mode/cpu.pm b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/cpu.pm new file mode 100644 index 000000000..773b9f7bf --- /dev/null +++ b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/cpu.pm @@ -0,0 +1,99 @@ +# +# 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 network::fortinet::fortimanager::snmp::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{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) = @_; + $self->{snmp} = $options{snmp}; + + my $oid_fmSysCpuUsage = '.1.3.6.1.4.1.12356.103.2.1.1.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_fmSysCpuUsage], nothing_quit => 1); + + my $exit = $self->{perfdata}->threshold_check(value => $result->{$oid_fmSysCpuUsage}, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU Usage : %.2f %%", $result->{$oid_fmSysCpuUsage})); + $self->{output}->perfdata_add(label => "cpu", unit => '%', + value => $result->{$oid_fmSysCpuUsage}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current CPU usage. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/network/fortinet/fortimanager/snmp/mode/devicestatus.pm b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/devicestatus.pm new file mode 100644 index 000000000..732db8654 --- /dev/null +++ b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/devicestatus.pm @@ -0,0 +1,273 @@ +# +# 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 network::fortinet::fortimanager::snmp::mode::devicestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'device', type => 1, cb_prefix_output => 'prefix_device_output', message_multiple => 'All devices are ok' }, + ]; + + $self->{maps_counters}->{device} = [ + { label => 'device-status', threshold => 0, set => { + key_values => [ { name => 'fmDeviceEntState' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'Status', name_status => 'fmDeviceEntState' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'device-connection-status', threshold => 0, set => { + key_values => [ { name => 'fmDeviceEntConnectState' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'Connection Status', name_status => 'fmDeviceEntConnectState' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'device-db-status', threshold => 0, set => { + key_values => [ { name => 'fmDeviceEntDbState' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'DB Status', name_status => 'fmDeviceEntDbState' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'device-config-status', threshold => 0, set => { + key_values => [ { name => 'fmDeviceEntConfigState' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_calc_extra_options => { output_label => 'Configuration Status', name_status => 'fmDeviceEntConfigState' }, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $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 = $self->{result_values}->{output_label} . ' : ' . $self->{result_values}->{status}; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{output_label} = $options{extra_options}->{output_label}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{name_status}}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-device-status:s" => { name => 'warning_device_status', default => '' }, + "critical-device-status:s" => { name => 'critical_device_status', default => '' }, + "warning-device-con-status:s" => { name => 'warning_device_con_status', default => '' }, + "critical-device-con-status:s" => { name => 'critical_device_con_status', default => '%{status} =~ /down/i' }, + "warning-device-db-status:s" => { name => 'warning_device_db_status', default => '' }, + "critical-device-db-status:s" => { name => 'critical_device_db_status', default => '' }, + "warning-device-config-status:s" => { name => 'warning_device_config_status', default => '' }, + "critical-device-config-status:s" => { name => 'critical_device_config_status', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_device_status', 'critical_device_status', 'warning_device_con_status', 'critical_device_con_status', + 'warning_device_db_status', 'critical_device_db_status', 'warning_device_config_status', 'critical_device_config_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub prefix_device_output { + my ($self, %options) = @_; + + return "Device '" . $options{instance_value}->{display} . "' "; +} + +my %map_connection_state = (0 => 'unknown', 1 => 'up', 2 => 'down'); +my %map_db_state = (0 => 'unknown', 1 => 'not-modified', 2 => 'modified'); +my %map_config_state = (0 => 'unknown', 1 => 'in-sync', 2 => 'out-of-sync'); +my %map_device_state = (0 => 'none', 1 => 'unknown', 2 => 'checked-in', 3 => 'in-progress', + 4 => 'installed', 5 => 'aborted', 6 => 'sched', 7 => 'retry', 8 => 'canceled', + 9 => 'pending', 10 => 'retrieved', 11 => 'changed-conf', 12 => 'sync-fail', + 13 => 'timeout', 14 => 'rev-reverted', 15 => 'auto-updated' +); + +my $mapping = { + fmDeviceEntConnectState => { oid => '.1.3.6.1.4.1.12356.103.6.2.1.12', map => \%map_connection_state }, + fmDeviceEntDbState => { oid => '.1.3.6.1.4.1.12356.103.6.2.1.13', map => \%map_db_state }, + fmDeviceEntConfigState => { oid => '.1.3.6.1.4.1.12356.103.6.2.1.14', map => \%map_config_state }, + fmDeviceEntState => { oid => '.1.3.6.1.4.1.12356.103.6.2.1.15', map => \%map_device_state }, +}; + +my $oid_fmDeviceEntName = '.1.3.6.1.4.1.12356.103.6.2.1.2'; +my $oid_fmDeviceEntry = '.1.3.6.1.4.1.12356.103.6.2.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_fmDeviceEntName }, + { oid => $oid_fmDeviceEntry, start => $mapping->{fmDeviceEntConnectState}->{oid}, end => $mapping->{fmDeviceEntState}->{oid} }, + ], + nothing_quit => 1); + $self->{device} = {}; + foreach my $oid (keys %{$snmp_result->{ $oid_fmDeviceEntName }}) { + $oid =~ /^$oid_fmDeviceEntName\.(.*)$/; + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{ $oid_fmDeviceEntry }, instance => $instance); + + my $name = $snmp_result->{ $oid_fmDeviceEntName }->{$oid}; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{device}->{$instance} = { + display => $name, %$result + }; + } + + if (scalar(keys %{$self->{device}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No device found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check device status. + +=over 8 + +=item B<--filter-name> + +Filter by device name (can be a regexp). + +=item B<--warning-device-status> + +Set warning threshold for device status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-device-status> + +Set critical threshold for device status +Can used special variables like: %{status}, %{display} + +=item B<--warning-con-status> + +Set warning threshold for device connection status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-con-status> + +Set critical threshold for device connection status (Default: '%{status} =~ /down/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-db-status> + +Set warning threshold for device DB status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-db-status> + +Set critical threshold for device DB status. +Can used special variables like: %{status}, %{display} + +=item B<--warning-config-status> + +Set warning threshold for device configuration status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-config-status> + +Set critical threshold for device configuration status. +Can used special variables like: %{status}, %{display} + +=back + +=cut diff --git a/centreon-plugins/network/fortinet/fortimanager/snmp/mode/disk.pm b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/disk.pm new file mode 100644 index 000000000..8cde82c53 --- /dev/null +++ b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/disk.pm @@ -0,0 +1,132 @@ +# +# 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 network::fortinet::fortimanager::snmp::mode::disk; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, 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("Disk 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}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_total'} - $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disk', type => 0 } + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + 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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_fmSysDiskCapacity = '.1.3.6.1.4.1.12356.103.2.1.5.0'; # MB + my $oid_fmSysDiskUsage = '.1.3.6.1.4.1.12356.103.2.1.4.0'; # MB + my $result = $options{snmp}->get_leef(oids => [$oid_fmSysDiskCapacity, $oid_fmSysDiskUsage], + nothing_quit => 1); + $self->{disk} = { used => $result->{$oid_fmSysDiskUsage} * 1024 * 1024, total => $result->{$oid_fmSysDiskCapacity} * 1024 * 1024 }; +} + +1; + +__END__ + +=head1 MODE + +Check disk usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut \ No newline at end of file diff --git a/centreon-plugins/network/fortinet/fortimanager/snmp/mode/memory.pm b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/memory.pm new file mode 100644 index 000000000..9c3384d9e --- /dev/null +++ b/centreon-plugins/network/fortinet/fortimanager/snmp/mode/memory.pm @@ -0,0 +1,132 @@ +# +# 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 network::fortinet::fortimanager::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, 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("Memory 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}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_total'} - $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + 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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_fmSysMemCapacity = '.1.3.6.1.4.1.12356.103.2.1.3.0'; # KB + my $oid_fmSysMemUsed = '.1.3.6.1.4.1.12356.103.2.1.2.0'; # KB + my $result = $options{snmp}->get_leef(oids => [$oid_fmSysMemCapacity, $oid_fmSysMemUsed], + nothing_quit => 1); + $self->{memory} = { used => $result->{$oid_fmSysMemUsed} * 1024, total => $result->{$oid_fmSysMemCapacity} * 1024 }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut \ No newline at end of file diff --git a/centreon-plugins/network/fortinet/fortimanager/snmp/plugin.pm b/centreon-plugins/network/fortinet/fortimanager/snmp/plugin.pm new file mode 100644 index 000000000..f7bacad03 --- /dev/null +++ b/centreon-plugins/network/fortinet/fortimanager/snmp/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 network::fortinet::fortimanager::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::fortinet::fortimanager::snmp::mode::cpu', + 'device-status' => 'network::fortinet::fortimanager::snmp::mode::devicestatus', + 'disk' => 'network::fortinet::fortimanager::snmp::mode::disk', + 'memory' => 'network::fortinet::fortimanager::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check FortiManager in SNMP. + +=cut diff --git a/centreon-plugins/network/juniper/mseries/plugin.pm b/centreon-plugins/network/juniper/mseries/plugin.pm index c5dc797af..f046df89f 100644 --- a/centreon-plugins/network/juniper/mseries/plugin.pm +++ b/centreon-plugins/network/juniper/mseries/plugin.pm @@ -49,6 +49,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Juniper M Series in SNMP. +Check Juniper M Series (M and MX) in SNMP. =cut diff --git a/centreon-plugins/os/linux/local/mode/quota.pm b/centreon-plugins/os/linux/local/mode/quota.pm new file mode 100644 index 000000000..8fb9c3460 --- /dev/null +++ b/centreon-plugins/os/linux/local/mode/quota.pm @@ -0,0 +1,301 @@ +# +# 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 os::linux::local::mode::quota; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my ($extra_label, $unit) = ('', ''); + $unit = 'B' if ($self->{result_values}->{label_ref} eq 'data'); + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + $self->{output}->perfdata_add(label => $self->{result_values}->{label_ref} . '_used' . $extra_label, unit => $unit, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{warn_label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{crit_label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used}, + threshold => [ { label => 'critical-' . $self->{result_values}->{crit_label}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{warn_label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $value = $self->{result_values}->{used} . ' files'; + if ($self->{result_values}->{label_ref} eq 'data') { + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + $value = $total_used_value . " " . $total_used_unit; + } + my ($limit_soft, $limit_hard) = ('', ''); + if (defined($self->{result_values}->{warn_limit}) && $self->{result_values}->{warn_limit} > 0) { + $limit_soft = sprintf(" (%.2f %% of soft limit)", $self->{result_values}->{used} * 100 / $self->{result_values}->{warn_limit}); + } + if (defined($self->{result_values}->{crit_limit}) && $self->{result_values}->{crit_limit} > 0) { + $limit_hard = sprintf(" (%.2f %% of hard limit)", $self->{result_values}->{used} * 100 / $self->{result_values}->{crit_limit}); + } + + my $msg = sprintf("%s Used: %s%s%s", + ucfirst($self->{result_values}->{label_ref}), + $value, + $limit_soft, $limit_hard); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{label_ref} = $options{extra_options}->{label_ref}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_used'}; + + $self->{result_values}->{warn_label} = $self->{label}; + if (defined($instance_mode->{option_results}->{'warning-' . $self->{label}}) && $instance_mode->{option_results}->{'warning-' . $self->{label}} ne '') { + $self->{result_values}->{warn_limit} = $instance_mode->{option_results}->{'warning-' . $self->{label}}; + } elsif ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_soft'} > 0) { + $self->{result_values}->{warn_limit} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_soft'}; + $self->{perfdata}->threshold_validate(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display}, value => $self->{result_values}->{warn_limit}); + $self->{result_values}->{warn_label} = $self->{label} . '_' . $self->{result_values}->{display}; + } + + $self->{result_values}->{crit_label} = $self->{label}; + if (defined($instance_mode->{option_results}->{'critical-' . $self->{label}}) && $instance_mode->{option_results}->{'critical-' . $self->{label}} ne '') { + $self->{result_values}->{crit_limit} = $instance_mode->{option_results}->{'critical-' . $self->{label}}; + } elsif ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_hard'} > 0) { + $self->{result_values}->{crit_limit} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_hard'} - 1; + $self->{perfdata}->threshold_validate(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display}, value => $self->{result_values}->{crit_limit}); + $self->{result_values}->{crit_label} = $self->{label} . '_' . $self->{result_values}->{display}; + } + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'quota', type => 1, cb_prefix_output => 'prefix_quota_output', message_multiple => 'All quotas are ok' } + ]; + + $self->{maps_counters}->{quota} = [ + { label => 'data-usage', set => { + key_values => [ { name => 'display' }, { name => 'data_used' }, { name => 'data_soft' }, { name => 'data_hard' } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'data' }, + 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'), + } + }, + { label => 'inode-usage', set => { + key_values => [ { name => 'display' }, { name => 'inode_used' }, { name => 'inode_soft' }, { name => 'inode_hard' } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'inode' }, + 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 prefix_quota_output { + my ($self, %options) = @_; + + return "Quota '" . $options{instance_value}->{display} . "' "; +} + +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 => 'repquota' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-a -i 2>&1' }, + "filter-user:s" => { name => 'filter_user', }, + "filter-fs:s" => { name => 'filter_fs', }, + }); + $self->{result} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout, $exit_code) = 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}, + no_quit => 1 + ); + + #*** Report for user quotas on device /dev/xxxx + #Block grace time: 7days; Inode grace time: 7days + # Block limits File limits + #User used soft hard grace used soft hard grace + #---------------------------------------------------------------------- + #root -- 20779412 0 0 5 0 0 + #apache -- 5721908 0 0 67076 0 0 + + $self->{quota} = {}; + while ($stdout =~ /^\*\*\*.*?(\S+?)\n(.*?)(?=\*\*\*|\z)/msig) { + my ($fs, $data) = ($1, $2); + + while ($data =~ /^(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(.*?)\n/msig) { + my ($user, $grace_on, $data_used, $data_soft, $data_hard, $usage) = ($1, $2, $3 * 1024, $4 * 1024, $5 * 1024, $6); + my @values = split /\s+/, $usage; + + shift @values if ($usage =~ /^\+/); + my ($inode_used, $inode_soft, $inode_hard) = (shift @values, shift @values, shift @values); + + my $name = $user . '.' . $fs; + if (defined($self->{option_results}->{filter_user}) && $self->{option_results}->{filter_user} ne '' && + $user !~ /$self->{option_results}->{filter_user}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_fs}) && $self->{option_results}->{filter_fs} ne '' && + $fs !~ /$self->{option_results}->{filter_fs}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{quota}->{$name} = { display => $name, + data_used => $data_used, data_soft => $data_soft, data_hard => $data_hard, + inode_used => $inode_used, inode_soft => $inode_soft, inode_hard => $inode_hard, + }; + } + } + + if (scalar(keys %{$self->{quota}}) <= 0) { + if ($exit_code != 0) { + $self->{output}->output_add(long_msg => "command output:" . $stdout); + } + $self->{output}->add_option_msg(short_msg => "No quota found (filters or command issue)"); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check quota usage on partitions. + +=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: 'repquota'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-a -i 2>&1'). + +=item B<--warning-*> + +Threshold warning. +Can be: 'inode-usage', 'data-usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'inode-usage', 'data-usage'. + +=item B<--filter-user> + +Filter username (regexp can be used). + +=item B<--filter-fs> + +Filter filesystem (regexp can be used). + +=back + +=cut diff --git a/centreon-plugins/os/linux/local/plugin.pm b/centreon-plugins/os/linux/local/plugin.pm index cdf655a1b..45216bb80 100644 --- a/centreon-plugins/os/linux/local/plugin.pm +++ b/centreon-plugins/os/linux/local/plugin.pm @@ -47,6 +47,7 @@ sub new { 'packet-errors' => 'os::linux::local::mode::packeterrors', 'paging' => 'os::linux::local::mode::paging', 'process' => 'os::linux::local::mode::process', + 'quota' => 'os::linux::local::mode::quota', 'storage' => 'os::linux::local::mode::storage', 'swap' => 'os::linux::local::mode::swap', 'systemd-sc-status' => 'os::linux::local::mode::systemdscstatus', diff --git a/centreon-plugins/storage/hp/eva/cli/custom/api.pm b/centreon-plugins/storage/hp/eva/cli/custom/api.pm new file mode 100644 index 000000000..4cbba0307 --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/custom/api.pm @@ -0,0 +1,211 @@ +# +# 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 storage::hp::eva::cli::custom::api; + +use strict; +use warnings; +use centreon::plugins::misc; +use XML::Simple; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => + { + "manager-hostname:s" => { name => 'manager_hostname' }, + "manager-username:s" => { name => 'manager_username' }, + "manager-password:s" => { name => 'manager_password' }, + "manager-system:s" => { name => 'manager_system' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'sssu_linux_x64' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'SSU CLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + if (!defined($self->{option_results}->{manager_hostname}) || $self->{option_results}->{manager_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set manager-hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{manager_username}) || $self->{option_results}->{manager_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set manager-username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{manager_password})) { + $self->{output}->add_option_msg(short_msg => "Need to set manager-password option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{manager_system}) || $self->{option_results}->{manager_system} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set manager-system option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub ssu_build_options { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + $self->{option_results}->{command_options} = + "'select manager \"$self->{option_results}->{manager_hostname}\" USERNAME=$self->{option_results}->{manager_username} PASSWORD=$self->{option_results}->{manager_password}' 'select system $self->{option_results}->{manager_system}'"; + foreach my $cmd (keys %{$options{commands}}) { + $self->{option_results}->{command_options} .= " '$cmd'"; + } +} + +sub ssu_execute { + my ($self, %options) = @_; + + $self->ssu_build_options(%options); + my ($response) = 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}); + my $xml_root = ''; + while ($response =~ /(.*?<\/object>)/msig) { + $xml_root .= $1; + } + $xml_root .= ''; + + my $xml_result; + eval { + $xml_result = XMLin($xml_root, + ForceArray => ['object', 'diskslot', 'powersupply', 'sensor', 'fan', 'deviceport', + 'module', 'vdcoutput', 'source'], + KeyAttr => [], SuppressEmpty => ''); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(long_msg => $response, debug => 1); + return $xml_result; +} + +1; + +__END__ + +=head1 NAME + +SSU CLI + +=head1 SYNOPSIS + +ssu cli + +=head1 SSU CLI OPTIONS + +=over 8 + +=item B<--manager-hostname> + +Manager hostname to query. + +=item B<--manager-username> + +Manager username. + +=item B<--manager-password> + +Manager password. + +=item B<--manager-system> + +Manager system. + +=item B<--timeout> + +Set timeout (Default: 50). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'sssu_linux_x64'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/battery.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/battery.pm new file mode 100644 index 000000000..6c9f132ad --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/battery.pm @@ -0,0 +1,66 @@ +# +# 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 storage::hp::eva::cli::mode::components::battery; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls controller full xml'} = 1; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking cache batteries"); + $self->{components}->{battery} = {name => 'cache battery', total => 0, skip => 0}; + return if ($self->check_filter(section => 'battery')); + + # + # controller + # \Hardware\Rack 1\Controller Enclosure 7\Controller B + # + # good + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'controller'); + + $object->{objectname} =~ s/\\/\//g; + my $instance = $object->{objectname}; + + next if ($self->check_filter(section => 'battery', instance => $instance)); + + $self->{components}->{battery}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("cache battery '%s' status is '%s' [instance = %s]", + $instance, $object->{cachebattery}->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'battery', value => $object->{cachebattery}->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Cache battery '%s' status is '%s'", $instance, $object->{cachebattery}->{operationalstate})); + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/disk.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/disk.pm new file mode 100644 index 000000000..da6549c0e --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/disk.pm @@ -0,0 +1,65 @@ +# +# 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 storage::hp::eva::cli::mode::components::disk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls disk full xml'} = 1; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'disk')); + + # + # disk + # \Disk Groups\Ungrouped Disks\Disk 133 + # good + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'disk'); + + $object->{objectname} =~ s/\\/\//g; + my $instance = $object->{objectname}; + + next if ($self->check_filter(section => 'disk', instance => $instance)); + + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("disk '%s' status is '%s' [instance = %s]", + $instance, $object->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'disk', value => $object->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", $instance, $object->{operationalstate})); + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/diskgrp.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/diskgrp.pm new file mode 100644 index 000000000..95794760b --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/diskgrp.pm @@ -0,0 +1,65 @@ +# +# 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 storage::hp::eva::cli::mode::components::diskgrp; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls disk_group full xml'} = 1; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disk groups"); + $self->{components}->{diskgrp} = {name => 'disk groups', total => 0, skip => 0}; + return if ($self->check_filter(section => 'diskgrp')); + + # + # diskgroupfolder + # \Disk Groups\XXX + # good + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'diskgroupfolder'); + + $object->{objectname} =~ s/\\/\//g; + my $instance = $object->{objectname}; + + next if ($self->check_filter(section => 'diskgrp', instance => $instance)); + + $self->{components}->{diskgrp}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("disk group '%s' status is '%s' [instance = %s]", + $instance, $object->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'diskgrp', value => $object->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk group '%s' status is '%s'", $instance, $object->{operationalstate})); + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/fan.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/fan.pm new file mode 100644 index 000000000..9ae236d1f --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/fan.pm @@ -0,0 +1,135 @@ +# +# 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 storage::hp::eva::cli::mode::components::fan; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls diskshelf full xml'} = 1; + $self->{ssu_commands}->{'ls controller full xml'} = 1; +} + +sub fan_ctrl { + my ($self) = @_; + + # + # controller + # \Hardware\Rack 1\Controller Enclosure 7\Controller B + # + # + # fan0 + # normal + # 2240 + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'controller'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{fans}->{fan}}) { + my $instance = $object->{objectname} . '/' . $result->{fanname}; + + next if ($self->check_filter(section => 'fan', instance => $instance)); + next if ($result->{status} =~ /notinstalled/i && + $self->absent_problem(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s] [value = %s]", + $instance, $result->{status}, $instance, + $result->{speed})); + + my $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' status is '%s'", $instance, $result->{status})); + } + + next if ($result->{speed} !~ /[0-9]/); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{speed}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fan '%s' is %s rpm", $instance, $result->{speed})); + } + $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', + value => $result->{speed}, + warning => $warn, + critical => $crit, + min => 0 + ); + } + } +} + +sub fan_diskshelf { + my ($self) = @_; + + # + # diskshelf + # \Hardware\Rack 1\Disk Enclosure 3 + # + # + # + # fan1 + # good + # No + # speed_1_lowest + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'diskshelf'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{cooling}->{fans}->{fan}}) { + my $instance = $object->{objectname} . '/' . $result->{name}; + + next if ($self->check_filter(section => 'fan', instance => $instance)); + next if ($result->{operationalstate} =~ /notinstalled/i && + $self->absent_problem(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s]", + $instance, $result->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' status is '%s'", $instance, $result->{operationalstate})); + } + } + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + fan_ctrl($self); + fan_diskshelf($self); +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/iomodule.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/iomodule.pm new file mode 100644 index 000000000..2b744a876 --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/iomodule.pm @@ -0,0 +1,72 @@ +# +# 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 storage::hp::eva::cli::mode::components::iomodule; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls diskshelf full xml'} = 1; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking IO modules"); + $self->{components}->{iomodule} = {name => 'io modules', total => 0, skip => 0}; + return if ($self->check_filter(section => 'iomodule')); + + # + # diskshelf + # \Hardware\Rack 1\Disk Enclosure 3 + # + # + # + # modulea + # good + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'diskshelf'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{iocomm}->{iomodules}->{module}}) { + next if ($result->{name} eq ''); + my $instance = $object->{objectname} . '/' . $result->{name}; + + next if ($self->check_filter(section => 'iomodule', instance => $instance)); + + $self->{components}->{iomodule}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("IO module '%s' status is '%s' [instance = %s]", + $instance, $object->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'iomodule', value => $object->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("IO module '%s' status is '%s'", $instance, $object->{operationalstate})); + } + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/psu.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/psu.pm new file mode 100644 index 000000000..7afef9270 --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/psu.pm @@ -0,0 +1,146 @@ +# +# 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 storage::hp::eva::cli::mode::components::psu; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls diskshelf full xml'} = 1; + $self->{ssu_commands}->{'ls controller full xml'} = 1; +} + +sub psu_ctrl { + my ($self) = @_; + + # + # controller + # \Hardware\Rack 1\Controller Enclosure 7\Controller B + # + # 12.32 + # + # powersupply0 + # good + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'controller'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{powersources}->{source}}) { + next if ($result->{type} eq ''); + my $instance = $object->{objectname} . '/' . $result->{type}; + + next if ($self->check_filter(section => 'psu', instance => $instance)); + next if ($result->{state} =~ /notinstalled/i && + $self->absent_problem(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $instance, $result->{state}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{state}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $instance, $result->{state})); + } + } + } +} + +sub psu_diskshelf { + my ($self) = @_; + + # + # diskshelf + # \Hardware\Rack 1\Disk Enclosure 3 + # + # + # powersupply1 + # good + # No + # + # + # vdc5output + # 5.5 + # 6.7 + # + # + # vdc12output + # 12.5 + # 4.1 + # + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'diskshelf'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{powersupplies}->{powersupply}}) { + my $instance = $object->{objectname} . '/' . $result->{name}; + + next if ($self->check_filter(section => 'psu', instance => $instance)); + next if ($result->{operationalstate} =~ /notinstalled/i && + $self->absent_problem(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power suuply '%s' status is '%s' [instance = %s]", + $instance, $result->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $instance, $result->{operationalstate})); + } + + foreach my $voltage (@{$result->{vdcoutputs}->{vdcoutput}}) { + next if ($voltage->{current} !~ /[0-9]/); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'psu', instance => $instance . '/' . $voltage->{type}, value => $voltage->{current}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Power supply '%s' is %s V", $instance, $voltage->{current})); + } + $self->{output}->perfdata_add(label => 'voltage_' . $instance . '/' . $voltage->{type}, unit => 'V', + value => $voltage->{current}, + warning => $warn, + critical => $crit, + ); + } + } + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + psu_ctrl($self); + psu_diskshelf($self); +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/system.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/system.pm new file mode 100644 index 000000000..2d9b368c8 --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/system.pm @@ -0,0 +1,65 @@ +# +# 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 storage::hp::eva::cli::mode::components::system; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls system full xml'} = 1; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking systems"); + $self->{components}->{system} = {name => 'systems', total => 0, skip => 0}; + return if ($self->check_filter(section => 'system')); + + # + # storagecell + # XXXXX + # attention + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'storagecell'); + + $object->{objectname} =~ s/\\/\//g; + my $instance = $object->{objectname}; + + next if ($self->check_filter(section => 'system', instance => $instance)); + + $self->{components}->{system}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("system '%s' status is '%s' [instance = %s]", + $instance, $object->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'system', value => $object->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("System '%s' status is '%s'", $instance, $object->{operationalstate})); + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/components/temperature.pm b/centreon-plugins/storage/hp/eva/cli/mode/components/temperature.pm new file mode 100644 index 000000000..29ed9cafc --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/components/temperature.pm @@ -0,0 +1,141 @@ +# +# 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 storage::hp::eva::cli::mode::components::temperature; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssu_commands}->{'ls diskshelf full xml'} = 1; + $self->{ssu_commands}->{'ls controller full xml'} = 1; +} + +sub temp_ctrl { + my ($self) = @_; + + # + # controller + # \Hardware\Rack 1\Controller Enclosure 7\Controller B + # + # + # i2csensor1 + # 28 + # 82 + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'controller'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{sensors}->{sensor}}) { + next if ($result->{name} eq ''); + my $instance = $object->{objectname} . '/' . $result->{name}; + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %s C [instance = %s]", + $instance, $result->{tempc}, $instance, + )); + + next if ($result->{tempc} !~ /[0-9]/); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{tempc}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is %s C", $instance, $result->{tempc})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $instance, unit => 'C', + value => $result->{tempc}, + warning => $warn, + critical => $crit, + ); + } + } +} + +sub temp_diskshelf { + my ($self) = @_; + + # + # diskshelf + # \Hardware\Rack 1\Disk Enclosure 3 + # + # + # + # ps1 + # 91.4 + # 33.0 + # good + # no_alarm + # + foreach my $object (@{$self->{xml_result}->{object}}) { + next if ($object->{objecttype} ne 'diskshelf'); + + $object->{objectname} =~ s/\\/\//g; + foreach my $result (@{$object->{cooling}->{sensors}->{sensor}}) { + next if ($result->{name} eq ''); + my $instance = $object->{objectname} . '/' . $result->{name}; + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + next if ($result->{operationalstate} =~ /notinstalled/i && + $self->absent_problem(section => 'temperature', instance => $instance)); + + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s]", + $instance, $result->{operationalstate}, $instance, + )); + + my $exit = $self->get_severity(label => 'default', section => 'temperature', value => $result->{operationalstate}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $instance, $result->{operationalstate})); + } + + next if ($result->{tempc} !~ /[0-9]/); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{tempc}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Temperature '%s' is %s C", $instance, $result->{tempc})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $instance, unit => 'C', + value => $result->{tempc}, + warning => $warn, + critical => $crit, + ); + } + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + temp_ctrl($self); + temp_diskshelf($self); +} + +1; diff --git a/centreon-plugins/storage/hp/eva/cli/mode/hardware.pm b/centreon-plugins/storage/hp/eva/cli/mode/hardware.pm new file mode 100644 index 000000000..b84a3526c --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/hardware.pm @@ -0,0 +1,120 @@ +# +# 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 storage::hp::eva::cli::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = + '^(fan|temperature|system|disk|diskgrp|psu|battery|iomodule)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(fan|temperature|psu)$'; + + $self->{cb_hook2} = 'api_execute'; + + $self->{thresholds} = { + default => [ + ['^good$', 'OK'], + ['notinstalled', 'OK'], + ['^normal$', 'OK'], + ['unsupported', 'OK'], + ['attention', 'WARNING'], + ['.*', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'storage::hp::eva::cli::mode::components'; + $self->{components_module} = ['fan', 'temperature', 'system', 'disk', 'diskgrp', 'psu', 'battery', 'iomodule']; +} + +sub api_execute { + my ($self, %options) = @_; + + $self->{xml_result} = $options{custom}->ssu_execute(commands => $self->{ssu_commands}); +} + +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 => + { + }); + + $self->{ssu_commands} = {}; + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'fan'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=temperature --filter=fan) +Can also exclude specific instance: --filter="fan,Fan Block 1" + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) +Can be specific or global: --absent-problem="fan,Fan Block 1" + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='fan,OK,degraded' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/storage/hp/eva/cli/mode/storageusage.pm b/centreon-plugins/storage/hp/eva/cli/mode/storageusage.pm new file mode 100644 index 000000000..ac64dfbe2 --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/mode/storageusage.pm @@ -0,0 +1,178 @@ +# +# 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 storage::hp::eva::cli::mode::storageusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'storage', type => 0 }, + ]; + $self->{maps_counters}->{storage} = [ + { label => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ], + 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'), + } + }, + ]; +} + +my $instance_mode; + +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 %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, 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("Storage '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $self->{result_values}->{display}, + $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}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $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 new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{xml_result} = $options{custom}->ssu_execute(commands => { 'ls system full xml' => 1 }); + + # + # XXXX + # 30168.18 + # 27935.14 + + foreach (@{$self->{xml_result}->{object}}) { + $self->{storage} = { display => $_->{objectname}, + used => $_->{usedstoragespace} * 1024 * 1024 * 1024, total => $_->{totalstoragespace} * 1024 * 1024 * 1024 + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check storage usage. + +=over 8 + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/storage/hp/eva/cli/plugin.pm b/centreon-plugins/storage/hp/eva/cli/plugin.pm new file mode 100644 index 000000000..c193eeebf --- /dev/null +++ b/centreon-plugins/storage/hp/eva/cli/plugin.pm @@ -0,0 +1,54 @@ +# +# 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 storage::hp::eva::cli::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'hardware' => 'storage::hp::eva::cli::mode::hardware', + 'storage-usage' => 'storage::hp::eva::cli::mode::storageusage', + ); + $self->{custom_modes}{api} = 'storage::hp::eva::cli::custom::api'; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check HP EVA Storage. + +=over 8 + +=back + +=cut diff --git a/centreon-plugins/storage/hp/lefthand/snmp/mode/volumeusage.pm b/centreon-plugins/storage/hp/lefthand/snmp/mode/volumeusage.pm index a61f6604b..d30473a7c 100644 --- a/centreon-plugins/storage/hp/lefthand/snmp/mode/volumeusage.pm +++ b/centreon-plugins/storage/hp/lefthand/snmp/mode/volumeusage.pm @@ -37,11 +37,11 @@ sub custom_status_threshold { 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}") { + if (defined($instance_mode->{option_results}->{critical_replication_status}) && $instance_mode->{option_results}->{critical_replication_status} ne '' && + eval "$instance_mode->{option_results}->{critical_replication_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}") { + } elsif (defined($instance_mode->{option_results}->{warning_replication_status}) && $instance_mode->{option_results}->{warning_replication_status} ne '' && + eval "$instance_mode->{option_results}->{warning_replication_status}") { $status = 'warning'; } }; diff --git a/centreon-plugins/storage/ibm/ts2900/snmp/mode/hardware.pm b/centreon-plugins/storage/ibm/ts2900/snmp/mode/hardware.pm new file mode 100644 index 000000000..73cf94fd9 --- /dev/null +++ b/centreon-plugins/storage/ibm/ts2900/snmp/mode/hardware.pm @@ -0,0 +1,220 @@ +# +# 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 storage::ibm::ts2900::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(cpu|temperature|psu|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['unknown', 'UNKNOWN'], + ['ok', 'OK'], + ['warning', 'WARNING'], + ['failed', 'CRITICAL'], + ['needClean', 'WARNING'], # for drive only + ], + }; + + $self->{components_path} = 'storage::ibm::ts2900::snmp::mode::components'; + $self->{components_module} = ['robot', 'drive', 'ctrl', 'ctrlpower', 'magazine']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + my $oid_contStatusEntry = '.1.3.6.1.4.1.2.6.219.2.2.1.1'; + my $oid_drvStatusEntry = '.1.3.6.1.4.1.2.6.219.2.2.2.1'; + $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_contStatusEntry }, { oid => $oid_drvStatusEntry } ], return_type => 1); +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'robot', 'drive', 'ctrl', 'ctrlpower', 'magazine'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=ctrl,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='drive,OK,needClean' + +=back + +=cut + +package storage::ibm::ts2900::snmp::mode::components::common; + +my %map_default_status = (1 => 'unknown', 2 => 'ok', 3 => 'warning', 4 => 'failed'); + +sub check { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => "Checking " . $options{description}); + $self->{components}->{$options{section}} = {name => $options{section}, total => 0, skip => 0}; + return if ($self->check_filter(section => $options{section})); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}, instance => $instance); + + next if ($self->check_filter(section => $options{section}, instance => $instance)); + + $self->{components}->{$options{section}}->{total}++; + $self->{output}->output_add(long_msg => sprintf("%s '%s' status is '%s' [instance = %s]", + $options{description}, $instance, $result->{$options{status}}, $instance)); + my $exit = $self->get_severity(label => 'default', section => $options{section}, value => $result->{$options{status}}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%s '%s' status is '%s'", $options{description}, $instance, $result->{$options{status}})); + } + } +} + +package storage::ibm::ts2900::snmp::mode::components::robot; + +use strict; +use warnings; + +my $mapping_robot = { + robotStatus => { oid => '.1.3.6.1.4.1.2.6.219.2.2.1.1.6', map => \%map_default_status }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + storage::ibm::ts2900::snmp::mode::components::common::check($self, + section => 'robot', mapping => $mapping_robot, description => 'robot', status => 'robotStatus'); +} + +package storage::ibm::ts2900::snmp::mode::components::ctrl; + +use strict; +use warnings; + +my $mapping_ctrl = { + contState => { oid => '.1.3.6.1.4.1.2.6.219.2.2.1.1.7', map => \%map_default_status }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + storage::ibm::ts2900::snmp::mode::components::common::check($self, + section => 'ctrl', mapping => $mapping_ctrl, description => 'controller', status => 'contState'); +} + +package storage::ibm::ts2900::snmp::mode::components::ctrlpower; + +use strict; +use warnings; + +my $mapping_ctrlpower = { + contPowerStatus => { oid => '.1.3.6.1.4.1.2.6.219.2.2.1.1.2', map => \%map_default_status }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + storage::ibm::ts2900::snmp::mode::components::common::check($self, + section => 'ctrlpower', mapping => $mapping_ctrlpower, description => 'controller power', status => 'contPowerStatus'); +} + +package storage::ibm::ts2900::snmp::mode::components::magazine; + +use strict; +use warnings; + +my $mapping_magazine = { + magStatus => { oid => '.1.3.6.1.4.1.2.6.219.2.2.1.1.4', map => \%map_default_status }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + storage::ibm::ts2900::snmp::mode::components::common::check($self, + section => 'magazine', mapping => $mapping_magazine, description => 'magazine', status => 'magStatus'); +} + +package storage::ibm::ts2900::snmp::mode::components::drive; + +use strict; +use warnings; + +my %map_drive_status = (1 => 'unknown', 2 => 'ok', 3 => 'needClean', 4 => 'warning', 5 => 'failed'); + +my $mapping_drive = { + driveStatus => { oid => '.1.3.6.1.4.1.2.6.219.2.2.2.1.3', map => \%map_drive_status }, +}; + +sub load {} + +sub check { + my ($self) = @_; + + storage::ibm::ts2900::snmp::mode::components::common::check($self, + section => 'drive', mapping => $mapping_drive, description => 'drive', status => 'driveStatus'); +} diff --git a/centreon-plugins/storage/ibm/ts2900/snmp/plugin.pm b/centreon-plugins/storage/ibm/ts2900/snmp/plugin.pm new file mode 100644 index 000000000..58fdf9f77 --- /dev/null +++ b/centreon-plugins/storage/ibm/ts2900/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 storage::ibm::ts2900::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'storage::ibm::ts2900::snmp::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM TS2900 in SNMP. + +=cut diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/components/disk.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/components/disk.pm new file mode 100644 index 000000000..3bf490762 --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/components/disk.pm @@ -0,0 +1,80 @@ +# +# 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 storage::qsan::nas::snmp::mode::components::disk; + +use strict; +use warnings; + +my $mapping = { + pd_location => { oid => '.1.3.6.1.4.1.22274.2.2.1.1.1' }, + pd_status_health => { oid => '.1.3.6.1.4.1.22274.2.2.1.1.3' }, + hdd_temperature => { oid => '.1.3.6.1.4.1.22274.2.3.4.1.4' }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{pd_location}->{oid} }, + { oid => $mapping->{pd_status_health}->{oid} }, { oid => $mapping->{hdd_temperature}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'disk')); + + my $results = { %{$self->{results}->{$mapping->{pd_location}->{oid}}}, %{$self->{results}->{$mapping->{pd_status_health}->{oid}}}, + %{$self->{results}->{$mapping->{hdd_temperature}->{oid}}}}; + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{pd_status_health}->{oid}}})) { + $oid =~ /^$mapping->{pd_status_health}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + next if ($self->check_filter(section => 'disk', instance => $instance)); + + $self->{components}->{disk}->{total}++; + $self->{output}->output_add(long_msg => sprintf("disk '%s' status is '%s' [instance = %s, temperature = %s]", + $result->{pd_location}, $result->{pd_status_health}, $instance, $result->{hdd_temperature})); + $exit = $self->get_severity(section => 'disk', value => $result->{pd_status_health}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", $result->{pd_location}, $result->{pd_status_health})); + } + + next if (!defined($result->{hdd_temperature}) || $result->{hdd_temperature} !~ /[0-9]/); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'disk.temperature', instance => $instance, value => $result->{hdd_temperature}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' is '%s' C", $result->{pd_location}, $result->{hdd_temperature})); + } + $self->{output}->perfdata_add(label => 'disk_temperature_' . $result->{pd_location}, unit => 'C', + value => $result->{hdd_temperature}, + warning => $warn, + critical => $crit + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/components/fan.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/components/fan.pm new file mode 100644 index 000000000..f6402ee30 --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/components/fan.pm @@ -0,0 +1,79 @@ +# +# 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 storage::qsan::nas::snmp::mode::components::fan; + +use strict; +use warnings; + +my $mapping = { + ems_type => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.2' }, + ems_item => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.3' }, + ems_value => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.4' }, + ems_status => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.5' }, +}; +my $oid_monitorEntry = '.1.3.6.1.4.1.22274.2.3.2.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_monitorEntry}})) { + next if ($oid !~ /^$mapping->{ems_type}->{oid}\.(.*)$/); + my $instance = $1; + next if ($self->{results}->{$oid_monitorEntry}->{$oid} !~ /Cooling/i); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_monitorEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + #3443 RPM + my $value = '-'; + $value = $1 if (defined($result->{ems_value}) && $result->{ems_value} =~ /^(\S+)\s+RPM/); + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, value = %s]", + $result->{ems_item}, $result->{ems_status}, $instance, $value)); + $exit = $self->get_severity(label => 'monitor', section => 'fan', value => $result->{ems_status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("fan '%s' status is '%s'", $result->{ems_item}, $result->{ems_status})); + } + + next if ($value !~ /[0-9]/); + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $value); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("fan '%s' is '%s' rpm", $result->{ems_item}, $value)); + } + $self->{output}->perfdata_add(label => 'fan_' . $result->{ems_item} . '_' . $instance, unit => 'rpm', + value => $value, + warning => $warn, + critical => $crit, min => 0 + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/components/psu.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/components/psu.pm new file mode 100644 index 000000000..b8f0c663f --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/components/psu.pm @@ -0,0 +1,64 @@ +# +# 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 storage::qsan::nas::snmp::mode::components::psu; + +use strict; +use warnings; + +my $mapping = { + ems_type => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.2' }, + ems_item => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.3' }, + ems_value => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.4' }, + ems_status => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.5' }, +}; +my $oid_monitorEntry = '.1.3.6.1.4.1.22274.2.3.2.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_monitorEntry}})) { + next if ($oid !~ /^$mapping->{ems_type}->{oid}\.(.*)$/); + my $instance = $1; + next if ($self->{results}->{$oid_monitorEntry}->{$oid} !~ /Power Supply/i); + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_monitorEntry}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s, value = %s]", + $result->{ems_item}, $result->{ems_status}, $instance, $result->{ems_value})); + $exit = $self->get_severity(label => 'monitor', section => 'psu', value => $result->{ems_status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("power supply '%s' status is '%s'", $result->{ems_item}, $result->{ems_status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/components/temperature.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..73ca93f44 --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/components/temperature.pm @@ -0,0 +1,79 @@ +# +# 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 storage::qsan::nas::snmp::mode::components::temperature; + +use strict; +use warnings; + +my $mapping = { + ems_type => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.2' }, + ems_item => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.3' }, + ems_value => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.4' }, + ems_status => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.5' }, +}; +my $oid_monitorEntry = '.1.3.6.1.4.1.22274.2.3.2.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_monitorEntry}})) { + next if ($oid !~ /^$mapping->{ems_type}->{oid}\.(.*)$/); + my $instance = $1; + next if ($self->{results}->{$oid_monitorEntry}->{$oid} !~ /Temperature/i); + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_monitorEntry}, instance => $instance); + next if ($self->check_filter(section => 'temperature', instance => $instance)); + + # +72.0 (C) (hyst = +5.0 (C), high = +90.0 (C)) + my $value = '-'; + $value = sprintf("%.2f", $1) if (defined($result->{ems_value}) && $result->{ems_value} =~ /^(\S+)\s+\(C\)/); + + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, value = %s]", + $result->{ems_item}, $result->{ems_status}, $instance, $value)); + $exit = $self->get_severity(label => 'monitor', section => 'temperature', value => $result->{ems_status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $result->{ems_item}, $result->{ems_status})); + } + + next if ($value !~ /[0-9]/); + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $value); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is '%s' C", $result->{ems_item}, $value)); + } + $self->{output}->perfdata_add(label => 'temperature_' . $result->{ems_item} . '_' . $instance, unit => 'C', + value => $value, + warning => $warn, + critical => $crit + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/components/voltage.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..042cfe84a --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/components/voltage.pm @@ -0,0 +1,79 @@ +# +# 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 storage::qsan::nas::snmp::mode::components::voltage; + +use strict; +use warnings; + +my $mapping = { + ems_type => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.2' }, + ems_item => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.3' }, + ems_value => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.4' }, + ems_status => { oid => '.1.3.6.1.4.1.22274.2.3.2.1.5' }, +}; +my $oid_monitorEntry = '.1.3.6.1.4.1.22274.2.3.2.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_monitorEntry}})) { + next if ($oid !~ /^$mapping->{ems_type}->{oid}\.(.*)$/); + my $instance = $1; + next if ($self->{results}->{$oid_monitorEntry}->{$oid} !~ /Voltage/i); + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_monitorEntry}, instance => $instance); + next if ($self->check_filter(section => 'voltage', instance => $instance)); + + #+0.99 V (min = +0.75 V, max = +1.35 V) + my $value = '-'; + $value = sprintf("%.2f", $1) if (defined($result->{ems_value}) && $result->{ems_value} =~ /^(\S+)\s+V/); + + $self->{components}->{voltage}->{total}++; + $self->{output}->output_add(long_msg => sprintf("voltage '%s' status is '%s' [instance = %s, value = %s]", + $result->{ems_item}, $result->{ems_status}, $instance, $value)); + $exit = $self->get_severity(label => 'monitor', section => 'voltage', value => $result->{ems_status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("voltage '%s' status is '%s'", $result->{ems_item}, $result->{ems_status})); + } + + next if ($value !~ /[0-9]/); + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $value); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("voltage '%s' is '%s' V", $result->{ems_item}, $value)); + } + $self->{output}->perfdata_add(label => 'voltage_' . $result->{ems_item} . '_' . $instance, unit => 'V', + value => $value, + warning => $warn, + critical => $crit + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/qsan/nas/snmp/mode/hardware.pm b/centreon-plugins/storage/qsan/nas/snmp/mode/hardware.pm new file mode 100644 index 000000000..577343d44 --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/mode/hardware.pm @@ -0,0 +1,117 @@ +# +# 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 storage::qsan::nas::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(disk|voltage|temperature|psu|fan)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|disk.temperature|voltage|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + disk => [ + ['reserved', 'OK'], + ['good', 'OK'], + ['.*', 'CRITICAL'], + ], + monitor => [ + ['OK', 'OK'], + ['.*', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'storage::qsan::nas::snmp::mode::components'; + $self->{components_module} = ['disk', 'voltage', 'temperature', 'psu', 'fan']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + my $oid_monitorEntry = '.1.3.6.1.4.1.22274.2.3.2.1'; + push @{$self->{request}}, { oid => $oid_monitorEntry }; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'disk', 'voltage', 'temperature', 'psu', 'fan' + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=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='psu,WARNING,^(?!(OK)$)' + +=item B<--warning> + +Set warning threshold for 'temperature', 'disk.temperature', 'voltage', 'fan' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature', 'disk.temperature', 'voltage', 'fan' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/storage/qsan/nas/snmp/plugin.pm b/centreon-plugins/storage/qsan/nas/snmp/plugin.pm new file mode 100644 index 000000000..768172631 --- /dev/null +++ b/centreon-plugins/storage/qsan/nas/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# 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 storage::qsan::nas::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'storage::qsan::nas::snmp::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check QSan NAS in SNMP. + +=cut