diff --git a/centreon-plugins/centreon/plugins/backend/http/curl.pm b/centreon-plugins/centreon/plugins/backend/http/curl.pm index 21297973c..dfc658c7a 100644 --- a/centreon-plugins/centreon/plugins/backend/http/curl.pm +++ b/centreon-plugins/centreon/plugins/backend/http/curl.pm @@ -194,7 +194,9 @@ sub set_auth { $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_BASIC')); } elsif (defined($options{request}->{ntlmv2})) { $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_NTLM')); - } else { + } if (defined($options{request}->{digest})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_DIGEST')); + }else { $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_ANY')); } $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_USERPWD'), parameter => $options{request}->{username} . ':' . $options{request}->{password}); diff --git a/centreon-plugins/centreon/plugins/backend/http/lwp.pm b/centreon-plugins/centreon/plugins/backend/http/lwp.pm index 661e9e047..285b7a3cc 100644 --- a/centreon-plugins/centreon/plugins/backend/http/lwp.pm +++ b/centreon-plugins/centreon/plugins/backend/http/lwp.pm @@ -236,7 +236,7 @@ sub request { Authen::NTLM::ntlmv2(1); } - if (defined($request_options->{credentials}) && defined($request_options->{basic})) { + if (defined($request_options->{credentials}) && (defined($request_options->{basic}) || defined($request_options->{digest}))) { $req->authorization_basic($request_options->{username}, $request_options->{password}); } diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/custom/api.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/custom/api.pm new file mode 100644 index 000000000..177160b23 --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/custom/api.pm @@ -0,0 +1,208 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use XML::LibXML::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 => { + 'api-username:s' => { name => 'api_username' }, + 'api-password:s' => { name => 'api_password' }, + 'hostname:s' => { name => 'hostname' }, + 'port:s' => { name => 'port' }, + 'proto:s' => { name => 'proto' }, + 'timeout:s' => { name => 'timeout' }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http_status' } + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'ISAPI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 50; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; + $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; + $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + + if ($self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if ($self->{api_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-username option."); + $self->{output}->option_exit(); + } + if ($self->{api_password} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-password option."); + $self->{output}->option_exit(); + } + + return 0; +} + +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}->{timeout} = $self->{timeout}; + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{digest} = 1; + $self->{option_results}->{username} = $self->{api_username}; + $self->{option_results}->{password} = $self->{api_password}; +} + +sub settings { + my ($self, %options) = @_; + + return if (defined($self->{settings_done})); + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); + $self->{settings_done} = 1; +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{port}; +} + +sub request_api { + my ($self, %options) = @_; + + $self->settings(); + my $content = $self->{http}->request( + url_path => $options{endpoint}, + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status} + ); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $xml_result; + eval { + $SIG{__WARN__} = sub {}; + $xml_result = XMLin($content, ForceArray => $options{force_array}, KeyAttr => []); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); + $self->{output}->option_exit(); + } + + return $xml_result; +} + +1; + +__END__ + +=head1 NAME + +Hikvision ISAPI + +=head1 ISAPI OPTIONS + +Hikvision ISAPI + +=over 8 + +=item B<--hostname> + +Set hostname. + +=item B<--port> + +Port used (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-username> + +API username. + +=item B<--api-password> + +API password. + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/cpu.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/cpu.pm new file mode 100644 index 000000000..88648e56e --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/cpu.pm @@ -0,0 +1,84 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and alarm 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::hikvision::nvr::isapi::mode::cpu; + +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, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'cpu-utilization', nlabel => 'cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu_util' } ], + output_template => 'Cpu utilization: %.2f%%', + perfdatas => [ + { template => '%s', min => 0, max => 100, unit => '%' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/System/status'); + if (!defined($result->{CPUList}->{CPU}->{cpuUtilization})) { + $self->{output}->add_option_msg(short_msg => "Cannot find cpu informations"); + $self->{output}->option_exit(); + } + + $self->{global} = { cpu_util => $result->{CPUList}->{CPU}->{cpuUtilization} }; +}; + +1; + +__END__ + +=head1 MODE + +Check cpu. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'cpu-utilization' (%). + +=back diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/device.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/device.pm new file mode 100644 index 000000000..4cb4a4985 --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/device.pm @@ -0,0 +1,74 @@ +# +# Copyright 2022 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and alarm 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::hikvision::nvr::isapi::mode::device; + +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; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/System/deviceInfo'); + + my $model = defined($result->{model}) ? $result->{model} : 'unknown'; + my $serial = defined($result->{serialNumber}) ? $result->{serialNumber} : 'unknown'; + my $firmware = defined($result->{firmwareVersion}) ? $result->{firmwareVersion} : 'unknown'; + + $self->{output}->output_add( + short_msg => sprintf( + 'Model: %s, Serial: %s, Firmware: %s', + $model, + $serial, + $firmware + ) + );; + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +}; + +1; + +__END__ + +=head1 MODE + +Display device information. + +=over 8 + +=back diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/disks.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/disks.pm new file mode 100644 index 000000000..3b4791125 --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/disks.pm @@ -0,0 +1,214 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::mode::disks; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_space_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}); + return sprintf( + 'space 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} + ); +} + +sub disk_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking disk '%s'", + $options{instance} + ); +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return sprintf( + "disk '%s' ", + $options{instance} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disks', type => 3, cb_prefix_output => 'prefix_disk_output', cb_long_output => 'disk_long_output', + indent_long_output => ' ', message_multiple => 'All disks are ok', + group => [ + { name => 'status', type => 0, skipped_code => { -10 => 1 } }, + { name => 'space', type => 0, skipped_code => { -10 => 1 } }, + { name => 'temperature', type => 0, skipped_code => { -10 => 1 } } + ] + } + ]; + + # status: ok,unformatted,error,idle,mismatch,offline,smartFailed,reparing,formating,notexist,unRecordHostFormatted + $self->{maps_counters}->{status} = [ + { + label => 'status', + type => 2, + warning_default => '%{status} =~ /reparing/i', + critical_default => '%{status} =~ /error|smartFailed/i', + set => { + key_values => [ { name => 'status' }, { name => 'name' } ], + output_template => 'status: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{space} = [ + { label => 'space-usage', nlabel => 'disk.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'space-usage-free', nlabel => 'disk.space.free.bytes', display_ok => 0, set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'space-usage-prct', nlabel => 'disk.space.usage.percentage', display_ok => 0, set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1 } + ] + } + } + ]; + + $self->{maps_counters}->{temperature} = [ + { label => 'temperature', nlabel => 'disk.temperature.celsius', set => { + key_values => [ { name => 'value' } ], + output_template => 'temperature: %s C', + perfdatas => [ + { template => '%s', unit => 'C', label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/ContentMgmt/Storage/hdd', force_array => ['hdd']); + if (!defined($result->{hdd})) { + $self->{output}->add_option_msg(short_msg => "Cannot find disk informations"); + $self->{output}->option_exit(); + } + + $self->{disks} = {}; + foreach my $hdd (@{$result->{hdd}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $hdd->{hddName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping disk '" . $hdd->{hddName} . "'.", debug => 1); + next; + } + + $hdd->{capacity} *= 1024 * 1024; + $hdd->{freeSpace} *= 1024 * 1024; + $self->{disks}->{ $hdd->{hddName} } = { + status => { name => $hdd->{hddName}, status => $hdd->{status} }, + space => { + total => $hdd->{capacity}, + used => $hdd->{capacity} - $hdd->{freeSpace}, + free => $hdd->{freeSpace}, + prct_used => 100 - ($hdd->{freeSpace} * 100 / $hdd->{capacity}), + prct_free => ($hdd->{freeSpace} * 100 / $hdd->{capacity}) + } + }; + + my $smart = $options{custom}->request_api(endpoint => '/ISAPI/ContentMgmt/Storage/hdd/' . $hdd->{id} . '/SMARTTest/status'); + $self->{disks}->{ $hdd->{hddName} }->{temperature} = { value => $smart->{temprature} }; + } +} + +1; + +__END__ + +=head1 MODE + +Check disks. + +=over 8 + +=item B<--filter-name> + +Filter disks by name (can be a regexp). + +=item B<--unknown-status> + +Set unknown threshold for status. +Can used special variables like: %{status}, %{name} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /reparing/i'). +Can used special variables like: %{status}, %{name} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /error|smartFailed/i'). +Can used special variables like: %{status}, %{name} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'space-usage', 'space-usage-free', 'space-usage-prct', +'temperature'. + +=back + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/memory.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/memory.pm new file mode 100644 index 000000000..ba8a5f60b --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/memory.pm @@ -0,0 +1,127 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_memory_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}); + return 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} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'memory-usage', nlabel => 'memory.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_memory_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1 } + ] + } + }, + { label => 'memory-usage-free', display_ok => 0, nlabel => 'memory.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_memory_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1 } + ] + } + }, + { label => 'memory-usage-prct', display_ok => 0, nlabel => 'memory.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'free' }, { name => 'used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_memory_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/System/status'); + if (!defined($result->{MemoryList}->{Memory}->{memoryUsage})) { + $self->{output}->add_option_msg(short_msg => "Cannot find memory informations"); + $self->{output}->option_exit(); + } + + my ($mem_used, $mem_free); + $mem_used = $1 * 1024 * 1024 if ($result->{MemoryList}->{Memory}->{memoryUsage} =~ /([0-9\.]+)/m); + $mem_free = $1 * 1024 * 1024 if ($result->{MemoryList}->{Memory}->{memoryAvailable} =~ /([0-9\.]+)/m); + + $self->{global} = { + used => $mem_used, + free => $mem_free, + total => $mem_used + $mem_free + }; + $self->{global}->{prct_used} = $mem_used * 100 / $self->{global}->{total}; + $self->{global}->{prct_free} = 100 - $self->{global}->{prct_used}; +} + +1; + +__END__ + +=head1 MODE + +Check memory. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'memory-usage-prct', 'memory-usage', 'memory-usage-free', + +=back + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm new file mode 100644 index 000000000..a5580bd3f --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/protocols.pm @@ -0,0 +1,125 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::mode::protocols; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub prefix_protocol_output { + my ($self, %options) = @_; + + return sprintf( + "protocol '%s' ", + $options{instance} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'protocols', type => 1, cb_prefix_output => 'prefix_protocol_output', message_multiple => 'All protocols are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{protocols} = [ + { + label => 'status', + type => 2, + set => { + key_values => [ { name => 'enabled' }, { name => 'name' } ], + output_template => 'enabled: %s', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/Security/adminAccesses/capabilities', force_array => ['AdminAccessProtocol']); + if (!defined($result->{AdminAccessProtocol})) { + $self->{output}->add_option_msg(short_msg => "Cannot find protocol informations"); + $self->{output}->option_exit(); + } + + $self->{protocols} = {}; + foreach (@{$result->{AdminAccessProtocol}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{protocol}->{content} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping protocol '" . $_->{protocol}->{content} . "'.", debug => 1); + next; + } + + $self->{protocols}->{ $_->{protocol}->{content} } = { + name => $_->{protocol}->{content}, + enabled => $_->{enabled}->{content} + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check protocols. + +=over 8 + +=item B<--filter-name> + +Filter protocols by name (can be a regexp). + +=item B<--unknown-status> + +Set unknown threshold for status. +Can used special variables like: %{enabled}, %{name} + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{enabled}, %{name} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{enabled}, %{name} +=back + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/time.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/time.pm new file mode 100644 index 000000000..600035258 --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/time.pm @@ -0,0 +1,179 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::mode::time; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use DateTime; + +sub custom_usage_output { + my ($self, %options) = @_; + + return sprintf( + 'Time offset %d second(s): %s', + $self->{result_values}->{offset}, + $self->{result_values}->{date} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'offset', type => 0 } + ]; + + $self->{maps_counters}->{offset} = [ + { label => 'offset', nlabel => 'time.offset.seconds', set => { + key_values => [ { name => 'offset' }, { name => 'date' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { template => '%d', unit => 's' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'ntp-hostname:s' => { name => 'ntp_hostname' }, + 'ntp-port:s' => { name => 'ntp_port', default => 123 }, + 'timezone:s' => { name => 'timezone' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{ntp_hostname})) { + centreon::plugins::misc::mymodule_load( + output => $self->{output}, module => 'Net::NTP', + error_msg => "Cannot load module 'Net::NTP'." + ); + } +} + +sub get_target_time { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/System/time/capabilities'); + if (!defined($result->{localTime})) { + $self->{output}->add_option_msg(short_msg => "Cannot find time informations"); + $self->{output}->option_exit(); + } + + if ($result->{localTime} !~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)(.*)$/) { + $self->{output}->add_option_msg(short_msg => "unsupported date format"); + $self->{output}->option_exit(); + } + + my $tz = $7; + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + } + + my $dt = DateTime->new( + year => $1, + month => $2, + day => $3, + hour => $4, + minute => $5, + second => $6, + time_zone => $7 + ); + + return ($dt->epoch(), $result->{localTime}); +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($distant_time, $remote_date) = $self->get_target_time(%options); + + my $ref_time; + if (defined($self->{option_results}->{ntp_hostname}) && $self->{option_results}->{ntp_hostname} ne '') { + my %ntp; + + eval { + %ntp = Net::NTP::get_ntp_response($self->{option_results}->{ntp_hostname}, $self->{option_results}->{ntp_port}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Couldn't connect to ntp server: " . $@); + $self->{output}->option_exit(); + } + + $ref_time = $ntp{'Transmit Timestamp'}; + } else { + $ref_time = time(); + } + + my $offset = $distant_time - $ref_time; + $self->{offset} = { + offset => sprintf('%d', $offset), + date => $remote_date + }; +} + +1; + +__END__ + +=head1 MODE + +Check time offset of server with ntp server. Use local time if ntp-host option is not set. + +=over 8 + +=item B<--warning-offset> + +Time offset warning threshold (in seconds). + +=item B<--critical-offset> + +Time offset critical Threshold (in seconds). + +=item B<--ntp-hostname> + +Set the ntp hostname (if not set, localtime is used). + +=item B<--ntp-port> + +Set the ntp port (Default: 123). + +=item B<--timezone> + +Override the timezone of distant equipment. +Can use format: 'Europe/London' or '+0100'. + +=back + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/uptime.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/uptime.pm new file mode 100644 index 000000000..67a24d03d --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/mode/uptime.pm @@ -0,0 +1,143 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::mode::uptime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use POSIX; +use centreon::plugins::misc; + +my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; +my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' }; + +sub custom_uptime_output { + my ($self, %options) = @_; + + return sprintf( + 'System uptime is: %s', + centreon::plugins::misc::change_seconds(value => $self->{result_values}->{uptime}, start => 'd') + ); +} + +sub custom_uptime_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => 'system.uptime.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} }, + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); +} + +sub custom_uptime_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }, + { label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' } + ] + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'uptime', set => { + key_values => [ { name => 'uptime' } ], + closure_custom_output => $self->can('custom_uptime_output'), + closure_custom_perfdata => $self->can('custom_uptime_perfdata'), + closure_custom_threshold_check => $self->can('custom_uptime_threshold') + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'unit:s' => { name => 'unit', default => 's' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) { + $self->{option_results}->{unit} = 's'; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->request_api(endpoint => '/ISAPI/System/status'); + if (!defined($result->{deviceUpTime})) { + $self->{output}->add_option_msg(short_msg => "Cannot find uptime information"); + $self->{output}->option_exit(); + } + + $self->{global} = { uptime => $result->{deviceUpTime} }; +} + +1; + +__END__ + +=head1 MODE + +Check system uptime. + +=over 8 + +=item B<--warning-uptime> + +Threshold warning. + +=item B<--critical-uptime> + +Threshold critical. + +=item B<--unit> + +Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds + +=back + +=cut diff --git a/centreon-plugins/hardware/devices/hikvision/nvr/isapi/plugin.pm b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/plugin.pm new file mode 100644 index 000000000..74235ef47 --- /dev/null +++ b/centreon-plugins/hardware/devices/hikvision/nvr/isapi/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2022 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::hikvision::nvr::isapi::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->{modes} = { + 'cpu' => 'hardware::devices::hikvision::nvr::isapi::mode::cpu', + 'device' => 'hardware::devices::hikvision::nvr::isapi::mode::device', + 'disks' => 'hardware::devices::hikvision::nvr::isapi::mode::disks', + 'memory' => 'hardware::devices::hikvision::nvr::isapi::mode::memory', + 'protocols' => 'hardware::devices::hikvision::nvr::isapi::mode::protocols', + 'time' => 'hardware::devices::hikvision::nvr::isapi::mode::time', + 'uptime' => 'hardware::devices::hikvision::nvr::isapi::mode::uptime' + }; + + $self->{custom_modes}->{isapi} = 'hardware::devices::hikvision::nvr::isapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Hikvision Network Video Recorder (NVR) using ISAPI (Intelligent Security API). + +=cut