From 1e17e91f337f07337476e5741efbe985c63c3895 Mon Sep 17 00:00:00 2001 From: scresto Date: Mon, 2 Jun 2025 10:01:00 +0200 Subject: [PATCH] feat(network::f5::bigip::snmp::plugin): add certificates mode (#5602) Refs: CTOR-1561 --- .../f5/bigip/snmp/mode/certificates.pm | 283 ++++++++++++++++++ src/network/f5/bigip/snmp/plugin.pm | 3 +- .../network/f5/bigip/snmp/certificates.robot | 37 +++ .../f5/bigip/snmp/certificates.snmpwalk | 45 +++ .../f5/bigip/snmp/certificates_date.pm | 9 + 5 files changed, 376 insertions(+), 1 deletion(-) create mode 100644 src/network/f5/bigip/snmp/mode/certificates.pm create mode 100644 tests/network/f5/bigip/snmp/certificates.robot create mode 100644 tests/network/f5/bigip/snmp/certificates.snmpwalk create mode 100644 tests/network/f5/bigip/snmp/certificates_date.pm diff --git a/src/network/f5/bigip/snmp/mode/certificates.pm b/src/network/f5/bigip/snmp/mode/certificates.pm new file mode 100644 index 000000000..19cd433eb --- /dev/null +++ b/src/network/f5/bigip/snmp/mode/certificates.pm @@ -0,0 +1,283 @@ +# +# Copyright 2025 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::f5::bigip::snmp::mode::certificates; + +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_expires_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} }, + unit => $self->{instance_mode}->{option_results}->{unit}, + instances => $self->{result_values}->{name}, + value => $self->{result_values}->{expires_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_expires_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{expires_unit}, + threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }, + { label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' } + ] + ); +} + +sub custom_expires_output { + my ($self, %options) = @_; + + my $msg = $self->{result_values}->{expires_seconds} > 0 ? + 'expires in ' . $self->{result_values}->{expires_human} : + 'has expired'; + + $msg.= ' ['. $self->{result_values}->{expires_date} .']' if $self->{output}->is_verbose(); + + return $msg; +} + +sub prefix_certificate_output { + my ($self, %options) = @_; + + return sprintf( + "Certificate '%s' ", + $options{instance_value}->{name} + ); +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{option_results}->{unit} = 's' + if $self->{option_results}->{unit} eq '' || not defined $unitdiv->{$self->{option_results}->{unit}}; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'certificates', type => 1, cb_prefix_output => 'prefix_certificate_output', + message_multiple => 'All certificates are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'certificates-count', nlabel => 'certificates.count', set => { + key_values => [ { name => 'count' } ], + output_template => 'number of certificates: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{certificates} = [ + { label => 'certificate-expires', critical_default => '@0:0', nlabel => 'certificate.expires', set => { + key_values => [ { name => 'expires_seconds' }, { name => 'expires_date' }, + { name => 'expires_human' }, { name => 'expires_unit' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_expires_output'), + closure_custom_perfdata => $self->can('custom_expires_perfdata'), + closure_custom_threshold_check => $self->can('custom_expires_threshold') + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + "include-name:s" => { name => 'include_name', default => '' }, + "exclude-name:s" => { name => 'exclude_name', default => '' }, + "include-issuer:s" => { name => 'include_issuer', default => '' }, + "exclude-issuer:s" => { name => 'exclude_issuer', default => '' }, + "include-validation:i" => { name => 'include_validation', default => '' }, + "exclude-validation:i" => { name => 'exclude_validation', default => '' }, + 'unit:s' => { name => 'unit', default => 's' } + }); + + return $self; +} + +my $mapping = { + sysCertificateFileObjectName => { oid => '.1.3.6.1.4.1.3375.2.1.15.1.2.1.1' }, + sysCertificateFileObjectIssuerCert => { oid => '.1.3.6.1.4.1.3375.2.1.15.1.2.1.2' }, + sysCertificateFileObjectCertStatusValidationOptions => { oid => '.1.3.6.1.4.1.3375.2.1.15.1.2.1.3' }, + sysCertificateFileObjectExpirationString => { oid => '.1.3.6.1.4.1.3375.2.1.15.1.2.1.4' }, + sysCertificateFileObjectExpirationDate => { oid => '.1.3.6.1.4.1.3375.2.1.15.1.2.1.5' }, +}; +my $oid_sysCertificateFileObjectEntry = '.1.3.6.1.4.1.3375.2.1.15.1.2.1'; + +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(); + } + + $self->{certificates} = {}; + $self->{global} = { total => 0 }; + + my $results = $options{snmp}->get_table( + oid => $oid_sysCertificateFileObjectEntry, + nothing_quit => 1 + ); + + my $now = time; + + foreach (keys %$results) { + next unless /^$mapping->{sysCertificateFileObjectName}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + if ($self->{option_results}->{include_name} ne '' || $self->{option_results}->{include_issuer} ne '' || $self->{option_results}->{include_validation} ne '') { + my $whitelist = 0; + $whitelist = 1 if $self->{option_results}->{include_name} ne '' && + $result->{sysCertificateFileObjectName} =~ /$self->{option_results}->{include_name}/; + $whitelist = 1 if $self->{option_results}->{include_issuer} ne '' && + $result->{sysCertificateFileObjectIssuerCert} =~ /$self->{option_results}->{include_issuer}/; + $whitelist = 1 if $self->{option_results}->{include_validation} ne '' && + $result->{sysCertificateFileObjectCertStatusValidationOptions} =~ /$self->{option_results}->{include_validation}/; + + if ($whitelist == 0) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{sysCertificateFileObjectName} . "': no including filter match.", debug => 1); + next + } + } + + if (($self->{option_results}->{exclude_name} ne '' && $result->{sysCertificateFileObjectName} =~ /$self->{option_results}->{exclude_name}/) || + ($self->{option_results}->{exclude_issuer} ne '' && $result->{sysCertificateFileObjectIssuerCert} =~ /$self->{option_results}->{exclude_issuer}/) || + ($self->{option_results}->{exclude_validation} ne '' && $result->{sysCertificateFileObjectCertStatusValidationOptions} =~ /$self->{option_results}->{exclude_validation}/)) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{sysCertificateFileObjectName} . "': excluding filter match.", debug => 1); + next + } + + my $expire_seconds = $result->{sysCertificateFileObjectExpirationDate} - $now; + $expire_seconds = 0 if $expire_seconds < 0; + + $self->{certificates}->{$instance} = { + name => $result->{sysCertificateFileObjectName}, + expires_date => $result->{sysCertificateFileObjectExpirationString}, + expires_seconds => $expire_seconds, + expires_unit => floor($expire_seconds / $unitdiv->{ $self->{option_results}->{unit} }), + expires_human => centreon::plugins::misc::change_seconds( value => $expire_seconds ), + }; + $self->{global}->{count}++; + } + + if (scalar(keys %{$self->{certificates}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No certificate found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check certificates. + + - certificates.count Number of matching certificates. + - certificate.expires Time remaining before the expiration of certificates. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). + +Can be : certificate-expires, certificates-count + +Example : --filter-counters='^certificate-expires$' + +=item B<--include-name> + +Filter certificate by name (regexp can be used). + +Example : --include-name='ABCaBundle' + +=item B<--include-issuer> + +Filter certificate by issuer (regexp can be used). + +=item B<--include-validation> + +Filter certificate by status validation options (regexp can be used). + +Example : --include-validation='1' + +=item B<--exclude-name> + +Exclude certificate by name (regexp can be used). + +=item B<--exclude-issuer> + +Exclude certificate by issuer (regexp can be used). + +=item B<--exclude-validation> + +Exclude certificate by status validation options (regexp can be used). + +=item B<--unit> + +Select the time unit for the expiration thresholds. May be 's' for seconds,'m' for minutes, 'h' for hours, 'd' for days, 'w' for weeks. Default is seconds. + +=item B<--warning-certificate-expires> + +Threshold. + +=item B<--critical-certificate-expires> + +Threshold. + +=item B<--warning-certificates-count> + +Threshold. + +=item B<--critical-certificates-count> + +Threshold. + +=back + +=cut diff --git a/src/network/f5/bigip/snmp/plugin.pm b/src/network/f5/bigip/snmp/plugin.pm index 2d13b8b67..c6b49c0f8 100644 --- a/src/network/f5/bigip/snmp/plugin.pm +++ b/src/network/f5/bigip/snmp/plugin.pm @@ -43,7 +43,8 @@ sub new { 'tmm-usage' => 'network::f5::bigip::snmp::mode::tmmusage', 'cpu-usage' => 'network::f5::bigip::snmp::mode::cpuusage', 'trunks' => 'network::f5::bigip::snmp::mode::trunks', - 'virtualserver-status' => 'network::f5::bigip::snmp::mode::virtualserverstatus' + 'virtualserver-status' => 'network::f5::bigip::snmp::mode::virtualserverstatus', + 'certificates' => 'network::f5::bigip::snmp::mode::certificates' }; return $self; diff --git a/tests/network/f5/bigip/snmp/certificates.robot b/tests/network/f5/bigip/snmp/certificates.robot new file mode 100644 index 000000000..290fc2a3b --- /dev/null +++ b/tests/network/f5/bigip/snmp/certificates.robot @@ -0,0 +1,37 @@ +*** Settings *** + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Test Timeout 120s + + +*** Variables *** +${INJECT_PERL} -Mcertificates_date -I${CURDIR} +${CMD} ${CENTREON_PLUGINS} --plugin=network::f5::bigip::snmp::plugin +... --mode=certificates +... --hostname=${HOSTNAME} +... --snmp-version=${SNMPVERSION} +... --snmp-port=${SNMPPORT} +... --snmp-community=network/f5/bigip/snmp/certificates + +*** Test Cases *** +certificates ${tc} + [Tags] network + + ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default= + Set Environment Variable PERL5OPT ${INJECT_PERL} ${OLD_PERL5OPT} + + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} CRITICAL: Certificate 'Anonymized 165' has expired - Certificate 'Anonymized 186' has expired | 'certificates-count'=9;;;0; '_Anonymized 981'=212738332s;;@0:0;0; '_Anonymized 165'=0s;;@0:0;0; '_Anonymized 982'=384058793s;;@0:0;0; '_Anonymized 983'=145466616s;;@0:0;0; '_Anonymized 196'=122214889s;;@0:0;0; '_Anonymized 141'=67955030s;;@0:0;0; '_Anonymized 881'=68447205s;;@0:0;0; '_Anonymized 068'=145466616s;;@0:0;0; '_Anonymized 186'=0s;;@0:0;0; + ... 2 --include-name="Anonymized 068" OK: number of certificates: 1 - Certificate 'Anonymized 068' expires in 4y 7M 1w 2d 14h 45m 11s | 'certificates-count'=1;;;0; '_Anonymized 068'=145466616s;;@0:0;0; + ... 3 --include-name=Anonym --exclude-name="Anonymized 035" CRITICAL: Certificate 'Anonymized 165' has expired - Certificate 'Anonymized 186' has expired | 'certificates-count'=9;;;0; '_Anonymized 981'=212738332s;;@0:0;0; '_Anonymized 165'=0s;;@0:0;0; '_Anonymized 982'=384058793s;;@0:0;0; '_Anonymized 983'=145466616s;;@0:0;0; '_Anonymized 196'=122214889s;;@0:0;0; '_Anonymized 141'=67955030s;;@0:0;0; '_Anonymized 881'=68447205s;;@0:0;0; '_Anonymized 068'=145466616s;;@0:0;0; '_Anonymized 186'=0s;;@0:0;0; + ... 4 --unit=w --warning-certificate-expires=150: --include-name="Anonymized 141" WARNING: Certificate 'Anonymized 141' expires in 2y 1M 3w 4d 14h 17m 15s | 'certificates-count'=1;;;0; '_Anonymized 141'=112w;150:;@0:0;0; + ... 5 --unit=m --critical-certificate-expires=:1111111 --include-name="Anonymized 141" CRITICAL: Certificate 'Anonymized 141' expires in 2y 1M 3w 4d 14h 17m 15s | 'certificates-count'=1;;;0; '_Anonymized 141'=1132583m;;0:1111111;0; + ... 6 --filter-counters=certificates-count --warning-certificates-count=10: WARNING: number of certificates: 9 | 'certificates-count'=9;10:;;0; diff --git a/tests/network/f5/bigip/snmp/certificates.snmpwalk b/tests/network/f5/bigip/snmp/certificates.snmpwalk new file mode 100644 index 000000000..05ed306e3 --- /dev/null +++ b/tests/network/f5/bigip/snmp/certificates.snmpwalk @@ -0,0 +1,45 @@ +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.15.47.67.111.109.109.111.110.47.65.78.77.68.77.67.65 = STRING: Anonymized 981 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.16.47.67.111.109.109.111.110.47.65.78.82.111.111.116.67.65 = STRING: Anonymized 982 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.16.47.67.111.109.109.111.110.47.115.97.46.97.110.46.102.114 = STRING: Anonymized 165 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.18.47.67.111.109.109.111.110.47.65.78.67.97.66.117.110.100.108.101 = STRING: Anonymized 983 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.19.47.67.111.109.109.111.110.47.100.101.102.97.117.108.116.46.99.114.116 = STRING: Anonymized 196 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.20.47.67.111.109.109.111.110.47.102.53.45.105.114.117.108.101.46.99.114.116 = STRING: Anonymized 141 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.21.47.67.111.109.109.111.110.47.65.78.67.111.109.112.117.116.101.114.115.67.65 = STRING: Anonymized 881 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.21.47.67.111.109.109.111.110.47.99.97.45.98.117.110.100.108.101.46.99.114.116 = STRING: Anonymized 068 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.1.22.47.67.111.109.109.111.110.47.102.53.95.97.112.105.95.99.111.109.46.99.114.116 = STRING: Anonymized 186 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.15.47.67.111.109.109.111.110.47.65.78.77.68.77.67.65 = STRING: Anonymized 121 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.16.47.67.111.109.109.111.110.47.65.78.82.111.111.116.67.65 = STRING: Anonymized 198 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.16.47.67.111.109.109.111.110.47.115.97.46.97.110.46.102.114 = STRING: Anonymized 139 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.18.47.67.111.109.109.111.110.47.65.78.67.97.66.117.110.100.108.101 = STRING: Anonymized 129 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.19.47.67.111.109.109.111.110.47.100.101.102.97.117.108.116.46.99.114.116 = STRING: Anonymized 062 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.20.47.67.111.109.109.111.110.47.102.53.45.105.114.117.108.101.46.99.114.116 = STRING: Anonymized 028 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.21.47.67.111.109.109.111.110.47.65.78.67.111.109.112.117.116.101.114.115.67.65 = STRING: Anonymized 048 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.21.47.67.111.109.109.111.110.47.99.97.45.98.117.110.100.108.101.46.99.114.116 = STRING: Anonymized 006 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.2.22.47.67.111.109.109.111.110.47.102.53.95.97.112.105.95.99.111.109.46.99.114.116 = STRING: Anonymized 035 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.15.47.67.111.109.109.111.110.47.65.78.77.68.77.67.65 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.16.47.67.111.109.109.111.110.47.65.78.82.111.111.116.67.65 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.16.47.67.111.109.109.111.110.47.115.97.46.97.110.46.102.114 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.18.47.67.111.109.109.111.110.47.65.78.67.97.66.117.110.100.108.101 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.19.47.67.111.109.109.111.110.47.100.101.102.97.117.108.116.46.99.114.116 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.20.47.67.111.109.109.111.110.47.102.53.45.105.114.117.108.101.46.99.114.116 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.21.47.67.111.109.109.111.110.47.65.78.67.111.109.112.117.116.101.114.115.67.65 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.21.47.67.111.109.109.111.110.47.99.97.45.98.117.110.100.108.101.46.99.114.116 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.3.22.47.67.111.109.109.111.110.47.102.53.95.97.112.105.95.99.111.109.46.99.114.116 = Gauge32: 0 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.15.47.67.111.109.109.111.110.47.65.78.77.68.77.67.65 = STRING: Anonymized 029 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.16.47.67.111.109.109.111.110.47.65.78.82.111.111.116.67.65 = STRING: Anonymized 204 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.16.47.67.111.109.109.111.110.47.115.97.46.97.110.46.102.114 = STRING: Anonymized 244 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.18.47.67.111.109.109.111.110.47.65.78.67.97.66.117.110.100.108.101 = STRING: Anonymized 115 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.19.47.67.111.109.109.111.110.47.100.101.102.97.117.108.116.46.99.114.116 = STRING: Anonymized 242 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.20.47.67.111.109.109.111.110.47.102.53.45.105.114.117.108.101.46.99.114.116 = STRING: Anonymized 135 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.21.47.67.111.109.109.111.110.47.65.78.67.111.109.112.117.116.101.114.115.67.65 = STRING: Anonymized 083 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.21.47.67.111.109.109.111.110.47.99.97.45.98.117.110.100.108.101.46.99.114.116 = STRING: Anonymized 076 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.4.22.47.67.111.109.109.111.110.47.102.53.95.97.112.105.95.99.111.109.46.99.114.116 = STRING: Anonymized 001 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.15.47.67.111.109.109.111.110.47.65.78.77.68.77.67.65 = Counter64: 1960727715 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.16.47.67.111.109.109.111.110.47.65.78.82.111.111.116.67.65 = Counter64: 2132048176 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.16.47.67.111.109.109.111.110.47.115.97.46.97.110.46.102.114 = Counter64: 1677628799 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.18.47.67.111.109.109.111.110.47.65.78.67.97.66.117.110.100.108.101 = Counter64: 1893455999 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.19.47.67.111.109.109.111.110.47.100.101.102.97.117.108.116.46.99.114.116 = Counter64: 1870204272 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.20.47.67.111.109.109.111.110.47.102.53.45.105.114.117.108.101.46.99.114.116 = Counter64: 1815944413 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.21.47.67.111.109.109.111.110.47.65.78.67.111.109.112.117.116.101.114.115.67.65 = Counter64: 1816436588 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.21.47.67.111.109.109.111.110.47.99.97.45.98.117.110.100.108.101.46.99.114.116 = Counter64: 1893455999 +.1.3.6.1.4.1.3375.2.1.15.1.2.1.5.22.47.67.111.109.109.111.110.47.102.53.95.97.112.105.95.99.111.109.46.99.114.116 = Counter64: 1724275836 diff --git a/tests/network/f5/bigip/snmp/certificates_date.pm b/tests/network/f5/bigip/snmp/certificates_date.pm new file mode 100644 index 000000000..ce5d4f227 --- /dev/null +++ b/tests/network/f5/bigip/snmp/certificates_date.pm @@ -0,0 +1,9 @@ +package certificates_date; + +# Always use the same fixed date to test certificate validity + +BEGIN { + *CORE::GLOBAL::time = sub { 1747989383 }; +} + +1