From e09a5ed5986d2b58629046ac829b32913269881f Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Tue, 26 Nov 2019 11:07:39 +0100 Subject: [PATCH] enhance ntp time to be used anywhere --- .../camera/hikvision/snmp/mode/time.pm | 96 +++++++++++++++++++ .../devices/camera/hikvision/snmp/plugin.pm | 1 + snmp_standard/mode/ntp.pm | 62 ++++++------ 3 files changed, 130 insertions(+), 29 deletions(-) create mode 100644 hardware/devices/camera/hikvision/snmp/mode/time.pm diff --git a/hardware/devices/camera/hikvision/snmp/mode/time.pm b/hardware/devices/camera/hikvision/snmp/mode/time.pm new file mode 100644 index 000000000..5ada6a675 --- /dev/null +++ b/hardware/devices/camera/hikvision/snmp/mode/time.pm @@ -0,0 +1,96 @@ +# +# Copyright 2019 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::camera::hikvision::snmp::mode::time; + +use base qw(snmp_standard::mode::ntp); + +use strict; +use warnings; + +sub get_target_time { + my ($self, %options) = @_; + + my $oid_sysTime = '.1.3.6.1.4.1.39165.1.19.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [ $oid_sysTime ], nothing_quit => 1); + + # format: "2019-11-18 20:13:17" + if ($snmp_result->{$oid_sysTime} !~ /^(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)/) { + $self->{output}->add_option_msg(short_msg => 'cannot parse date format: ' . $snmp_result->{$oid_sysTime}); + $self->{output}->option_exit(); + } + + my $remote_date = [$1, $2, $3, $4, $5, $6]; + + my $timezone = 'UTC'; + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $timezone = $self->{option_results}->{timezone}; + } + + my $tz = centreon::plugins::misc::set_timezone(name => $timezone); + my $dt = DateTime->new( + year => $remote_date->[0], + month => $remote_date->[1], + day => $remote_date->[2], + hour => $remote_date->[3], + minute => $remote_date->[4], + second => $remote_date->[5], + %$tz + ); + + return ($dt->epoch, $remote_date, $timezone); +} + +1; + +__END__ + +=head1 MODE + +Check time offset of server with ntp server. Use local time if ntp-host option is not set. +SNMP gives a date with second precision (no milliseconds). Time precision is not very accurate. +Use threshold with (+-) 2 seconds offset (minimum). + +=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> + +Set the timezone of distant server. For Windows, you need to set it. +Can use format: 'Europe/London' or '+0100'. + +=back + +=cut diff --git a/hardware/devices/camera/hikvision/snmp/plugin.pm b/hardware/devices/camera/hikvision/snmp/plugin.pm index 30b9a3d1d..997f846ff 100644 --- a/hardware/devices/camera/hikvision/snmp/plugin.pm +++ b/hardware/devices/camera/hikvision/snmp/plugin.pm @@ -34,6 +34,7 @@ sub new { 'cpu' => 'hardware::devices::camera::hikvision::snmp::mode::cpu', 'disk' => 'hardware::devices::camera::hikvision::snmp::mode::disk', 'memory' => 'hardware::devices::camera::hikvision::snmp::mode::memory', + 'time' => 'hardware::devices::camera::hikvision::snmp::mode::time' ); return $self; diff --git a/snmp_standard/mode/ntp.pm b/snmp_standard/mode/ntp.pm index 40bf43219..2d4ef47e8 100644 --- a/snmp_standard/mode/ntp.pm +++ b/snmp_standard/mode/ntp.pm @@ -82,13 +82,39 @@ sub check_options { } } -sub manage_selection { +sub get_target_time { my ($self, %options) = @_; - $self->{offset} = {}; - my ($ref_time, $distant_time); my $oid_hrSystemDate = '.1.3.6.1.2.1.25.1.2.0'; my $result = $options{snmp}->get_leef(oids => [ $oid_hrSystemDate ], nothing_quit => 1); + + my @remote_date = unpack 'n C6 a C2', $result->{$oid_hrSystemDate}; + my $timezone = 'UTC'; + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $timezone = $self->{option_results}->{timezone}; + } elsif (defined($remote_date[9])) { + $timezone = sprintf("%s%02d%02d", $remote_date[7], $remote_date[8], $remote_date[9]); # format +0630 + } + + my $tz = centreon::plugins::misc::set_timezone(name => $timezone); + my $dt = DateTime->new( + year => $remote_date[0], + month => $remote_date[1], + day => $remote_date[2], + hour => $remote_date[3], + minute => $remote_date[4], + second => $remote_date[5], + %$tz + ); + + return ($dt->epoch, \@remote_date, $timezone); +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($disant_time, $remote_date, $timezone) = $self->get_target_time(%options); + my $ref_time; if (defined($self->{option_results}->{ntp_hostname}) && $self->{option_results}->{ntp_hostname} ne '') { my %ntp; @@ -109,37 +135,15 @@ sub manage_selection { $ref_time = time(); } - my @remote_date = unpack 'n C6 a C2', $result->{$oid_hrSystemDate}; - my $timezone = 'UTC'; - if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { - $timezone = $self->{option_results}->{timezone}; - } elsif (defined($remote_date[9])) { - $timezone = sprintf("%s%02d%02d", $remote_date[7], $remote_date[8], $remote_date[9]); # format +0630 - } - - my $tz = centreon::plugins::misc::set_timezone(name => $timezone); - my $dt = DateTime->new( - year => $remote_date[0], - month => $remote_date[1], - day => $remote_date[2], - hour => $remote_date[3], - minute => $remote_date[4], - second => $remote_date[5], - %$tz - ); - $distant_time = $dt->epoch; - - my $offset = $distant_time - $ref_time; + my $offset = $disant_time - $ref_time; my $remote_date_formated = sprintf( 'Local Time : %02d-%02d-%02dT%02d:%02d:%02d (%s)', - $remote_date[0], $remote_date[1], $remote_date[2], - $remote_date[3], $remote_date[4], $remote_date[5], $timezone + $remote_date->[0], $remote_date->[1], $remote_date->[2], + $remote_date->[3], $remote_date->[4], $remote_date->[5], $timezone ); - my $formated_offset = sprintf("%d", $offset); - $self->{offset} = { - offset => $formated_offset, + offset => sprintf("%d", $offset), date => $remote_date_formated, }; }