From 39ceb31bd465672097e455a1852d5b8076ff2090 Mon Sep 17 00:00:00 2001 From: crsuser Date: Fri, 19 Jun 2026 17:26:44 +0200 Subject: [PATCH 01/50] feat: update and add modes for Stormshield SNMP monitoring --- .../stormshield/snmp/mode/auto_update.pm | 237 ++++++++ .../stormshield/snmp/mode/components/disk.pm | 131 +++-- .../stormshield/snmp/mode/components/fan.pm | 118 ++-- .../stormshield/snmp/mode/components/psu.pm | 94 +++- .../snmp/mode/components/temperature.pm | 112 ++-- .../stormshield/snmp/mode/connections.pm | 136 ++++- .../stormshield/snmp/mode/ha_cluster.pm | 334 ++++++++++++ src/network/stormshield/snmp/mode/hardware.pm | 101 +++- src/network/stormshield/snmp/mode/health.pm | 71 ++- .../stormshield/snmp/mode/interfaces_disco.pm | 510 ++++++++++++++++++ .../stormshield/snmp/mode/memorydetailed.pm | 295 +++++++--- src/network/stormshield/snmp/plugin.pm | 33 +- 12 files changed, 1863 insertions(+), 309 deletions(-) create mode 100644 src/network/stormshield/snmp/mode/auto_update.pm create mode 100644 src/network/stormshield/snmp/mode/ha_cluster.pm create mode 100644 src/network/stormshield/snmp/mode/interfaces_disco.pm diff --git a/src/network/stormshield/snmp/mode/auto_update.pm b/src/network/stormshield/snmp/mode/auto_update.pm new file mode 100644 index 0000000000..334739d7de --- /dev/null +++ b/src/network/stormshield/snmp/mode/auto_update.pm @@ -0,0 +1,237 @@ +# Copyright 2026-Present 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 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::stormshield::snmp::mode::auto_update; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use DateTime; +use centreon::plugins::constants qw(:counters); +use centreon::plugins::misc; + +sub custom_auto_update_output { + my ($self, %options) = @_; + + my $state = $self->{result_values}->{state}; + my $last_date = $self->{result_values}->{last_date} // 'N/A'; + my $display = $self->{result_values}->{display}; + + my $msg = ""; + + if ($state eq 'Uptodate') { + $msg = "$display is up to date"; + } elsif ($state eq 'Disabled') { + $msg = "$display is disabled"; + } elsif ($state eq 'NeverStarted') { + $msg = "$display never started"; + } else { + $msg = "$display $state (Last Update: $last_date)"; + } + + if (!$self->{output}->{long_msg_added}) { + $self->{output}->{long_msg_added} = 1; + $self->{output}->output_add( + long_msg => "-----------------------------------------------------------------------\n" + ); + } + + return $msg; + +} + +sub custom_auto_update_threshold_check { + my ($self, %options) = @_; + + my $state = $self->{result_values}->{state}; + + if ($state eq 'Failed' || $state eq 'Broken') { + return 'CRITICAL'; + } elsif ($state eq 'Partially Failed') { + return 'WARNING'; + } elsif ($state eq 'Disabled' || $state eq 'NeverStarted') { + return 'OK'; + } else { + return 'OK'; + } +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { + name => 'updates', + type => COUNTER_TYPE_INSTANCE, + message_multiple => 'All Updates and Webservices are up to date', + skipped_code => { -10 => 1 } + } + ]; + + $self->{maps_counters}->{updates} = [ + { + label => 'status', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'display' }, + { name => 'state' }, + { name => 'last_date' } + ], + closure_custom_output => $self->can('custom_auto_update_output'), + closure_custom_threshold_check => $self->can('custom_auto_update_threshold_check'), + closure_custom_perfdata => sub { return 0; } + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{updates} = {}; + + my $oid_snsAutoupdateEntry = '.1.3.6.1.4.1.11256.1.9.1.1'; + my $oid_snsAutoupdateIndex = '.1.3.6.1.4.1.11256.1.9.1.1.1'; + my $oid_snsAutoupdateSubsys = '.1.3.6.1.4.1.11256.1.9.1.1.2'; + my $oid_snsAutoupdateState = '.1.3.6.1.4.1.11256.1.9.1.1.3'; + my $oid_snsAutoupdateLast = '.1.3.6.1.4.1.11256.1.9.1.1.4'; + + my $oid_snsCustomWebServicesEntry = '.1.3.6.1.4.1.11256.1.9.2.1'; + my $oid_snsCustomWebServicesIndex = '.1.3.6.1.4.1.11256.1.9.2.1.1'; + my $oid_snsCustomWebServicesName = '.1.3.6.1.4.1.11256.1.9.2.1.2'; + my $oid_snsCustomWebServicesState = '.1.3.6.1.4.1.11256.1.9.2.1.3'; + my $oid_snsCustomWebServicesLast = '.1.3.6.1.4.1.11256.1.9.2.1.4'; + + + my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; + my $snmp_result_version = $options{snmp}->get_leef(oids => [ $oid_snsVersion ], nothing_quit => 1); + my $version_clean = ''; + + if (defined $snmp_result_version && defined $snmp_result_version->{$oid_snsVersion}) { + $version_clean = $snmp_result_version->{$oid_snsVersion}; + $version_clean =~ s/([0-9]+(?:\.[0-9]+)*).*/$1/; + } + + my $snmp_result_update = $options{snmp}->get_table( + oid => $oid_snsAutoupdateEntry, + nothing_quit => 0 + ); + + my $snmp_result_webservice = {}; + + # The MIB WebService is available only starting with version 5.1.0 + if (defined $version_clean && centreon::plugins::misc::minimal_version($version_clean, '5.1.0')) { + $snmp_result_webservice = $options{snmp}->get_table( + oid => $oid_snsCustomWebServicesEntry, + nothing_quit => 0 + ); + } + + $self->process_table( + snmp_result => $snmp_result_update, + index_oid => $oid_snsAutoupdateIndex, + name_oid => $oid_snsAutoupdateSubsys, + state_oid => $oid_snsAutoupdateState, + date_oid => $oid_snsAutoupdateLast, + prefix => 'Update' + ); + + if (scalar(keys %{$snmp_result_webservice}) > 0) { + $self->process_table( + snmp_result => $snmp_result_webservice, + index_oid => $oid_snsCustomWebServicesIndex, + name_oid => $oid_snsCustomWebServicesName, + state_oid => $oid_snsCustomWebServicesState, + date_oid => $oid_snsCustomWebServicesLast, + prefix => 'WebService' + ); + } + + if (scalar(keys %{$self->{updates}}) == 0) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => 'No updates or web services found.' + ); + $self->{updates} = {}; + return; + } +} + +sub process_table { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp_result}; + my $index_oid = $options{index_oid}; + my $name_oid = $options{name_oid}; + my $state_oid = $options{state_oid}; + my $date_oid = $options{date_oid}; + my $prefix = $options{prefix}; + + foreach my $oid (sort keys %{$snmp_result}) { + next unless $oid =~ /^$index_oid\./; + + my $index = $oid; + $index =~ s/^$index_oid\.//; + + my $name = $snmp_result->{"$name_oid.$index"} // 'N/A'; + my $state = $snmp_result->{"$state_oid.$index"} // 'N/A'; + my $lastDate = $snmp_result->{"$date_oid.$index"} // 'N/A'; + + my $normalized_state = $state; + if ($normalized_state eq 'Disabled') { + $normalized_state = 'Disabled'; + } elsif ($normalized_state !~ /^(Uptodate|Failed|Broken|Partially Failed)/) { + $normalized_state = 'NeverStarted'; + } + + $self->{updates}->{$prefix . '_' . $index} = { + display => $prefix . ': ' . $name, + state => $normalized_state, + last_date => $lastDate + }; + } +} + +1; + +__END__ + +=head1 MODE + +This mode allows you to monitor the status of auto-updates and web services on a Stormshield device. +It checks for failed, broken, or partially failed updates and reports their status. + +=over 8 + +=back + +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/components/disk.pm b/src/network/stormshield/snmp/mode/components/disk.pm index e451770745..8ea6e8b7bd 100644 --- a/src/network/stormshield/snmp/mode/components/disk.pm +++ b/src/network/stormshield/snmp/mode/components/disk.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -23,17 +23,32 @@ package network::stormshield::snmp::mode::components::disk; use strict; use warnings; -my $mapping = { - name => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.2' }, # snsDiskEntryDiskName - isRaid => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.4' }, # snsDiskEntryIsRaid - raidStatus => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.5' } # snsDiskEntryRaidStatus +# Single-node OIDs — structure: oid. +my $mapping_single = { + name => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.2' }, # snsDiskEntryDiskName + smartResult => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.3' }, # snsDiskEntrySmartResult + isRaid => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.4' }, # snsDiskEntryIsRaid + raidStatus => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.5' }, # snsDiskEntryRaidStatus + position => { oid => '.1.3.6.1.4.1.11256.1.10.5.1.6' } # snsDiskEntryPosition }; -my $oid_diskEntry = '.1.3.6.1.4.1.11256.1.10.5.1'; # snsDiskEntry +my $oid_diskEntry_single = '.1.3.6.1.4.1.11256.1.10.5.1'; # snsDiskEntry + +# HA OIDs — structure: oid.. +my $oid_disk_name_ha = '.1.3.6.1.4.1.11256.1.11.11.1.2'; # snsNodeDiskName +my $oid_disk_smartResult_ha = '.1.3.6.1.4.1.11256.1.11.11.1.3'; # snsNodeDiskSmartResult +my $oid_disk_isRaid_ha = '.1.3.6.1.4.1.11256.1.11.11.1.4'; # snsNodeDiskIsRaid +my $oid_disk_raidStatus_ha = '.1.3.6.1.4.1.11256.1.11.11.1.5'; # snsNodeDiskRaidStatus +my $oid_disk_position_ha = '.1.3.6.1.4.1.11256.1.11.11.1.6'; # snsNodeDiskPosition +my $oid_diskEntry_ha = '.1.3.6.1.4.1.11256.1.11.11.1'; # snsNodeDiskEntry sub load { my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_diskEntry, end => $mapping->{raidStatus}->{oid} }; + + if ($self->{is_ha}) { + push @{$self->{request}}, { oid => $oid_diskEntry_ha }; + } else { + push @{$self->{request}}, { oid => $oid_diskEntry_single, end => $mapping_single->{position}->{oid} }; + } } sub check { @@ -43,44 +58,82 @@ sub check { $self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 }; return if ($self->check_filter(section => 'disk')); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $oid_diskEntry }})) { - next if ($oid !~ /^$mapping->{name}->{oid}\.(.*)$/); - my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $oid_diskEntry }, instance => $instance); - - next if ($self->check_filter(section => 'disk', instance => $instance)); + my $nodes = $self->{is_ha} ? $self->{ha_nodes} : ['0']; + my $serials = $self->{ha_serials}; - $self->{components}->{disk}->{total}++; - if ($result->{isRaid} == 0) { - $self->{output}->output_add( - long_msg => sprintf( - "disk '%s' is not member of a raid [instance: %s]", - $result->{name}, - $instance - ) - ); - next; + foreach my $node_id (@$nodes) { + my $label_prefix = $self->{is_ha} ? $serials->{$node_id} . '_' : ''; + my %disks_data = (); + + if ($self->{is_ha}) { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_diskEntry_ha}})) { + if ($oid =~ /^$oid_disk_name_ha\.$node_id\.(\d+)$/) { + $disks_data{$1}{name} = $self->{results}->{$oid_diskEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_disk_smartResult_ha\.$node_id\.(\d+)$/) { + $disks_data{$1}{smartResult} = $self->{results}->{$oid_diskEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_disk_isRaid_ha\.$node_id\.(\d+)$/) { + $disks_data{$1}{isRaid} = $self->{results}->{$oid_diskEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_disk_raidStatus_ha\.$node_id\.(\d+)$/) { + $disks_data{$1}{raidStatus} = $self->{results}->{$oid_diskEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_disk_position_ha\.$node_id\.(\d+)$/) { + $disks_data{$1}{position} = $self->{results}->{$oid_diskEntry_ha}->{$oid}; + } + } + } else { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_diskEntry_single}})) { + next if ($oid !~ /^$mapping_single->{name}->{oid}\.(\d+)$/); + my $disk_id = $1; + my $result = $self->{snmp}->map_instance( + mapping => $mapping_single, + results => $self->{results}->{$oid_diskEntry_single}, + instance => $disk_id + ); + $disks_data{$disk_id} = $result; + } } - $self->{output}->output_add( - long_msg => sprintf( - "disk '%s' raid status is '%s' [instance: %s]", - $result->{name}, - $result->{raidStatus}, - $instance - ) - ); - - my $exit = $self->get_severity(section => 'raid', value => $result->{raidStatus}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + foreach my $disk_id (sort { $a <=> $b } keys %disks_data) { + my $disk = $disks_data{$disk_id}; + my $instance = $label_prefix . 'disk' . $disk_id; + + next if ($self->check_filter(section => 'disk', instance => $instance)); + $self->{components}->{disk}->{total}++; + + my $smart = $disk->{smartResult} // 'N/A'; + my $name = $label_prefix . $disk->{name} // $instance; + $self->{output}->output_add( - severity => $exit, - short_msg => sprintf( - "Disk '%s' raid status is '%s'", $result->{name}, $result->{raidStatus} + long_msg => sprintf( + "disk '%s' smart result is '%s' [isRaid: %s, raidStatus: %s, position: %s]", + $name, + $smart, + (defined $disk->{isRaid} && $disk->{isRaid} == 1) ? 'true' : 'false', + (defined $disk->{raidStatus} && $disk->{raidStatus} ne '') ? $disk->{raidStatus} : '/', + $disk->{position} // 'N/A' ) ); + + my $exit = $self->get_severity(section => 'disk', value => $smart); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Disk '%s' smart result is '%s'", $name, $smart) + ); + } + + if (defined $disk->{isRaid} && $disk->{isRaid} == 1 + && defined $disk->{raidStatus} && $disk->{raidStatus} ne '' + && $disk->{raidStatus} ne 'optimal') + { + $self->{output}->output_add( + severity => 'WARNING', + short_msg => sprintf( + "Disk '%s' RAID status is '%s'", $name, $disk->{raidStatus} + ) + ); + } } } } -1; +1; \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/components/fan.pm b/src/network/stormshield/snmp/mode/components/fan.pm index 9dda6a12cc..8018690b17 100644 --- a/src/network/stormshield/snmp/mode/components/fan.pm +++ b/src/network/stormshield/snmp/mode/components/fan.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -23,20 +23,28 @@ package network::stormshield::snmp::mode::components::fan; use strict; use warnings; -my $mapping = { +# Single-node OIDs — structure: oid. +my $mapping_single = { name => { oid => '.1.3.6.1.4.1.11256.1.10.9.1.2' }, # snsFanName status => { oid => '.1.3.6.1.4.1.11256.1.10.9.1.3' }, # snsFanStatus - rpm => { oid => '.1.3.6.1.4.1.11256.1.10.9.1.4' } # snsFanRpm + rpm => { oid => '.1.3.6.1.4.1.11256.1.10.9.1.4' } # snsFanRpm }; -my $oid_fanEntry = '.1.3.6.1.4.1.11256.1.10.9.1'; # snsFanEntry +my $oid_fanEntry_single = '.1.3.6.1.4.1.11256.1.10.9.1'; # snsFanEntry + +# HA OIDs — structure: oid.. +my $oid_fan_name_ha = '.1.3.6.1.4.1.11256.1.11.13.1.2'; # snsNodeFanName +my $oid_fan_status_ha = '.1.3.6.1.4.1.11256.1.11.13.1.3'; # snsNodeFanStatus +my $oid_fan_rpm_ha = '.1.3.6.1.4.1.11256.1.11.13.1.4'; # snsNodeFanRpm +my $oid_fanEntry_ha = '.1.3.6.1.4.1.11256.1.11.13.1'; # snsNodeFanEntry sub load { my ($self) = @_; - - push @{$self->{request}}, { - oid => $oid_fanEntry, - start => $mapping->{name}->{oid} - }; + + if ($self->{is_ha}) { + push @{$self->{request}}, { oid => $oid_fanEntry_ha }; + } else { + push @{$self->{request}}, { oid => $oid_fanEntry_single }; + } } sub check { @@ -46,51 +54,71 @@ sub check { $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_fanEntry }})) { - next if ($oid !~ /^$mapping->{name}->{oid}\.(.*)$/); - my $instance = $1; + my $nodes = $self->{is_ha} ? $self->{ha_nodes} : ['0']; + my $serials = $self->{ha_serials}; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $oid_fanEntry }, instance => $instance); + foreach my $node_id (@$nodes) { + my $label_prefix = $self->{is_ha} ? $serials->{$node_id} . '_' : ''; + my %fans_data = (); - next if ($self->check_filter(section => 'fan', instance => $instance)); + if ($self->{is_ha}) { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanEntry_ha}})) { + if ($oid =~ /^$oid_fan_name_ha\.$node_id\.(\d+)$/) { + $fans_data{$1}{name} = $self->{results}->{$oid_fanEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_fan_status_ha\.$node_id\.(\d+)$/) { + $fans_data{$1}{status} = $self->{results}->{$oid_fanEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_fan_rpm_ha\.$node_id\.(\d+)$/) { + $fans_data{$1}{rpm} = $self->{results}->{$oid_fanEntry_ha}->{$oid}; + } + } + } else { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanEntry_single}})) { + next if ($oid !~ /^$mapping_single->{name}->{oid}\.(\d+)$/); + my $fan_id = $1; + my $result = $self->{snmp}->map_instance( + mapping => $mapping_single, + results => $self->{results}->{$oid_fanEntry_single}, + instance => $fan_id + ); + $fans_data{$fan_id} = $result; + } + } - $self->{components}->{fan}->{total}++; - $self->{output}->output_add( - long_msg => sprintf( - "fan '%s' status is '%s' [instance: %s, rpm: %s]", - $result->{name}, $result->{status}, $instance, $result->{rpm} - ) - ); + foreach my $fan_id (sort { $a <=> $b } keys %fans_data) { + my $fan = $fans_data{$fan_id}; + my $instance = $label_prefix . $fan->{name}; - $exit = $self->get_severity(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'", $result->{name}, $result->{status} - ) - ); - } + next if ($self->check_filter(section => 'fan', instance => $instance)); + $self->{components}->{fan}->{total}++; + + my $status = $fan->{status} // 'unknown'; - ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{rpm}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( - severity => $exit, - short_msg => sprintf( - "fan '%s' speed is '%s' rpm", $result->{name}, $result->{rpm} + long_msg => sprintf( + "fan '%s' status is '%s'", + $instance, $status ) ); + + if (defined $fan->{rpm}) { + $self->{output}->perfdata_add( + nlabel => 'hardware.fan.speed.rpm', + unit => 'rpm', + instances => $instance, + value => $fan->{rpm}, + min => 0 + ); + } + + my $exit = $self->get_severity(section => 'fan', value => $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, $status) + ); + } } - $self->{output}->perfdata_add( - nlabel => 'hardware.fan.speed.rpm', - unit => 'rpm', - instances => $result->{fanName}, - value => $result->{fanValue}, - warning => $warn, - critical => $crit, min => 0 - ); } } -1; +1; \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/components/psu.pm b/src/network/stormshield/snmp/mode/components/psu.pm index feef573266..01b81023e9 100644 --- a/src/network/stormshield/snmp/mode/components/psu.pm +++ b/src/network/stormshield/snmp/mode/components/psu.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -23,16 +23,26 @@ package network::stormshield::snmp::mode::components::psu; use strict; use warnings; -my $mapping = { +# Single-node OIDs — structure: oid. +my $mapping_single = { powered => { oid => '.1.3.6.1.4.1.11256.1.10.6.1.2' }, # snsPowerSupplyPowered status => { oid => '.1.3.6.1.4.1.11256.1.10.6.1.3' } # snsPowerSupplyStatus }; -my $oid_psuEntry = '.1.3.6.1.4.1.11256.1.10.6.1'; # snsPowerSupplyEntry +my $oid_psuEntry_single = '.1.3.6.1.4.1.11256.1.10.6.1'; # snsPowerSupplyEntry + +# HA OIDs — structure: oid.. +my $oid_psu_powered_ha = '.1.3.6.1.4.1.11256.1.11.10.1.2'; # snsNodePowerSupplyPowered +my $oid_psu_status_ha = '.1.3.6.1.4.1.11256.1.11.10.1.3'; # snsNodePowerSupplyStatus +my $oid_psuEntry_ha = '.1.3.6.1.4.1.11256.1.11.10.1'; # snsNodePowerSupplyEntry sub load { my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_psuEntry }; + + if ($self->{is_ha}) { + push @{$self->{request}}, { oid => $oid_psuEntry_ha }; + } else { + push @{$self->{request}}, { oid => $oid_psuEntry_single }; + } } sub check { @@ -42,33 +52,61 @@ sub check { $self->{components}->{psu} = { name => 'psu', total => 0, skip => 0 }; return if ($self->check_filter(section => 'psu')); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $oid_psuEntry }})) { - next if ($oid !~ /^$mapping->{status}->{oid}\.(.*)$/); - my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $oid_psuEntry }, 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]", - $instance, - $result->{status}, - $instance - ) - ); - - my $exit = $self->get_severity(section => 'psu', value => $result->{status}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + my $nodes = $self->{is_ha} ? $self->{ha_nodes} : ['0']; + my $serials = $self->{ha_serials}; + + foreach my $node_id (@$nodes) { + my $label_prefix = $self->{is_ha} ? $serials->{$node_id} . '_' : ''; + my %psus_data = (); + + if ($self->{is_ha}) { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_psuEntry_ha}})) { + if ($oid =~ /^$oid_psu_powered_ha\.$node_id\.(\d+)$/) { + $psus_data{$1}{powered} = $self->{results}->{$oid_psuEntry_ha}->{$oid}; + } elsif ($oid =~ /^$oid_psu_status_ha\.$node_id\.(\d+)$/) { + $psus_data{$1}{status} = $self->{results}->{$oid_psuEntry_ha}->{$oid}; + } + } + } else { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_psuEntry_single}})) { + next if ($oid !~ /^$mapping_single->{status}->{oid}\.(\d+)$/); + my $psu_id = $1; + my $result = $self->{snmp}->map_instance( + mapping => $mapping_single, + results => $self->{results}->{$oid_psuEntry_single}, + instance => $psu_id + ); + $psus_data{$psu_id} = $result; + } + } + + foreach my $psu_id (sort { $a <=> $b } keys %psus_data) { + my $psu = $psus_data{$psu_id}; + my $instance = $label_prefix . 'psu' . $psu_id; + + next if ($self->check_filter(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + my $status = $psu->{status} // 'unknown'; + $self->{output}->output_add( - severity => $exit, - short_msg => sprintf( - "Power supply '%s' status is '%s'", $instance, $result->{status} + long_msg => sprintf( + "power supply '%s' status is '%s' [powered: %s]", + $instance, + $status, + (defined $psu->{powered} && $psu->{powered} == 1) ? 'yes' : 'no' ) ); + + my $exit = $self->get_severity(section => 'psu', value => $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'", $instance, $status) + ); + } } } } -1; +1; \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/components/temperature.pm b/src/network/stormshield/snmp/mode/components/temperature.pm index 22aa4ad3f9..229820ba33 100644 --- a/src/network/stormshield/snmp/mode/components/temperature.pm +++ b/src/network/stormshield/snmp/mode/components/temperature.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -23,16 +23,20 @@ package network::stormshield::snmp::mode::components::temperature; use strict; use warnings; -my $mapping = { - cpuTemp => { oid => '.1.3.6.1.4.1.11256.1.10.7.1.2' } # snsCpuTemp -}; +# Single-node OIDs +my $oid_cpu_temp_single = '.1.3.6.1.4.1.11256.1.10.7.1.2'; # snsCpuTemp + +# HA OIDs — structure: oid.. +my $oid_cpu_temp_ha = '.1.3.6.1.4.1.11256.1.11.12.1.2'; # snsNodeCpuTemp sub load { my ($self) = @_; - - push @{$self->{request}}, { - oid => $mapping->{cpuTemp}->{oid} - }; + + if ($self->{is_ha}) { + push @{$self->{request}}, { oid => $oid_cpu_temp_ha }; + } else { + push @{$self->{request}}, { oid => $oid_cpu_temp_single }; + } } sub check { @@ -42,38 +46,84 @@ sub check { $self->{components}->{temperature} = { name => 'temperatures', total => 0, skip => 0 }; return if ($self->check_filter(section => 'temperature')); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping->{cpuTemp}->{oid} }})) { - next if ($oid !~ /^$mapping->{cpuTemp}->{oid}\.(.*)$/); + my $nodes = $self->{is_ha} ? $self->{ha_nodes} : ['0']; + my $serials = $self->{ha_serials}; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{cpuTemp}->{oid} }, instance => $1); + foreach my $node_id (@$nodes) { + my $label_prefix = $self->{is_ha} ? $serials->{$node_id} . '_' : ''; - my $instance = 'cpu' . $1; - next if ($self->check_filter(section => 'temperature', instance => $instance)); + my @cpu_ids = (); + my %cpu_temps = (); - $self->{components}->{temperature}->{total}++; - $self->{output}->output_add( - long_msg => sprintf( - "temperature '%s' is %s celsius [instance: %s]", - $instance, $result->{cpuTemp}, $instance - ) - ); + if ($self->{is_ha}) { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cpu_temp_ha}})) { + next if ($oid !~ /^$oid_cpu_temp_ha\.$node_id\.(\d+)$/); + my $cpu_id = $1; + push @cpu_ids, $cpu_id; + $cpu_temps{$cpu_id} = $self->{results}->{$oid_cpu_temp_ha}->{$oid}; + $self->{components}->{temperature}->{total}++; + } + } else { + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cpu_temp_single}})) { + next if ($oid !~ /^$oid_cpu_temp_single\.(\d+)$/); + my $cpu_id = $1; + push @cpu_ids, $cpu_id; + $cpu_temps{$cpu_id} = $self->{results}->{$oid_cpu_temp_single}->{$oid}; + $self->{components}->{temperature}->{total}++; + } + } + + next if (scalar @cpu_ids == 0); + @cpu_ids = sort { $a <=> $b } @cpu_ids; + + my $cpu_sum = 0; + foreach my $cpu_id (@cpu_ids) { + my $temp = $cpu_temps{$cpu_id}; + my $instance = $label_prefix . 'cpu' . $cpu_id; + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + + $cpu_sum += $temp; - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{cpuTemp}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add( - severity => $exit, - short_msg => sprintf( - "temperature '%s' is %s celsius", $instance, $result->{cpuTemp} + long_msg => sprintf( + "temperature '%s' is '%s' celsius", + $instance, $temp ) ); + + $self->{output}->perfdata_add( + nlabel => 'hardware.cpu.temperature.celsius', + unit => 'C', + instances => $instance, + value => $temp, + min => 0 + ); + + my ($exit) = $self->get_severity_numeric( + section => 'temperature', + instance => $instance, + value => $temp + ); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf( + "Temperature '%s' is '%s' celsius", $instance, $temp + ) + ); + } } + + my $cpu_avg = int($cpu_sum / scalar(@cpu_ids)); + my $avg_instance = $label_prefix . 'cpu_average_temp'; + $self->{output}->perfdata_add( - nlabel => 'hardware.temperature.celsius', - unit => 'C', - instances => $instance, - value => $result->{cpuTemp}, - warning => $warn, - critical => $crit, min => 0 + nlabel => 'hardware.cpu.average.temperature.celsius', + unit => 'C', + instances => $avg_instance, + value => $cpu_avg, + min => 0 ); } } diff --git a/src/network/stormshield/snmp/mode/connections.pm b/src/network/stormshield/snmp/mode/connections.pm index 615b97fbbc..761b90265c 100644 --- a/src/network/stormshield/snmp/mode/connections.pm +++ b/src/network/stormshield/snmp/mode/connections.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -24,38 +24,77 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use Digest::MD5 qw(md5_hex); +use centreon::plugins::constants qw(:counters); sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0 }, + { name => 'global', type => COUNTER_TYPE_GLOBAL }, + { name => 'policy', type => COUNTER_TYPE_INSTANCE }, ]; $self->{maps_counters}->{global} = [ { label => 'udp', set => { - key_values => [ { name => 'udp', per_second => 1 } ], - output_template => 'UDP : %d connections/s', + key_values => [ { name => 'udp' } ], + output_template => 'UDP : %d connections', perfdatas => [ { label => 'udp', template => '%d', min => 0, unit => 'con' } ] } }, { label => 'tcp', set => { - key_values => [ { name => 'tcp', per_second => 1 } ], - output_template => 'TCP : %d connections/s', + key_values => [ { name => 'tcp' } ], + output_template => 'TCP : %d connections', perfdatas => [ { label => 'tcp', template => '%d', min => 0, unit => 'con' } ] } + }, + { label => 'major', set => { + key_values => [ { name => 'major' } ], + output_template => 'Major Alarms : %d', + perfdatas => [ + { label => 'major', template => '%d', min => 0, unit => 'alarms' } + ] + } + }, + { label => 'minor', set => { + key_values => [ { name => 'minor' } ], + output_template => 'Minor Alarms : %d', + perfdatas => [ + { label => 'minor', template => '%d', min => 0, unit => 'alarms' } + ] + } } ]; + + $self->{maps_counters}->{policy} = [ + { label => 'policy-dummy', threshold => 0, set => { + key_values => [ { name => 'index' }, { name => 'name' }, { name => 'slot_name' }, + { name => 'active' }, { name => 'sync' } ], + closure_custom_output => $self->can('custom_policy_output'), + perfdatas => [] + } + } + ]; +} + +sub custom_policy_output { + my ($self, %options) = @_; + my $obj = $options{new_datas}; + return sprintf( + "Policy: '%s', slot: '%s', active: '%s', sync: %s", + $self->{result_values}->{name}, + $self->{result_values}->{slot_name}, + $self->{result_values}->{active}, + $self->{result_values}->{sync} ? 'True' : 'False' + ); } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; $options{options}->add_options(arguments => { @@ -67,20 +106,47 @@ sub new { sub manage_selection { my ($self, %options) = @_; - $self->{cache_name} = 'fw_stormshield_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); - - my $oid_ntqASQStatsStatefulUdpConn = '.1.3.6.1.4.1.11256.1.12.1.33.0'; - my $oid_ntqASQStatsStatefulTcpConn = '.1.3.6.1.4.1.11256.1.12.1.23.0'; + my $oid_snsASQStatsStatefulUdpConn = '.1.3.6.1.4.1.11256.1.12.1.33.0'; + my $oid_snsASQStatsStatefulTcpConn = '.1.3.6.1.4.1.11256.1.12.1.23.0'; + my $oid_snsASQStatsStatefulMajorAlarm = '.1.3.6.1.4.1.11256.1.12.1.12.0'; + my $oid_snsASQStatsStatefulMinorAlarm = '.1.3.6.1.4.1.11256.1.12.1.11.0'; - my $result = $options{snmp}->get_leef( - oids => [ $oid_ntqASQStatsStatefulUdpConn, $oid_ntqASQStatsStatefulTcpConn ], + my $result_asq = $options{snmp}->get_leef( + oids => [ $oid_snsASQStatsStatefulUdpConn, $oid_snsASQStatsStatefulTcpConn, $oid_snsASQStatsStatefulMajorAlarm, $oid_snsASQStatsStatefulMinorAlarm ], nothing_quit => 1 ); $self->{global} = { - udp => $result->{$oid_ntqASQStatsStatefulUdpConn}, - tcp => $result->{$oid_ntqASQStatsStatefulTcpConn} + udp => $result_asq->{$oid_snsASQStatsStatefulUdpConn}, + tcp => $result_asq->{$oid_snsASQStatsStatefulTcpConn}, + major => $result_asq->{$oid_snsASQStatsStatefulMajorAlarm}, + minor => $result_asq->{$oid_snsASQStatsStatefulMinorAlarm} }; + + + my $oid_snsPolicyIndex = '.1.3.6.1.4.1.11256.1.8.1.1.1'; + my $oid_snsPolicyName = '.1.3.6.1.4.1.11256.1.8.1.1.2'; + my $oid_snsPolicySlotName = '.1.3.6.1.4.1.11256.1.8.1.1.3'; + my $oid_snsPolicyActive = '.1.3.6.1.4.1.11256.1.8.1.1.4'; + my $oid_snsPolicySync = '.1.3.6.1.4.1.11256.1.8.1.1.5'; + + my $result_policy = $options{snmp}->get_table( + oid => '.1.3.6.1.4.1.11256.1.8.1.1', + nothing_quit => 1 + ); + + $self->{policy} = {}; + foreach my $oid (keys %{$result_policy}) { + next unless $oid =~ /^$oid_snsPolicyIndex\.(\d+)$/; + my $idx = $1; + $self->{policy}->{$idx} = { + index => $idx, + name => $result_policy->{"$oid_snsPolicyName.$idx"} // '', + slot_name => $result_policy->{"$oid_snsPolicySlotName.$idx"} // '', + active => $result_policy->{"$oid_snsPolicyActive.$idx"} // '', + sync => $result_policy->{"$oid_snsPolicySync.$idx"} // 0, + }; + } } 1; @@ -89,20 +155,42 @@ __END__ =head1 MODE -Check connections setup rate on Stormshield Firewall equipments. +Check connections setup rate and policy table on Stormshield Firewall equipments. =over 8 -=item B<--warning-*> +=item B<--warning-tcp> + +Warning threshold for TCP connections. + +=item B<--warning-udp> + +Warning threshold for UDP connections. + +=item B<--warning-major> + +Warning threshold for Major Alarms. + +=item B<--warning-minor> + +Warning threshold for Minor Alarms. + +=item B<--critical-tcp> + +Critical threshold for TCP connections. + +=item B<--critical-udp> + +Critical threshold for UDP connections. + +=item B<--critical-major> -Warning threshold. -Can be: 'tcp', 'udp' +Critical threshold for Major Alarms. -=item B<--critical-*> +=item B<--critical-minor> -Critical threshold. -Can be: 'tcp', 'udp' +Critical threshold for Minor Alarms. =back -=cut +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/ha_cluster.pm b/src/network/stormshield/snmp/mode/ha_cluster.pm new file mode 100644 index 0000000000..0b4a2fb128 --- /dev/null +++ b/src/network/stormshield/snmp/mode/ha_cluster.pm @@ -0,0 +1,334 @@ +# Copyright 2026-Present 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::stormshield::snmp::mode::ha_cluster; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::constants qw(:counters); + + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf( + "Configuration Synced: %s", + $self->{result_values}->{sync_status} + ); +} + +sub custom_node_output { + my ($self, %options) = @_; + + return sprintf( + "Dead Nodes: %s/%s (%s%%)", + $self->{result_values}->{dead_nodes}, + $self->{result_values}->{nb_nodes}, + $self->{result_values}->{dead_pct}, + ); +} + +sub custom_link_output { + my ($self, %options) = @_; + + return sprintf( + "Faulty Links: %s/%s (%s%%)", + $self->{result_values}->{faulty_links}, + $self->{result_values}->{nb_links}, + $self->{result_values}->{faulty_pct}, + ); +} + +sub custom_active_output { + my ($self, %options) = @_; + + return sprintf( + "Active Firewalls: %s/2", + $self->{result_values}->{nb_active}, + ); +} + + +sub custom_node_perfdata { + my ($self, %options) = @_; + my $nb = $self->{result_values}->{nb_nodes}; + my $warn = defined($nb) ? int($nb * 0.5) : undef; + my $crit = defined($nb) ? $nb : undef; + + $self->{output}->perfdata_add( + label => 'ha.dead_nodes.count', + value => $self->{result_values}->{dead_nodes}, + warning => $warn, + critical => $crit, + min => 0, + max => $nb, + ) +} + +sub custom_link_perfdata { + my ($self, %options) = @_; + my $nb = $self->{result_values}->{nb_links}; + my $warn = defined($nb) ? int($nb * 0.5) : undef; + my $crit = defined($nb) ? $nb : undef; + + $self->{output}->perfdata_add( + label => 'ha.faulty_links.count', + value => $self->{result_values}->{faulty_links}, + warning => $warn, + critical => $crit, + min => 0, + max => $nb, + ) +} + +sub custom_node_threshold { + my ($self, %options) = @_; + my $nb = $self->{result_values}->{nb_nodes}; + my $dead = $self->{result_values}->{dead_nodes}; + return 'OK' if !defined($nb) || $nb == 0; + return 'WARNING' if $dead >= int($nb*0.5); + return 'CRITICAL' if $dead >= $nb; + return 'OK'; +} + + +sub custom_link_threshold { + my ($self, %options) = @_; + my $nb = $self->{result_values}->{nb_links}; + my $dead = $self->{result_values}->{faulty_links}; + return 'OK' if !defined($nb) || $nb == 0; + return 'WARNING' if $dead >= int($nb*0.5); + return 'CRITICAL' if $dead >= $nb; + return 'OK'; +} + +sub custom_active_threshold { + my ($self, %options) = @_; + my $nb = $self->{result_values}->{nb_active}; + return 'OK' if !defined($nb) || $nb == 1; + return 'CRITICAL' if $nb == 2 || $nb == 0; + return 'UNKNOWN'; +} + +sub custom_sync_threshold { + my ($self, %options) = @_; + return 'WARNING' if $self->{result_values}->{sync_status} eq 'False'; + return 'OK'; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { + label => 'dead-nodes', + set => { + key_values => [ { name => 'dead_nodes' }, { name => 'nb_nodes' }, { name => 'dead_pct' } ], + closure_custom_output => $self->can('custom_node_output'), + closure_custom_perfdata => $self->can('custom_node_perfdata'), + closure_custom_threshold_check => $self->can('custom_node_threshold'), + } + }, + { + label => 'faulty-links', + set => { + key_values => [ { name => 'faulty_links' }, { name => 'nb_links' }, { name => 'faulty_pct' } ], + closure_custom_output => $self->can('custom_link_output'), + closure_custom_perfdata => $self->can('custom_link_perfdata'), + closure_custom_threshold_check => $self->can('custom_link_threshold'), + } + }, + { + label => 'active-firewall', + set => { + key_values => [ { name => 'nb_active' } ], + closure_custom_output => $self->can('custom_active_output'), + closure_custom_threshold_check => $self->can('custom_active_threshold'), + } + }, + { + label => 'sync-status', + set => { + key_values => [ { name => 'sync_status' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_sync_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => {}); + + $self->{output}->{option_results}->{verbose} = 1; + + return $self; +} + + +my $oid_snsNode = '.1.3.6.1.4.1.11256.1.11.7.1'; +my $oid_snsNbNode = '.1.3.6.1.4.1.11256.1.11.1.0'; +my $oid_snsNbDeadNode = '.1.3.6.1.4.1.11256.1.11.2.0'; +my $oid_snsNbActiveNode = '.1.3.6.1.4.1.11256.1.11.3.0'; +my $oid_snsNbHALinks = '.1.3.6.1.4.1.11256.1.11.5.0'; +my $oid_snsNbFaultyHALinks = '.1.3.6.1.4.1.11256.1.11.6.0'; +my $oid_snsHASyncStatus = '.1.3.6.1.4.1.11256.1.11.8.0'; + + +my %mapping = ( + snsNodeIndex => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.1' }, + snsFwSerial => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.2' }, + snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.3' }, + snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.4' }, + snsVersion => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.5' }, + snsHALicence => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.6' }, + snsHAQuality => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.7' }, + snsHAPriority => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.8' }, + snsHAStatusForced => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.9' }, + snsHAActive => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.10' }, +); + +my %map_online = ( 0 => 'False', 1 => 'True' ); +my %map_status = ( 0 => 'False', 1 => 'True' ); +my %map_act_pass = ( 2 => 'Passive', 1 => 'Active' ); +my %map_sync = ( 0 => 'False', 1 => 'True' ); + + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result_scalar = $options{snmp}->get_leef( + oids => [ + $oid_snsNbNode, + $oid_snsNbDeadNode, + $oid_snsNbActiveNode, + $oid_snsNbHALinks, + $oid_snsNbFaultyHALinks, + $oid_snsHASyncStatus, + ], + nothing_quit => 0 + ); + + my $nb_nodes = $snmp_result_scalar->{$oid_snsNbNode} // 0; + my $dead_nodes = $snmp_result_scalar->{$oid_snsNbDeadNode} // 0; + my $nb_active = $snmp_result_scalar->{$oid_snsNbActiveNode} // 0; + my $nb_links = $snmp_result_scalar->{$oid_snsNbHALinks} // 0; + my $faulty_links = $snmp_result_scalar->{$oid_snsNbFaultyHALinks} // 0; + my $sync_raw = $snmp_result_scalar->{$oid_snsHASyncStatus} // -1; + + if (!(defined $nb_nodes && $nb_nodes > 0)) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => 'No HA cluster detected' + ); + return; + } + + my $dead_pct = ($nb_nodes > 0) ? int(($dead_nodes / $nb_nodes) * 100) : 0; + my $faulty_pct = ($nb_links > 0) ? int(($faulty_links / $nb_links) * 100) : 0; + my $sync_str = $map_sync{$sync_raw} // 'UNKNOWN'; + + $self->{global} = { + dead_nodes => $dead_nodes, + nb_nodes => $nb_nodes, + dead_pct => $dead_pct, + faulty_links => $faulty_links, + nb_links => $nb_links, + faulty_pct => $faulty_pct, + nb_active => $nb_active, + sync_status => $sync_str, + }; + + my $snmp_result_table = $options{snmp}->get_table( + oid => $oid_snsNode, + nothing_quit => 1 + ); + + my %nodes; + foreach my $oid (sort keys %{$snmp_result_table}) { + foreach my $field (keys %mapping) { + my $col_oid = $mapping{$field}->{oid}; + next if !defined($col_oid); + if ($oid =~ /^\Q$col_oid\E\.(\d+)$/) { + my $idx = $1; + $nodes{$idx}->{$field} = $snmp_result_table->{$oid}; + } + } + } + + + my $cluster_desc = "---- Cluster Description ----\n"; + + foreach my $idx(sort { $a <=> $b } keys %nodes) { + my $n = $nodes{$idx}; + + my $serial = $n->{snsFwSerial} // 'N/A'; + my $model = $n->{snsOnline} // 'N/A'; + my $version = $n->{snsVersion} // 'N/A'; + my $status_f = $map_status{$n->{snsHAStatusForced} // 0 } // 'UNKNOWN'; + my $act_pass = $map_act_pass{$n->{snsHAActive} // 0 } // 'UNKNOWN'; + my $online = $map_online{$n->{snsOnline} // 0 } // 'UNKNOWN'; + my $licence = $n->{snsHALicence} // 'N/A'; + my $quality = $n->{snsHAQuality} // 'N/A'; + my $priority = $n->{snsHAPriority} // 'N/A'; + + + $cluster_desc .= sprintf( + "Serial: %s\nModel: %s\nVersion: %s\nStatus Forced: %s\nActive/Passive: %s\nOnline: %s\nLicense: %s\nQuality: %s\nPriority: %s\n%s\n", + $serial, + $model, + $version, + $status_f, + $act_pass, + $online, + $licence, + $quality, + $priority, + '-' x 25 + ); + } + + $self->{output}->output_add(long_msg => $cluster_desc); +} + +1; + +__END__ + +=head1 MODE + +Check Stormshield HA cluster global status. + +=over 8 + +=back + +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/hardware.pm b/src/network/stormshield/snmp/mode/hardware.pm index dc337cfb95..176fe62f77 100644 --- a/src/network/stormshield/snmp/mode/hardware.pm +++ b/src/network/stormshield/snmp/mode/hardware.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -25,36 +25,78 @@ use base qw(centreon::plugins::templates::hardware); use strict; use warnings; +my $oid_snsNodeIndex = '.1.3.6.1.4.1.11256.1.11.7.1.1'; +my $oid_snsFwSerial = '.1.3.6.1.4.1.11256.1.11.7.1.2'; + sub set_system { my ($self, %options) = @_; $self->{regexp_threshold_numeric_check_section_option} = '^(?:fan|temperature)$'; - + + $self->{cb_hook1} = 'detect_topology'; $self->{cb_hook2} = 'snmp_execute'; - + $self->{thresholds} = { fan => [ ['running', 'OK'], - ['.*', 'CRITICAL'] + ['.*', 'CRITICAL'] ], psu => [ - ['OK', 'OK'], - ['.*', 'CRITICAL'] + ['OK', 'OK'], + ['.*', 'CRITICAL'] ], - raid => [ - ['optimal', 'OK'], - ['.*', 'CRITICAL'] + disk => [ + ['PASSED', 'OK'], + ['NotSupported', 'OK'], + ['.*', 'CRITICAL'] ] }; - - $self->{components_path} = 'network::stormshield::snmp::mode::components'; - $self->{components_module} = ['disk', 'fan', 'psu', 'temperature']; + + $self->{components_path} = 'network::stormshield::snmp::mode::components'; + $self->{components_module} = ['temperature', 'fan', 'psu', 'disk']; } -sub snmp_execute { +sub detect_topology { my ($self, %options) = @_; - + $self->{snmp} = $options{snmp}; + + my $ha_result = $options{snmp}->get_table( + oid => $oid_snsNodeIndex, + nothing_quit => 0 + ); + + $self->{ha_nodes} = []; + $self->{ha_serials} = {}; + + if (!defined $ha_result || scalar(keys %$ha_result) == 0) { + # Single Node + $self->{is_ha} = 0; + push @{$self->{ha_nodes}}, '0'; + $self->{ha_serials}->{'0'} = 'single'; + return; + } + + # HA + $self->{is_ha} = 1; + foreach my $oid (sort keys %$ha_result) { + if ($oid =~ /^$oid_snsNodeIndex\.(\d+)$/) { + push @{$self->{ha_nodes}}, $1; + } + } + + my @serial_oids = map { "$oid_snsFwSerial.$_" } @{$self->{ha_nodes}}; + my $serial_res = $options{snmp}->get_leef(oids => \@serial_oids, nothing_quit => 0); + foreach my $node_id (@{$self->{ha_nodes}}) { + my $s = $serial_res->{"$oid_snsFwSerial.$node_id"}; + $self->{ha_serials}->{$node_id} = defined $s ? $s : "node$node_id"; + } +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); } @@ -74,7 +116,8 @@ __END__ =head1 MODE -Check hardware. +Check hardware components (temperature, fan, PSU, disk). +Automatically detects single-node and high-availability (HA) cluster configurations. =over 8 @@ -85,13 +128,14 @@ Can be: 'disk', 'fan', 'psu', 'temperature'. =item B<--filter> -Exclude the items given as a comma-separated list (example: --filter=fan). -You can also exclude items from specific instances: --filter=fan,1 +Exclude items given as a comma-separated list (example: --filter=fan). +You can also exclude specific instances: --filter=fan,1 =item B<--absent-problem> -Return an error if a component is not 'present' (default is skipping). -It can be set globally or for a specific instance: --absent-problem='component_name' or --absent-problem='component_name,instance_value'. +Return an error if a component is not present (default: skip). +Can be set globally or per instance: --absent-problem='component_name' or +--absent-problem='component_name,instance_value'. =item B<--no-component> @@ -99,27 +143,30 @@ Define the expected status if no components are found (default: critical). =item B<--threshold-overload> -Use this option to override the status returned by the plugin when the status label matches a regular expression (syntax: section,[instance,]status,regexp). +Override the status returned by the plugin when the status label matches a +regular expression (syntax: section,[instance,]status,regexp). Example: --threshold-overload='disk,WARNING,missing' =item B<--warning> -Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) -Example: --warning='temperature,.*,40' +Set warning threshold for 'temperature' or 'fan' (syntax: type,regexp,threshold). +Example: --warning='temperature,.*,60' =item B<--critical> -Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) -Example: --critical='temperature,.*,50' +Set critical threshold for 'temperature' or 'fan' (syntax: type,regexp,threshold). +Example: --critical='temperature,.*,70' =item B<--warning-count-*> -Define the warning threshold for the number of components of one type (replace '*' with the component type). +Define the warning threshold for the number of components of one type +(replace '*' with the component type). =item B<--critical-count-*> -Define the critical threshold for the number of components of one type (replace '*' with the component type). +Define the critical threshold for the number of components of one type +(replace '*' with the component type). =back -=cut +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/health.pm b/src/network/stormshield/snmp/mode/health.pm index 7fab848355..9364ed6d0d 100644 --- a/src/network/stormshield/snmp/mode/health.pm +++ b/src/network/stormshield/snmp/mode/health.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -25,26 +25,39 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::constants qw/:counters :values/; + +our $GLOBAL_PROBLEM; sub custom_service_status_output { my ($self, %options) = @_; - return sprintf( + my $msg = sprintf( "health: %s", $self->{result_values}->{health} ); -} -sub firewall_long_output { - my ($self, %options) = @_; + my $health = $self->{result_values}->{health}; + + if ($health !~ /minor/i && $health !~ /major/i) { + if (!$GLOBAL_PROBLEM) { + $self->{output}->output_add( + long_msg => "service '" . $self->{result_values}->{service} . "' " . $msg + ); + } + } - return "checking firewall '" . $options{instance_value}->{display} . "'"; + return $msg; } -sub prefix_firewall_output { +sub firewall_long_output { my ($self, %options) = @_; + my $display = $options{instance_value}->{display}; - return "firewall '" . $options{instance_value}->{display} . "' "; + if (defined $display && $display ne '') { + return "--------------Firewall $display--------------"; + } + return "------------------------------------------------------------"; } sub prefix_service_output { @@ -57,10 +70,16 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'firewalls', type => 3, cb_prefix_output => 'prefix_firewall_output', cb_long_output => 'firewall_long_output', - indent_long_output => ' ', message_multiple => 'All firewalls are ok', + { name => 'firewalls', type => COUNTER_TYPE_GROUP, cb_long_output => 'firewall_long_output', + message_multiple => 'All firewalls are ok', group => [ - { name => 'services', display_long => 1, cb_prefix_output => 'prefix_service_output', message_multiple => 'All services are ok', type => 1, skipped_code => { -10 => 1 } } + { + name => 'services', + display_long => 1, + cb_prefix_output => 'prefix_service_output', + message_multiple => 'All services are ok', + type => COUNTER_TYPE_INSTANCE, + skipped_code => { -10 => 1 } } ] } ]; @@ -68,7 +87,7 @@ sub set_counters { $self->{maps_counters}->{services} = [ { label => 'service-status', - type => 2, + type => COUNTER_KIND_TEXT, warning_default => '%{health} =~ /minor/i', critical_default => '%{health} =~ /major/i', set => { @@ -94,18 +113,21 @@ sub new { } my $mapping = { + hamode => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.3' }, # snsHaModeHealth link => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.4' }, # snsHaLinkHealth powersupply => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.5' }, # snsPowerSupplyHealth fan => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.6' }, # snsFanHealth - cpu => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.7' }, # snsFanHealth + cpu => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.7' }, # snsCpuHealth memory => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.8' }, # snsMemHealth disk => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.9' }, # snsDiskHealth raid => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.10' }, # snsRaidHealth certificate => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.11' }, # snsCertHealth CRL => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.12' }, # snsCRLHealth - #password => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.13' }, # snsPasswdHealth - #cpu_temperature => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.14' }, # snsCpuTempHealth - #TPM => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.15' } # snsTPMHealth + TPM => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.13' }, # snsTPMHealth + password => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.14' }, # snsPasswdHealth + cpu_temperature => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.15' }, # snsCpuTempHealth + router => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.16' }, # snsRouterHealth + NTP => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.17' }, # snsNTPHealth }; my $oid_snsSerialHealth = '.1.3.6.1.4.1.11256.1.16.2.1.2'; @@ -130,13 +152,20 @@ sub manage_selection { } $self->{firewalls}->{$instance} = { - display => $serial, + display => $serial, services => {} }; } return if (scalar(keys %{$self->{firewalls}}) <= 0); + $GLOBAL_PROBLEM = 0; + + my @instances = keys %{$self->{firewalls}}; + if (scalar(@instances) == 1) { + $self->{firewalls}->{ $instances[0] }->{display} = ''; + } + $options{snmp}->load( oids => [ map($_->{oid}, values(%$mapping)) ], instances => [ keys %{$self->{firewalls}} ], @@ -147,9 +176,13 @@ sub manage_selection { my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); foreach my $service (keys %$result) { + my $health = $result->{$service}; + if (defined $health && ($health =~ /minor/i || $health =~ /major/i)) { + $GLOBAL_PROBLEM = 1; + } $self->{firewalls}->{$_}->{services}->{$service} = { service => $service, - health => $result->{$service} + health => $health }; } } @@ -186,4 +219,4 @@ You can use the following variables: %{health}, %{service} =back -=cut +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/interfaces_disco.pm b/src/network/stormshield/snmp/mode/interfaces_disco.pm new file mode 100644 index 0000000000..44ca98bcc4 --- /dev/null +++ b/src/network/stormshield/snmp/mode/interfaces_disco.pm @@ -0,0 +1,510 @@ +# +# Copyright 2026-Present 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::stormshield::snmp::mode::interfaces_disco; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::constants qw/:counters :values/; + +sub generic_interface_output { + my ($self, %options) = @_; + return sprintf("Interface %s, Address: %s, Mask: %s, Type: %s, Is Protected: %s", + $self->{result_values}->{if_name}, + $self->{result_values}->{if_address}, + $self->{result_values}->{if_mask}, + $self->{result_values}->{if_type}, + $self->{result_values}->{if_protected}, + ); +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { + name => 'interfaces', + type => COUNTER_TYPE_INSTANCE, + message_multiple => 'All interfaces are OK', + display_long => 1, + skipped_code => { -10 => 1 } + } + ]; + + $self->{maps_counters}->{interfaces} = [ + { + label => 'textual-info', + type => COUNTER_KIND_TEXT, + set => { + key_values => [ + { name => 'if_name' }, + { name => 'if_address' }, + { name => 'if_mask' }, + { name => 'if_type' }, + { name => 'if_protected' } + ], + closure_custom_output => $self->can('generic_interface_output'), + } + }, + { + label => 'throughput-in', + nlabel => 'interface.throughput.in.bitspersecond', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_throughput_in' }, + { name => 'if_name' } + ], + output_template => 'Throughput In: %s b/s', + perfdatas => [ + { + label => 'throughput_in', + value => 'if_throughput_in', + template => '%s', + unit => 'b/s', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-throughput-in'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-throughput-in'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'throughput-out', + nlabel => 'interface.throughput.out.bitspersecond', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_throughput_out' }, + { name => 'if_name' } + ], + output_template => 'Throughput Out: %s b/s', + perfdatas => [ + { + label => 'throughput_out', + value => 'if_throughput_out', + template => '%s', + unit => 'b/s', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-throughput-out'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-throughput-out'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'current-tcp', + nlabel => 'interface.connections.tcp.count', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_current_tcp' }, + { name => 'if_name' } + ], + output_template => 'Current TCP Connections: %s', + perfdatas => [ + { + label => 'current_tcp_con', + value => 'if_current_tcp', + template => '%s', + unit => 'con', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-current-tcp'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-current-tcp'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'current-udp', + nlabel => 'interface.connections.udp.count', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_current_udp' }, + { name => 'if_name' } + ], + output_template => 'Current UDP Connections: %s', + perfdatas => [ + { + label => 'current_udp_con', + value => 'if_current_udp', + template => '%s', + unit => 'con', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-current-udp'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-current-udp'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'tcp-in', + nlabel => 'interface.traffic.tcp.in.bytes', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_tcp_in' }, + { name => 'if_name' } + ], + output_template => 'TCP In: %s bytes', + perfdatas => [ + { + label => 'tcp_in', + value => 'if_tcp_in', + template => '%s', + unit => 'bytes', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-tcp-in'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-tcp-in'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'tcp-out', + nlabel => 'interface.traffic.tcp.out.bytes', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_tcp_out' }, + { name => 'if_name' } + ], + output_template => 'TCP Out: %s bytes', + perfdatas => [ + { + label => 'tcp_out', + value => 'if_tcp_out', + template => '%s', + unit => 'bytes', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-tcp-out'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-tcp-out'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'udp-in', + nlabel => 'interface.traffic.udp.in.bytes', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_udp_in' }, + { name => 'if_name' } + ], + output_template => 'UDP In: %s bytes', + perfdatas => [ + { + label => 'udp_in', + value => 'if_udp_in', + template => '%s', + unit => 'bytes', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-udp-in'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-udp-in'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'udp-out', + nlabel => 'interface.traffic.udp.out.bytes', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_udp_out' }, + { name => 'if_name' } + ], + output_template => 'UDP Out: %s bytes', + perfdatas => [ + { + label => 'udp_out', + value => 'if_udp_out', + template => '%s', + unit => 'bytes', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-udp-out'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-udp-out'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'packets-accepted', + nlabel => 'interface.packets.accepted.count', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_pack_accepted' }, + { name => 'if_name' } + ], + output_template => 'Packets Accepted: %s', + perfdatas => [ + { + label => 'pack_accepted', + value => 'if_pack_accepted', + template => '%s', + unit => 'packets', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-packets-accepted'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-packets-accepted'), + instance_use => 'if_name' + } + ] + } + }, + { + label => 'packets-blocked', + nlabel => 'interface.packets.blocked.count', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'if_pack_blocked' }, + { name => 'if_name' } + ], + output_template => 'Packets Blocked: %s', + perfdatas => [ + { + label => 'pack_blocked', + value => 'if_pack_blocked', + template => '%s', + unit => 'packets', + min => 0, + label_extra_instance => 1, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-packets-blocked'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-packets-blocked'), + instance_use => 'if_name' + } + ] + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + }); + + return $self; +} + +my $mapping = { + snsifName => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.2' }, + snsifAddr => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.4' }, + snsifMask => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.5' }, + snsifType => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.6' }, + snsifProtected => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.37' }, + snsifPktAccepted => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.11' }, + snsifPktBlocked => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.12' }, + snsifTcpConnCount => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.23' }, + snsifUdpConnCount => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.24' }, + snsifInCurThroughput => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.25' }, + snsifOutCurThroughput => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.26' }, + snsifInTcpBytes => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.31' }, + snsifOutTcpBytes => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.32' }, + snsifInUdpBytes => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.33' }, + snsifOutUdpBytes => { oid => '.1.3.6.1.4.1.11256.1.4.1.1.34' } +}; +my $oid_snsifEntry = '.1.3.6.1.4.1.11256.1.4.1.1'; + + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_snsifEntry, + start => $mapping->{snsifName}->{oid}, + end => $mapping->{snsifProtected}->{oid}, + ); + + + $self->{interfaces} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{snsifName}->{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->{snsifName} ne $self->{option_results}->{filter_name}) || ($result->{snsifName} =~ /^mgmt/)) { + next; + } + + $self->{interfaces}->{$instance} = { + if_name => $result->{snsifName} // '-', + if_address => $result->{snsifAddr} // '-', + if_mask => $result->{snsifMask} // '-', + if_type => $result->{snsifType} // '-', + if_protected => ($result->{snsifProtected} ? 'true' : 'false'), + if_throughput_in => $result->{snsifInCurThroughput} // 0, + if_throughput_out => $result->{snsifOutCurThroughput} // 0, + if_current_tcp => $result->{snsifTcpConnCount} // 0, + if_current_udp => $result->{snsifUdpConnCount} // 0, + if_tcp_in => $result->{snsifInTcpBytes} // 0, + if_tcp_out => $result->{snsifOutTcpBytes} // 0, + if_udp_in => $result->{snsifInUdpBytes} // 0, + if_udp_out => $result->{snsifOutUdpBytes} // 0, + if_pack_accepted => $result->{snsifPktAccepted} // 0, + if_pack_blocked => $result->{snsifPktBlocked} // 0, + }; + } + + if (scalar(keys %{$self->{interfaces}}) <= 0) { + $self->{output}->add_option_msg( + short_msg => 'No interface found matching: ' . ($self->{option_results}->{filter_name} // '') + ); + $self->{output}->option_exit(); + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['if_name', 'if_address', 'if_mask', 'if_type', 'if_protected', 'if_throughput_in', 'if_throughput_out', 'if_current_tcp', 'if_current_udp', 'if_tcp_in', 'if_tcp_out', 'if_udp_in', 'if_udp_out', 'if_pack_accepted', 'if_pack_blocked']); +} + +sub disco_show { + my ($self, %options) = @_; + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{interfaces}}) { + $self->{output}->add_disco_entry(%{$self->{interfaces}->{$instance}}); + } +} + +1; + +__END__ + +=head1 MODE + +This mode retrieves and displays the status of interfaces on the Stormshield device, including their name, global in/out traffic, TCP/UDP in/out traffic, and packet acceptance/blocking statistics. + +=over 8 + +=item B<--filter-name> + +Filter by name to only display this interface + +=item B<--warning-throughput-in> + +Set the warning threshold for throughput in (bits per second). + +=item B<--critical-throughput-in> + +Set the critical threshold for throughput in (bits per second). + +=item B<--warning-throughput-out> + +Set the warning threshold for throughput out (bits per second). + +=item B<--critical-throughput-out> + +Set the critical threshold for throughput out (bits per second). + +=item B<--warning-current-tcp> + +Set the warning threshold for current TCP connections. + +=item B<--critical-current-tcp> + +Set the critical threshold for current TCP connections. + +=item B<--warning-current-udp> + +Set the warning threshold for current UDP connections. + +=item B<--critical-current-udp> + +Set the critical threshold for current UDP connections. + +=item B<--warning-tcp-in> + +Set the warning threshold for TCP in traffic (bytes). + +=item B<--critical-tcp-in> + +Set the critical threshold for TCP in traffic (bytes). + +=item B<--warning-tcp-out> + +Set the warning threshold for TCP out traffic (bytes). + +=item B<--critical-tcp-out> + +Set the critical threshold for TCP out traffic (bytes). + +=item B<--warning-udp-in> + +Set the warning threshold for UDP in traffic (bytes). + +=item B<--critical-udp-in> + +Set the critical threshold for UDP in traffic (bytes). + +=item B<--warning-udp-out> + +Set the warning threshold for UDP out traffic (bytes). + +=item B<--critical-udp-out> + +Set the critical threshold for UDP out traffic (bytes). + +=item B<--warning-packets-accepted> + +Set the warning threshold for packets accepted. + +=item B<--critical-packets-accepted> + +Set the critical threshold for packets accepted. + +=item B<--warning-packets-blocked> + +Set the warning threshold for packets blocked. + +=item B<--critical-packets-blocked> + +Set the critical threshold for packets blocked. + +=back + +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index 36fc7b46b3..bd82835187 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -24,152 +24,285 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::constants qw/:counters :values/; +use centreon::plugins::misc; -sub prefix_memory_output { - my ($self, %options) = @_; - - return 'Memory usage '; -} +my @mem_labels = qw(asq icmp frag host system dtrack socket etherstate user); sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ - { name => 'global', type => 0, cb_prefix_output => 'prefix_memory_output', skipped_code => { -10 => 1 } } + { name => 'global', type => 0, skipped_code => { NO_VALUE() => 1 } } ]; - + $self->{maps_counters}->{global} = [ - { label => 'total', nlabel => 'memory.usage.percentage', set => { - key_values => [ { name => 'total' } ], - output_template => 'total: %.2f %%', + { label => 'asq', set => { + key_values => [ { name => 'asq' } ], + output_template => "ASQ: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_asq', + value => 'asq', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'host', nlabel => 'memory.protected_host.percentage', set => { - key_values => [ { name => 'host' } ], - output_template => 'protected host: %.2f %%', + { label => 'icmp', set => { + key_values => [ { name => 'icmp' } ], + output_template => "ICMP: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_icmp', + value => 'icmp', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'frag', nlabel => 'memory.fragmented.percentage', set => { + { label => 'frag', set => { key_values => [ { name => 'frag' } ], - output_template => 'fragmented: %.2f %%', + output_template => "Frag: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_frag', + value => 'frag', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'conn', nlabel => 'memory.connections.percentage', set => { - key_values => [ { name => 'conn' } ], - output_template => 'connections: %.2f %%', + { label => 'host', set => { + key_values => [ { name => 'host' } ], + output_template => "Host: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_host', + value => 'host', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'icmp', nlabel => 'memory.icmp.percentage', set => { - key_values => [ { name => 'icmp' } ], - output_template => 'icmp: %.2f %%', + { label => 'system', set => { + key_values => [ { name => 'system' } ], + output_template => "System: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_system', + value => 'system', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'dtrack', nlabel => 'memory.data_tracking.percentage', set => { + { label => 'dtrack', set => { key_values => [ { name => 'dtrack' } ], - output_template => 'data tracking: %.2f %%', + output_template => "Data Tracking: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_dtrack', + value => 'dtrack', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'dyn', nlabel => 'memory.dynamic.percentage', set => { - key_values => [ { name => 'dyn' } ], - output_template => 'dynamic: %.2f %%', + { label => 'socket', set => { + key_values => [ { name => 'socket' } ], + output_template => "Socket: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_socket', + value => 'socket', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, - { label => 'etherstate', nlabel => 'memory.ether_state.percentage', set => { - key_values => [ { name => 'ether_state' } ], - output_template => 'ether state: %.2f %%', + { label => 'etherstate', set => { + key_values => [ { name => 'etherstate' } ], + output_template => "EtherState: %s%%", perfdatas => [ - { template => '%.2f', min => 0, max => 100, unit => '%' } + { + label => 'mem_etherstate', + value => 'etherstate', + template => '%s', + unit => '%', + min => 0, + max => 100, + } ] } }, + # only for version >= 4.8.9 + { label => 'user', set => { + key_values => [ { name => 'user' } ], + output_template => "User: %s%%", + perfdatas => [ + { + label => 'mem_user', + value => 'user', + template => '%s', + unit => '%', + min => 0, + max => 100, + } + ] + } + } ]; } sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - - $options{options}->add_options(arguments => {}); - + + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning_memory' }, + "critical:s" => { name => 'critical_memory' }, + }); + return $self; } +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $label (@mem_labels) { + if (($self->{perfdata}->threshold_validate(label => 'warning-' . $label,value => $self->{option_results}->{warning_memory})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning_memory} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-' . $label,value => $self->{option_results}->{critical_memory})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical_memory} . "'."); + $self->{output}->option_exit(); + } + } +} + sub manage_selection { my ($self, %options) = @_; - my $oid_snsMem = '.1.3.6.1.4.1.11256.1.10.3.0'; - my $snmp_result = $options{snmp}->get_leef( - oids => [ $oid_snsMem ], - nothing_quit => 1 - ); - - # host,frag,icmp,conn,dtrack,dyn - # host,frag,icmp,conn,ether_state,dtrack,dyn - - my @values = split(/,/, $snmp_result->{$oid_snsMem}); - my $fields = scalar(@values); - if ($fields == 7) { - $self->{global} = { - total => $values[0] + $values[1] + $values[2] + $values[3] + $values[4] + $values[5] + $values[6], - host => $values[0], - frag => $values[1], - icmp => $values[2], - conn => $values[3], - ether_state => $values[4], - dtrack => $values[5], - dyn => $values[6] - }; - } elsif ($fields == 6) { - $self->{global} = { - total => $values[0] + $values[1] + $values[2] + $values[3] + $values[4] + $values[5], - host => $values[0], - frag => $values[1], - icmp => $values[2], - conn => $values[3], - dtrack => $values[4], - dyn => $values[5] - }; + my $oid_os_version = '.1.3.6.1.4.1.11256.1.0.2.0'; + + # Récupération de la version pour déterminer quel OID utiliser + my $snmp_result = $options{snmp}->get_leef(oids => [ $oid_os_version ], nothing_quit => 1); + my $version_raw = $snmp_result->{$oid_os_version}; + my $version_clean = $version_raw; + $version_clean =~ s/([0-9]+(?:\.[0-9]+)*).*/$1/; + + my %mem_values; + my $is_new_version = centreon::plugins::misc::minimal_version($version_clean, '4.8.9'); + + if ($is_new_version) { + # version >= 4.8.9 + my $oids = [ + '.1.3.6.1.4.1.11256.1.10.10.1.2.1', # snsMemHost + '.1.3.6.1.4.1.11256.1.10.10.1.3.1', # snsMemFrag + '.1.3.6.1.4.1.11256.1.10.10.1.4.1', # snsMemIcmp + '.1.3.6.1.4.1.11256.1.10.10.1.5.1', # snsMemConn + '.1.3.6.1.4.1.11256.1.10.10.1.6.1', # snsMemEther + '.1.3.6.1.4.1.11256.1.10.10.1.7.1', # snsMemDataTrack + '.1.3.6.1.4.1.11256.1.10.10.1.8.1', # snsMemSystem + '.1.3.6.1.4.1.11256.1.10.10.1.9.1', # snsMemUser + '.1.3.6.1.4.1.11256.1.10.10.1.10.1' # snsMemMbuf + ]; + + $snmp_result = $options{snmp}->get_leef(oids => $oids, nothing_quit => 1); + + $mem_values{'host'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.2.1'}; + $mem_values{'frag'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.3.1'}; + $mem_values{'icmp'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.4.1'}; + $mem_values{'asq'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.5.1'}; + $mem_values{'etherstate'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.6.1'}; + $mem_values{'dtrack'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.7.1'}; + $mem_values{'system'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.8.1'}; + $mem_values{'user'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.9.1'}; + $mem_values{'socket'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.10.1'}; + + } else { + # oid for version < 4.8.9 + my $oid_snsMem = '.1.3.6.1.4.1.11256.1.10.3.0'; + $snmp_result = $options{snmp}->get_leef(oids => [ $oid_snsMem ], nothing_quit => 1); + + my @values = split(/,/, $snmp_result->{$oid_snsMem}); + my $fields = scalar(@values); + if ($fields >= 7) { + $mem_values{'host'} = $values[0]; + $mem_values{'frag'} = $values[1]; + $mem_values{'icmp'} = $values[2]; + $mem_values{'asq'} = $values[3]; + $mem_values{'etherstate'} = $values[4]; + $mem_values{'dtrack'} = $values[5]; + $mem_values{'system'} = $values[6]; + + if ($fields == 8) { + $mem_values{'socket'} = $values[7]; + } + } + } + + # Cleaning and Converting Values + foreach my $key (keys %mem_values) { + if (defined $mem_values{$key}) { + $mem_values{$key} =~ s/%//g; + $mem_values{$key} =~ s/^\s+|\s+$//g; + # If the value is not a number, it is removed + if ($mem_values{$key} !~ /^\d+\.?\d*$/) { + delete $mem_values{$key}; + } + } else { + delete $mem_values{$key}; + } } + + $self->{global} = \%mem_values; } + 1; __END__ =head1 MODE -Check memory detailed. +Check memory utilization on Stormshield firewalls. =over 8 -=item B<--warning-*> B<--critical-*> +=item B<--warning> + +Set warning threshold for all memory types (asq, icmp, frag, host, system, dtrack, socket, etherstate, user). + +=item B<--critical> -Thresholds. -Can be: 'total', 'host', 'frag', 'conn', 'icmp', -'dtrack', 'dyn', 'etherstate'. +Set critical threshold for all memory types (asq, icmp, frag, host, system, dtrack, socket, etherstate, user). =back -=cut +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/plugin.pm b/src/network/stormshield/snmp/plugin.pm index 068b62a77d..2d81fe59ae 100644 --- a/src/network/stormshield/snmp/plugin.pm +++ b/src/network/stormshield/snmp/plugin.pm @@ -31,21 +31,24 @@ sub new { $self->{version} = '1.0'; $self->{modes} = { - 'cpu' => 'snmp_standard::mode::cpu', - 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', - 'connections' => 'network::stormshield::snmp::mode::connections', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'load' => 'snmp_standard::mode::loadaverage', - 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', - 'hardware' => 'network::stormshield::snmp::mode::hardware', - 'health' => 'network::stormshield::snmp::mode::health', - 'memory' => 'os::freebsd::snmp::mode::memory', - 'memory-detailed' => 'network::stormshield::snmp::mode::memorydetailed', - 'qos' => 'network::stormshield::snmp::mode::qos', - 'storage' => 'snmp_standard::mode::storage', - 'swap' => 'snmp_standard::mode::swap', - 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus' + 'auto-update' => 'network::stormshield::snmp::mode::auto_update', + 'cpu' => 'snmp_standard::mode::cpu', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'connections' => 'network::stormshield::snmp::mode::connections', + 'interfaces-disco' => 'network::stormshield::snmp::mode::interfaces_disco', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', + 'ha-cluster' => 'network::stormshield::snmp::mode::ha_cluster', + 'hardware' => 'network::stormshield::snmp::mode::hardware', + 'health' => 'network::stormshield::snmp::mode::health', + 'memory' => 'snmp_standard::mode::memory', + 'memory-detailed' => 'network::stormshield::snmp::mode::memorydetailed', + 'qos' => 'network::stormshield::snmp::mode::qos', + 'storage' => 'snmp_standard::mode::storage', + 'swap' => 'snmp_standard::mode::swap', + 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus' }; return $self; From 64f7c45a0a4f4bb80fab76db142f1729368df6c6 Mon Sep 17 00:00:00 2001 From: crsuser Date: Tue, 23 Jun 2026 10:24:47 +0200 Subject: [PATCH 02/50] Fix: changed type in set_counters from 0 to "COUNTER_TYPE_GLOBAL" convention --- src/network/stormshield/snmp/mode/memorydetailed.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index bd82835187..7878c93fd3 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -33,7 +33,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0, skipped_code => { NO_VALUE() => 1 } } + { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { NO_VALUE() => 1 } } ]; $self->{maps_counters}->{global} = [ @@ -305,4 +305,4 @@ Set critical threshold for all memory types (asq, icmp, frag, host, system, dtra =back -=cut \ No newline at end of file +=cut From 8f5bc726b4699341bea881212a0fe077a48f7e53 Mon Sep 17 00:00:00 2001 From: crsuser Date: Tue, 30 Jun 2026 14:06:35 +0200 Subject: [PATCH 03/50] Fix: wrong oid name in ha_cluster.pm --- src/network/stormshield/snmp/mode/ha_cluster.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/stormshield/snmp/mode/ha_cluster.pm b/src/network/stormshield/snmp/mode/ha_cluster.pm index 0b4a2fb128..bd05424ecf 100644 --- a/src/network/stormshield/snmp/mode/ha_cluster.pm +++ b/src/network/stormshield/snmp/mode/ha_cluster.pm @@ -207,7 +207,7 @@ my %mapping = ( snsNodeIndex => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.1' }, snsFwSerial => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.2' }, snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.3' }, - snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.4' }, + snsModel => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.4' }, snsVersion => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.5' }, snsHALicence => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.6' }, snsHAQuality => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.7' }, @@ -216,7 +216,7 @@ my %mapping = ( snsHAActive => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.10' }, ); -my %map_online = ( 0 => 'False', 1 => 'True' ); +my %map_online = ( 2 => 'False', 1 => 'True' ); my %map_status = ( 0 => 'False', 1 => 'True' ); my %map_act_pass = ( 2 => 'Passive', 1 => 'Active' ); my %map_sync = ( 0 => 'False', 1 => 'True' ); @@ -291,7 +291,7 @@ sub manage_selection { my $n = $nodes{$idx}; my $serial = $n->{snsFwSerial} // 'N/A'; - my $model = $n->{snsOnline} // 'N/A'; + my $model = $n->{snsModel} // 'N/A'; my $version = $n->{snsVersion} // 'N/A'; my $status_f = $map_status{$n->{snsHAStatusForced} // 0 } // 'UNKNOWN'; my $act_pass = $map_act_pass{$n->{snsHAActive} // 0 } // 'UNKNOWN'; @@ -331,4 +331,4 @@ Check Stormshield HA cluster global status. =back -=cut \ No newline at end of file +=cut From 4f7be032d9d1cca4bdacec16458ce138c3e090c1 Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 6 Jul 2026 11:28:48 +0200 Subject: [PATCH 04/50] Add discovery mode router_disco.pm --- .../stormshield/snmp/mode/router_disco.pm | 653 ++++++++++++++++++ 1 file changed, 653 insertions(+) create mode 100644 src/network/stormshield/snmp/mode/router_disco.pm diff --git a/src/network/stormshield/snmp/mode/router_disco.pm b/src/network/stormshield/snmp/mode/router_disco.pm new file mode 100644 index 0000000000..abac3b3c60 --- /dev/null +++ b/src/network/stormshield/snmp/mode/router_disco.pm @@ -0,0 +1,653 @@ +# +# Copyright 2026-Present 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::stormshield::snmp::mode::router_disco; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::constants qw/:counters :values/; +use centreon::plugins::misc; + + +sub build_gateways_detail { + my ($self, %options) = @_; + + my @lines = "----------------------------List of the Gateways----------------------------"; + + foreach my $gateway (@{ $options{gateways} }) { + my $packet_loss_str = defined($gateway->{packet_loss_prct}) + ? sprintf('%s %%', $gateway->{packet_loss_prct}) + : 'not monitored'; + my $active_str = $gateway->{active} == 1 ? 'yes' : 'no'; + + if ($gateway->{latency} == 0) { + push @lines, sprintf( + "Gateway '%s' (%s - %s) state: %s, active: %s, unreachable (latency: 0 ms), packet loss: %s.", + $gateway->{display}, $gateway->{gateway_type}, $gateway->{address}, + $gateway->{state}, $active_str, $packet_loss_str + ); + } else { + push @lines, sprintf( + "Gateway '%s' (%s - %s) state: %s, active: %s, latency: %s ms, jitter: %s ms, packet loss: %s.", + $gateway->{display}, $gateway->{gateway_type}, $gateway->{address}, + $gateway->{state}, $active_str, $gateway->{latency}, $gateway->{jitter}, $packet_loss_str + ); + } + } + + return join("\n", @lines); +} + +sub custom_router_status_output { + my ($self, %options) = @_; + + my $principal_total = $self->{result_values}->{principal_total}; + my $principal_down = $self->{result_values}->{principal_down}; + my $backup_total = $self->{result_values}->{backup_total}; + my $backup_down = $self->{result_values}->{backup_down}; + + if ($principal_down == 0 && $backup_down == 0) { + return sprintf( + 'All gateways are working (%d/%d principal, %d/%d backup).', + $principal_total, $principal_total, $backup_total, $backup_total + ); + } + + my $principal_seg = ($principal_total > 0) + ? ($principal_down > 0 + ? sprintf('%d/%d principal down', $principal_down, $principal_total) + : sprintf('%d/%d principal up', $principal_total, $principal_total)) + : ''; + my $backup_seg = ($backup_total > 0) + ? ($backup_down > 0 + ? sprintf('%d/%d backup down', $backup_down, $backup_total) + : sprintf('%d/%d backup up', $backup_total, $backup_total)) + : ''; + + if ($principal_down > 0 && $backup_down > 0) { + return sprintf(join(', ', grep { $_ ne '' } ($principal_seg, $backup_seg)) . '.'); + } + + if ($principal_seg ne '' && $backup_seg ne '') { + return sprintf('%s (%s).', $principal_seg, $backup_seg); + } + return $principal_seg ne '' ? $principal_seg . '.' : $backup_seg . '.'; +} + +sub custom_gateways_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{gateways} = $options{new_datas}->{$self->{instance} . '_gateways'}; + + return 0; +} + +sub custom_packetloss_threshold { + my ($self, %options) = @_; + + my $severity_rank = { ok => 0, warning => 1, unknown => 2, critical => 3 }; + my $worst_status = 'ok'; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if (!defined($gateway->{packet_loss_prct})); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{packet_loss_prct}, + threshold => [ + { label => 'critical-packet-loss', exit_litteral => 'critical' }, + { label => 'warning-packet-loss', exit_litteral => 'warning' } + ] + ); + + if ($severity_rank->{$gw_status} > $severity_rank->{$worst_status}) { + $worst_status = $gw_status; + } + } + + return $worst_status; +} + +sub custom_packetloss_output { + my ($self, %options) = @_; + + my @bad; + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if (!defined($gateway->{packet_loss_prct})); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{packet_loss_prct}, + threshold => [ + { label => 'critical-packet-loss', exit_litteral => 'critical' }, + { label => 'warning-packet-loss', exit_litteral => 'warning' } + ] + ); + next if ($gw_status eq 'ok'); + + push @bad, sprintf( + "packet loss: gateway '%s' %s%% (%s)", + $gateway->{display}, $gateway->{packet_loss_prct}, $gw_status + ); + } + + return join(', ', @bad); +} + +sub custom_packetloss_perfdata { + my ($self, %options) = @_; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if (!defined($gateway->{packet_loss_prct})); + + $self->{output}->perfdata_add( + nlabel => 'router.gateway.packetloss.percentage', + instances => [$self->{result_values}->{display}, $gateway->{display}], + value => $gateway->{packet_loss_prct}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-packet-loss'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-packet-loss'), + unit => '%', + min => 0, + max => 100 + ); + } +} + +sub custom_latency_threshold { + my ($self, %options) = @_; + + my $severity_rank = { ok => 0, warning => 1, unknown => 2, critical => 3 }; + my $worst_status = 'ok'; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + # latency 0 means unreachable: already covered by router-status, not a latency problem + next if ($gateway->{latency} == 0); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{latency}, + threshold => [ + { label => 'critical-latency', exit_litteral => 'critical' }, + { label => 'warning-latency', exit_litteral => 'warning' } + ] + ); + + if ($severity_rank->{$gw_status} > $severity_rank->{$worst_status}) { + $worst_status = $gw_status; + } + } + + return $worst_status; +} + +sub custom_latency_output { + my ($self, %options) = @_; + + my @bad; + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if ($gateway->{latency} == 0); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{latency}, + threshold => [ + { label => 'critical-latency', exit_litteral => 'critical' }, + { label => 'warning-latency', exit_litteral => 'warning' } + ] + ); + next if ($gw_status eq 'ok'); + + push @bad, sprintf( + "latency: gateway '%s' %s ms (%s)", + $gateway->{display}, $gateway->{latency}, $gw_status + ); + } + + return join(', ', @bad); +} + +sub custom_latency_perfdata { + my ($self, %options) = @_; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if ($gateway->{latency} == 0); + + $self->{output}->perfdata_add( + nlabel => 'router.gateway.latency.milliseconds', + instances => [$self->{result_values}->{display}, $gateway->{display}], + value => $gateway->{latency}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-latency'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-latency'), + unit => 'ms', + min => 0 + ); + } +} + + +sub custom_principal_count_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{down} = $options{new_datas}->{$self->{instance} . '_principal_down'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_principal_total'}; + + return 0; +} + +sub custom_principal_count_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{down}, + threshold => [ + { label => 'critical-principal-count', exit_litteral => 'critical' }, + { label => 'warning-principal-count', exit_litteral => 'warning' } + ] + ); +} + +# silent: the down count is already shown in the router-status line, this counter +# only exists to drive warning/critical off a user-defined numeric threshold +sub custom_principal_count_output { + my ($self, %options) = @_; + + return ''; +} + +sub custom_principal_count_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => 'router.gateway.principal.down.count', + instances => [$self->{result_values}->{display}], + value => $self->{result_values}->{down}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-principal-count'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-principal-count'), + min => 0, + max => $self->{result_values}->{total} + ); +} + +sub custom_backup_count_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{down} = $options{new_datas}->{$self->{instance} . '_backup_down'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_backup_total'}; + + return 0; +} + +sub custom_backup_count_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{down}, + threshold => [ + { label => 'critical-backup-count', exit_litteral => 'critical' }, + { label => 'warning-backup-count', exit_litteral => 'warning' } + ] + ); +} + +sub custom_backup_count_output { + my ($self, %options) = @_; + + return ''; +} + +sub custom_backup_count_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => 'router.gateway.backup.down.count', + instances => [$self->{result_values}->{display}], + value => $self->{result_values}->{down}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-backup-count'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-backup-count'), + min => 0, + max => $self->{result_values}->{total} + ); +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { + name => 'router', + type => COUNTER_TYPE_INSTANCE, + message_multiple => 'All gateways are ok', + display_long => 0, + message_separator => ' ', + skipped_code => { -10 => 1 } + } + ]; + + $self->{maps_counters}->{router} = [ + { + label => 'router-status', + type => 2, + warning_default => '%{one_principal_down} == 1', + critical_default => '%{all_down} == 1', + set => { + key_values => [ + { name => 'one_principal_down' }, { name => 'all_down' }, { name => 'display' }, + { name => 'principal_down' }, { name => 'principal_total' }, + { name => 'backup_down' }, { name => 'backup_total' } + ], + closure_custom_output => $self->can('custom_router_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { + label => 'packet-loss', + nlabel => 'router.gateway.packetloss.percentage', + type => COUNTER_KIND_METRIC, + threshold => 0, + set => { + key_values => [ { name => 'display' }, { name => 'gateways' } ], + closure_custom_calc => $self->can('custom_gateways_calc'), + closure_custom_output => $self->can('custom_packetloss_output'), + closure_custom_perfdata => $self->can('custom_packetloss_perfdata'), + closure_custom_threshold_check => $self->can('custom_packetloss_threshold') + } + }, + { + label => 'latency', + nlabel => 'router.gateway.latency.milliseconds', + type => COUNTER_KIND_METRIC, + threshold => 0, + set => { + key_values => [ { name => 'display' }, { name => 'gateways' } ], + closure_custom_calc => $self->can('custom_gateways_calc'), + closure_custom_output => $self->can('custom_latency_output'), + closure_custom_perfdata => $self->can('custom_latency_perfdata'), + closure_custom_threshold_check => $self->can('custom_latency_threshold') + } + }, + { + label => 'principal-down-count', + nlabel => 'router.gateway.principal.down.count', + type => COUNTER_KIND_METRIC, + threshold => 0, + set => { + key_values => [ { name => 'display' }, { name => 'principal_down' }, { name => 'principal_total' } ], + closure_custom_calc => $self->can('custom_principal_count_calc'), + closure_custom_output => $self->can('custom_principal_count_output'), + closure_custom_perfdata => $self->can('custom_principal_count_perfdata'), + closure_custom_threshold_check => $self->can('custom_principal_count_threshold') + } + }, + { + label => 'backup-down-count', + nlabel => 'router.gateway.backup.down.count', + type => COUNTER_KIND_METRIC, + threshold => 0, + set => { + key_values => [ { name => 'display' }, { name => 'backup_down' }, { name => 'backup_total' } ], + closure_custom_calc => $self->can('custom_backup_count_calc'), + closure_custom_output => $self->can('custom_backup_count_output'), + closure_custom_perfdata => $self->can('custom_backup_count_perfdata'), + closure_custom_threshold_check => $self->can('custom_backup_count_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 => { + 'warning-packet-loss:s' => { name => 'warning_packet_loss' }, + 'critical-packet-loss:s' => { name => 'critical_packet_loss' }, + 'warning-latency:s' => { name => 'warning_latency' }, + 'critical-latency:s' => { name => 'critical_latency' }, + 'warning-principal-count:s' => { name => 'warning_principal_count' }, + 'critical-principal-count:s' => { name => 'critical_principal_count' }, + 'warning-backup-count:s' => { name => 'warning_backup_count' }, + 'critical-backup-count:s' => { name => 'critical_backup_count' }, + 'filter-name:s' => { name => 'filter_name' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + my @thresholds = ( + ['warning-packet-loss', 'warning_packet_loss'], + ['critical-packet-loss', 'critical_packet_loss'], + ['warning-latency', 'warning_latency'], + ['critical-latency', 'critical_latency'], + ['warning-principal-count', 'warning_principal_count'], + ['critical-principal-count', 'critical_principal_count'], + ['warning-backup-count', 'warning_backup_count'], + ['critical-backup-count', 'critical_backup_count'] + ); + + foreach my $threshold (@thresholds) { + my ($label, $option_name) = @$threshold; + + if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$option_name})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold '" . $label . "' value '" . $self->{option_results}->{$option_name} . "'."); + $self->{output}->option_exit(); + } + } +} + +my $mapping = { + snsRouteRouterName => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.4' }, + snsRouteGatewayName => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.5' }, + snsRouteGatewayAddr => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.6' }, + snsRouteGatewayType => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.7' }, + snsRouteState => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.9' }, + snsRouteActive => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.11' }, + snsRouteLatency => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.18' }, + snsRouteJitter => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.19' }, + snsRoutePacketLossPrctRaw => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.23' } +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{snsRouteRouterName}->{oid} }, + { oid => $mapping->{snsRouteGatewayName}->{oid} }, + { oid => $mapping->{snsRouteGatewayAddr}->{oid} }, + { oid => $mapping->{snsRouteGatewayType}->{oid} }, + { oid => $mapping->{snsRouteState}->{oid} }, + { oid => $mapping->{snsRouteActive}->{oid} }, + { oid => $mapping->{snsRouteLatency}->{oid} }, + { oid => $mapping->{snsRouteJitter}->{oid} }, + { oid => $mapping->{snsRoutePacketLossPrctRaw}->{oid} } + ], + nothing_quit => 1 + ); + + $self->{router} = {}; + foreach my $oid (keys %{$snmp_result->{ $mapping->{snsRouteRouterName}->{oid} }}) { + next if ($oid !~ /^$mapping->{snsRouteRouterName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if ( + defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && lc($result->{snsRouteRouterName}) ne lc($self->{option_results}->{filter_name}) + ); + + my $router_name = $result->{snsRouteRouterName}; + if (!defined($self->{router}->{$router_name})) { + $self->{router}->{$router_name} = { + display => $router_name, + gateways => [] + }; + } + + my $is_principal = ($result->{snsRouteGatewayType} =~ /^principal$/i) ? 1 : 0; + my $is_down; + if ($is_principal) { + # for a principal gateway, active=no while state=up is itself a problem + # it's ready/up but not actually carrying traffic -> counted as down + $is_down = ( + $result->{snsRouteState} =~ /^(down|undef)$/i + || $result->{snsRouteActive} == 0 + || $result->{snsRouteLatency} == 0 + ) ? 1 : 0; + } else { + # for a backup gateway, active=no is the normal/expected state when it's + # not currently taking over -> it does not make the gateway "down" + $is_down = ( + $result->{snsRouteState} =~ /^(down|undef)$/i + || $result->{snsRouteLatency} == 0 + ) ? 1 : 0; + } + + my $raw = $result->{snsRoutePacketLossPrctRaw}; + + push @{ $self->{router}->{$router_name}->{gateways} }, { + display => $result->{snsRouteGatewayName}, + address => $result->{snsRouteGatewayAddr}, + gateway_type => $result->{snsRouteGatewayType}, + state => $result->{snsRouteState}, + active => $result->{snsRouteActive}, + latency => $result->{snsRouteLatency}, + jitter => $result->{snsRouteJitter}, + packet_loss_prct => ($raw < 0 ? undef : $raw / 10), + is_down => $is_down + }; + } + + if (scalar(keys %{$self->{router}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No routes found matching filters.'); + $self->{output}->option_exit(); + } + + foreach my $router_name (keys %{$self->{router}}) { + my @gateways = @{ $self->{router}->{$router_name}->{gateways} }; + my @principal_gateways = grep { $_->{gateway_type} =~ /^principal$/i } @gateways; + my @backup_gateways = grep { $_->{gateway_type} =~ /^backup$/i } @gateways; + + my $principal_total = scalar(@principal_gateways); + my $principal_down = scalar(grep { $_->{is_down} == 1 } @principal_gateways); + my $backup_total = scalar(@backup_gateways); + my $backup_down = scalar(grep { $_->{is_down} == 1 } @backup_gateways); + + $self->{router}->{$router_name}->{principal_total} = $principal_total; + $self->{router}->{$router_name}->{principal_down} = $principal_down; + $self->{router}->{$router_name}->{backup_total} = $backup_total; + $self->{router}->{$router_name}->{backup_down} = $backup_down; + + $self->{router}->{$router_name}->{one_principal_down} = ($principal_down > 0) ? 1 : 0; + $self->{router}->{$router_name}->{all_down} = ( + scalar(@gateways) > 0 && $principal_down == $principal_total && $backup_down == $backup_total + ) ? 1 : 0; + + $self->{output}->output_add( + long_msg => $self->build_gateways_detail(gateways => $self->{router}->{$router_name}->{gateways}) + ); + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['display', 'gateway_count', 'principal_count', 'backup_count', 'gateways_summary']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $router_name (sort keys %{$self->{router}}) { + my $router = $self->{router}->{$router_name}; + my @gateways = @{ $router->{gateways} }; + + $self->{output}->add_disco_entry( + display => $router->{display}, + gateway_count => scalar(@gateways), + principal_count => scalar(grep { $_->{gateway_type} =~ /^principal$/i } @gateways), + backup_count => scalar(grep { $_->{gateway_type} =~ /^backup$/i } @gateways), + gateways_summary => join(', ', map { $_->{display} . '(' . $_->{gateway_type} . ')' } @gateways) + ); + } +} + +1; + +__END__ + +=head1 MODE + +Discovery mode for Stormshield SD-WAN/VPN routes, grouped by router. +This mode produces a single Centreon service per router, with every gateway of that router (latency, jitter, packet loss, reachability state) +folded into that one service's output and perfdata, plus an aggregated router-level status. + +=over 8 + +=item B<--warning-principal-count> + +Warning threshold on the number of Principal gateways currently DOWN for the router. + +=item B<--critical-principal-count> + +Critical threshold on the number of Principal gateways currently DOWN for the router. + +=item B<--warning-backup-count> + +Warning threshold on the number of Backup gateways currently DOWN for the router. + +=item B<--critical-backup-count> + +Critical threshold on the number of Backup gateways currently DOWN for the router. + +=item B<--warning-packet-loss> + +Warning threshold on packet loss (in percent), applied to C for each gateway of the router. + +=item B<--critical-packet-loss> + +Critical threshold on packet loss (in percent), applied to C for each gateway of the router. + +=item B<--warning-latency> + +Warning threshold on latency (in milliseconds), applied to C for each gateway of the router. +Gateways with a latency of 0 (unreachable) are excluded from this check, since they are already covered by the down logic above. + +=item B<--critical-latency> + +Critical threshold on latency (in milliseconds), applied to C for each gateway of the router. +Gateways with a latency of 0 (unreachable) are excluded from this check, since they are already covered by the down logic above. + +=item B<--filter-name> + +Filter routers on the exact router name (for discovery). + +=back + +=cut From a42e0126c1d43f8cf72321b2dc7970495b1cd27b Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 6 Jul 2026 11:30:39 +0200 Subject: [PATCH 05/50] Declared router_disco.pm in plugin.pm --- src/network/stormshield/snmp/plugin.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/stormshield/snmp/plugin.pm b/src/network/stormshield/snmp/plugin.pm index 2d81fe59ae..75c1518f67 100644 --- a/src/network/stormshield/snmp/plugin.pm +++ b/src/network/stormshield/snmp/plugin.pm @@ -48,7 +48,8 @@ sub new { 'qos' => 'network::stormshield::snmp::mode::qos', 'storage' => 'snmp_standard::mode::storage', 'swap' => 'snmp_standard::mode::swap', - 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus' + 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus', + 'router-disco' => 'network::stormshield::snmp::mode::router_disco' }; return $self; From 3928ce8ecba91bc928e493c52f31a7f8d116b5ea Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 6 Jul 2026 13:36:02 +0200 Subject: [PATCH 06/50] Fix Latency and PacketLoss output --- src/network/stormshield/snmp/mode/router_disco.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/stormshield/snmp/mode/router_disco.pm b/src/network/stormshield/snmp/mode/router_disco.pm index abac3b3c60..a815c8fbcc 100644 --- a/src/network/stormshield/snmp/mode/router_disco.pm +++ b/src/network/stormshield/snmp/mode/router_disco.pm @@ -150,7 +150,7 @@ sub custom_packetloss_output { ); } - return join(', ', @bad); + return join(', ', @bad) . '.'; } sub custom_packetloss_perfdata { @@ -220,7 +220,7 @@ sub custom_latency_output { ); } - return join(', ', @bad); + return join(', ', @bad) . '.'; } sub custom_latency_perfdata { From 33791e3664512655661c551cb02b7bd9fb6a5d0d Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 8 Jul 2026 17:30:52 +0200 Subject: [PATCH 07/50] Fix: add version-based filtering for OIDs in router_disco.pm --- .../stormshield/snmp/mode/router_disco.pm | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/network/stormshield/snmp/mode/router_disco.pm b/src/network/stormshield/snmp/mode/router_disco.pm index a815c8fbcc..fca26babb9 100644 --- a/src/network/stormshield/snmp/mode/router_disco.pm +++ b/src/network/stormshield/snmp/mode/router_disco.pm @@ -469,12 +469,41 @@ my $mapping = { snsRouteActive => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.11' }, snsRouteLatency => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.18' }, snsRouteJitter => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.19' }, + snsRoutePacketLossPrctOld => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.20' }, snsRoutePacketLossPrctRaw => { oid => '.1.3.6.1.4.1.11256.1.14.1.1.23' } }; sub manage_selection { my ($self, %options) = @_; + my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; + + my $snmp_result_version = $options{snmp}->get_leef( + oids => [ $oid_snsVersion ], + nothing_quit => 0, + ); + + my $use_old_packet_loss_oid = 0; + my $version_clean = ''; + + if (defined $snmp_result_version && defined $snmp_result_version->{$oid_snsVersion}) { + $version_clean = $snmp_result_version->{$oid_snsVersion}; + $version_clean =~ s/([0-9]+(?:\.[0-9]+)*).*/$1/; + + if (!centreon::plugins::misc::minimal_version($version_clean, '5.1.0')) { + $use_old_packet_loss_oid = 1; + } + } else { + $use_old_packet_loss_oid = 1; + } + + my %packet_loss_oid_map = ( + use_old => $mapping->{snsRoutePacketLossPrctOld}->{oid}, + use_new => $mapping->{snsRoutePacketLossPrctRaw}->{oid} + ); + + my $packet_loss_oid = $use_old_packet_loss_oid ? $packet_loss_oid_map{use_old} : $packet_loss_oid_map{use_new}; + my $snmp_result = $options{snmp}->get_multiple_table( oids => [ { oid => $mapping->{snsRouteRouterName}->{oid} }, @@ -485,7 +514,7 @@ sub manage_selection { { oid => $mapping->{snsRouteActive}->{oid} }, { oid => $mapping->{snsRouteLatency}->{oid} }, { oid => $mapping->{snsRouteJitter}->{oid} }, - { oid => $mapping->{snsRoutePacketLossPrctRaw}->{oid} } + { oid => $packet_loss_oid } ], nothing_quit => 1 ); @@ -527,8 +556,23 @@ sub manage_selection { || $result->{snsRouteLatency} == 0 ) ? 1 : 0; } - - my $raw = $result->{snsRoutePacketLossPrctRaw}; + + my $packet_loss_value; + my $raw = $result->{ $use_old_packet_loss_oid ? 'snsRoutePacketLossPrctOld' : 'snsRoutePacketLossPrctRaw' }; + + if (defined $raw) { + if ($use_old_packet_loss_oid) { + if ($raw =~ /^-?[0-9]+(\.[0-9]+)?$/) { + $packet_loss_value = $raw; + } else { + $packet_loss_value = undef; + } + } else { + $packet_loss_value = ($raw < 0 ? undef : $raw / 10); + } + } else { + $packet_loss_value = undef; + } push @{ $self->{router}->{$router_name}->{gateways} }, { display => $result->{snsRouteGatewayName}, @@ -538,7 +582,7 @@ sub manage_selection { active => $result->{snsRouteActive}, latency => $result->{snsRouteLatency}, jitter => $result->{snsRouteJitter}, - packet_loss_prct => ($raw < 0 ? undef : $raw / 10), + packet_loss_prct => $packet_loss_value, is_down => $is_down }; } From 07bfb746544ef64ae9cc28bec4878aca53e36a31 Mon Sep 17 00:00:00 2001 From: crsuser Date: Fri, 10 Jul 2026 15:20:12 +0200 Subject: [PATCH 08/50] Added jitter in counters, file : router_disco.pm --- .../stormshield/snmp/mode/router_disco.pm | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/src/network/stormshield/snmp/mode/router_disco.pm b/src/network/stormshield/snmp/mode/router_disco.pm index fca26babb9..aee939a05d 100644 --- a/src/network/stormshield/snmp/mode/router_disco.pm +++ b/src/network/stormshield/snmp/mode/router_disco.pm @@ -242,6 +242,76 @@ sub custom_latency_perfdata { } +sub custom_jitter_threshold { + my ($self, %options) = @_; + + my $severity_rank = { ok => 0, warning => 1, unknown => 2, critical => 3 }; + my $worst_status = 'ok'; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + # if latency 0 jitter is not valid + next if ($gateway->{latency} == 0); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{jitter}, + threshold => [ + { label => 'critical-jitter', exit_litteral => 'critical' }, + { label => 'warning-jitter', exit_litteral => 'warning' } + ] + ); + + if ($severity_rank->{$gw_status} > $severity_rank->{$worst_status}) { + $worst_status = $gw_status; + } + } + + return $worst_status; +} + +sub custom_jitter_output { + my ($self, %options) = @_; + + my @bad; + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if ($gateway->{latency} == 0); + + my $gw_status = $self->{perfdata}->threshold_check( + value => $gateway->{jitter}, + threshold => [ + { label => 'critical-jitter', exit_litteral => 'critical' }, + { label => 'warning-jitter', exit_litteral => 'warning' } + ] + ); + next if ($gw_status eq 'ok'); + + push @bad, sprintf( + "jitter: gateway '%s' %s ms (%s)", + $gateway->{display}, $gateway->{jitter}, $gw_status + ); + } + + return join(', ', @bad) . '.'; +} + +sub custom_jitter_perfdata { + my ($self, %options) = @_; + + foreach my $gateway (@{ $self->{result_values}->{gateways} }) { + next if ($gateway->{latency} == 0); + + $self->{output}->perfdata_add( + nlabel => 'router.gateway.jitter.milliseconds', + instances => [$self->{result_values}->{display}, $gateway->{display}], + value => $gateway->{jitter}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-jitter'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-jitter'), + unit => 'ms', + min => 0 + ); + } +} + + sub custom_principal_count_calc { my ($self, %options) = @_; @@ -386,6 +456,19 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_latency_threshold') } }, + { + label => 'jitter', + nlabel => 'router.gateway.jitter.milliseconds', + type => COUNTER_KIND_METRIC, + threshold => 0, + set => { + key_values => [ { name => 'display' }, { name => 'gateways' } ], + closure_custom_calc => $self->can('custom_gateways_calc'), + closure_custom_output => $self->can('custom_jitter_output'), + closure_custom_perfdata => $self->can('custom_jitter_perfdata'), + closure_custom_threshold_check => $self->can('custom_jitter_threshold') + } + }, { label => 'principal-down-count', nlabel => 'router.gateway.principal.down.count', @@ -425,6 +508,8 @@ sub new { 'critical-packet-loss:s' => { name => 'critical_packet_loss' }, 'warning-latency:s' => { name => 'warning_latency' }, 'critical-latency:s' => { name => 'critical_latency' }, + 'warning-jitter:s' => { name => 'warning_jitter' }, + 'critical-jitter:s' => { name => 'critical_jitter' }, 'warning-principal-count:s' => { name => 'warning_principal_count' }, 'critical-principal-count:s' => { name => 'critical_principal_count' }, 'warning-backup-count:s' => { name => 'warning_backup_count' }, @@ -444,6 +529,8 @@ sub check_options { ['critical-packet-loss', 'critical_packet_loss'], ['warning-latency', 'warning_latency'], ['critical-latency', 'critical_latency'], + ['warning-jitter', 'warning_jitter'], + ['critical-jitter', 'critical_jitter'], ['warning-principal-count', 'warning_principal_count'], ['critical-principal-count', 'critical_principal_count'], ['warning-backup-count', 'warning_backup_count'], @@ -672,11 +759,11 @@ Critical threshold on the number of Backup gateways currently DOWN for the route =item B<--warning-packet-loss> -Warning threshold on packet loss (in percent), applied to C for each gateway of the router. +Warning threshold on packet loss (in percent), applied to C / C for each gateway of the router. =item B<--critical-packet-loss> -Critical threshold on packet loss (in percent), applied to C for each gateway of the router. +Critical threshold on packet loss (in percent), applied to C / C for each gateway of the router. =item B<--warning-latency> @@ -688,6 +775,14 @@ Gateways with a latency of 0 (unreachable) are excluded from this check, since t Critical threshold on latency (in milliseconds), applied to C for each gateway of the router. Gateways with a latency of 0 (unreachable) are excluded from this check, since they are already covered by the down logic above. +=item B<--warning-jitter> + +Warning threshold on jitter (in milliseconds), applied to C for each gateway of the router. + +=item B<--critical-jitter> + +Critical threshold on jitter (in milliseconds), applied to C for each gateway of the router. + =item B<--filter-name> Filter routers on the exact router name (for discovery). From 6d28e54df6fef4d17646b44be075356668ae5cb4 Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 15 Jul 2026 15:44:11 +0200 Subject: [PATCH 09/50] Fix: OID name link -> halink in health.pm --- src/network/stormshield/snmp/mode/health.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/stormshield/snmp/mode/health.pm b/src/network/stormshield/snmp/mode/health.pm index 9364ed6d0d..0274498988 100644 --- a/src/network/stormshield/snmp/mode/health.pm +++ b/src/network/stormshield/snmp/mode/health.pm @@ -114,7 +114,7 @@ sub new { my $mapping = { hamode => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.3' }, # snsHaModeHealth - link => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.4' }, # snsHaLinkHealth + halink => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.4' }, # snsHaLinkHealth powersupply => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.5' }, # snsPowerSupplyHealth fan => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.6' }, # snsFanHealth cpu => { oid => '.1.3.6.1.4.1.11256.1.16.2.1.7' }, # snsCpuHealth @@ -219,4 +219,4 @@ You can use the following variables: %{health}, %{service} =back -=cut \ No newline at end of file +=cut From b3476c8ae7293a3cc9d9821cd966d593f6661aa9 Mon Sep 17 00:00:00 2001 From: crsuser Date: Thu, 16 Jul 2026 12:08:20 +0200 Subject: [PATCH 10/50] fix: right thresholds for PSU and Disk --- .../stormshield/snmp/mode/components/disk.pm | 27 ++++++++++++------- src/network/stormshield/snmp/mode/hardware.pm | 5 ++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/network/stormshield/snmp/mode/components/disk.pm b/src/network/stormshield/snmp/mode/components/disk.pm index 8ea6e8b7bd..f5f3d9c3d6 100644 --- a/src/network/stormshield/snmp/mode/components/disk.pm +++ b/src/network/stormshield/snmp/mode/components/disk.pm @@ -101,7 +101,6 @@ sub check { my $smart = $disk->{smartResult} // 'N/A'; my $name = $label_prefix . $disk->{name} // $instance; - $self->{output}->output_add( long_msg => sprintf( "disk '%s' smart result is '%s' [isRaid: %s, raidStatus: %s, position: %s]", @@ -122,18 +121,26 @@ sub check { } if (defined $disk->{isRaid} && $disk->{isRaid} == 1 - && defined $disk->{raidStatus} && $disk->{raidStatus} ne '' - && $disk->{raidStatus} ne 'optimal') + && defined $disk->{raidStatus} && $disk->{raidStatus} ne '') { - $self->{output}->output_add( - severity => 'WARNING', - short_msg => sprintf( - "Disk '%s' RAID status is '%s'", $name, $disk->{raidStatus} - ) - ); + if ($disk->{raidStatus} eq 'missing'){ + $self->{output}->output_add( + severity => 'WARNING', + short_msg => sprintf( + "Disk '%s' RAID status is '%s'", $name, $disk->{raidStatus} + ) + ); + } elsif ($disk->{raidStatus} eq 'degraded') { + $self->{output}->output_add( + severity => 'CRITICAL', + short_msg => sprintf( + "Disk '%s' RAID status is '%s'", $name, $disk->{raidStatus} + ) + ); + } } } } } -1; \ No newline at end of file +1; \ No newline at end of file diff --git a/src/network/stormshield/snmp/mode/hardware.pm b/src/network/stormshield/snmp/mode/hardware.pm index 176fe62f77..226da7db57 100644 --- a/src/network/stormshield/snmp/mode/hardware.pm +++ b/src/network/stormshield/snmp/mode/hardware.pm @@ -42,8 +42,9 @@ sub set_system { ['.*', 'CRITICAL'] ], psu => [ - ['OK', 'OK'], - ['.*', 'CRITICAL'] + ['FAILED', 'CRITICAL'], + ['NOTFOUND', 'WARNING'], + ['.*', 'OK'] ], disk => [ ['PASSED', 'OK'], From b1a666a6e26463528745f6b1e590da006fb43eec Mon Sep 17 00:00:00 2001 From: crsuser Date: Thu, 9 Apr 2026 14:59:23 +0200 Subject: [PATCH 11/50] Add Stormshield SNMP mode properties --- .../stormshield/snmp/mode/properties.pm | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/network/stormshield/snmp/mode/properties.pm diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm new file mode 100644 index 0000000000..0d0acfeb7e --- /dev/null +++ b/src/network/stormshield/snmp/mode/properties.pm @@ -0,0 +1,91 @@ +# +# Copyright 2024 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::stormshield::snmp::mode::properties; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + return $self; +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; + my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; + my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; + my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; + my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; + my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; + my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; + my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; + + my $oids = [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ]; + + my $snmp_result = $options{snmp}->get_leef( + oids => $oids, + nothing_quit => 1 + ); + + my $system_name = $snmp_result->{$oid_system_name}; + my $system_node_name = $snmp_result->{$oid_system_node_name}; + my $bios_version = $snmp_result->{$oid_bios_version}; + my $model = $snmp_result->{$oid_model}; + my $version = $snmp_result->{$oid_version}; + my $serial_number = $snmp_result->{$oid_serial_number}; + my $date = $snmp_result->{$oid_date}; + my $uptime = $snmp_result->{$oid_uptime}; + + $self->{output}->output_add( + severity => 'OK', + short_msg => sprintf("Click to see more infos: ...\nSystem Name: %s \nSystem node Name: %s \nModel: %s \nSerial Number: %s \nVersion: %s \nBios Version: %s \nDate: %s \nUptime: %s", + $system_name, $system_node_name, $model, $serial_number, $version, $bios_version, $date, $uptime + ) + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +These options are not applicable for this mode as it does not generate performance data or thresholds. + +=back + +=cut \ No newline at end of file From 05d382ac942a414995c48b048878b7eccc5387ab Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 20 Apr 2026 17:15:33 +0200 Subject: [PATCH 12/50] fix: add version-based filtering for OIDs to avoid displaying unsupported fields --- .../stormshield/snmp/mode/properties.pm | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm index 0d0acfeb7e..6a07d21027 100644 --- a/src/network/stormshield/snmp/mode/properties.pm +++ b/src/network/stormshield/snmp/mode/properties.pm @@ -61,11 +61,31 @@ sub run { my $date = $snmp_result->{$oid_date}; my $uptime = $snmp_result->{$oid_uptime}; + my @info = ( + "Click to see more infos: ...", + "System Name: $system_name", + "Model: $model", + "Serial Number: $serial_number", + "Version: $version", + "Date: $date", + "Uptime: $uptime", + ); + + # Add 'System node Name' if Stormshield firmware version >= 4.8.6 + # This field was introduced in firmware version 4.8.6 + if (centreon::plugins::misc::minimal_version($version, '4.8.6')) { + splice @info, 2, 0, "System node Name: $system_node_name"; + } + + # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 + # This field was introduced in firmware version 4.8.15 + if (centreon::plugins::misc::minimal_version($version, '4.8.15')) { + splice @info, 6, 0, "Bios Version: $bios_version"; + } + $self->{output}->output_add( - severity => 'OK', - short_msg => sprintf("Click to see more infos: ...\nSystem Name: %s \nSystem node Name: %s \nModel: %s \nSerial Number: %s \nVersion: %s \nBios Version: %s \nDate: %s \nUptime: %s", - $system_name, $system_node_name, $model, $serial_number, $version, $bios_version, $date, $uptime - ) + severity => 'OK', + short_msg => join("\n", @info) ); $self->{output}->display(); From d8565d16a6057e8793bc340e6e05bbb1457d61fb Mon Sep 17 00:00:00 2001 From: crsuser Date: Tue, 21 Apr 2026 10:49:43 +0200 Subject: [PATCH 13/50] Fix: Add exact firmawre-version check for Stormshield SNMP properties --- src/network/stormshield/snmp/mode/properties.pm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm index 6a07d21027..232c383344 100644 --- a/src/network/stormshield/snmp/mode/properties.pm +++ b/src/network/stormshield/snmp/mode/properties.pm @@ -71,15 +71,17 @@ sub run { "Uptime: $uptime", ); - # Add 'System node Name' if Stormshield firmware version >= 4.8.6 - # This field was introduced in firmware version 4.8.6 - if (centreon::plugins::misc::minimal_version($version, '4.8.6')) { + my ($base_version) = $version =~ /^(\d+\.\d+\.\d+)/; + + # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or == 4.3.40 + # This field was introduced in firmware version 4.8.6 and in 4.3.40 + if (centreon::plugins::misc::minimal_version($version, '4.8.6') || (defined $base_version && $base_version eq '4.3.40')) { splice @info, 2, 0, "System node Name: $system_node_name"; } - # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 - # This field was introduced in firmware version 4.8.15 - if (centreon::plugins::misc::minimal_version($version, '4.8.15')) { + # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or == 4.3.42 + # This field was introduced in firmware version 4.8.15 and in 4.3.42 + if (centreon::plugins::misc::minimal_version($version, '4.8.15') || (defined $base_version && $base_version eq '4.3.42')) { splice @info, 6, 0, "Bios Version: $bios_version"; } @@ -108,4 +110,4 @@ These options are not applicable for this mode as it does not generate performan =back -=cut \ No newline at end of file +=cut From 175e176bb083b0a73dca9db743513d3ae5e3a475 Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 22 Apr 2026 14:14:38 +0200 Subject: [PATCH 14/50] Fix: firmware-version check for 4.3.x and above --- src/network/stormshield/snmp/mode/properties.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm index 232c383344..5131c95177 100644 --- a/src/network/stormshield/snmp/mode/properties.pm +++ b/src/network/stormshield/snmp/mode/properties.pm @@ -71,17 +71,17 @@ sub run { "Uptime: $uptime", ); - my ($base_version) = $version =~ /^(\d+\.\d+\.\d+)/; - - # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or == 4.3.40 + # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 # This field was introduced in firmware version 4.8.6 and in 4.3.40 - if (centreon::plugins::misc::minimal_version($version, '4.8.6') || (defined $base_version && $base_version eq '4.3.40')) { + if (centreon::plugins::misc::minimal_version($version, '4.8.6') || + (centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { splice @info, 2, 0, "System node Name: $system_node_name"; } - # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or == 4.3.42 + # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or 4.3.x with x>=42 # This field was introduced in firmware version 4.8.15 and in 4.3.42 - if (centreon::plugins::misc::minimal_version($version, '4.8.15') || (defined $base_version && $base_version eq '4.3.42')) { + if (centreon::plugins::misc::minimal_version($version, '4.8.15') || + (centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { splice @info, 6, 0, "Bios Version: $bios_version"; } From bef7bc5bc98489b0210c48286e824e13628c3e95 Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 29 Apr 2026 17:30:27 +0200 Subject: [PATCH 15/50] Fix structure to match standards --- .../stormshield/snmp/mode/properties.pm | 113 ------- src/network/stormshield/snmp/mode/uptime.pm | 275 ++++++++++++++++++ 2 files changed, 275 insertions(+), 113 deletions(-) delete mode 100644 src/network/stormshield/snmp/mode/properties.pm create mode 100644 src/network/stormshield/snmp/mode/uptime.pm diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm deleted file mode 100644 index 5131c95177..0000000000 --- a/src/network/stormshield/snmp/mode/properties.pm +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright 2024 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::stormshield::snmp::mode::properties; - -use base qw(centreon::plugins::templates::counter); - -use strict; -use warnings; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - return $self; -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; - my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; - my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; - my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; - my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; - my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; - my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; - my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; - - my $oids = [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ]; - - my $snmp_result = $options{snmp}->get_leef( - oids => $oids, - nothing_quit => 1 - ); - - my $system_name = $snmp_result->{$oid_system_name}; - my $system_node_name = $snmp_result->{$oid_system_node_name}; - my $bios_version = $snmp_result->{$oid_bios_version}; - my $model = $snmp_result->{$oid_model}; - my $version = $snmp_result->{$oid_version}; - my $serial_number = $snmp_result->{$oid_serial_number}; - my $date = $snmp_result->{$oid_date}; - my $uptime = $snmp_result->{$oid_uptime}; - - my @info = ( - "Click to see more infos: ...", - "System Name: $system_name", - "Model: $model", - "Serial Number: $serial_number", - "Version: $version", - "Date: $date", - "Uptime: $uptime", - ); - - # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 - # This field was introduced in firmware version 4.8.6 and in 4.3.40 - if (centreon::plugins::misc::minimal_version($version, '4.8.6') || - (centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { - splice @info, 2, 0, "System node Name: $system_node_name"; - } - - # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or 4.3.x with x>=42 - # This field was introduced in firmware version 4.8.15 and in 4.3.42 - if (centreon::plugins::misc::minimal_version($version, '4.8.15') || - (centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { - splice @info, 6, 0, "Bios Version: $bios_version"; - } - - $self->{output}->output_add( - severity => 'OK', - short_msg => join("\n", @info) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. - -=over 8 - -=item B<--warning-*> B<--critical-*> - -These options are not applicable for this mode as it does not generate performance data or thresholds. - -=back - -=cut diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm new file mode 100644 index 0000000000..0c92caef11 --- /dev/null +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -0,0 +1,275 @@ +# +# Copyright 2024 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::stormshield::snmp::mode::uptime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::constants qw/:counters :values/; +use centreon::plugins::misc; + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + {name => 'global', type => 0, message_separator => "\n", skipped_code => { NO_VALUE() => 1 }} + ]; + + + $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_check'), + output_template => "Uptime: %s", + } + }, + { label => 'system_name', set => { + key_values => [ { name => 'system_name' } ], + output_template => "System Name: %s", + } + }, + { label => 'system_node_name', set => { + key_values => [ { name => 'system_node_name' } ], + output_template => "System node Name: %s", + } + }, + { label => 'model', set => { + key_values => [ { name => 'model' } ], + output_template => "Model: %s", + } + }, + { label => 'serial_number', set => { + key_values => [ { name => 'serial_number' } ], + output_template => "Serial Number: %s", + } + }, + { label => 'version', set => { + key_values => [ { name => 'version' } ], + perfdatas => [], + closure_custom_output => $self->can('custom_version_output'), + } + }, + { label => 'bios_version', set => { + key_values => [ { name => 'bios_version' } ], + perfdatas => [], + closure_custom_output => $self->can('custom_bios_version_output'), + } + }, + { label => 'date', set => { + key_values => [ { name => 'date' } ], + output_template => "Date: %s", + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = 'fw_stormshield_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); + + my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; + my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; + my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; + my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; + my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; + my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; + my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; + my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; + + my $result = $options{snmp}->get_leef( + oids => [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ], + nothing_quit => 1 + ); + + my $version = $result->{$oid_version}; + + # Used to make sure Perl see this as a string (without dots). Making sure we use an unique separator so it doesn't destroy anything else. + # With dots, it displays: Argument "x.x.x" isn't numeric in sprintf + my $version_clean = $version; + $version_clean =~ s/\./_ç_/g; + + + # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 + # This field was introduced in firmware version 4.8.6 and in 4.3.40 + my $system_node_name = $result->{$oid_system_node_name}; + if (!centreon::plugins::misc::minimal_version($version, '4.8.6') && + !(centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { + $system_node_name = undef; + } + + + # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or 4.3.x with x>=42 + # This field was introduced in firmware version 4.8.15 and in 4.3.42 + my $bios_version = $result->{$oid_bios_version}; + if (!centreon::plugins::misc::minimal_version($version, '4.8.15') && + !(centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { + $bios_version = undef; + } else{ + #Same as $version_clean + $bios_version =~ s/\./_ç_/g; + } + + my $uptime_raw = $result->{$oid_uptime}; + my $uptime_seconds = 0; + + if (defined($uptime_raw) && $uptime_raw ne "") { + my @parts = split(/:/, $uptime_raw); + + if (scalar(@parts) == 4) { + my ($days, $hours, $minutes, $seconds) = @parts; + $uptime_seconds = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds; + } else { + $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Format d'uptime inattendu: $uptime_raw"); + } + } + + $self->{global} = { + system_name => $result->{$oid_system_name}, + system_node_name => $system_node_name, + model => $result->{$oid_model}, + serial_number => $result->{$oid_serial_number}, + version => $version_clean, + bios_version => $bios_version, + date => $result->{$oid_date}, + uptime => $uptime_seconds, + }; +} + +sub custom_version_output { + my ($self, %options) = @_; + + my $val = $self->{result_values}->{version}; + + # Now, rebuilding the "version" string with dots + my $display_val = defined($val) ? $val : "N/A"; + $display_val =~ s/_ç_/./g; + + return "Version: " . $display_val; +} + +sub custom_bios_version_output { + my ($self, %options) = @_; + + my $val = $self->{result_values}->{bios_version}; + + # Now, rebuilding the "bios_version" string with dots + my $display_val = defined($val) ? $val : "N/A"; + $display_val =~ s/_ç_/./g; + + return "Bios Version: " . $display_val; +} + +sub custom_uptime_output { + my ($self, %options) = @_; + + my $uptime_seconds = $self->{result_values}->{uptime}; + + my $days = $uptime_seconds / 86400; + my $hours = ($uptime_seconds % 86400) / 3600; + my $minutes = ($uptime_seconds % 3600) / 60; + my $seconds = $uptime_seconds % 60; + + my $msg = sprintf( + "Uptime: %d days %02d hours %02d minutes %02d seconds", + $days, $hours, $minutes, $seconds + ); + + return $msg; +} + +sub custom_uptime_perfdata { + my ($self, %options) = @_; + + my $uptime_seconds = $self->{result_values}->{uptime}; + + $self->{output}->perfdata_add( + label => 'uptime', + nlabel => 'system.uptime.seconds', + value => $uptime_seconds, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-uptime'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-uptime'), + min => 0, + unit => 's' + ); +} + +sub custom_uptime_threshold_check { + my ($self, %options) = @_; + my $uptime_seconds = $self->{result_values}->{uptime}; + + return $self->{perfdata}->threshold_check( + value => $uptime_seconds, + threshold => [ + { label => 'critical-uptime', exit_litteral => 'critical' }, + { label => 'warning-uptime', exit_litteral => 'warning' }, + ] + ); +} + +sub check { + my ($self, %options) = @_; + $self->SUPER::check(%options); + +} + +1; + +__END__ + +=head1 MODE + +This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. +It also monitors the uptime with configurable warning and critical thresholds. + +=over 8 + +=item B<--warning-uptime> + +Warning threshold for uptime (in seconds). + +=item B<--critical-uptime> + +Critical threshold for uptime (in seconds). + +=item B<--warning-*> B<--critical-*> + +Other thresholds (system_name, model, etc.) are not applicable as these are informational only. + +=back + +=cut From a844641a924cd7a167e71d5d9520566d9e43df54 Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 29 Apr 2026 17:31:22 +0200 Subject: [PATCH 16/50] Update plugin.pm --- src/network/stormshield/snmp/plugin.pm | 34 ++++++++++++++------------ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/network/stormshield/snmp/plugin.pm b/src/network/stormshield/snmp/plugin.pm index 75c1518f67..f2daf55bc6 100644 --- a/src/network/stormshield/snmp/plugin.pm +++ b/src/network/stormshield/snmp/plugin.pm @@ -32,24 +32,26 @@ sub new { $self->{version} = '1.0'; $self->{modes} = { 'auto-update' => 'network::stormshield::snmp::mode::auto_update', - 'cpu' => 'snmp_standard::mode::cpu', - 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', - 'connections' => 'network::stormshield::snmp::mode::connections', + 'cpu' => 'snmp_standard::mode::cpu', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'connections' => 'network::stormshield::snmp::mode::connections', 'interfaces-disco' => 'network::stormshield::snmp::mode::interfaces_disco', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'load' => 'snmp_standard::mode::loadaverage', - 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', - 'ha-cluster' => 'network::stormshield::snmp::mode::ha_cluster', - 'hardware' => 'network::stormshield::snmp::mode::hardware', - 'health' => 'network::stormshield::snmp::mode::health', - 'memory' => 'snmp_standard::mode::memory', - 'memory-detailed' => 'network::stormshield::snmp::mode::memorydetailed', - 'qos' => 'network::stormshield::snmp::mode::qos', - 'storage' => 'snmp_standard::mode::storage', - 'swap' => 'snmp_standard::mode::swap', - 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', + 'ha-cluster' => 'network::stormshield::snmp::mode::ha_cluster', + 'hardware' => 'network::stormshield::snmp::mode::hardware', + 'health' => 'network::stormshield::snmp::mode::health', + 'memory' => 'os::freebsd::snmp::mode::memory', + 'memory-detailed' => 'network::stormshield::snmp::mode::memorydetailed', + 'qos' => 'network::stormshield::snmp::mode::qos', + 'storage' => 'snmp_standard::mode::storage', + 'swap' => 'snmp_standard::mode::swap', + 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus', + 'uptime' => 'network::stormshield::snmp::mode::uptime', 'router-disco' => 'network::stormshield::snmp::mode::router_disco' + }; return $self; From 33bf6df95af820a8377fd6c08b7fc0e6eeb2edbf Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 29 Apr 2026 17:34:26 +0200 Subject: [PATCH 17/50] Fixing non ASCII concern --- src/network/stormshield/snmp/mode/uptime.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index 0c92caef11..149197641e 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -121,7 +121,7 @@ sub manage_selection { # Used to make sure Perl see this as a string (without dots). Making sure we use an unique separator so it doesn't destroy anything else. # With dots, it displays: Argument "x.x.x" isn't numeric in sprintf my $version_clean = $version; - $version_clean =~ s/\./_ç_/g; + $version_clean =~ s/\./__/g; # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 @@ -141,7 +141,7 @@ sub manage_selection { $bios_version = undef; } else{ #Same as $version_clean - $bios_version =~ s/\./_ç_/g; + $bios_version =~ s/\./__/g; } my $uptime_raw = $result->{$oid_uptime}; @@ -177,7 +177,7 @@ sub custom_version_output { # Now, rebuilding the "version" string with dots my $display_val = defined($val) ? $val : "N/A"; - $display_val =~ s/_ç_/./g; + $display_val =~ s/__/./g; return "Version: " . $display_val; } @@ -189,7 +189,7 @@ sub custom_bios_version_output { # Now, rebuilding the "bios_version" string with dots my $display_val = defined($val) ? $val : "N/A"; - $display_val =~ s/_ç_/./g; + $display_val =~ s/__/./g; return "Bios Version: " . $display_val; } From d0861034b073bfda65f96dc1d9d9a93fd1be0f53 Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 4 May 2026 10:14:07 +0200 Subject: [PATCH 18/50] Fix: French to English output message --- src/network/stormshield/snmp/mode/uptime.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index 149197641e..bd9ad5d13a 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -154,7 +154,7 @@ sub manage_selection { my ($days, $hours, $minutes, $seconds) = @parts; $uptime_seconds = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds; } else { - $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Format d'uptime inattendu: $uptime_raw"); + $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Unexpected uptime format: $uptime_raw"); } } From a37d4c01f9eb2f7a8ace7276ecd53f55d91143dd Mon Sep 17 00:00:00 2001 From: crsuser Date: Mon, 11 May 2026 11:24:17 +0200 Subject: [PATCH 19/50] Fix issues raised in code review --- src/network/stormshield/snmp/mode/uptime.pm | 130 +++++--------------- 1 file changed, 33 insertions(+), 97 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index bd9ad5d13a..0336fb5a35 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -1,5 +1,5 @@ # -# Copyright 2024 Centreon (http://www.centreon.com/) +# Copyright 2026-Present Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -33,10 +33,9 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - {name => 'global', type => 0, message_separator => "\n", skipped_code => { NO_VALUE() => 1 }} + {name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { NO_VALUE() => 1 }} ]; - $self->{maps_counters}->{global} = [ { label => 'uptime', set => { key_values => [ { name => 'uptime' } ], @@ -46,43 +45,6 @@ sub set_counters { output_template => "Uptime: %s", } }, - { label => 'system_name', set => { - key_values => [ { name => 'system_name' } ], - output_template => "System Name: %s", - } - }, - { label => 'system_node_name', set => { - key_values => [ { name => 'system_node_name' } ], - output_template => "System node Name: %s", - } - }, - { label => 'model', set => { - key_values => [ { name => 'model' } ], - output_template => "Model: %s", - } - }, - { label => 'serial_number', set => { - key_values => [ { name => 'serial_number' } ], - output_template => "Serial Number: %s", - } - }, - { label => 'version', set => { - key_values => [ { name => 'version' } ], - perfdatas => [], - closure_custom_output => $self->can('custom_version_output'), - } - }, - { label => 'bios_version', set => { - key_values => [ { name => 'bios_version' } ], - perfdatas => [], - closure_custom_output => $self->can('custom_bios_version_output'), - } - }, - { label => 'date', set => { - key_values => [ { name => 'date' } ], - output_template => "Date: %s", - } - }, ]; } @@ -102,49 +64,39 @@ sub manage_selection { $self->{cache_name} = 'fw_stormshield_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); - my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; - my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; - my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; - my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; - my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; - my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; - my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; - my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; + my $oid_snsSystemName = '.1.3.6.1.4.1.11256.1.18.4.0'; + my $oid_snsSystemNodeName = '.1.3.6.1.4.1.11256.1.18.16.0'; + my $oid_snsBiosVersion = '.1.3.6.1.4.1.11256.1.18.17.0'; + my $oid_snsModel = '.1.3.6.1.4.1.11256.1.18.1.0'; + my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; + my $oid_snsSerialNumber = '.1.3.6.1.4.1.11256.1.18.3.0'; + my $oid_snsDate = '.1.3.6.1.4.1.11256.1.10.1.0'; + my $oid_snsUptime = '.1.3.6.1.4.1.11256.1.10.2.0'; my $result = $options{snmp}->get_leef( - oids => [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ], + oids => [ $oid_snsSystemName, $oid_snsSystemNodeName, $oid_snsBiosVersion, $oid_snsModel, $oid_snsVersion, $oid_snsSerialNumber, $oid_snsDate, $oid_snsUptime ], nothing_quit => 1 ); - my $version = $result->{$oid_version}; - - # Used to make sure Perl see this as a string (without dots). Making sure we use an unique separator so it doesn't destroy anything else. - # With dots, it displays: Argument "x.x.x" isn't numeric in sprintf - my $version_clean = $version; - $version_clean =~ s/\./__/g; - + my $version = $result->{$oid_snsVersion}; # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 # This field was introduced in firmware version 4.8.6 and in 4.3.40 - my $system_node_name = $result->{$oid_system_node_name}; + my $system_node_name = $result->{$oid_snsSystemNodeName}; if (!centreon::plugins::misc::minimal_version($version, '4.8.6') && !(centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { $system_node_name = undef; } - # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or 4.3.x with x>=42 # This field was introduced in firmware version 4.8.15 and in 4.3.42 - my $bios_version = $result->{$oid_bios_version}; + my $bios_version = $result->{$oid_snsBiosVersion}; if (!centreon::plugins::misc::minimal_version($version, '4.8.15') && !(centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { $bios_version = undef; - } else{ - #Same as $version_clean - $bios_version =~ s/\./__/g; } - my $uptime_raw = $result->{$oid_uptime}; + my $uptime_raw = $result->{$oid_snsUptime}; my $uptime_seconds = 0; if (defined($uptime_raw) && $uptime_raw ne "") { @@ -158,40 +110,28 @@ sub manage_selection { } } - $self->{global} = { - system_name => $result->{$oid_system_name}, - system_node_name => $system_node_name, - model => $result->{$oid_model}, - serial_number => $result->{$oid_serial_number}, - version => $version_clean, - bios_version => $bios_version, - date => $result->{$oid_date}, - uptime => $uptime_seconds, - }; -} - -sub custom_version_output { - my ($self, %options) = @_; + my $long_msg = "System Name: " . $result->{$oid_snsSystemName} . "\n"; + $long_msg .= "Model: " . $result->{$oid_snsModel} . "\n"; + $long_msg .= "Serial Number: " . $result->{$oid_snsSerialNumber} . "\n"; + $long_msg .= "Version: " . $version . "\n"; + $long_msg .= "Date: " . $result->{$oid_snsDate} . "\n"; - my $val = $self->{result_values}->{version}; + if (defined($system_node_name)) { + $long_msg .= "System Node Name: " . $system_node_name . "\n"; + } - # Now, rebuilding the "version" string with dots - my $display_val = defined($val) ? $val : "N/A"; - $display_val =~ s/__/./g; + if (defined($bios_version)) { + $long_msg .= "Bios Version: " . $bios_version . "\n"; + } - return "Version: " . $display_val; -} + $self->{output}->output_add( + long_msg => $long_msg, + forced_output => 1 + ); -sub custom_bios_version_output { - my ($self, %options) = @_; - - my $val = $self->{result_values}->{bios_version}; - - # Now, rebuilding the "bios_version" string with dots - my $display_val = defined($val) ? $val : "N/A"; - $display_val =~ s/__/./g; - - return "Bios Version: " . $display_val; + $self->{global} = { + uptime => $uptime_seconds, + }; } sub custom_uptime_output { @@ -266,10 +206,6 @@ Warning threshold for uptime (in seconds). Critical threshold for uptime (in seconds). -=item B<--warning-*> B<--critical-*> - -Other thresholds (system_name, model, etc.) are not applicable as these are informational only. - =back =cut From 5804b366f7cd6335b95703e469702967f3a165c8 Mon Sep 17 00:00:00 2001 From: crsuser Date: Tue, 2 Jun 2026 14:44:09 +0200 Subject: [PATCH 20/50] Apply suggestions from code review Co-authored-by: omercier <32134301+omercier@users.noreply.github.com> --- src/network/stormshield/snmp/mode/uptime.pm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index 0336fb5a35..22056b0164 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -24,7 +24,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use Digest::MD5 qw(md5_hex); use centreon::plugins::constants qw/:counters :values/; use centreon::plugins::misc; @@ -62,7 +61,6 @@ sub new { sub manage_selection { my ($self, %options) = @_; - $self->{cache_name} = 'fw_stormshield_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); my $oid_snsSystemName = '.1.3.6.1.4.1.11256.1.18.4.0'; my $oid_snsSystemNodeName = '.1.3.6.1.4.1.11256.1.18.16.0'; @@ -126,7 +124,6 @@ sub manage_selection { $self->{output}->output_add( long_msg => $long_msg, - forced_output => 1 ); $self->{global} = { @@ -181,12 +178,6 @@ sub custom_uptime_threshold_check { ); } -sub check { - my ($self, %options) = @_; - $self->SUPER::check(%options); - -} - 1; __END__ From e4d01b69ea669ee01ee21efaaeb696b38c9696ba Mon Sep 17 00:00:00 2001 From: crsuser Date: Tue, 9 Jun 2026 10:31:30 +0200 Subject: [PATCH 21/50] Add new Uptime oid for version 5.1.0 and later --- src/network/stormshield/snmp/mode/uptime.pm | 32 +++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index 22056b0164..7760065b17 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -69,10 +69,11 @@ sub manage_selection { my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; my $oid_snsSerialNumber = '.1.3.6.1.4.1.11256.1.18.3.0'; my $oid_snsDate = '.1.3.6.1.4.1.11256.1.10.1.0'; - my $oid_snsUptime = '.1.3.6.1.4.1.11256.1.10.2.0'; + my $oid_snsUptime = '.1.3.6.1.4.1.11256.1.10.2.0'; # version < 5.1.0 + my $oid_snsSysUptime = '.1.3.6.1.4.1.11256.1.10.11.0'; # version >= 5.1.0 my $result = $options{snmp}->get_leef( - oids => [ $oid_snsSystemName, $oid_snsSystemNodeName, $oid_snsBiosVersion, $oid_snsModel, $oid_snsVersion, $oid_snsSerialNumber, $oid_snsDate, $oid_snsUptime ], + oids => [ $oid_snsSystemName, $oid_snsSystemNodeName, $oid_snsBiosVersion, $oid_snsModel, $oid_snsVersion, $oid_snsSerialNumber, $oid_snsDate, $oid_snsUptime, $oid_snsSysUptime ], nothing_quit => 1 ); @@ -94,18 +95,25 @@ sub manage_selection { $bios_version = undef; } - my $uptime_raw = $result->{$oid_snsUptime}; + # $oid_snsUptime is deprecated in version >= 5.1.0 and is replaced by $oid_snsSysUptime which is in TimeTicks instead of String my $uptime_seconds = 0; - - if (defined($uptime_raw) && $uptime_raw ne "") { - my @parts = split(/:/, $uptime_raw); - - if (scalar(@parts) == 4) { - my ($days, $hours, $minutes, $seconds) = @parts; - $uptime_seconds = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds; - } else { - $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Unexpected uptime format: $uptime_raw"); + if (!centreon::plugins::misc::minimal_version($version, '5.1.0')) { + my $uptime_raw = $result->{$oid_snsUptime}; + $uptime_seconds = 0; + + if (defined($uptime_raw) && $uptime_raw ne "") { + my @parts = split(/:/, $uptime_raw); + + if (scalar(@parts) == 4) { + my ($days, $hours, $minutes, $seconds) = @parts; + $uptime_seconds = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds; + } else { + $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Unexpected uptime format: $uptime_raw"); + } } + } else{ + my $uptime_raw = $result->{$oid_snsSysUptime}; + $uptime_seconds = $uptime_raw / 100; } my $long_msg = "System Name: " . $result->{$oid_snsSystemName} . "\n"; From 7f32fe3b3e77a4868cecd2a43f3cc333af83c44b Mon Sep 17 00:00:00 2001 From: omercier Date: Tue, 28 Jul 2026 10:53:19 +0200 Subject: [PATCH 22/50] review --- src/network/stormshield/snmp/mode/uptime.pm | 36 +- tests/network/stormshield/snmp/help.robot | 77 + tests/network/stormshield/snmp/sn910.snmpwalk | 1286 +++++++++++++++++ tests/network/stormshield/snmp/uptime.robot | 46 + 4 files changed, 1427 insertions(+), 18 deletions(-) create mode 100644 tests/network/stormshield/snmp/help.robot create mode 100644 tests/network/stormshield/snmp/sn910.snmpwalk create mode 100644 tests/network/stormshield/snmp/uptime.robot diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index 7760065b17..c891ddd95c 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -25,7 +25,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::constants qw/:counters :values/; -use centreon::plugins::misc; +use centreon::plugins::misc qw(is_not_empty); sub set_counters { @@ -82,16 +82,16 @@ sub manage_selection { # Add 'System node Name' if Stormshield firmware version >= 4.8.6 or 4.3.x with x>=40 # This field was introduced in firmware version 4.8.6 and in 4.3.40 my $system_node_name = $result->{$oid_snsSystemNodeName}; - if (!centreon::plugins::misc::minimal_version($version, '4.8.6') && - !(centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { + if (!centreon::plugins::misc::minimal_version($version, '4.8.6') + && !(centreon::plugins::misc::minimal_version($version, '4.3.40') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { $system_node_name = undef; } # Add 'Bios Version' if Stormshield firmware version >= 4.8.15 or 4.3.x with x>=42 # This field was introduced in firmware version 4.8.15 and in 4.3.42 my $bios_version = $result->{$oid_snsBiosVersion}; - if (!centreon::plugins::misc::minimal_version($version, '4.8.15') && - !(centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { + if (!centreon::plugins::misc::minimal_version($version, '4.8.15') + && !(centreon::plugins::misc::minimal_version($version, '4.3.42') && !centreon::plugins::misc::minimal_version($version, '4.4.0'))) { $bios_version = undef; } @@ -101,17 +101,17 @@ sub manage_selection { my $uptime_raw = $result->{$oid_snsUptime}; $uptime_seconds = 0; - if (defined($uptime_raw) && $uptime_raw ne "") { + if (is_not_empty($uptime_raw)) { my @parts = split(/:/, $uptime_raw); - + if (scalar(@parts) == 4) { my ($days, $hours, $minutes, $seconds) = @parts; $uptime_seconds = ($days * 86400) + ($hours * 3600) + ($minutes * 60) + $seconds; } else { - $self->{output}->message_add(severity => 'CRITICAL', short_msg => "Unexpected uptime format: $uptime_raw"); + $self->{output}->output_add(severity => 'CRITICAL', short_msg => "Unexpected uptime format: $uptime_raw"); } } - } else{ + } else { my $uptime_raw = $result->{$oid_snsSysUptime}; $uptime_seconds = $uptime_raw / 100; } @@ -121,15 +121,15 @@ sub manage_selection { $long_msg .= "Serial Number: " . $result->{$oid_snsSerialNumber} . "\n"; $long_msg .= "Version: " . $version . "\n"; $long_msg .= "Date: " . $result->{$oid_snsDate} . "\n"; - + if (defined($system_node_name)) { $long_msg .= "System Node Name: " . $system_node_name . "\n"; } - + if (defined($bios_version)) { $long_msg .= "Bios Version: " . $bios_version . "\n"; } - + $self->{output}->output_add( long_msg => $long_msg, ); @@ -143,12 +143,12 @@ sub custom_uptime_output { my ($self, %options) = @_; my $uptime_seconds = $self->{result_values}->{uptime}; - + my $days = $uptime_seconds / 86400; my $hours = ($uptime_seconds % 86400) / 3600; my $minutes = ($uptime_seconds % 3600) / 60; my $seconds = $uptime_seconds % 60; - + my $msg = sprintf( "Uptime: %d days %02d hours %02d minutes %02d seconds", $days, $hours, $minutes, $seconds @@ -192,18 +192,18 @@ __END__ =head1 MODE -This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. -It also monitors the uptime with configurable warning and critical thresholds. +This mode monitors the uptime and retrieves and displays basic properties of the Stormshield device such as system name, +model, version, serial number, and date. =over 8 =item B<--warning-uptime> -Warning threshold for uptime (in seconds). +Threshold (in seconds). =item B<--critical-uptime> -Critical threshold for uptime (in seconds). +Threshold (in seconds). =back diff --git a/tests/network/stormshield/snmp/help.robot b/tests/network/stormshield/snmp/help.robot new file mode 100644 index 0000000000..81b72430ac --- /dev/null +++ b/tests/network/stormshield/snmp/help.robot @@ -0,0 +1,77 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} --plugin=network::stormshield::snmp::plugin + + +*** Test Cases *** +Standard ${tc} - ${mode} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... --mode=${mode} + ... --help + + Ctn Run Command And Check Result As Regexp ${command} ${expected_result} flags=IGNORECASE + + Examples: + ... tc + ... mode + ... expected_result + ... -- + ... 1 + ... connections + ... Mode:\n.*connections + ... 2 + ... cpu + ... Mode:\n.*cpu + ... 3 + ... cpu-detailed + ... Mode:\n.*Check system CPUs + ... 4 + ... ha-nodes + ... Mode:\n.*Check Stormshield nodes status + ... 5 + ... hardware + ... Mode:\n.*hardware + ... 6 + ... health + ... Mode:\n.*health + ... 7 + ... interfaces + ... Mode:\n.*interfaces + ... 8 + ... list-interfaces + ... Mode:\n.*--interface + ... 9 + ... load + ... Mode:\n.*load + ... 10 + ... memory + ... Mode:\n.*memory + ... 11 + ... memory-detailed + ... Mode:\n.*memory.detailed + ... 12 + ... qos + ... Mode:\n.*qos + ... 13 + ... storage + ... Mode:\n.*--warning-usage + ... 14 + ... swap + ... Mode:\n.*swap + ... 15 + ... uptime + ... Mode:\n.*uptime + ... 16 + ... vpn-status + ... Mode:\n.*Check vpn diff --git a/tests/network/stormshield/snmp/sn910.snmpwalk b/tests/network/stormshield/snmp/sn910.snmpwalk new file mode 100644 index 0000000000..50c4e3f933 --- /dev/null +++ b/tests/network/stormshield/snmp/sn910.snmpwalk @@ -0,0 +1,1286 @@ +.1.3.6.1.4.1.11256.1.0.1.0 = STRING: "SN910" +.1.3.6.1.4.1.11256.1.0.2.0 = STRING: "5.2.0.dev" +.1.3.6.1.4.1.11256.1.0.3.0 = STRING: "" +.1.3.6.1.4.1.11256.1.0.4.0 = STRING: "" +.1.3.6.1.4.1.11256.1.0.5.0 = STRING: "fr" +.1.3.6.1.4.1.11256.1.0.6.0 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.0.7.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.0.8.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.0.9.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.0.10.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.0.11.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.0.12.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.0.13.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.0.14.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.0.15.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.0.16.0 = STRING: "None" +.1.3.6.1.4.1.11256.1.3.1.1.1.1 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.2 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.3 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.4 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.5 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.6 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.7 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.8 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.9 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.10 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.11 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.12 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.1.13 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.2.1 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.2.2 = STRING: "netasq_dns2" +.1.3.6.1.4.1.11256.1.3.1.1.2.3 = STRING: "sandboxing2.stormshieldcs.eu" +.1.3.6.1.4.1.11256.1.3.1.1.2.4 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.2.5 = STRING: "update4-sns.stormshieldcs.eu" +.1.3.6.1.4.1.11256.1.3.1.1.2.6 = STRING: "sandboxing1.stormshieldcs.eu" +.1.3.6.1.4.1.11256.1.3.1.1.2.7 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.2.8 = STRING: "fw_gateway" +.1.3.6.1.4.1.11256.1.3.1.1.2.9 = STRING: "update1-sns.stormshieldcs.eu" +.1.3.6.1.4.1.11256.1.3.1.1.2.10 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.2.11 = STRING: "update2-sns.stormshieldcs.eu" +.1.3.6.1.4.1.11256.1.3.1.1.2.12 = STRING: "netasq_dns1" +.1.3.6.1.4.1.11256.1.3.1.1.2.13 = STRING: "" +.1.3.6.1.4.1.11256.1.3.1.1.3.1 = STRING: "HA" +.1.3.6.1.4.1.11256.1.3.1.1.3.2 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.3 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.4 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.5 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.6 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.7 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.8 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.9 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.10 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.11 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.12 = STRING: "out" +.1.3.6.1.4.1.11256.1.3.1.1.3.13 = STRING: "ha2" +.1.3.6.1.4.1.11256.1.3.1.1.4.1 = Counter64: 22357 +.1.3.6.1.4.1.11256.1.3.1.1.4.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.4.13 = Counter64: 15814 +.1.3.6.1.4.1.11256.1.3.1.1.5.1 = Counter64: 3454771 +.1.3.6.1.4.1.11256.1.3.1.1.5.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.5.13 = Counter64: 2644250 +.1.3.6.1.4.1.11256.1.3.1.1.7.1 = Counter64: 6290 +.1.3.6.1.4.1.11256.1.3.1.1.7.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.7.13 = Counter64: 5059 +.1.3.6.1.4.1.11256.1.3.1.1.8.1 = Counter64: 34636 +.1.3.6.1.4.1.11256.1.3.1.1.8.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.8.13 = Counter64: 38092 +.1.3.6.1.4.1.11256.1.3.1.1.9.1 = Counter64: 1695957 +.1.3.6.1.4.1.11256.1.3.1.1.9.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.9.13 = Counter64: 1275084 +.1.3.6.1.4.1.11256.1.3.1.1.10.1 = Counter64: 1758814 +.1.3.6.1.4.1.11256.1.3.1.1.10.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.10.13 = Counter64: 1369166 +.1.3.6.1.4.1.11256.1.3.1.1.11.1 = Counter64: 3356 +.1.3.6.1.4.1.11256.1.3.1.1.11.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.11.13 = Counter64: 2219 +.1.3.6.1.4.1.11256.1.3.1.1.12.1 = Counter64: 2934 +.1.3.6.1.4.1.11256.1.3.1.1.12.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.12.13 = Counter64: 2840 +.1.3.6.1.4.1.11256.1.3.1.1.13.1 = Counter64: 15074 +.1.3.6.1.4.1.11256.1.3.1.1.13.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.13.13 = Counter64: 13834 +.1.3.6.1.4.1.11256.1.3.1.1.14.1 = Counter64: 19562 +.1.3.6.1.4.1.11256.1.3.1.1.14.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.3.1.1.14.13 = Counter64: 24258 +.1.3.6.1.4.1.11256.1.4.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.4.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.4.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.4.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.4.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.4.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.4.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.4.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.4.1.1.1.10 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.4.1.1.1.11 = INTEGER: 11 +.1.3.6.1.4.1.11256.1.4.1.1.1.12 = INTEGER: 12 +.1.3.6.1.4.1.11256.1.4.1.1.1.13 = INTEGER: 13 +.1.3.6.1.4.1.11256.1.4.1.1.1.14 = INTEGER: 14 +.1.3.6.1.4.1.11256.1.4.1.1.2.1 = STRING: "sslvpn_dco" +.1.3.6.1.4.1.11256.1.4.1.1.2.2 = STRING: "sslvpn_udp" +.1.3.6.1.4.1.11256.1.4.1.1.2.3 = STRING: "sslvpn" +.1.3.6.1.4.1.11256.1.4.1.1.2.4 = STRING: "ipsec" +.1.3.6.1.4.1.11256.1.4.1.1.2.5 = STRING: "dmz8" +.1.3.6.1.4.1.11256.1.4.1.1.2.6 = STRING: "dmz7" +.1.3.6.1.4.1.11256.1.4.1.1.2.7 = STRING: "in" +.1.3.6.1.4.1.11256.1.4.1.1.2.8 = STRING: "out" +.1.3.6.1.4.1.11256.1.4.1.1.2.9 = STRING: "server1" +.1.3.6.1.4.1.11256.1.4.1.1.2.10 = STRING: "client1" +.1.3.6.1.4.1.11256.1.4.1.1.2.11 = STRING: "server0" +.1.3.6.1.4.1.11256.1.4.1.1.2.12 = STRING: "client0" +.1.3.6.1.4.1.11256.1.4.1.1.2.13 = STRING: "ha2" +.1.3.6.1.4.1.11256.1.4.1.1.2.14 = STRING: "HA" +.1.3.6.1.4.1.11256.1.4.1.1.3.1 = STRING: "sslvpn_dco0" +.1.3.6.1.4.1.11256.1.4.1.1.3.2 = STRING: "sslvpn1" +.1.3.6.1.4.1.11256.1.4.1.1.3.3 = STRING: "sslvpn0" +.1.3.6.1.4.1.11256.1.4.1.1.3.4 = STRING: "ipsec" +.1.3.6.1.4.1.11256.1.4.1.1.3.5 = STRING: "Ethernet9" +.1.3.6.1.4.1.11256.1.4.1.1.3.6 = STRING: "Ethernet8" +.1.3.6.1.4.1.11256.1.4.1.1.3.7 = STRING: "Ethernet1" +.1.3.6.1.4.1.11256.1.4.1.1.3.8 = STRING: "Ethernet0" +.1.3.6.1.4.1.11256.1.4.1.1.3.9 = STRING: "Ethernet7" +.1.3.6.1.4.1.11256.1.4.1.1.3.10 = STRING: "Ethernet6" +.1.3.6.1.4.1.11256.1.4.1.1.3.11 = STRING: "Ethernet5" +.1.3.6.1.4.1.11256.1.4.1.1.3.12 = STRING: "Ethernet4" +.1.3.6.1.4.1.11256.1.4.1.1.3.13 = STRING: "Ethernet3" +.1.3.6.1.4.1.11256.1.4.1.1.3.14 = STRING: "Ethernet2" +.1.3.6.1.4.1.11256.1.4.1.1.4.1 = "" +.1.3.6.1.4.1.11256.1.4.1.1.4.2 = "" +.1.3.6.1.4.1.11256.1.4.1.1.4.3 = "" +.1.3.6.1.4.1.11256.1.4.1.1.4.4 = "" +.1.3.6.1.4.1.11256.1.4.1.1.4.5 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.6 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.7 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.8 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.9 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.10 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.11 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.12 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.13 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.4.14 = STRING: "" +.1.3.6.1.4.1.11256.1.4.1.1.5.1 = "" +.1.3.6.1.4.1.11256.1.4.1.1.5.2 = "" +.1.3.6.1.4.1.11256.1.4.1.1.5.3 = "" +.1.3.6.1.4.1.11256.1.4.1.1.5.4 = "" +.1.3.6.1.4.1.11256.1.4.1.1.5.5 = STRING: "255.255.255.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.6 = STRING: "255.255.255.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.7 = STRING: "255.255.255.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.8 = STRING: "255.255.0.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.9 = STRING: "255.255.0.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.10 = STRING: "255.255.0.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.11 = STRING: "255.255.0.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.12 = STRING: "255.255.0.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.13 = STRING: "255.255.255.0" +.1.3.6.1.4.1.11256.1.4.1.1.5.14 = STRING: "255.255.255.0" +.1.3.6.1.4.1.11256.1.4.1.1.6.1 = STRING: "sslvpn_dco" +.1.3.6.1.4.1.11256.1.4.1.1.6.2 = STRING: "sslvpn" +.1.3.6.1.4.1.11256.1.4.1.1.6.3 = STRING: "sslvpn" +.1.3.6.1.4.1.11256.1.4.1.1.6.4 = STRING: "ipsec" +.1.3.6.1.4.1.11256.1.4.1.1.6.5 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.6 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.7 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.8 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.9 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.10 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.11 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.12 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.13 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.6.14 = STRING: "Ethernet" +.1.3.6.1.4.1.11256.1.4.1.1.7.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.7 = INTEGER: 4227200 +.1.3.6.1.4.1.11256.1.4.1.1.7.8 = INTEGER: 8388672 +.1.3.6.1.4.1.11256.1.4.1.1.7.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.13 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.7.14 = INTEGER: 16744512 +.1.3.6.1.4.1.11256.1.4.1.1.8.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.7 = Counter64: 1000000000 +.1.3.6.1.4.1.11256.1.4.1.1.8.8 = Counter64: 1000000000 +.1.3.6.1.4.1.11256.1.4.1.1.8.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.8.13 = Counter64: 1000000000 +.1.3.6.1.4.1.11256.1.4.1.1.8.14 = Counter64: 1000000000 +.1.3.6.1.4.1.11256.1.4.1.1.9.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.8 = Counter64: 775 +.1.3.6.1.4.1.11256.1.4.1.1.9.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.9.13 = Counter64: 14725 +.1.3.6.1.4.1.11256.1.4.1.1.9.14 = Counter64: 17464 +.1.3.6.1.4.1.11256.1.4.1.1.10.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.8 = Counter64: 48206 +.1.3.6.1.4.1.11256.1.4.1.1.10.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.10.13 = Counter64: 43442 +.1.3.6.1.4.1.11256.1.4.1.1.10.14 = Counter64: 42500 +.1.3.6.1.4.1.11256.1.4.1.1.11.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.8 = Counter64: 1407 +.1.3.6.1.4.1.11256.1.4.1.1.11.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.11.13 = Counter64: 10923 +.1.3.6.1.4.1.11256.1.4.1.1.11.14 = Counter64: 16688 +.1.3.6.1.4.1.11256.1.4.1.1.12.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.12.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.13.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.8 = Counter64: 30 +.1.3.6.1.4.1.11256.1.4.1.1.14.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.14.14 = Counter64: 5763 +.1.3.6.1.4.1.11256.1.4.1.1.15.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.8 = Counter64: 1209 +.1.3.6.1.4.1.11256.1.4.1.1.15.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.15.13 = Counter64: 10923 +.1.3.6.1.4.1.11256.1.4.1.1.15.14 = Counter64: 10925 +.1.3.6.1.4.1.11256.1.4.1.1.16.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.8 = Counter64: 168 +.1.3.6.1.4.1.11256.1.4.1.1.16.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.16.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.8 = Counter64: 424251 +.1.3.6.1.4.1.11256.1.4.1.1.17.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.17.13 = Counter64: 2548188 +.1.3.6.1.4.1.11256.1.4.1.1.17.14 = Counter64: 3284391 +.1.3.6.1.4.1.11256.1.4.1.1.18.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.8 = Counter64: 25792 +.1.3.6.1.4.1.11256.1.4.1.1.18.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.18.14 = Counter64: 698729 +.1.3.6.1.4.1.11256.1.4.1.1.19.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.8 = Counter64: 382927 +.1.3.6.1.4.1.11256.1.4.1.1.19.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.19.13 = Counter64: 2420212 +.1.3.6.1.4.1.11256.1.4.1.1.19.14 = Counter64: 2456206 +.1.3.6.1.4.1.11256.1.4.1.1.20.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.8 = Counter64: 15532 +.1.3.6.1.4.1.11256.1.4.1.1.20.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.20.13 = Counter64: 127976 +.1.3.6.1.4.1.11256.1.4.1.1.20.14 = Counter64: 127976 +.1.3.6.1.4.1.11256.1.4.1.1.21.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.21.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.8 = Counter64: 281 +.1.3.6.1.4.1.11256.1.4.1.1.22.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.22.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.8 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.13 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.23.14 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.4.1.1.24.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.8 = INTEGER: 90 +.1.3.6.1.4.1.11256.1.4.1.1.24.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.24.13 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.4.1.1.24.14 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.4.1.1.25.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.8 = INTEGER: 91 +.1.3.6.1.4.1.11256.1.4.1.1.25.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.25.13 = INTEGER: 6536 +.1.3.6.1.4.1.11256.1.4.1.1.25.14 = INTEGER: 8200 +.1.3.6.1.4.1.11256.1.4.1.1.26.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.8 = INTEGER: 684 +.1.3.6.1.4.1.11256.1.4.1.1.26.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.26.13 = INTEGER: 8189 +.1.3.6.1.4.1.11256.1.4.1.1.26.14 = INTEGER: 9264 +.1.3.6.1.4.1.11256.1.4.1.1.27.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.8 = INTEGER: 29404 +.1.3.6.1.4.1.11256.1.4.1.1.27.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.27.13 = INTEGER: 24258 +.1.3.6.1.4.1.11256.1.4.1.1.27.14 = INTEGER: 19562 +.1.3.6.1.4.1.11256.1.4.1.1.28.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.8 = INTEGER: 18802 +.1.3.6.1.4.1.11256.1.4.1.1.28.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.28.13 = INTEGER: 19184 +.1.3.6.1.4.1.11256.1.4.1.1.28.14 = INTEGER: 22938 +.1.3.6.1.4.1.11256.1.4.1.1.29.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.8 = Counter64: 210312 +.1.3.6.1.4.1.11256.1.4.1.1.29.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.29.13 = Counter64: 1221210 +.1.3.6.1.4.1.11256.1.4.1.1.29.14 = Counter64: 1573800 +.1.3.6.1.4.1.11256.1.4.1.1.30.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.8 = Counter64: 213939 +.1.3.6.1.4.1.11256.1.4.1.1.30.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.30.13 = Counter64: 1326978 +.1.3.6.1.4.1.11256.1.4.1.1.30.14 = Counter64: 1710591 +.1.3.6.1.4.1.11256.1.4.1.1.31.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.8 = Counter64: 22104 +.1.3.6.1.4.1.11256.1.4.1.1.31.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.31.14 = Counter64: 329676 +.1.3.6.1.4.1.11256.1.4.1.1.32.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.8 = Counter64: 3688 +.1.3.6.1.4.1.11256.1.4.1.1.32.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.32.14 = Counter64: 369053 +.1.3.6.1.4.1.11256.1.4.1.1.33.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.8 = Counter64: 180442 +.1.3.6.1.4.1.11256.1.4.1.1.33.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.33.13 = Counter64: 1221210 +.1.3.6.1.4.1.11256.1.4.1.1.33.14 = Counter64: 1244124 +.1.3.6.1.4.1.11256.1.4.1.1.34.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.8 = Counter64: 202485 +.1.3.6.1.4.1.11256.1.4.1.1.34.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.34.13 = Counter64: 1199002 +.1.3.6.1.4.1.11256.1.4.1.1.34.14 = Counter64: 1212082 +.1.3.6.1.4.1.11256.1.4.1.1.35.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.8 = Counter64: 7766 +.1.3.6.1.4.1.11256.1.4.1.1.35.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.13 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.35.14 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.8 = Counter64: 7766 +.1.3.6.1.4.1.11256.1.4.1.1.36.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.12 = Counter64: 0 +.1.3.6.1.4.1.11256.1.4.1.1.36.13 = Counter64: 127976 +.1.3.6.1.4.1.11256.1.4.1.1.36.14 = Counter64: 127976 +.1.3.6.1.4.1.11256.1.4.1.1.37.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.2 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.3 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.37.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.37.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.37.7 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.8 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.37.9 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.10 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.37.12 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.13 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.37.14 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.4.1.1.38.1 = STRING: "tun2" +.1.3.6.1.4.1.11256.1.4.1.1.38.2 = STRING: "tun1" +.1.3.6.1.4.1.11256.1.4.1.1.38.3 = STRING: "tun0" +.1.3.6.1.4.1.11256.1.4.1.1.38.4 = STRING: "enc0" +.1.3.6.1.4.1.11256.1.4.1.1.38.5 = STRING: "igb9" +.1.3.6.1.4.1.11256.1.4.1.1.38.6 = STRING: "igb8" +.1.3.6.1.4.1.11256.1.4.1.1.38.7 = STRING: "igb7" +.1.3.6.1.4.1.11256.1.4.1.1.38.8 = STRING: "igb6" +.1.3.6.1.4.1.11256.1.4.1.1.38.9 = STRING: "igb5" +.1.3.6.1.4.1.11256.1.4.1.1.38.10 = STRING: "igb4" +.1.3.6.1.4.1.11256.1.4.1.1.38.11 = STRING: "igb3" +.1.3.6.1.4.1.11256.1.4.1.1.38.12 = STRING: "igb2" +.1.3.6.1.4.1.11256.1.4.1.1.38.13 = STRING: "igb1" +.1.3.6.1.4.1.11256.1.4.1.1.38.14 = STRING: "igb0" +.1.3.6.1.4.1.11256.1.4.1.1.39.1 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.2 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.3 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.4 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.5 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.6 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.7 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.8 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.9 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.10 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.11 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.12 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.13 = "" +.1.3.6.1.4.1.11256.1.4.1.1.39.14 = "" +.1.3.6.1.4.1.11256.1.4.1.1.40.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.8 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.13 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.40.14 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.2 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.3 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.4 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.5 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.6 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.7 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.8 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.9 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.10 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.11 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.12 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.13 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.4.1.1.41.14 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.7.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.7.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.7.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.7.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.7.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.7.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.7.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.7.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.7.1.1.1.10 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.7.1.1.1.11 = INTEGER: 11 +.1.3.6.1.4.1.11256.1.7.1.1.1.12 = INTEGER: 12 +.1.3.6.1.4.1.11256.1.7.1.1.1.13 = INTEGER: 13 +.1.3.6.1.4.1.11256.1.7.1.1.1.14 = INTEGER: 14 +.1.3.6.1.4.1.11256.1.7.1.1.1.15 = INTEGER: 15 +.1.3.6.1.4.1.11256.1.7.1.1.1.16 = INTEGER: 16 +.1.3.6.1.4.1.11256.1.7.1.1.1.17 = INTEGER: 17 +.1.3.6.1.4.1.11256.1.7.1.1.1.18 = INTEGER: 18 +.1.3.6.1.4.1.11256.1.7.1.1.2.1 = STRING: "alived" +.1.3.6.1.4.1.11256.1.7.1.1.2.2 = STRING: "asqd" +.1.3.6.1.4.1.11256.1.7.1.1.2.3 = STRING: "authd" +.1.3.6.1.4.1.11256.1.7.1.1.2.4 = STRING: "certreqd" +.1.3.6.1.4.1.11256.1.7.1.1.2.5 = STRING: "corosync" +.1.3.6.1.4.1.11256.1.7.1.1.2.6 = STRING: "eventd" +.1.3.6.1.4.1.11256.1.7.1.1.2.7 = STRING: "gatewayd" +.1.3.6.1.4.1.11256.1.7.1.1.2.8 = STRING: "hardwared" +.1.3.6.1.4.1.11256.1.7.1.1.2.9 = STRING: "logd" +.1.3.6.1.4.1.11256.1.7.1.1.2.10 = STRING: "monitord" +.1.3.6.1.4.1.11256.1.7.1.1.2.11 = STRING: "routerd" +.1.3.6.1.4.1.11256.1.7.1.1.2.12 = STRING: "serverd" +.1.3.6.1.4.1.11256.1.7.1.1.2.13 = STRING: "sld" +.1.3.6.1.4.1.11256.1.7.1.1.2.14 = STRING: "snmpd" +.1.3.6.1.4.1.11256.1.7.1.1.2.15 = STRING: "sshd" +.1.3.6.1.4.1.11256.1.7.1.1.2.16 = STRING: "stated" +.1.3.6.1.4.1.11256.1.7.1.1.2.17 = STRING: "thind" +.1.3.6.1.4.1.11256.1.7.1.1.2.18 = STRING: "userreqd" +.1.3.6.1.4.1.11256.1.7.1.1.3.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.2 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.3 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.4 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.5 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.6 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.7 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.8 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.9 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.10 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.11 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.12 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.13 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.14 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.15 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.16 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.17 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.3.18 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.7.1.1.4.1 = INTEGER: 6208658 +.1.3.6.1.4.1.11256.1.7.1.1.4.2 = INTEGER: 6208675 +.1.3.6.1.4.1.11256.1.7.1.1.4.3 = INTEGER: 6208669 +.1.3.6.1.4.1.11256.1.7.1.1.4.4 = INTEGER: 6208667 +.1.3.6.1.4.1.11256.1.7.1.1.4.5 = INTEGER: 6208662 +.1.3.6.1.4.1.11256.1.7.1.1.4.6 = INTEGER: 6208650 +.1.3.6.1.4.1.11256.1.7.1.1.4.7 = INTEGER: 6208664 +.1.3.6.1.4.1.11256.1.7.1.1.4.8 = INTEGER: 6208677 +.1.3.6.1.4.1.11256.1.7.1.1.4.9 = INTEGER: 6208679 +.1.3.6.1.4.1.11256.1.7.1.1.4.10 = INTEGER: 6208677 +.1.3.6.1.4.1.11256.1.7.1.1.4.11 = INTEGER: 6208656 +.1.3.6.1.4.1.11256.1.7.1.1.4.12 = INTEGER: 6208671 +.1.3.6.1.4.1.11256.1.7.1.1.4.13 = INTEGER: 6208653 +.1.3.6.1.4.1.11256.1.7.1.1.4.14 = INTEGER: 1389236 +.1.3.6.1.4.1.11256.1.7.1.1.4.15 = INTEGER: 6208673 +.1.3.6.1.4.1.11256.1.7.1.1.4.16 = INTEGER: 6208660 +.1.3.6.1.4.1.11256.1.7.1.1.4.17 = INTEGER: 6208648 +.1.3.6.1.4.1.11256.1.7.1.1.4.18 = INTEGER: 6208675 +.1.3.6.1.4.1.11256.1.7.1.1.5.1 = 620865800 +.1.3.6.1.4.1.11256.1.7.1.1.5.2 = 620867500 +.1.3.6.1.4.1.11256.1.7.1.1.5.3 = 620866900 +.1.3.6.1.4.1.11256.1.7.1.1.5.4 = 620866700 +.1.3.6.1.4.1.11256.1.7.1.1.5.5 = 620866200 +.1.3.6.1.4.1.11256.1.7.1.1.5.6 = 620865000 +.1.3.6.1.4.1.11256.1.7.1.1.5.7 = 620866400 +.1.3.6.1.4.1.11256.1.7.1.1.5.8 = 620867700 +.1.3.6.1.4.1.11256.1.7.1.1.5.9 = 620867900 +.1.3.6.1.4.1.11256.1.7.1.1.5.10 = 620867700 +.1.3.6.1.4.1.11256.1.7.1.1.5.11 = 620865600 +.1.3.6.1.4.1.11256.1.7.1.1.5.12 = 620867100 +.1.3.6.1.4.1.11256.1.7.1.1.5.13 = 620865300 +.1.3.6.1.4.1.11256.1.7.1.1.5.14 = 138923600 +.1.3.6.1.4.1.11256.1.7.1.1.5.15 = 620867300 +.1.3.6.1.4.1.11256.1.7.1.1.5.16 = 620866000 +.1.3.6.1.4.1.11256.1.7.1.1.5.17 = 620864800 +.1.3.6.1.4.1.11256.1.7.1.1.5.18 = 620867500 +.1.3.6.1.4.1.11256.1.8.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.8.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.8.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.8.1.1.2.1 = STRING: "globalfilter" +.1.3.6.1.4.1.11256.1.8.1.1.2.2 = STRING: "filter" +.1.3.6.1.4.1.11256.1.8.1.1.2.3 = STRING: "vpn" +.1.3.6.1.4.1.11256.1.8.1.1.3.1 = STRING: "No broadcast on out interface" +.1.3.6.1.4.1.11256.1.8.1.1.3.2 = STRING: "Pass all High" +.1.3.6.1.4.1.11256.1.8.1.1.3.3 = "" +.1.3.6.1.4.1.11256.1.8.1.1.4.1 = STRING: "09" +.1.3.6.1.4.1.11256.1.8.1.1.4.2 = STRING: "09" +.1.3.6.1.4.1.11256.1.8.1.1.4.3 = STRING: "00" +.1.3.6.1.4.1.11256.1.8.1.1.5.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.8.1.1.5.2 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.8.1.1.5.3 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.9.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.9.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.9.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.9.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.9.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.9.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.9.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.9.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.9.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.9.1.1.1.10 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.9.1.1.1.11 = INTEGER: 11 +.1.3.6.1.4.1.11256.1.9.1.1.2.1 = STRING: "Antispam" +.1.3.6.1.4.1.11256.1.9.1.1.2.2 = STRING: "Patterns" +.1.3.6.1.4.1.11256.1.9.1.1.2.3 = STRING: "CustomPatterns" +.1.3.6.1.4.1.11256.1.9.1.1.2.4 = STRING: "AdvancedAV" +.1.3.6.1.4.1.11256.1.9.1.1.2.5 = STRING: "URLFiltering" +.1.3.6.1.4.1.11256.1.9.1.1.2.6 = STRING: "CompromisedUrls" +.1.3.6.1.4.1.11256.1.9.1.1.2.7 = STRING: "Vaderetro" +.1.3.6.1.4.1.11256.1.9.1.1.2.8 = STRING: "RootCertificates" +.1.3.6.1.4.1.11256.1.9.1.1.2.9 = STRING: "IPData" +.1.3.6.1.4.1.11256.1.9.1.1.2.10 = STRING: "Metadata" +.1.3.6.1.4.1.11256.1.9.1.1.2.11 = STRING: "CustomWebServices" +.1.3.6.1.4.1.11256.1.9.1.1.3.1 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.2 = STRING: "Broken" +.1.3.6.1.4.1.11256.1.9.1.1.3.3 = STRING: "Failed" +.1.3.6.1.4.1.11256.1.9.1.1.3.4 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.5 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.6 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.7 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.8 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.9 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.10 = STRING: "Never started" +.1.3.6.1.4.1.11256.1.9.1.1.3.11 = STRING: "Disabled" +.1.3.6.1.4.1.11256.1.9.1.1.4.1 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.2 = STRING: "2026-02-16 18:29:14" +.1.3.6.1.4.1.11256.1.9.1.1.4.3 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.4 = STRING: "2025-12-08 16:44:58" +.1.3.6.1.4.1.11256.1.9.1.1.4.5 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.6 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.7 = STRING: "2025-12-08 16:42:28" +.1.3.6.1.4.1.11256.1.9.1.1.4.8 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.9 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.10 = "" +.1.3.6.1.4.1.11256.1.9.1.1.4.11 = "" +.1.3.6.1.4.1.11256.1.10.1.0 = STRING: "2026-04-29 17:29:10" +.1.3.6.1.4.1.11256.1.10.2.0 = STRING: "71:20:39:47" +.1.3.6.1.4.1.11256.1.10.3.0 = STRING: "0,0,7,0,0,0,1,0" +.1.3.6.1.4.1.11256.1.10.4.0 = STRING: "2026-02-16 19:49:53" +.1.3.6.1.4.1.11256.1.10.5.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.10.5.1.2.1 = STRING: "ada0" +.1.3.6.1.4.1.11256.1.10.5.1.3.1 = STRING: "PASSED" +.1.3.6.1.4.1.11256.1.10.5.1.4.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.5.1.5.1 = "" +.1.3.6.1.4.1.11256.1.10.5.1.6.1 = STRING: "internal" +.1.3.6.1.4.1.11256.1.10.7.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.10.7.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.10.7.1.2.1 = INTEGER: 45 +.1.3.6.1.4.1.11256.1.10.7.1.2.2 = INTEGER: 46 +.1.3.6.1.4.1.11256.1.10.10.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.10.10.1.2.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.10.1.3.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.10.1.4.1 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.10.10.1.5.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.10.1.6.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.10.1.7.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.10.1.8.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.10.10.1.9.1 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.10.10.1.10.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.10.11.0 = 620878700 +.1.3.6.1.4.1.11256.1.11.1.0 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.11.2.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.3.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.5.0 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.11.6.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.7.1.1.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.7.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.7.1.2.0 = STRING: "" +.1.3.6.1.4.1.11256.1.11.7.1.2.1 = STRING: "" +.1.3.6.1.4.1.11256.1.11.7.1.3.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.7.1.3.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.7.1.4.0 = STRING: "SN910" +.1.3.6.1.4.1.11256.1.11.7.1.4.1 = STRING: "SN910" +.1.3.6.1.4.1.11256.1.11.7.1.5.0 = STRING: "5.0.2" +.1.3.6.1.4.1.11256.1.11.7.1.5.1 = STRING: "5.2.0.dev" +.1.3.6.1.4.1.11256.1.11.7.1.6.0 = STRING: "Master" +.1.3.6.1.4.1.11256.1.11.7.1.6.1 = STRING: "Master" +.1.3.6.1.4.1.11256.1.11.7.1.7.0 = INTEGER: 100 +.1.3.6.1.4.1.11256.1.11.7.1.7.1 = INTEGER: 33 +.1.3.6.1.4.1.11256.1.11.7.1.8.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.7.1.8.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.7.1.9.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.7.1.9.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.7.1.10.0 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.11.7.1.10.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.7.1.11.0 = INTEGER: 6492561 +.1.3.6.1.4.1.11256.1.11.7.1.11.1 = INTEGER: 6208757 +.1.3.6.1.4.1.11256.1.11.7.1.12.0 = 649256100 +.1.3.6.1.4.1.11256.1.11.7.1.12.1 = 620875700 +.1.3.6.1.4.1.11256.1.11.8.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.9.0 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.11.12.1.1.1.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.12.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.12.1.2.1.0 = INTEGER: 45 +.1.3.6.1.4.1.11256.1.11.12.1.2.1.1 = INTEGER: 46 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.11.14.1.1.0.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.11.14.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.11.14.1.2.0.0 = STRING: "Update" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.1 = STRING: "Pattern" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.2 = STRING: "VirusVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.3 = STRING: "URLVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.4 = STRING: "SPAMVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.5 = STRING: "Sandboxing" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.6 = STRING: "Warranty" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.7 = STRING: "ExpressWarranty" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.8 = STRING: "NotAfter" +.1.3.6.1.4.1.11256.1.11.14.1.2.0.9 = STRING: "Industrial" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.0 = STRING: "Update" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.1 = STRING: "Pattern" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.2 = STRING: "VirusVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.3 = STRING: "URLVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.4 = STRING: "SPAMVendor" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.5 = STRING: "Sandboxing" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.6 = STRING: "Warranty" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.7 = STRING: "ExpressWarranty" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.8 = STRING: "NotAfter" +.1.3.6.1.4.1.11256.1.11.14.1.2.1.9 = STRING: "Industrial" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.0 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.1 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.2 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.3 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.4 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.5 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.6 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.7 = STRING: "0000-00-00" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.8 = STRING: "2037-12-31" +.1.3.6.1.4.1.11256.1.11.14.1.3.0.9 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.0 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.1 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.2 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.3 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.4 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.5 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.6 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.7 = STRING: "0000-00-00" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.8 = STRING: "2037-12-31" +.1.3.6.1.4.1.11256.1.11.14.1.3.1.9 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.12.1.1.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.2.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.3.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.4.0 = Counter64: 33565 +.1.3.6.1.4.1.11256.1.12.1.5.0 = Counter64: 318 +.1.3.6.1.4.1.11256.1.12.1.6.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.7.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.8.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.9.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.10.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.11.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.12.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.13.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.14.0 = STRING: "3.29M" +.1.3.6.1.4.1.11256.1.12.1.15.0 = STRING: "3.54M" +.1.3.6.1.4.1.11256.1.12.1.16.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.17.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.18.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.19.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.20.0 = Counter64: 6654 +.1.3.6.1.4.1.11256.1.12.1.21.0 = STRING: "394K" +.1.3.6.1.4.1.11256.1.12.1.22.0 = STRING: "418K" +.1.3.6.1.4.1.11256.1.12.1.23.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.24.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.25.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.26.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.27.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.28.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.29.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.30.0 = Counter64: 26721 +.1.3.6.1.4.1.11256.1.12.1.31.0 = STRING: "2.89M" +.1.3.6.1.4.1.11256.1.12.1.32.0 = STRING: "2.84M" +.1.3.6.1.4.1.11256.1.12.1.33.0 = Counter64: 318 +.1.3.6.1.4.1.11256.1.12.1.34.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.35.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.36.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.37.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.38.0 = Counter64: 190 +.1.3.6.1.4.1.11256.1.12.1.39.0 = STRING: "8.46K" +.1.3.6.1.4.1.11256.1.12.1.40.0 = STRING: "295K" +.1.3.6.1.4.1.11256.1.12.1.41.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.42.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.43.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.44.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.45.0 = STRING: "0.00 " +.1.3.6.1.4.1.11256.1.12.1.46.0 = STRING: "0.00 " +.1.3.6.1.4.1.11256.1.12.1.47.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.48.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.12.1.49.0 = STRING: "0.00 " +.1.3.6.1.4.1.11256.1.12.1.50.0 = STRING: "0.00 " +.1.3.6.1.4.1.11256.1.12.2.1.0 = Counter32: 432 +.1.3.6.1.4.1.11256.1.13.1.1.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.1.2.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.2.1.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.2.2.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.2.3.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.2.4.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.3.1.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.13.3.2.0 = Counter64: 0 +.1.3.6.1.4.1.11256.1.14.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.14.1.1.2.1 = STRING: "DefaultRoute" +.1.3.6.1.4.1.11256.1.14.1.1.3.1 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.14.1.1.4.1 = STRING: "dr4_router" +.1.3.6.1.4.1.11256.1.14.1.1.5.1 = STRING: "fw_gateway" +.1.3.6.1.4.1.11256.1.14.1.1.6.1 = STRING: "" +.1.3.6.1.4.1.11256.1.14.1.1.7.1 = STRING: "Principal" +.1.3.6.1.4.1.11256.1.14.1.1.8.1 = STRING: "2026-04-29 17:29:09" +.1.3.6.1.4.1.11256.1.14.1.1.9.1 = STRING: "UP" +.1.3.6.1.4.1.11256.1.14.1.1.10.1 = STRING: "2026-04-21 20:22:23" +.1.3.6.1.4.1.11256.1.14.1.1.11.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.14.1.1.12.1 = STRING: "2026-02-16 19:51:34" +.1.3.6.1.4.1.11256.1.14.1.1.13.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.14.1.1.14.1 = STRING: "2026-02-16 19:51:34" +.1.3.6.1.4.1.11256.1.14.1.1.15.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.14.1.1.16.1 = STRING: "100.0" +.1.3.6.1.4.1.11256.1.14.1.1.17.1 = STRING: "icmp" +.1.3.6.1.4.1.11256.1.14.1.1.18.1 = Gauge32: 1 +.1.3.6.1.4.1.11256.1.14.1.1.19.1 = Gauge32: 0 +.1.3.6.1.4.1.11256.1.14.1.1.20.1 = STRING: "0.0" +.1.3.6.1.4.1.11256.1.14.1.1.21.1 = STRING: "0.0" +.1.3.6.1.4.1.11256.1.14.1.1.22.1 = INTEGER: 1000 +.1.3.6.1.4.1.11256.1.14.1.1.23.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.14.1.1.24.1 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.15.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.15.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.15.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.15.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.15.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.15.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.15.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.15.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.15.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.15.1.1.1.10 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.15.1.1.1.11 = INTEGER: 11 +.1.3.6.1.4.1.11256.1.15.1.1.2.1 = STRING: "BYPASS_HA" +.1.3.6.1.4.1.11256.1.15.1.1.2.2 = STRING: "BYPASS_ha2" +.1.3.6.1.4.1.11256.1.15.1.1.2.3 = STRING: "BYPASS_client0" +.1.3.6.1.4.1.11256.1.15.1.1.2.4 = STRING: "BYPASS_server0" +.1.3.6.1.4.1.11256.1.15.1.1.2.5 = STRING: "BYPASS_client1" +.1.3.6.1.4.1.11256.1.15.1.1.2.6 = STRING: "BYPASS_server1" +.1.3.6.1.4.1.11256.1.15.1.1.2.7 = STRING: "BYPASS_out" +.1.3.6.1.4.1.11256.1.15.1.1.2.8 = STRING: "BYPASS_in" +.1.3.6.1.4.1.11256.1.15.1.1.2.9 = STRING: "BYPASS_dmz7" +.1.3.6.1.4.1.11256.1.15.1.1.2.10 = STRING: "BYPASS_dmz8" +.1.3.6.1.4.1.11256.1.15.1.1.2.11 = STRING: "BYPASS_ipsec" +.1.3.6.1.4.1.11256.1.15.1.1.3.1 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.2 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.3 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.4 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.5 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.6 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.7 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.8 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.9 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.10 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.3.11 = STRING: "CBQ" +.1.3.6.1.4.1.11256.1.15.1.1.4.1 = Counter64: 1813802 +.1.3.6.1.4.1.11256.1.15.1.1.4.2 = Counter64: 1512728 +.1.3.6.1.4.1.11256.1.15.1.1.4.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.7 = Counter64: 13886 +.1.3.6.1.4.1.11256.1.15.1.1.4.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.4.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.1 = Counter64: 22643 +.1.3.6.1.4.1.11256.1.15.1.1.5.2 = Counter64: 19184 +.1.3.6.1.4.1.11256.1.15.1.1.5.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.7 = Counter64: 1258 +.1.3.6.1.4.1.11256.1.15.1.1.5.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.5.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.6.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.1 = Counter64: 127738 +.1.3.6.1.4.1.11256.1.15.1.1.7.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.7 = Counter64: 303844 +.1.3.6.1.4.1.11256.1.15.1.1.7.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.7.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.1 = Counter64: 531 +.1.3.6.1.4.1.11256.1.15.1.1.8.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.7 = Counter64: 26641 +.1.3.6.1.4.1.11256.1.15.1.1.8.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.8.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.1 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.2 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.3 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.4 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.5 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.6 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.7 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.8 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.9 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.10 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.9.11 = Counter64: 0 +.1.3.6.1.4.1.11256.1.15.1.1.10.1 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.2 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.3 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.4 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.5 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.6 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.7 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.8 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.9 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.10 = "" +.1.3.6.1.4.1.11256.1.15.1.1.10.11 = "" +.1.3.6.1.4.1.11256.1.16.1.0 = STRING: "Major" +.1.3.6.1.4.1.11256.1.16.2.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.16.2.1.2.1 = STRING: "" +.1.3.6.1.4.1.11256.1.16.2.1.3.1 = STRING: "Active" +.1.3.6.1.4.1.11256.1.16.2.1.4.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.5.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.6.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.7.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.8.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.9.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.10.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.11.1 = STRING: "Major" +.1.3.6.1.4.1.11256.1.16.2.1.12.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.13.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.14.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.15.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.16.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.17.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.18.1.0 = STRING: "SN910" +.1.3.6.1.4.1.11256.1.18.2.0 = STRING: "5.2.0.dev" +.1.3.6.1.4.1.11256.1.18.3.0 = STRING: "" +.1.3.6.1.4.1.11256.1.18.4.0 = STRING: "" +.1.3.6.1.4.1.11256.1.18.5.0 = STRING: "fr" +.1.3.6.1.4.1.11256.1.18.6.0 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.18.7.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.18.8.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.18.9.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.18.10.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.18.11.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.18.12.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.18.13.0 = INTEGER: 0 +.1.3.6.1.4.1.11256.1.18.14.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.18.15.0 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.18.16.0 = STRING: "None" +.1.3.6.1.4.1.11256.1.18.17.0 = STRING: "4.6.5" +.1.3.6.1.4.1.11256.1.21.1.1.1.1 = INTEGER: 1 +.1.3.6.1.4.1.11256.1.21.1.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.21.1.1.1.3 = INTEGER: 3 +.1.3.6.1.4.1.11256.1.21.1.1.1.4 = INTEGER: 4 +.1.3.6.1.4.1.11256.1.21.1.1.1.5 = INTEGER: 5 +.1.3.6.1.4.1.11256.1.21.1.1.1.6 = INTEGER: 6 +.1.3.6.1.4.1.11256.1.21.1.1.1.7 = INTEGER: 7 +.1.3.6.1.4.1.11256.1.21.1.1.1.8 = INTEGER: 8 +.1.3.6.1.4.1.11256.1.21.1.1.1.9 = INTEGER: 9 +.1.3.6.1.4.1.11256.1.21.1.1.1.10 = INTEGER: 10 +.1.3.6.1.4.1.11256.1.21.1.1.2.1 = STRING: "Update" +.1.3.6.1.4.1.11256.1.21.1.1.2.2 = STRING: "Pattern" +.1.3.6.1.4.1.11256.1.21.1.1.2.3 = STRING: "VirusVendor" +.1.3.6.1.4.1.11256.1.21.1.1.2.4 = STRING: "URLVendor" +.1.3.6.1.4.1.11256.1.21.1.1.2.5 = STRING: "SPAMVendor" +.1.3.6.1.4.1.11256.1.21.1.1.2.6 = STRING: "Sandboxing" +.1.3.6.1.4.1.11256.1.21.1.1.2.7 = STRING: "Warranty" +.1.3.6.1.4.1.11256.1.21.1.1.2.8 = STRING: "ExpressWarranty" +.1.3.6.1.4.1.11256.1.21.1.1.2.9 = STRING: "NotAfter" +.1.3.6.1.4.1.11256.1.21.1.1.2.10 = STRING: "Industrial" +.1.3.6.1.4.1.11256.1.21.1.1.3.1 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.2 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.3 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.4 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.5 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.6 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.7 = STRING: "2030-02-05" +.1.3.6.1.4.1.11256.1.21.1.1.3.8 = STRING: "0000-00-00" +.1.3.6.1.4.1.11256.1.21.1.1.3.9 = STRING: "2037-12-31" +.1.3.6.1.4.1.11256.1.21.1.1.3.10 = STRING: "2030-02-05" \ No newline at end of file diff --git a/tests/network/stormshield/snmp/uptime.robot b/tests/network/stormshield/snmp/uptime.robot new file mode 100644 index 0000000000..f63158cf69 --- /dev/null +++ b/tests/network/stormshield/snmp/uptime.robot @@ -0,0 +1,46 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=uptime +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} +... --snmp-community=network/stormshield/snmp/sn910 + + +*** Test Cases *** +Uptime ${tc} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;;0; + ... 2 + ... --warning-uptime=1 + ... WARNING: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;0:1;;0; + ... 3 + ... --critical-uptime=1 + ... CRITICAL: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;0:1;0; + ... 4 + ... --verbose + ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;;0; System Name: Model: SN910 Serial Number: Version: 5.2.0.dev Date: 2026-04-29 17:29:10 System Node Name: None Bios Version: 4.6.5 From 87434208c5f98cf3bb1fb9a5bcfb0bc90990e943 Mon Sep 17 00:00:00 2001 From: omercier Date: Tue, 28 Jul 2026 14:22:01 +0200 Subject: [PATCH 23/50] remove useless code --- src/network/stormshield/snmp/mode/uptime.pm | 37 +++------------------ 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index c891ddd95c..ec0afc65b0 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -36,12 +36,12 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'uptime', set => { + { label => 'uptime', nlabel => 'system.uptime.seconds', 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_check'), - output_template => "Uptime: %s", + perfdatas => [ + { template => '%s', unit => 's', min => 0 } + ] } }, ]; @@ -157,35 +157,6 @@ sub custom_uptime_output { return $msg; } -sub custom_uptime_perfdata { - my ($self, %options) = @_; - - my $uptime_seconds = $self->{result_values}->{uptime}; - - $self->{output}->perfdata_add( - label => 'uptime', - nlabel => 'system.uptime.seconds', - value => $uptime_seconds, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-uptime'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-uptime'), - min => 0, - unit => 's' - ); -} - -sub custom_uptime_threshold_check { - my ($self, %options) = @_; - my $uptime_seconds = $self->{result_values}->{uptime}; - - return $self->{perfdata}->threshold_check( - value => $uptime_seconds, - threshold => [ - { label => 'critical-uptime', exit_litteral => 'critical' }, - { label => 'warning-uptime', exit_litteral => 'warning' }, - ] - ); -} - 1; __END__ From 2732e7475af47d7c840e64e7175f394010e2cf53 Mon Sep 17 00:00:00 2001 From: omercier Date: Tue, 28 Jul 2026 14:37:22 +0200 Subject: [PATCH 24/50] fix spelling --- tests/resources/spellcheck/stopwords.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/resources/spellcheck/stopwords.txt b/tests/resources/spellcheck/stopwords.txt index e9375126d4..4a632542a3 100644 --- a/tests/resources/spellcheck/stopwords.txt +++ b/tests/resources/spellcheck/stopwords.txt @@ -237,6 +237,7 @@ nagios Nagios NagVis --nagvis-perfdata +Netasq Netconf Netscaler net-snmp From f4f584778ea0c877b56683affc1fd6359a607edc Mon Sep 17 00:00:00 2001 From: omercier Date: Tue, 28 Jul 2026 15:01:11 +0200 Subject: [PATCH 25/50] force new perfdata on uptime --- src/network/stormshield/snmp/mode/uptime.pm | 2 +- tests/network/stormshield/snmp/uptime.robot | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/stormshield/snmp/mode/uptime.pm b/src/network/stormshield/snmp/mode/uptime.pm index ec0afc65b0..c24f744491 100644 --- a/src/network/stormshield/snmp/mode/uptime.pm +++ b/src/network/stormshield/snmp/mode/uptime.pm @@ -49,7 +49,7 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { diff --git a/tests/network/stormshield/snmp/uptime.robot b/tests/network/stormshield/snmp/uptime.robot index f63158cf69..38adfbb2d1 100644 --- a/tests/network/stormshield/snmp/uptime.robot +++ b/tests/network/stormshield/snmp/uptime.robot @@ -34,13 +34,13 @@ Uptime ${tc} ... -- ... 1 ... ${EMPTY} - ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;;0; + ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;;0; ... 2 ... --warning-uptime=1 - ... WARNING: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;0:1;;0; + ... WARNING: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;0:1;;0; ... 3 ... --critical-uptime=1 - ... CRITICAL: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;0:1;0; + ... CRITICAL: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;0:1;0; ... 4 ... --verbose - ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'uptime'=6208787s;;;0; System Name: Model: SN910 Serial Number: Version: 5.2.0.dev Date: 2026-04-29 17:29:10 System Node Name: None Bios Version: 4.6.5 + ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;;0; System Name: Model: SN910 Serial Number: Version: 5.2.0.dev Date: 2026-04-29 17:29:10 System Node Name: None Bios Version: 4.6.5 From da2a78763cf95eafe5373e54fb411fad53787568 Mon Sep 17 00:00:00 2001 From: crsuser Date: Wed, 13 May 2026 14:55:12 +0200 Subject: [PATCH 26/50] Feat: Add licences.pm mode --- src/network/stormshield/snmp/mode/licences.pm | 381 ++++++++++++++++++ src/network/stormshield/snmp/plugin.pm | 1 + 2 files changed, 382 insertions(+) create mode 100644 src/network/stormshield/snmp/mode/licences.pm diff --git a/src/network/stormshield/snmp/mode/licences.pm b/src/network/stormshield/snmp/mode/licences.pm new file mode 100644 index 0000000000..7eb55326f3 --- /dev/null +++ b/src/network/stormshield/snmp/mode/licences.pm @@ -0,0 +1,381 @@ +# +# Copyright 2026-Present 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::stormshield::snmp::mode::licences; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::constants qw/:counters :values/; +use centreon::plugins::misc; +use DateTime; + +our $GLOBAL_WARNING_THRESHOLD; +our $GLOBAL_PROBLEM; + +sub custom_licence_output { + my ($self, %options) = @_; + + my $name = $self->{result_values}->{name}; + my $days_left = $self->{result_values}->{days_left}; + my $exp_date = $self->{result_values}->{exp_date}; + my $seconds_left = $self->{result_values}->{seconds_left}; + my $fw_display = $options{instance_value}->{display}; + + my $msg = ""; + if (defined $seconds_left) { + if ($seconds_left < 0) { + $msg = "Licence: $name (Expired: $exp_date)"; + } elsif ($days_left <= $GLOBAL_WARNING_THRESHOLD) { + $msg = "Licence: $name (Expires in $days_left days: $exp_date)"; + } else { + $msg = "Licence: $name (Expiration Date: $exp_date)"; + + # Only add to long output if there isn't a warning/critical/unknown + if(!$GLOBAL_PROBLEM) { + $self->{output}->output_add( + long_msg => $msg + ); + } + } + } + + return sprintf($msg); +} + +sub custom_licence_threshold_check { + my ($self, %options) = @_; + + my $days = $self->{result_values}->{days_left}; + my $seconds_left = $self->{result_values}->{seconds_left}; + + if ($seconds_left < 0) { + return 'CRITICAL'; + } elsif ($days <= $GLOBAL_WARNING_THRESHOLD) { + return 'WARNING'; + } else { + return 'OK'; + } +} + + +sub firewall_long_output { + my ($self, %options) = @_; + my $display = $options{instance_value}->{display}; + + if (defined $display && $display ne '') { + return "--------------Firewall $display--------------"; + } + return "------------------------------------------------------------"; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { + name => 'firewalls', + type => COUNTER_TYPE_GROUP, + cb_long_output => 'firewall_long_output', + message_multiple => 'All licences of the cluster are up to date', + group => [ + { + name => 'licences', + display_long => 1, + cb_prefix_output => sub { return ''; }, + message_multiple => 'All licences are up to date', + type => COUNTER_TYPE_INSTANCE, + skipped_code => { -10 => 1 } + } + ] + } + ]; + + $self->{maps_counters}->{licences} = [ + { + label => 'expiry', + type => COUNTER_KIND_METRIC, + set => { + key_values => [ + { name => 'days_left' }, + { name => 'name' }, + { name => 'exp_date' }, + { name => 'seconds_left' } + ], + closure_custom_output => $self->can('custom_licence_output'), + closure_custom_threshold_check => $self->can('custom_licence_threshold_check'), + closure_custom_perfdata => sub { return 0; } + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'timezone:s' => { name => 'timezone' }, + 'warning-days:s' => { name => 'warning' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{option_results}->{timezone} = 'CET' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); + $self->{option_results}->{warning} = 60 if (!defined($self->{option_results}->{warning}) || $self->{option_results}->{warning} eq ''); + + $GLOBAL_WARNING_THRESHOLD = $self->{option_results}->{warning}; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{firewalls} = {}; + + my $oid_snsNode = '.1.3.6.1.4.1.11256.1.11.7.1.1'; + my $oid_snsFwSerial = '.1.3.6.1.4.1.11256.1.11.7.1.2'; + my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; + + my $snmp_result_version = $options{snmp}->get_leef( + oids => [ $oid_snsVersion ], + nothing_quit => 0, + ); + + if (defined $snmp_result_version && defined $snmp_result_version->{$oid_snsVersion}) { + my $version_clean = $snmp_result_version->{$oid_snsVersion}; + # Extract major.minor.patch version number + $version_clean =~ s/([0-9]+(?:\.[0-9]+)*).*/$1/; + + if (!centreon::plugins::misc::minimal_version($version_clean, '5.1.0')) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => 'Firmware version too old. Minimum required: 5.1.0' + ); + return; + } + } + + # Detect if the device is in High Availability (HA) mode or Single Node + my $ha_instances = []; + my $ha_error = 0; + my $ha_result = undef; + my $serials = {}; + + eval { + $ha_result = $options{snmp}->get_table( + oid => $oid_snsNode, + nothing_quit => 0 + ); + }; + if ($@) { + $ha_error = 1; + $self->{output}->output_add(long_msg => "HA Check OID error: $@", debug => 1); + } + + my $is_ha = 0; + if ($ha_error || !defined $ha_result || scalar(keys %$ha_result) == 0) { + # No data returned from HA OID, assume Single Node mode + $self->{output}->output_add(long_msg => "HA Check returned no data, assuming single node mode.", debug => 1); + push @$ha_instances, '0'; + $is_ha = 0; + } else { + # Data returned, parse instances to determine HA cluster members + foreach my $oid (sort keys %$ha_result) { + if ($oid =~ /^$oid_snsNode\.(.*)/) { + my $instance = $1; + push @$ha_instances, $instance; + } + } + + if (scalar(@$ha_instances) == 0) { + push @$ha_instances, '0'; + } + $is_ha = 1; + } + + # Fetch serial numbers for each detected instance (useful for display in HA) + foreach my $inst (@$ha_instances) { + my $oid_serial = "$oid_snsFwSerial.$inst"; + my $serial_res = $options{snmp}->get_leef(oids => [$oid_serial], nothing_quit => 0); + if (defined $serial_res && defined $serial_res->{$oid_serial}) { + $serials->{$inst} = $serial_res->{$oid_serial}; + } else { + $serials->{$inst} = "Unknown"; + } + } + + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + my $licence_count_total = 0; + + + # Define OIDs based on HA or non-HA mode + # Stormshield uses different MIB for HA clusters vs standalone devices + my $oid_table; + my $oid_index_base; + my $oid_name_base; + my $oid_exp_base; + + if ($is_ha) { + $oid_table = '.1.3.6.1.4.1.11256.1.11.14.1'; # oid_snsNodeLicenceOptionEntry + $oid_index_base = '.1.3.6.1.4.1.11256.1.11.14.1.1'; # oid_snsNodeLicenceOptionIndex + $oid_name_base = '.1.3.6.1.4.1.11256.1.11.14.1.2'; # oid_snsNodeLicenceOptionName + $oid_exp_base = '.1.3.6.1.4.1.11256.1.11.14.1.3'; # oid_snsNodeLicenceExpirationDate + } else { + $oid_table = '.1.3.6.1.4.1.11256.1.21.1.1'; # oid_snsLicenceOptionEntry + $oid_index_base = '.1.3.6.1.4.1.11256.1.21.1.1.1'; # oid_snsLicenceOptionIndex + $oid_name_base = '.1.3.6.1.4.1.11256.1.21.1.1.2'; # oid_snsLicenceOptionName + $oid_exp_base = '.1.3.6.1.4.1.11256.1.21.1.1.3'; # oid_snsLicenceExpirationDate + } + + my $snmp_lic_result = $options{snmp}->get_table( + oid => $oid_table, + nothing_quit => 0 + ); + + if (!defined $snmp_lic_result || scalar(keys %{$snmp_lic_result}) == 0) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => 'No valid licences found (SNMP table empty)' + ); + return; + } + + $GLOBAL_PROBLEM = 0; + + # Iterate over each firewall instance (HA node or single node) + foreach my $fw_instance (@$ha_instances) { + my $display_name = ''; + if (scalar(@$ha_instances) > 1) { + $display_name = $serials->{$fw_instance} // 'Unknown'; + } + + $self->{firewalls}->{$fw_instance} = { + display => $display_name, + licences => {} + }; + + foreach my $oid (sort keys %{$snmp_lic_result}) { + my $index; + my $instance_id; + + if ($is_ha) { + # In HA mode, OID structure is: base.instance.index + # We must filter to ensure we only process licenses for the current $fw_instance + if ($oid =~ /^$oid_index_base\.(\d+)\.(\d+)$/) { + $instance_id = $1; + $index = $2; + next unless $instance_id eq $fw_instance; + } else { + next; + } + } else { + # In Single Node mode, OID structure is: base.index + if ($oid =~ /^$oid_index_base\.(.*)$/) { + $index = $1; + } else { + next; + } + } + + my $name_oid = $is_ha ? "$oid_name_base.$fw_instance.$index" : "$oid_name_base.$index"; + my $exp_oid = $is_ha ? "$oid_exp_base.$fw_instance.$index" : "$oid_exp_base.$index"; + + my $name = $snmp_lic_result->{$name_oid}; + my $exp_date = $snmp_lic_result->{$exp_oid}; + + if (!defined $name || $name eq '' || !defined $exp_date || $exp_date eq '' || $exp_date eq 'N/A' || $exp_date eq '0000-00-00') { + next; + } + + my ($year, $month, $day); + if ($exp_date =~ /^\s*(\d{4})-(\d{2})-(\d{2})\s*$/) { + ($year, $month, $day) = ($1, $2, $3); + } else { + next; + } + + my $dt = DateTime->new( + year => $year, + month => $month, + day => $day, + hour => 0, + minute => 0, + second => 0, + %$tz + ); + + my $seconds_left = $dt->epoch - time(); + my $days_left = int($seconds_left / 86400); + + if ($seconds_left < 0 || $days_left <= $GLOBAL_WARNING_THRESHOLD){ + $GLOBAL_PROBLEM = 1; + } + + $self->{firewalls}->{$fw_instance}->{licences}->{$index} = { + name => $name, + exp_date => $exp_date, + days_left => $days_left, + seconds_left => $seconds_left + }; + $licence_count_total++; + } + } + + if ($licence_count_total == 0) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => 'No valid licences found' + ); + $self->{firewalls} = {}; + return; + } + +} + +1; + +__END__ + +=head1 MODE + +This mode allows you to retrieve and display the licenses for the Stormshield device, as well as their expiration dates. +It automatically supports high-availability (HA) configurations by detecting the nodes in the cluster. + +=over 8 + +=item B<--warning-days> + +Warning threshold for the number of days remaining before expiration (default: 60). + +=item B<--timezone> + +Timezone options. Default is 'CET'. + +=back + +=cut \ No newline at end of file diff --git a/src/network/stormshield/snmp/plugin.pm b/src/network/stormshield/snmp/plugin.pm index f2daf55bc6..aea415a782 100644 --- a/src/network/stormshield/snmp/plugin.pm +++ b/src/network/stormshield/snmp/plugin.pm @@ -37,6 +37,7 @@ sub new { 'connections' => 'network::stormshield::snmp::mode::connections', 'interfaces-disco' => 'network::stormshield::snmp::mode::interfaces_disco', 'interfaces' => 'snmp_standard::mode::interfaces', + 'licences' => 'network::stormshield::snmp::mode::licences', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'load' => 'snmp_standard::mode::loadaverage', 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', From 4cdd14eae22d71d813fb346036b994f9571ded29 Mon Sep 17 00:00:00 2001 From: crsuser Date: Fri, 15 May 2026 16:40:29 +0200 Subject: [PATCH 27/50] Fix issues raised by "aikido-pr-checks" --- src/network/stormshield/snmp/mode/licences.pm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/network/stormshield/snmp/mode/licences.pm b/src/network/stormshield/snmp/mode/licences.pm index 7eb55326f3..b9f8a14960 100644 --- a/src/network/stormshield/snmp/mode/licences.pm +++ b/src/network/stormshield/snmp/mode/licences.pm @@ -194,13 +194,11 @@ sub manage_selection { }; if ($@) { $ha_error = 1; - $self->{output}->output_add(long_msg => "HA Check OID error: $@", debug => 1); } my $is_ha = 0; if ($ha_error || !defined $ha_result || scalar(keys %$ha_result) == 0) { # No data returned from HA OID, assume Single Node mode - $self->{output}->output_add(long_msg => "HA Check returned no data, assuming single node mode.", debug => 1); push @$ha_instances, '0'; $is_ha = 0; } else { @@ -219,9 +217,10 @@ sub manage_selection { } # Fetch serial numbers for each detected instance (useful for display in HA) + my @serial_oids = map { "$oid_snsFwSerial.$_" } @$ha_instances; + my $serial_res = $options{snmp}->get_leef(oids => \@serial_oids, nothing_quit => 0); foreach my $inst (@$ha_instances) { my $oid_serial = "$oid_snsFwSerial.$inst"; - my $serial_res = $options{snmp}->get_leef(oids => [$oid_serial], nothing_quit => 0); if (defined $serial_res && defined $serial_res->{$oid_serial}) { $serials->{$inst} = $serial_res->{$oid_serial}; } else { @@ -232,7 +231,6 @@ sub manage_selection { my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); my $licence_count_total = 0; - # Define OIDs based on HA or non-HA mode # Stormshield uses different MIB for HA clusters vs standalone devices my $oid_table; @@ -378,4 +376,4 @@ Timezone options. Default is 'CET'. =back -=cut \ No newline at end of file +=cut From db5e67e7eb7ec185058f6b5097bc5546ffac97dc Mon Sep 17 00:00:00 2001 From: crsuser Date: Thu, 9 Apr 2026 14:59:23 +0200 Subject: [PATCH 28/50] Add Stormshield SNMP mode properties --- .../stormshield/snmp/mode/properties.pm | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/network/stormshield/snmp/mode/properties.pm diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm new file mode 100644 index 0000000000..0d0acfeb7e --- /dev/null +++ b/src/network/stormshield/snmp/mode/properties.pm @@ -0,0 +1,91 @@ +# +# Copyright 2024 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::stormshield::snmp::mode::properties; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + return $self; +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; + my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; + my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; + my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; + my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; + my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; + my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; + my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; + + my $oids = [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ]; + + my $snmp_result = $options{snmp}->get_leef( + oids => $oids, + nothing_quit => 1 + ); + + my $system_name = $snmp_result->{$oid_system_name}; + my $system_node_name = $snmp_result->{$oid_system_node_name}; + my $bios_version = $snmp_result->{$oid_bios_version}; + my $model = $snmp_result->{$oid_model}; + my $version = $snmp_result->{$oid_version}; + my $serial_number = $snmp_result->{$oid_serial_number}; + my $date = $snmp_result->{$oid_date}; + my $uptime = $snmp_result->{$oid_uptime}; + + $self->{output}->output_add( + severity => 'OK', + short_msg => sprintf("Click to see more infos: ...\nSystem Name: %s \nSystem node Name: %s \nModel: %s \nSerial Number: %s \nVersion: %s \nBios Version: %s \nDate: %s \nUptime: %s", + $system_name, $system_node_name, $model, $serial_number, $version, $bios_version, $date, $uptime + ) + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +These options are not applicable for this mode as it does not generate performance data or thresholds. + +=back + +=cut \ No newline at end of file From 225dcdb07a7a1ff64a76de7fa67cce7d04f7a302 Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 11:05:04 +0200 Subject: [PATCH 29/50] anonymization was not specific enough --- tests/network/stormshield/snmp/sn910.snmpwalk | 14 +++++++------- tests/network/stormshield/snmp/uptime.robot | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/network/stormshield/snmp/sn910.snmpwalk b/tests/network/stormshield/snmp/sn910.snmpwalk index 50c4e3f933..5cc952a052 100644 --- a/tests/network/stormshield/snmp/sn910.snmpwalk +++ b/tests/network/stormshield/snmp/sn910.snmpwalk @@ -1,7 +1,7 @@ .1.3.6.1.4.1.11256.1.0.1.0 = STRING: "SN910" .1.3.6.1.4.1.11256.1.0.2.0 = STRING: "5.2.0.dev" -.1.3.6.1.4.1.11256.1.0.3.0 = STRING: "" -.1.3.6.1.4.1.11256.1.0.4.0 = STRING: "" +.1.3.6.1.4.1.11256.1.0.3.0 = STRING: "fw_1" +.1.3.6.1.4.1.11256.1.0.4.0 = STRING: "fw_2" .1.3.6.1.4.1.11256.1.0.5.0 = STRING: "fr" .1.3.6.1.4.1.11256.1.0.6.0 = INTEGER: 10 .1.3.6.1.4.1.11256.1.0.7.0 = INTEGER: 0 @@ -938,8 +938,8 @@ .1.3.6.1.4.1.11256.1.11.6.0 = INTEGER: 0 .1.3.6.1.4.1.11256.1.11.7.1.1.0 = INTEGER: 0 .1.3.6.1.4.1.11256.1.11.7.1.1.1 = INTEGER: 1 -.1.3.6.1.4.1.11256.1.11.7.1.2.0 = STRING: "" -.1.3.6.1.4.1.11256.1.11.7.1.2.1 = STRING: "" +.1.3.6.1.4.1.11256.1.11.7.1.2.0 = STRING: "fw_1" +.1.3.6.1.4.1.11256.1.11.7.1.2.1 = STRING: "fw_2" .1.3.6.1.4.1.11256.1.11.7.1.3.0 = INTEGER: 1 .1.3.6.1.4.1.11256.1.11.7.1.3.1 = INTEGER: 1 .1.3.6.1.4.1.11256.1.11.7.1.4.0 = STRING: "SN910" @@ -1239,8 +1239,8 @@ .1.3.6.1.4.1.11256.1.16.2.1.17.1 = STRING: "N/A" .1.3.6.1.4.1.11256.1.18.1.0 = STRING: "SN910" .1.3.6.1.4.1.11256.1.18.2.0 = STRING: "5.2.0.dev" -.1.3.6.1.4.1.11256.1.18.3.0 = STRING: "" -.1.3.6.1.4.1.11256.1.18.4.0 = STRING: "" +.1.3.6.1.4.1.11256.1.18.3.0 = STRING: "" +.1.3.6.1.4.1.11256.1.18.4.0 = STRING: "" .1.3.6.1.4.1.11256.1.18.5.0 = STRING: "fr" .1.3.6.1.4.1.11256.1.18.6.0 = INTEGER: 10 .1.3.6.1.4.1.11256.1.18.7.0 = INTEGER: 0 @@ -1283,4 +1283,4 @@ .1.3.6.1.4.1.11256.1.21.1.1.3.7 = STRING: "2030-02-05" .1.3.6.1.4.1.11256.1.21.1.1.3.8 = STRING: "0000-00-00" .1.3.6.1.4.1.11256.1.21.1.1.3.9 = STRING: "2037-12-31" -.1.3.6.1.4.1.11256.1.21.1.1.3.10 = STRING: "2030-02-05" \ No newline at end of file +.1.3.6.1.4.1.11256.1.21.1.1.3.10 = STRING: "2030-02-05" diff --git a/tests/network/stormshield/snmp/uptime.robot b/tests/network/stormshield/snmp/uptime.robot index 38adfbb2d1..69ceb2fc24 100644 --- a/tests/network/stormshield/snmp/uptime.robot +++ b/tests/network/stormshield/snmp/uptime.robot @@ -43,4 +43,4 @@ Uptime ${tc} ... CRITICAL: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;0:1;0; ... 4 ... --verbose - ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;;0; System Name: Model: SN910 Serial Number: Version: 5.2.0.dev Date: 2026-04-29 17:29:10 System Node Name: None Bios Version: 4.6.5 + ... OK: Uptime: 71 days 20 hours 39 minutes 47 seconds | 'system.uptime.seconds'=6208787s;;;0; System Name: Model: SN910 Serial Number: Version: 5.2.0.dev Date: 2026-04-29 17:29:10 System Node Name: None Bios Version: 4.6.5 From 896185a0f532707cd719842ef3728a3849934003 Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 11:33:21 +0200 Subject: [PATCH 30/50] make it work like a centreon-plugin --- .githooks/pre-commit.d/20_plugins.sh | 2 +- src/network/stormshield/snmp/mode/licences.pm | 96 +++++-------------- 2 files changed, 27 insertions(+), 71 deletions(-) diff --git a/.githooks/pre-commit.d/20_plugins.sh b/.githooks/pre-commit.d/20_plugins.sh index 8890524c5a..a39c878265 100755 --- a/.githooks/pre-commit.d/20_plugins.sh +++ b/.githooks/pre-commit.d/20_plugins.sh @@ -43,7 +43,7 @@ function check_constants() { grep -nH -- "-\(1\|2\|10\)[[:space:]]*=>[[:space:]]*1" "$file" > "$tmpfile" grep -nH "\[[:space:]]*[0-9]" "$file" >> "$tmpfile" if [ -s "$tmpfile" ] ; then - error "It seems that some counters are not using constants defined in centreon/plugins/constants.pm. You may also need to add `use centreon::plugins::constants qw(:counters);` in your file." + error "It seems that some counters are not using constants defined in centreon/plugins/constants.pm. You may also need to add 'use centreon::plugins::constants qw(:counters);' in your file." cat $tmpfile fi } diff --git a/src/network/stormshield/snmp/mode/licences.pm b/src/network/stormshield/snmp/mode/licences.pm index b9f8a14960..0fead48dff 100644 --- a/src/network/stormshield/snmp/mode/licences.pm +++ b/src/network/stormshield/snmp/mode/licences.pm @@ -24,14 +24,10 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use Digest::MD5 qw(md5_hex); use centreon::plugins::constants qw/:counters :values/; use centreon::plugins::misc; use DateTime; -our $GLOBAL_WARNING_THRESHOLD; -our $GLOBAL_PROBLEM; - sub custom_licence_output { my ($self, %options) = @_; @@ -41,43 +37,11 @@ sub custom_licence_output { my $seconds_left = $self->{result_values}->{seconds_left}; my $fw_display = $options{instance_value}->{display}; - my $msg = ""; - if (defined $seconds_left) { - if ($seconds_left < 0) { - $msg = "Licence: $name (Expired: $exp_date)"; - } elsif ($days_left <= $GLOBAL_WARNING_THRESHOLD) { - $msg = "Licence: $name (Expires in $days_left days: $exp_date)"; - } else { - $msg = "Licence: $name (Expiration Date: $exp_date)"; - - # Only add to long output if there isn't a warning/critical/unknown - if(!$GLOBAL_PROBLEM) { - $self->{output}->output_add( - long_msg => $msg - ); - } - } - } - - return sprintf($msg); -} - -sub custom_licence_threshold_check { - my ($self, %options) = @_; - - my $days = $self->{result_values}->{days_left}; - my $seconds_left = $self->{result_values}->{seconds_left}; + my $msg = "Licence: $name (Expires in $days_left days: $exp_date)"; - if ($seconds_left < 0) { - return 'CRITICAL'; - } elsif ($days <= $GLOBAL_WARNING_THRESHOLD) { - return 'WARNING'; - } else { - return 'OK'; - } + return sprintf($msg); } - sub firewall_long_output { my ($self, %options) = @_; my $display = $options{instance_value}->{display}; @@ -94,17 +58,16 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'firewalls', - type => COUNTER_TYPE_GROUP, + type => COUNTER_TYPE_MULTIPLE, cb_long_output => 'firewall_long_output', message_multiple => 'All licences of the cluster are up to date', group => [ { name => 'licences', display_long => 1, - cb_prefix_output => sub { return ''; }, + #cb_prefix_output => sub { return ''; }, message_multiple => 'All licences are up to date', - type => COUNTER_TYPE_INSTANCE, - skipped_code => { -10 => 1 } + type => COUNTER_MULTIPLE_SUBINSTANCE, } ] } @@ -112,8 +75,11 @@ sub set_counters { $self->{maps_counters}->{licences} = [ { - label => 'expiry', + label => 'expires-days', + nlabel => 'license.expiration.days', type => COUNTER_KIND_METRIC, + warning_default => '60:', + critical_default => '0:', set => { key_values => [ { name => 'days_left' }, @@ -121,9 +87,10 @@ sub set_counters { { name => 'exp_date' }, { name => 'seconds_left' } ], - closure_custom_output => $self->can('custom_licence_output'), - closure_custom_threshold_check => $self->can('custom_licence_threshold_check'), - closure_custom_perfdata => sub { return 0; } + output_template => "Licence: %{name} (Expires in %{days_left} days: %{exp_date})", + perfdatas => [ + { template => '%s', unit => 'd', cast_int => 1, label_extra_instance => 1 } + ] } }, ]; @@ -131,27 +98,17 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { - 'timezone:s' => { name => 'timezone' }, + 'timezone:s' => { name => 'timezone', default => 'CET' }, 'warning-days:s' => { name => 'warning' }, }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->{option_results}->{timezone} = 'CET' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); - $self->{option_results}->{warning} = 60 if (!defined($self->{option_results}->{warning}) || $self->{option_results}->{warning} eq ''); - - $GLOBAL_WARNING_THRESHOLD = $self->{option_results}->{warning}; -} - sub manage_selection { my ($self, %options) = @_; @@ -263,16 +220,15 @@ sub manage_selection { return; } - $GLOBAL_PROBLEM = 0; - # Iterate over each firewall instance (HA node or single node) foreach my $fw_instance (@$ha_instances) { + my $fw_key = $serials->{$fw_instance} // 'Unknown'; my $display_name = ''; if (scalar(@$ha_instances) > 1) { - $display_name = $serials->{$fw_instance} // 'Unknown'; + $display_name = $fw_key; } - $self->{firewalls}->{$fw_instance} = { + $self->{firewalls}->{$fw_key} = { display => $display_name, licences => {} }; @@ -330,11 +286,7 @@ sub manage_selection { my $seconds_left = $dt->epoch - time(); my $days_left = int($seconds_left / 86400); - if ($seconds_left < 0 || $days_left <= $GLOBAL_WARNING_THRESHOLD){ - $GLOBAL_PROBLEM = 1; - } - - $self->{firewalls}->{$fw_instance}->{licences}->{$index} = { + $self->{firewalls}->{$fw_key}->{licences}->{$name} = { name => $name, exp_date => $exp_date, days_left => $days_left, @@ -366,13 +318,17 @@ It automatically supports high-availability (HA) configurations by detecting the =over 8 -=item B<--warning-days> +=item B<--warning-expires-days> + +Threshold in days (default: 60). + +=item B<--critical-expires-days> -Warning threshold for the number of days remaining before expiration (default: 60). +Threshold in days (default: 0). =item B<--timezone> -Timezone options. Default is 'CET'. +Timezone options. Default is C. =back From d61de0b0755c78ddde969cee62cef61830e53ec1 Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 12:14:45 +0200 Subject: [PATCH 31/50] rename licences to licenses + add tests --- .../snmp/mode/{licences.pm => licenses.pm} | 2 +- src/network/stormshield/snmp/plugin.pm | 2 +- tests/network/stormshield/snmp/fixed_date.pm | 14 ++++++ tests/network/stormshield/snmp/help.robot | 3 ++ tests/network/stormshield/snmp/licenses.robot | 50 +++++++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) rename src/network/stormshield/snmp/mode/{licences.pm => licenses.pm} (99%) create mode 100644 tests/network/stormshield/snmp/fixed_date.pm create mode 100644 tests/network/stormshield/snmp/licenses.robot diff --git a/src/network/stormshield/snmp/mode/licences.pm b/src/network/stormshield/snmp/mode/licenses.pm similarity index 99% rename from src/network/stormshield/snmp/mode/licences.pm rename to src/network/stormshield/snmp/mode/licenses.pm index 0fead48dff..1fed1cd3f3 100644 --- a/src/network/stormshield/snmp/mode/licences.pm +++ b/src/network/stormshield/snmp/mode/licenses.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::stormshield::snmp::mode::licences; +package network::stormshield::snmp::mode::licenses; use base qw(centreon::plugins::templates::counter); diff --git a/src/network/stormshield/snmp/plugin.pm b/src/network/stormshield/snmp/plugin.pm index aea415a782..7d0f186178 100644 --- a/src/network/stormshield/snmp/plugin.pm +++ b/src/network/stormshield/snmp/plugin.pm @@ -37,7 +37,7 @@ sub new { 'connections' => 'network::stormshield::snmp::mode::connections', 'interfaces-disco' => 'network::stormshield::snmp::mode::interfaces_disco', 'interfaces' => 'snmp_standard::mode::interfaces', - 'licences' => 'network::stormshield::snmp::mode::licences', + 'licenses' => 'network::stormshield::snmp::mode::licenses', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'load' => 'snmp_standard::mode::loadaverage', 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', diff --git a/tests/network/stormshield/snmp/fixed_date.pm b/tests/network/stormshield/snmp/fixed_date.pm new file mode 100644 index 0000000000..9c36f00927 --- /dev/null +++ b/tests/network/stormshield/snmp/fixed_date.pm @@ -0,0 +1,14 @@ +package fixed_date; + +# Copyright 2026-Present Centreon +# Always use the same fixed date so licence expiration tests keep a stable output + +use DateTime; + +BEGIN { + $now = 1785448800; + *CORE::GLOBAL::time = sub { $now }; + *DateTime::now = sub { DateTime->from_epoch(epoch => $now) }; +} + +1 diff --git a/tests/network/stormshield/snmp/help.robot b/tests/network/stormshield/snmp/help.robot index 81b72430ac..7055bb4316 100644 --- a/tests/network/stormshield/snmp/help.robot +++ b/tests/network/stormshield/snmp/help.robot @@ -75,3 +75,6 @@ Standard ${tc} - ${mode} ... 16 ... vpn-status ... Mode:\n.*Check vpn + ... 17 + ... licenses + ... Mode:\n.*licenses diff --git a/tests/network/stormshield/snmp/licenses.robot b/tests/network/stormshield/snmp/licenses.robot new file mode 100644 index 0000000000..d6889af05f --- /dev/null +++ b/tests/network/stormshield/snmp/licenses.robot @@ -0,0 +1,50 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${INJECT_PERL} -Mfixed_date -I${CURDIR} +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=licenses +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} +... --snmp-community=network/stormshield/snmp/sn910 + + +*** Test Cases *** +Licenses ${tc} + [Tags] network stormshield snmp + ${OLD_PERL5OPT}= Get Environment Variable PERL5OPT default=${EMPTY} + Set Environment Variable PERL5OPT ${INJECT_PERL} ${OLD_PERL5OPT} + + ${command}= Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command Without Connector And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: All licences of the cluster are up to date | 'fw_1~Industrial#license.expiration.days'=1285d;60:;0:;; 'fw_1~NotAfter#license.expiration.days'=4171d;60:;0:;; 'fw_1~Pattern#license.expiration.days'=1285d;60:;0:;; 'fw_1~SPAMVendor#license.expiration.days'=1285d;60:;0:;; 'fw_1~Sandboxing#license.expiration.days'=1285d;60:;0:;; 'fw_1~URLVendor#license.expiration.days'=1285d;60:;0:;; 'fw_1~Update#license.expiration.days'=1285d;60:;0:;; 'fw_1~VirusVendor#license.expiration.days'=1285d;60:;0:;; 'fw_1~Warranty#license.expiration.days'=1285d;60:;0:;; 'fw_2~Industrial#license.expiration.days'=1285d;60:;0:;; 'fw_2~NotAfter#license.expiration.days'=4171d;60:;0:;; 'fw_2~Pattern#license.expiration.days'=1285d;60:;0:;; 'fw_2~SPAMVendor#license.expiration.days'=1285d;60:;0:;; 'fw_2~Sandboxing#license.expiration.days'=1285d;60:;0:;; 'fw_2~URLVendor#license.expiration.days'=1285d;60:;0:;; 'fw_2~Update#license.expiration.days'=1285d;60:;0:;; 'fw_2~VirusVendor#license.expiration.days'=1285d;60:;0:;; 'fw_2~Warranty#license.expiration.days'=1285d;60:;0:;; + ... 2 + ... --warning-expires-days=1 + ... WARNING: Licence: Industrial (Expires in 1285 days: 2030-02-05) - Licence: NotAfter (Expires in 4171 days: 2037-12-31) - Licence: Pattern (Expires in 1285 days: 2030-02-05) - Licence: SPAMVendor (Expires in 1285 days: 2030-02-05) - Licence: Sandboxing (Expires in 1285 days: 2030-02-05) - Licence: URLVendor (Expires in 1285 days: 2030-02-05) - Licence: Update (Expires in 1285 days: 2030-02-05) - Licence: VirusVendor (Expires in 1285 days: 2030-02-05) - Licence: Warranty (Expires in 1285 days: 2030-02-05) - Licence: Industrial (Expires in 1285 days: 2030-02-05) - Licence: NotAfter (Expires in 4171 days: 2037-12-31) - Licence: Pattern (Expires in 1285 days: 2030-02-05) - Licence: SPAMVendor (Expires in 1285 days: 2030-02-05) - Licence: Sandboxing (Expires in 1285 days: 2030-02-05) - Licence: URLVendor (Expires in 1285 days: 2030-02-05) - Licence: Update (Expires in 1285 days: 2030-02-05) - Licence: VirusVendor (Expires in 1285 days: 2030-02-05) - Licence: Warranty (Expires in 1285 days: 2030-02-05) | 'fw_1~Industrial#license.expiration.days'=1285d;0:1;0:;; 'fw_1~NotAfter#license.expiration.days'=4171d;0:1;0:;; 'fw_1~Pattern#license.expiration.days'=1285d;0:1;0:;; 'fw_1~SPAMVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_1~Sandboxing#license.expiration.days'=1285d;0:1;0:;; 'fw_1~URLVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_1~Update#license.expiration.days'=1285d;0:1;0:;; 'fw_1~VirusVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_1~Warranty#license.expiration.days'=1285d;0:1;0:;; 'fw_2~Industrial#license.expiration.days'=1285d;0:1;0:;; 'fw_2~NotAfter#license.expiration.days'=4171d;0:1;0:;; 'fw_2~Pattern#license.expiration.days'=1285d;0:1;0:;; 'fw_2~SPAMVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_2~Sandboxing#license.expiration.days'=1285d;0:1;0:;; 'fw_2~URLVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_2~Update#license.expiration.days'=1285d;0:1;0:;; 'fw_2~VirusVendor#license.expiration.days'=1285d;0:1;0:;; 'fw_2~Warranty#license.expiration.days'=1285d;0:1;0:;; + ... 3 + ... --critical-expires-days=1 + ... CRITICAL: Licence: Industrial (Expires in 1285 days: 2030-02-05) - Licence: NotAfter (Expires in 4171 days: 2037-12-31) - Licence: Pattern (Expires in 1285 days: 2030-02-05) - Licence: SPAMVendor (Expires in 1285 days: 2030-02-05) - Licence: Sandboxing (Expires in 1285 days: 2030-02-05) - Licence: URLVendor (Expires in 1285 days: 2030-02-05) - Licence: Update (Expires in 1285 days: 2030-02-05) - Licence: VirusVendor (Expires in 1285 days: 2030-02-05) - Licence: Warranty (Expires in 1285 days: 2030-02-05) - Licence: Industrial (Expires in 1285 days: 2030-02-05) - Licence: NotAfter (Expires in 4171 days: 2037-12-31) - Licence: Pattern (Expires in 1285 days: 2030-02-05) - Licence: SPAMVendor (Expires in 1285 days: 2030-02-05) - Licence: Sandboxing (Expires in 1285 days: 2030-02-05) - Licence: URLVendor (Expires in 1285 days: 2030-02-05) - Licence: Update (Expires in 1285 days: 2030-02-05) - Licence: VirusVendor (Expires in 1285 days: 2030-02-05) - Licence: Warranty (Expires in 1285 days: 2030-02-05) | 'fw_1~Industrial#license.expiration.days'=1285d;60:;0:1;; 'fw_1~NotAfter#license.expiration.days'=4171d;60:;0:1;; 'fw_1~Pattern#license.expiration.days'=1285d;60:;0:1;; 'fw_1~SPAMVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_1~Sandboxing#license.expiration.days'=1285d;60:;0:1;; 'fw_1~URLVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_1~Update#license.expiration.days'=1285d;60:;0:1;; 'fw_1~VirusVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_1~Warranty#license.expiration.days'=1285d;60:;0:1;; 'fw_2~Industrial#license.expiration.days'=1285d;60:;0:1;; 'fw_2~NotAfter#license.expiration.days'=4171d;60:;0:1;; 'fw_2~Pattern#license.expiration.days'=1285d;60:;0:1;; 'fw_2~SPAMVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_2~Sandboxing#license.expiration.days'=1285d;60:;0:1;; 'fw_2~URLVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_2~Update#license.expiration.days'=1285d;60:;0:1;; 'fw_2~VirusVendor#license.expiration.days'=1285d;60:;0:1;; 'fw_2~Warranty#license.expiration.days'=1285d;60:;0:1;; + ... 4 + ... --timezone=Asia/Tokyo + ... OK: All licences of the cluster are up to date | 'fw_1~Industrial#license.expiration.days'=1284d;60:;0:;; 'fw_1~NotAfter#license.expiration.days'=4170d;60:;0:;; 'fw_1~Pattern#license.expiration.days'=1284d;60:;0:;; 'fw_1~SPAMVendor#license.expiration.days'=1284d;60:;0:;; 'fw_1~Sandboxing#license.expiration.days'=1284d;60:;0:;; 'fw_1~URLVendor#license.expiration.days'=1284d;60:;0:;; 'fw_1~Update#license.expiration.days'=1284d;60:;0:;; 'fw_1~VirusVendor#license.expiration.days'=1284d;60:;0:;; 'fw_1~Warranty#license.expiration.days'=1284d;60:;0:;; 'fw_2~Industrial#license.expiration.days'=1284d;60:;0:;; 'fw_2~NotAfter#license.expiration.days'=4170d;60:;0:;; 'fw_2~Pattern#license.expiration.days'=1284d;60:;0:;; 'fw_2~SPAMVendor#license.expiration.days'=1284d;60:;0:;; 'fw_2~Sandboxing#license.expiration.days'=1284d;60:;0:;; 'fw_2~URLVendor#license.expiration.days'=1284d;60:;0:;; 'fw_2~Update#license.expiration.days'=1284d;60:;0:;; 'fw_2~VirusVendor#license.expiration.days'=1284d;60:;0:;; 'fw_2~Warranty#license.expiration.days'=1284d;60:;0:;; From f7e45367425ddc1d0a0b1ee33c1b97613944048c Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 14:28:24 +0200 Subject: [PATCH 32/50] modernize --- src/network/stormshield/snmp/mode/licenses.pm | 65 +++++++------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/src/network/stormshield/snmp/mode/licenses.pm b/src/network/stormshield/snmp/mode/licenses.pm index 1fed1cd3f3..26ebaf2f69 100644 --- a/src/network/stormshield/snmp/mode/licenses.pm +++ b/src/network/stormshield/snmp/mode/licenses.pm @@ -25,27 +25,13 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::constants qw/:counters :values/; -use centreon::plugins::misc; +use centreon::plugins::misc qw(is_empty); use DateTime; -sub custom_licence_output { - my ($self, %options) = @_; - - my $name = $self->{result_values}->{name}; - my $days_left = $self->{result_values}->{days_left}; - my $exp_date = $self->{result_values}->{exp_date}; - my $seconds_left = $self->{result_values}->{seconds_left}; - my $fw_display = $options{instance_value}->{display}; - - my $msg = "Licence: $name (Expires in $days_left days: $exp_date)"; - - return sprintf($msg); -} - sub firewall_long_output { my ($self, %options) = @_; my $display = $options{instance_value}->{display}; - + if (defined $display && $display ne '') { return "--------------Firewall $display--------------"; } @@ -56,17 +42,17 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { - name => 'firewalls', + { + name => 'firewalls', type => COUNTER_TYPE_MULTIPLE, - cb_long_output => 'firewall_long_output', + cb_long_output => 'firewall_long_output', message_multiple => 'All licences of the cluster are up to date', group => [ - { - name => 'licences', + { + name => 'licences', display_long => 1, #cb_prefix_output => sub { return ''; }, - message_multiple => 'All licences are up to date', + message_multiple => 'All licences are up to date', type => COUNTER_MULTIPLE_SUBINSTANCE, } ] @@ -81,7 +67,7 @@ sub set_counters { warning_default => '60:', critical_default => '0:', set => { - key_values => [ + key_values => [ { name => 'days_left' }, { name => 'name' }, { name => 'exp_date' }, @@ -102,8 +88,7 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { - 'timezone:s' => { name => 'timezone', default => 'CET' }, - 'warning-days:s' => { name => 'warning' }, + 'timezone:s' => { name => 'timezone', default => 'CET' } }); return $self; @@ -113,8 +98,8 @@ sub manage_selection { my ($self, %options) = @_; $self->{firewalls} = {}; - - my $oid_snsNode = '.1.3.6.1.4.1.11256.1.11.7.1.1'; + + my $oid_snsNode = '.1.3.6.1.4.1.11256.1.11.7.1.1'; my $oid_snsFwSerial = '.1.3.6.1.4.1.11256.1.11.7.1.2'; my $oid_snsVersion = '.1.3.6.1.4.1.11256.1.18.2.0'; @@ -122,7 +107,7 @@ sub manage_selection { oids => [ $oid_snsVersion ], nothing_quit => 0, ); - + if (defined $snmp_result_version && defined $snmp_result_version->{$oid_snsVersion}) { my $version_clean = $snmp_result_version->{$oid_snsVersion}; # Extract major.minor.patch version number @@ -146,7 +131,7 @@ sub manage_selection { eval { $ha_result = $options{snmp}->get_table( oid => $oid_snsNode, - nothing_quit => 0 + nothing_quit => 0 ); }; if ($@) { @@ -166,9 +151,9 @@ sub manage_selection { push @$ha_instances, $instance; } } - + if (scalar(@$ha_instances) == 0) { - push @$ha_instances, '0'; + push @$ha_instances, '0'; } $is_ha = 1; } @@ -189,12 +174,12 @@ sub manage_selection { my $licence_count_total = 0; # Define OIDs based on HA or non-HA mode - # Stormshield uses different MIB for HA clusters vs standalone devices + # Stormshield uses different MIB for HA clusters vs standalone devices my $oid_table; my $oid_index_base; my $oid_name_base; my $oid_exp_base; - + if ($is_ha) { $oid_table = '.1.3.6.1.4.1.11256.1.11.14.1'; # oid_snsNodeLicenceOptionEntry $oid_index_base = '.1.3.6.1.4.1.11256.1.11.14.1.1'; # oid_snsNodeLicenceOptionIndex @@ -209,7 +194,7 @@ sub manage_selection { my $snmp_lic_result = $options{snmp}->get_table( oid => $oid_table, - nothing_quit => 0 + nothing_quit => 0 ); if (!defined $snmp_lic_result || scalar(keys %{$snmp_lic_result}) == 0) { @@ -236,7 +221,7 @@ sub manage_selection { foreach my $oid (sort keys %{$snmp_lic_result}) { my $index; my $instance_id; - + if ($is_ha) { # In HA mode, OID structure is: base.instance.index # We must filter to ensure we only process licenses for the current $fw_instance @@ -262,7 +247,7 @@ sub manage_selection { my $name = $snmp_lic_result->{$name_oid}; my $exp_date = $snmp_lic_result->{$exp_oid}; - if (!defined $name || $name eq '' || !defined $exp_date || $exp_date eq '' || $exp_date eq 'N/A' || $exp_date eq '0000-00-00') { + if (is_empty($name) || is_empty($exp_date) || $exp_date eq 'N/A' || $exp_date eq '0000-00-00') { next; } @@ -282,7 +267,7 @@ sub manage_selection { second => 0, %$tz ); - + my $seconds_left = $dt->epoch - time(); my $days_left = int($seconds_left / 86400); @@ -301,10 +286,10 @@ sub manage_selection { severity => 'UNKNOWN', short_msg => 'No valid licences found' ); - $self->{firewalls} = {}; + $self->{firewalls} = {}; return; - } - + } + } 1; From 33c50712d080c49fde1f3db09ddce94172e3c0b0 Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 18:00:54 +0200 Subject: [PATCH 33/50] fix missing dependency --- packaging/centreon-plugin-Network-Stormshield-Snmp/rpm.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/centreon-plugin-Network-Stormshield-Snmp/rpm.json b/packaging/centreon-plugin-Network-Stormshield-Snmp/rpm.json index 418a331fce..ff5e30b76c 100644 --- a/packaging/centreon-plugin-Network-Stormshield-Snmp/rpm.json +++ b/packaging/centreon-plugin-Network-Stormshield-Snmp/rpm.json @@ -1,5 +1,6 @@ { "dependencies": [ + "perl(DateTime)", "perl(SNMP)" ] -} \ No newline at end of file +} From 934208fb551cc8d034ad46a10b6ac8440c13575e Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 18:01:27 +0200 Subject: [PATCH 34/50] switch to counter text instead of metric --- .../stormshield/snmp/mode/auto_update.pm | 104 ++++++++---------- .../stormshield/snmp/auto-update.robot | 49 +++++++++ 2 files changed, 93 insertions(+), 60 deletions(-) create mode 100644 tests/network/stormshield/snmp/auto-update.robot diff --git a/src/network/stormshield/snmp/mode/auto_update.pm b/src/network/stormshield/snmp/mode/auto_update.pm index 334739d7de..9e0407c888 100644 --- a/src/network/stormshield/snmp/mode/auto_update.pm +++ b/src/network/stormshield/snmp/mode/auto_update.pm @@ -20,6 +20,8 @@ package network::stormshield::snmp::mode::auto_update; use base qw(centreon::plugins::templates::counter); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::misc qw(is_empty); use strict; use warnings; @@ -27,50 +29,25 @@ use DateTime; use centreon::plugins::constants qw(:counters); use centreon::plugins::misc; +my %STATES_TO_READABLE = ( + 'Uptodate' => 'is up to date', + 'Disabled' => 'is disabled', + 'NeverStarted' => 'never started', + 'Failed' => 'has failed', + 'Broken' => 'is broken', + 'Partially Failed' => 'partially failed', + 'N/A' => 'has no available state' +); + sub custom_auto_update_output { my ($self, %options) = @_; my $state = $self->{result_values}->{state}; - my $last_date = $self->{result_values}->{last_date} // 'N/A'; my $display = $self->{result_values}->{display}; - my $msg = ""; - - if ($state eq 'Uptodate') { - $msg = "$display is up to date"; - } elsif ($state eq 'Disabled') { - $msg = "$display is disabled"; - } elsif ($state eq 'NeverStarted') { - $msg = "$display never started"; - } else { - $msg = "$display $state (Last Update: $last_date)"; - } - - if (!$self->{output}->{long_msg_added}) { - $self->{output}->{long_msg_added} = 1; - $self->{output}->output_add( - long_msg => "-----------------------------------------------------------------------\n" - ); - } - - return $msg; - -} - -sub custom_auto_update_threshold_check { - my ($self, %options) = @_; - - my $state = $self->{result_values}->{state}; - - if ($state eq 'Failed' || $state eq 'Broken') { - return 'CRITICAL'; - } elsif ($state eq 'Partially Failed') { - return 'WARNING'; - } elsif ($state eq 'Disabled' || $state eq 'NeverStarted') { - return 'OK'; - } else { - return 'OK'; - } + return "$display " . $STATES_TO_READABLE{$state} if $STATES_TO_READABLE{$state}; + return "$display " . $state + . " (Last Update: " . ($self->{result_values}->{last_date} // 'N/A') . ")"; } sub set_counters { @@ -80,24 +57,24 @@ sub set_counters { { name => 'updates', type => COUNTER_TYPE_INSTANCE, - message_multiple => 'All Updates and Webservices are up to date', - skipped_code => { -10 => 1 } + message_multiple => 'All Updates and Webservices are up to date' } ]; $self->{maps_counters}->{updates} = [ { - label => 'status', - type => COUNTER_KIND_METRIC, - set => { - key_values => [ + label => 'status', + type => COUNTER_KIND_TEXT, + warning_default => '%{state} =~ /Partially Failed/i', + critical_default => '%{state} =~ /^(Failed|Broken)$/i', + set => { + key_values => [ { name => 'display' }, { name => 'state' }, { name => 'last_date' } ], closure_custom_output => $self->can('custom_auto_update_output'), - closure_custom_threshold_check => $self->can('custom_auto_update_threshold_check'), - closure_custom_perfdata => sub { return 0; } + closure_custom_threshold_check => \&catalog_status_threshold_ng } }, ]; @@ -108,9 +85,6 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => { - }); - return $self; } @@ -202,20 +176,15 @@ sub process_table { my $index = $oid; $index =~ s/^$index_oid\.//; - my $name = $snmp_result->{"$name_oid.$index"} // 'N/A'; - my $state = $snmp_result->{"$state_oid.$index"} // 'N/A'; - my $lastDate = $snmp_result->{"$date_oid.$index"} // 'N/A'; + my $name = is_empty($snmp_result->{"$name_oid.$index"}) ? 'N/A' : $snmp_result->{"$name_oid.$index"}; + my $state = is_empty($snmp_result->{"$state_oid.$index"}) ? 'N/A' : $snmp_result->{"$state_oid.$index"}; + my $lastDate = is_empty($snmp_result->{"$date_oid.$index"}) ? 'N/A' : $snmp_result->{"$date_oid.$index"}; - my $normalized_state = $state; - if ($normalized_state eq 'Disabled') { - $normalized_state = 'Disabled'; - } elsif ($normalized_state !~ /^(Uptodate|Failed|Broken|Partially Failed)/) { - $normalized_state = 'NeverStarted'; - } + my $normalized_state = ($state =~ /^(Uptodate|Failed|Disabled|Broken|Partially Failed)$/) ? $state : 'NeverStarted'; $self->{updates}->{$prefix . '_' . $index} = { - display => $prefix . ': ' . $name, - state => $normalized_state, + display => $prefix . ': ' . $name, + state => $normalized_state, last_date => $lastDate }; } @@ -232,6 +201,21 @@ It checks for failed, broken, or partially failed updates and reports their stat =over 8 +=item B<--unknown-status> + +Define the conditions to match for the status to be UNKNOWN. +You can use the following variables: %{display}, %{state}, %{last_date} + +=item B<--warning-status> + +Define the conditions to match for the status to be WARNING (default: C<%{state} =~ /Partially Failed/i>). +You can use the following variables: %{display}, %{state}, %{last_date} + +=item B<--critical-status> + +Define the conditions to match for the status to be CRITICAL (default: C<%{state} =~ /^(Failed|Broken)$/i>). +You can use the following variables: %{display}, %{state}, %{last_date} + =back =cut \ No newline at end of file diff --git a/tests/network/stormshield/snmp/auto-update.robot b/tests/network/stormshield/snmp/auto-update.robot new file mode 100644 index 0000000000..0187def2d1 --- /dev/null +++ b/tests/network/stormshield/snmp/auto-update.robot @@ -0,0 +1,49 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=auto-update +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} +... --snmp-community=network/stormshield/snmp/sn910 + + +*** Test Cases *** +Auto-update ${tc} + [Tags] network stormshield snmp + ${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: Update: Patterns is broken - Update: CustomPatterns has failed + ... 2 + ... --unknown-status='${PERCENT}\\{state\\} eq "Failed"' --warning-status= --critical-status= + ... UNKNOWN: Update: CustomPatterns has failed + ... 3 + ... --warning-status='${PERCENT}\\{state\\} eq "Failed"' --critical-status= --unknown-status= + ... WARNING: Update: CustomPatterns has failed + ... 4 + ... --critical-status='${PERCENT}\\{state\\} eq "Failed"' --unknown-status= --warning-status= + ... CRITICAL: Update: CustomPatterns has failed + ... 5 + ... --critical-status= --unknown-status= --warning-status= --verbose + ... OK: All Updates and Webservices are up to date Update: Antispam never started Update: Metadata never started Update: CustomWebServices is disabled Update: Patterns is broken Update: CustomPatterns has failed Update: AdvancedAV never started Update: URLFiltering never started Update: CompromisedUrls never started Update: Vaderetro never started Update: RootCertificates never started Update: IPData never started From b021ba5e46654456bb55bbbe9c4ce15b5acaf9f4 Mon Sep 17 00:00:00 2001 From: omercier Date: Thu, 30 Jul 2026 18:10:08 +0200 Subject: [PATCH 35/50] fix memory help test --- tests/network/stormshield/snmp/help.robot | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/network/stormshield/snmp/help.robot b/tests/network/stormshield/snmp/help.robot index 7055bb4316..bf1ba09bd7 100644 --- a/tests/network/stormshield/snmp/help.robot +++ b/tests/network/stormshield/snmp/help.robot @@ -59,7 +59,7 @@ Standard ${tc} - ${mode} ... Mode:\n.*memory ... 11 ... memory-detailed - ... Mode:\n.*memory.detailed + ... Mode:\n.*memory ... 12 ... qos ... Mode:\n.*qos @@ -78,3 +78,6 @@ Standard ${tc} - ${mode} ... 17 ... licenses ... Mode:\n.*licenses + ... 18 + ... auto-update + ... Mode:\n.*auto.update From 75544b3e7219f8c3178ada16bf2f6d425065bcf6 Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 10:27:46 +0200 Subject: [PATCH 36/50] ha_cluster: first fix --- .../stormshield/snmp/mode/ha_cluster.pm | 70 ++++--------------- 1 file changed, 14 insertions(+), 56 deletions(-) diff --git a/src/network/stormshield/snmp/mode/ha_cluster.pm b/src/network/stormshield/snmp/mode/ha_cluster.pm index bd05424ecf..7c5a31f2a0 100644 --- a/src/network/stormshield/snmp/mode/ha_cluster.pm +++ b/src/network/stormshield/snmp/mode/ha_cluster.pm @@ -23,49 +23,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); -use centreon::plugins::constants qw(:counters); - - -sub custom_status_output { - my ($self, %options) = @_; - - return sprintf( - "Configuration Synced: %s", - $self->{result_values}->{sync_status} - ); -} - -sub custom_node_output { - my ($self, %options) = @_; - - return sprintf( - "Dead Nodes: %s/%s (%s%%)", - $self->{result_values}->{dead_nodes}, - $self->{result_values}->{nb_nodes}, - $self->{result_values}->{dead_pct}, - ); -} - -sub custom_link_output { - my ($self, %options) = @_; - - return sprintf( - "Faulty Links: %s/%s (%s%%)", - $self->{result_values}->{faulty_links}, - $self->{result_values}->{nb_links}, - $self->{result_values}->{faulty_pct}, - ); -} - -sub custom_active_output { - my ($self, %options) = @_; - - return sprintf( - "Active Firewalls: %s/2", - $self->{result_values}->{nb_active}, - ); -} +use centreon::plugins::constants qw(:counters :values); sub custom_node_perfdata { @@ -73,7 +31,7 @@ sub custom_node_perfdata { my $nb = $self->{result_values}->{nb_nodes}; my $warn = defined($nb) ? int($nb * 0.5) : undef; my $crit = defined($nb) ? $nb : undef; - + $self->{output}->perfdata_add( label => 'ha.dead_nodes.count', value => $self->{result_values}->{dead_nodes}, @@ -89,7 +47,7 @@ sub custom_link_perfdata { my $nb = $self->{result_values}->{nb_links}; my $warn = defined($nb) ? int($nb * 0.5) : undef; my $crit = defined($nb) ? $nb : undef; - + $self->{output}->perfdata_add( label => 'ha.faulty_links.count', value => $self->{result_values}->{faulty_links}, @@ -139,7 +97,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { -10 => 1 } }, + { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { NO_VALUE() => 1 } }, ]; $self->{maps_counters}->{global} = [ @@ -147,7 +105,7 @@ sub set_counters { label => 'dead-nodes', set => { key_values => [ { name => 'dead_nodes' }, { name => 'nb_nodes' }, { name => 'dead_pct' } ], - closure_custom_output => $self->can('custom_node_output'), + output_template => 'Dead Nodes: %{dead_nodes}/%{nb_nodes} (%{dead_pct}%%)', closure_custom_perfdata => $self->can('custom_node_perfdata'), closure_custom_threshold_check => $self->can('custom_node_threshold'), } @@ -156,7 +114,7 @@ sub set_counters { label => 'faulty-links', set => { key_values => [ { name => 'faulty_links' }, { name => 'nb_links' }, { name => 'faulty_pct' } ], - closure_custom_output => $self->can('custom_link_output'), + output_template => 'Faulty Links: %{faulty_links}/%{nb_links} (%{faulty_pct}%%)', closure_custom_perfdata => $self->can('custom_link_perfdata'), closure_custom_threshold_check => $self->can('custom_link_threshold'), } @@ -165,7 +123,7 @@ sub set_counters { label => 'active-firewall', set => { key_values => [ { name => 'nb_active' } ], - closure_custom_output => $self->can('custom_active_output'), + output_template => 'Active Firewalls: %{nb_active}/2', closure_custom_threshold_check => $self->can('custom_active_threshold'), } }, @@ -173,7 +131,7 @@ sub set_counters { label => 'sync-status', set => { key_values => [ { name => 'sync_status' } ], - closure_custom_output => $self->can('custom_status_output'), + output_template => 'Configuration Synced: %{sync_status}', closure_custom_perfdata => sub { return 0; }, closure_custom_threshold_check => $self->can('custom_sync_threshold'), } @@ -224,7 +182,7 @@ my %map_sync = ( 0 => 'False', 1 => 'True' ); sub manage_selection { my ($self, %options) = @_; - + my $snmp_result_scalar = $options{snmp}->get_leef( oids => [ $oid_snsNbNode, @@ -243,7 +201,7 @@ sub manage_selection { my $nb_links = $snmp_result_scalar->{$oid_snsNbHALinks} // 0; my $faulty_links = $snmp_result_scalar->{$oid_snsNbFaultyHALinks} // 0; my $sync_raw = $snmp_result_scalar->{$oid_snsHASyncStatus} // -1; - + if (!(defined $nb_nodes && $nb_nodes > 0)) { $self->{output}->output_add( severity => 'UNKNOWN', @@ -287,9 +245,9 @@ sub manage_selection { my $cluster_desc = "---- Cluster Description ----\n"; - foreach my $idx(sort { $a <=> $b } keys %nodes) { - my $n = $nodes{$idx}; - + foreach my $idx (sort { $a <=> $b } keys %nodes) { + my $n = $nodes{$idx}; + my $serial = $n->{snsFwSerial} // 'N/A'; my $model = $n->{snsModel} // 'N/A'; my $version = $n->{snsVersion} // 'N/A'; @@ -299,7 +257,7 @@ sub manage_selection { my $licence = $n->{snsHALicence} // 'N/A'; my $quality = $n->{snsHAQuality} // 'N/A'; my $priority = $n->{snsHAPriority} // 'N/A'; - + $cluster_desc .= sprintf( "Serial: %s\nModel: %s\nVersion: %s\nStatus Forced: %s\nActive/Passive: %s\nOnline: %s\nLicense: %s\nQuality: %s\nPriority: %s\n%s\n", From c318d7328022e1abbba31c88092ff6183312b7be Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 11:55:40 +0200 Subject: [PATCH 37/50] reshape ha-cluster --- .../stormshield/snmp/mode/ha_cluster.pm | 185 ++++++++---------- .../network/stormshield/snmp/ha-cluster.robot | 61 ++++++ tests/network/stormshield/snmp/help.robot | 3 + 3 files changed, 141 insertions(+), 108 deletions(-) create mode 100644 tests/network/stormshield/snmp/ha-cluster.robot diff --git a/src/network/stormshield/snmp/mode/ha_cluster.pm b/src/network/stormshield/snmp/mode/ha_cluster.pm index 7c5a31f2a0..da206e5cb7 100644 --- a/src/network/stormshield/snmp/mode/ha_cluster.pm +++ b/src/network/stormshield/snmp/mode/ha_cluster.pm @@ -24,118 +24,67 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::constants qw(:counters :values); - - -sub custom_node_perfdata { - my ($self, %options) = @_; - my $nb = $self->{result_values}->{nb_nodes}; - my $warn = defined($nb) ? int($nb * 0.5) : undef; - my $crit = defined($nb) ? $nb : undef; - - $self->{output}->perfdata_add( - label => 'ha.dead_nodes.count', - value => $self->{result_values}->{dead_nodes}, - warning => $warn, - critical => $crit, - min => 0, - max => $nb, - ) -} - -sub custom_link_perfdata { - my ($self, %options) = @_; - my $nb = $self->{result_values}->{nb_links}; - my $warn = defined($nb) ? int($nb * 0.5) : undef; - my $crit = defined($nb) ? $nb : undef; - - $self->{output}->perfdata_add( - label => 'ha.faulty_links.count', - value => $self->{result_values}->{faulty_links}, - warning => $warn, - critical => $crit, - min => 0, - max => $nb, - ) -} - -sub custom_node_threshold { - my ($self, %options) = @_; - my $nb = $self->{result_values}->{nb_nodes}; - my $dead = $self->{result_values}->{dead_nodes}; - return 'OK' if !defined($nb) || $nb == 0; - return 'WARNING' if $dead >= int($nb*0.5); - return 'CRITICAL' if $dead >= $nb; - return 'OK'; -} - - -sub custom_link_threshold { - my ($self, %options) = @_; - my $nb = $self->{result_values}->{nb_links}; - my $dead = $self->{result_values}->{faulty_links}; - return 'OK' if !defined($nb) || $nb == 0; - return 'WARNING' if $dead >= int($nb*0.5); - return 'CRITICAL' if $dead >= $nb; - return 'OK'; -} - -sub custom_active_threshold { - my ($self, %options) = @_; - my $nb = $self->{result_values}->{nb_active}; - return 'OK' if !defined($nb) || $nb == 1; - return 'CRITICAL' if $nb == 2 || $nb == 0; - return 'UNKNOWN'; -} - -sub custom_sync_threshold { - my ($self, %options) = @_; - return 'WARNING' if $self->{result_values}->{sync_status} eq 'False'; - return 'OK'; -} +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { NO_VALUE() => 1 } }, + { name => 'global', type => COUNTER_TYPE_GLOBAL }, ]; $self->{maps_counters}->{global} = [ { label => 'dead-nodes', + nlabel => 'cluster.dead-nodes.count', + type => COUNTER_KIND_METRIC, + warning_default => '50', + critical_default => '100', set => { - key_values => [ { name => 'dead_nodes' }, { name => 'nb_nodes' }, { name => 'dead_pct' } ], + key_values => [ { name => 'dead_pct' }, { name => 'nb_nodes' }, { name => 'dead_nodes' } ], output_template => 'Dead Nodes: %{dead_nodes}/%{nb_nodes} (%{dead_pct}%%)', - closure_custom_perfdata => $self->can('custom_node_perfdata'), - closure_custom_threshold_check => $self->can('custom_node_threshold'), + perfdatas => [ + { label => 'ha.dead_nodes.count', value => 'dead_nodes', template => '%s', min => 0, max => 'nb_nodes', threshold_total => 'nb_nodes', cast_int => 1 } + ] } }, { label => 'faulty-links', + nlabel => 'cluster.faulty-links.count', + type => COUNTER_KIND_METRIC, + warning_default => '50', + critical_default => '100', set => { - key_values => [ { name => 'faulty_links' }, { name => 'nb_links' }, { name => 'faulty_pct' } ], + key_values => [ { name => 'faulty_pct' }, { name => 'nb_links' }, { name => 'faulty_links' } ], output_template => 'Faulty Links: %{faulty_links}/%{nb_links} (%{faulty_pct}%%)', - closure_custom_perfdata => $self->can('custom_link_perfdata'), - closure_custom_threshold_check => $self->can('custom_link_threshold'), + perfdatas => [ + { label => 'ha.faulty_links.count', value => 'faulty_links', template => '%s', min => 0, max => 'nb_links', threshold_total => 'nb_links', cast_int => 1 } + ] } }, { label => 'active-firewall', + nlabel => 'cluster.active-firewalls.count', + type => COUNTER_KIND_METRIC, + critical_default => '1:1', set => { key_values => [ { name => 'nb_active' } ], output_template => 'Active Firewalls: %{nb_active}/2', - closure_custom_threshold_check => $self->can('custom_active_threshold'), + perfdatas => [ + { label => 'ha.active_firewalls.count', value => 'nb_active', template => '%s', min => 0, max => 2, cast_int => 1 } + ] } }, { label => 'sync-status', + type => COUNTER_KIND_TEXT, + warning_default => '%{sync_status} eq "False"', set => { key_values => [ { name => 'sync_status' } ], output_template => 'Configuration Synced: %{sync_status}', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => $self->can('custom_sync_threshold'), + closure_custom_threshold_check => \&catalog_status_threshold_ng } - }, + } ]; } @@ -144,14 +93,9 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => {}); - - $self->{output}->{option_results}->{verbose} = 1; - return $self; } - my $oid_snsNode = '.1.3.6.1.4.1.11256.1.11.7.1'; my $oid_snsNbNode = '.1.3.6.1.4.1.11256.1.11.1.0'; my $oid_snsNbDeadNode = '.1.3.6.1.4.1.11256.1.11.2.0'; @@ -160,18 +104,17 @@ my $oid_snsNbHALinks = '.1.3.6.1.4.1.11256.1.11.5.0'; my $oid_snsNbFaultyHALinks = '.1.3.6.1.4.1.11256.1.11.6.0'; my $oid_snsHASyncStatus = '.1.3.6.1.4.1.11256.1.11.8.0'; - my %mapping = ( - snsNodeIndex => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.1' }, - snsFwSerial => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.2' }, - snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.3' }, - snsModel => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.4' }, - snsVersion => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.5' }, - snsHALicence => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.6' }, - snsHAQuality => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.7' }, - snsHAPriority => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.8' }, - snsHAStatusForced => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.9' }, - snsHAActive => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.10' }, + snsNodeIndex => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.1' }, + snsFwSerial => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.2' }, + snsOnline => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.3' }, + snsModel => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.4' }, + snsVersion => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.5' }, + snsHALicence => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.6' }, + snsHAQuality => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.7' }, + snsHAPriority => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.8' }, + snsHAStatusForced => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.9' }, + snsHAActive => { oid => '.1.3.6.1.4.1.11256.1.11.7.1.10' }, ); my %map_online = ( 2 => 'False', 1 => 'True' ); @@ -179,7 +122,6 @@ my %map_status = ( 0 => 'False', 1 => 'True' ); my %map_act_pass = ( 2 => 'Passive', 1 => 'Active' ); my %map_sync = ( 0 => 'False', 1 => 'True' ); - sub manage_selection { my ($self, %options) = @_; @@ -202,13 +144,8 @@ sub manage_selection { my $faulty_links = $snmp_result_scalar->{$oid_snsNbFaultyHALinks} // 0; my $sync_raw = $snmp_result_scalar->{$oid_snsHASyncStatus} // -1; - if (!(defined $nb_nodes && $nb_nodes > 0)) { - $self->{output}->output_add( - severity => 'UNKNOWN', - short_msg => 'No HA cluster detected' - ); - return; - } + $self->{output}->option_exit(severity => 'UNKNOWN', short_msg => 'No HA cluster detected') + unless $nb_nodes; my $dead_pct = ($nb_nodes > 0) ? int(($dead_nodes / $nb_nodes) * 100) : 0; my $faulty_pct = ($nb_links > 0) ? int(($faulty_links / $nb_links) * 100) : 0; @@ -242,7 +179,6 @@ sub manage_selection { } } - my $cluster_desc = "---- Cluster Description ----\n"; foreach my $idx (sort { $a <=> $b } keys %nodes) { @@ -251,14 +187,13 @@ sub manage_selection { my $serial = $n->{snsFwSerial} // 'N/A'; my $model = $n->{snsModel} // 'N/A'; my $version = $n->{snsVersion} // 'N/A'; - my $status_f = $map_status{$n->{snsHAStatusForced} // 0 } // 'UNKNOWN'; - my $act_pass = $map_act_pass{$n->{snsHAActive} // 0 } // 'UNKNOWN'; - my $online = $map_online{$n->{snsOnline} // 0 } // 'UNKNOWN'; + my $status_f = $map_status{ $n->{snsHAStatusForced} // 0 } // 'UNKNOWN'; + my $act_pass = $map_act_pass{ $n->{snsHAActive} // 0 } // 'UNKNOWN'; + my $online = $map_online{ $n->{snsOnline} // 0 } // 'UNKNOWN'; my $licence = $n->{snsHALicence} // 'N/A'; my $quality = $n->{snsHAQuality} // 'N/A'; my $priority = $n->{snsHAPriority} // 'N/A'; - $cluster_desc .= sprintf( "Serial: %s\nModel: %s\nVersion: %s\nStatus Forced: %s\nActive/Passive: %s\nOnline: %s\nLicense: %s\nQuality: %s\nPriority: %s\n%s\n", $serial, @@ -287,6 +222,40 @@ Check Stormshield HA cluster global status. =over 8 +=item B<--warning-active-firewall> + +Threshold. + +=item B<--critical-active-firewall> + +Threshold. Default: C<1:1> since there must be only one active firewall per cluster. + +=item B<--warning-dead-nodes> + +Threshold in percentage of the total number of nodes. Default: 50. + +=item B<--critical-dead-nodes> + +Threshold in percentage of the total number of nodes. Default: 100. + +=item B<--warning-faulty-links> + +Threshold in percentage of the total number of links. Default: 50. + +=item B<--critical-faulty-links> + +Threshold in percentage of the total number of links. Default: 100. + +=item B<--warning-sync-status> + +Define the conditions to match for the status to be WARNING (default: C<%{sync_status} eq "False">). +You can use the following variables: %{sync_status}. + +=item B<--critical-sync-status> + +Define the conditions to match for the status to be CRITICAL. +You can use the following variables: %{sync_status}. + =back =cut diff --git a/tests/network/stormshield/snmp/ha-cluster.robot b/tests/network/stormshield/snmp/ha-cluster.robot new file mode 100644 index 0000000000..5da340a420 --- /dev/null +++ b/tests/network/stormshield/snmp/ha-cluster.robot @@ -0,0 +1,61 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=ha-cluster +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} +... --snmp-community=network/stormshield/snmp/sn910 + + +*** Test Cases *** +Ha-cluster ${tc} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... WARNING: Configuration Synced: False | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 2 + ... --warning-active-firewall=0:0 --warning-sync-status=0 + ... WARNING: Active Firewalls: 1/2 | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;0:0;1:1;0;2 + ... 3 + ... --critical-active-firewall=0:0 --warning-sync-status=0 + ... CRITICAL: Active Firewalls: 1/2 | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;0:0;0;2 + ... 4 + ... --warning-dead-nodes=1: --warning-sync-status=0 + ... WARNING: Dead Nodes: 0/2 (0%) | 'ha.dead_nodes.count'=0;0:;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 5 + ... --critical-dead-nodes=1: --warning-sync-status=0 + ... CRITICAL: Dead Nodes: 0/2 (0%) | 'ha.dead_nodes.count'=0;0:1;0:;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 6 + ... --warning-faulty-links=1: --warning-sync-status=0 + ... WARNING: Faulty Links: 0/2 (0%) | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 7 + ... --critical-faulty-links=1: --warning-sync-status=0 + ... CRITICAL: Faulty Links: 0/2 (0%) | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 8 + ... --warning-sync-status='${PERCENT}\\{sync_status\\} eq "False"' + ... WARNING: Configuration Synced: False | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + ... 9 + ... --critical-sync-status='${PERCENT}\\{sync_status\\} eq "False"' + ... CRITICAL: Configuration Synced: False | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 diff --git a/tests/network/stormshield/snmp/help.robot b/tests/network/stormshield/snmp/help.robot index bf1ba09bd7..8ae3de575e 100644 --- a/tests/network/stormshield/snmp/help.robot +++ b/tests/network/stormshield/snmp/help.robot @@ -81,3 +81,6 @@ Standard ${tc} - ${mode} ... 18 ... auto-update ... Mode:\n.*auto.update + ... 19 + ... ha-cluster + ... Mode:\n.*ha.cluster From 940e556f1faaa050bf4e43836091031aaff05326 Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 15:01:35 +0200 Subject: [PATCH 38/50] format hardware.robot --- tests/network/stormshield/snmp/hardware.robot | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tests/network/stormshield/snmp/hardware.robot b/tests/network/stormshield/snmp/hardware.robot index 8c0497be76..3c5e06abda 100644 --- a/tests/network/stormshield/snmp/hardware.robot +++ b/tests/network/stormshield/snmp/hardware.robot @@ -27,10 +27,26 @@ hardware ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} - Examples: tc extra_options expected_result -- - ... 1 --critical='temperature,.*,50' CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;;0:50;0; 'cpu2#hardware.temperature.celsius'=30C;;0:50;0; 'cpu3#hardware.temperature.celsius'=0C;;0:50;0; 'hardware.temperature.count'=3;;;; - ... 2 --threshold-overload='disk,WARNING,missing' OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; - ... 3 --warning='temperature,.*,40' WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:40;;0; 'cpu2#hardware.temperature.celsius'=30C;0:40;;0; 'cpu3#hardware.temperature.celsius'=0C;0:40;;0; 'hardware.temperature.count'=3;;;; - ... 4 --warning='temperature,cpu1,60' WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:60;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; - ... 5 --critical='temperature,cpu1,75' OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;0:75;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; - ... 6 --warning='temperature,cpu1,300' --critical='temperature,cpu1,17' CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:300;0:17;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... --critical='temperature,.*,50' + ... CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;;0:50;0; 'cpu2#hardware.temperature.celsius'=30C;;0:50;0; 'cpu3#hardware.temperature.celsius'=0C;;0:50;0; 'hardware.temperature.count'=3;;;; + ... 2 + ... --threshold-overload='disk,WARNING,missing' + ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... 3 + ... --warning='temperature,.*,40' + ... WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:40;;0; 'cpu2#hardware.temperature.celsius'=30C;0:40;;0; 'cpu3#hardware.temperature.celsius'=0C;0:40;;0; 'hardware.temperature.count'=3;;;; + ... 4 + ... --warning='temperature,cpu1,60' + ... WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:60;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... 5 + ... --critical='temperature,cpu1,75' + ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;0:75;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... 6 + ... --warning='temperature,cpu1,300' --critical='temperature,cpu1,17' + ... CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:300;0:17;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; From 3bf96add73b00890f5459248f07b2ca4616752f1 Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 15:17:45 +0200 Subject: [PATCH 39/50] fix+complete hardware tests --- tests/network/stormshield/snmp/hardware.robot | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/tests/network/stormshield/snmp/hardware.robot b/tests/network/stormshield/snmp/hardware.robot index 3c5e06abda..3a93b18a1d 100644 --- a/tests/network/stormshield/snmp/hardware.robot +++ b/tests/network/stormshield/snmp/hardware.robot @@ -34,19 +34,57 @@ hardware ${tc} ... -- ... 1 ... --critical='temperature,.*,50' - ... CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;;0:50;0; 'cpu2#hardware.temperature.celsius'=30C;;0:50;0; 'cpu3#hardware.temperature.celsius'=0C;;0:50;0; 'hardware.temperature.count'=3;;;; + ... CRITICAL: Temperature 'cpu1' is '70' celsius | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; ... 2 ... --threshold-overload='disk,WARNING,missing' - ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; ... 3 ... --warning='temperature,.*,40' - ... WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:40;;0; 'cpu2#hardware.temperature.celsius'=30C;0:40;;0; 'cpu3#hardware.temperature.celsius'=0C;0:40;;0; 'hardware.temperature.count'=3;;;; + ... WARNING: Temperature 'cpu1' is '70' celsius | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; ... 4 ... --warning='temperature,cpu1,60' - ... WARNING: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:60;;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... WARNING: Temperature 'cpu1' is '70' celsius | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; ... 5 ... --critical='temperature,cpu1,75' - ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.temperature.celsius'=70C;;0:75;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... OK: All 3 components are ok [3/3 temperatures]. | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; ... 6 ... --warning='temperature,cpu1,300' --critical='temperature,cpu1,17' - ... CRITICAL: temperature 'cpu1' is 70 celsius | 'cpu1#hardware.temperature.celsius'=70C;0:300;0:17;0; 'cpu2#hardware.temperature.celsius'=30C;;;0; 'cpu3#hardware.temperature.celsius'=0C;;;0; 'hardware.temperature.count'=3;;;; + ... CRITICAL: Temperature 'cpu1' is '70' celsius | 'cpu1#hardware.cpu.temperature.celsius'=70C;;;0; 'cpu2#hardware.cpu.temperature.celsius'=30C;;;0; 'cpu3#hardware.cpu.temperature.celsius'=0C;;;0; 'cpu_average_temp#hardware.cpu.average.temperature.celsius'=33C;;;0; 'hardware.temperature.count'=3;;;; + +hardware SN910 ${tc} + [Tags] network stormshield + ${command} Catenate + ... ${CMD} + ... --mode=hardware + ... --hostname=${HOSTNAME} + ... --snmp-version=${SNMPVERSION} + ... --snmp-port=${SNMPPORT} + ... --snmp-community=network/stormshield/snmp/sn910 + ... --snmp-timeout=1 + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: All 2 components are ok [2/2 temperatures]. | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; + ... 2 + ... --warning='temperature,.*,10' + ... WARNING: Temperature 'fw_2_cpu0' is '45' celsius - Temperature 'fw_2_cpu1' is '46' celsius | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; + ... 3 + ... --critical='temperature,.*,10' + ... CRITICAL: Temperature 'fw_2_cpu0' is '45' celsius - Temperature 'fw_2_cpu1' is '46' celsius | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; + ... 4 + ... --warning='temperature,cpu1,10' + ... WARNING: Temperature 'fw_2_cpu1' is '46' celsius | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; + ... 5 + ... --critical='temperature,cpu1,10' + ... CRITICAL: Temperature 'fw_2_cpu1' is '46' celsius | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; + ... 6 + ... --warning='temperature,cpu1,300' --critical='temperature,cpu1,17' + ... CRITICAL: Temperature 'fw_2_cpu1' is '46' celsius | 'fw_2_cpu0#hardware.cpu.temperature.celsius'=45C;;;0; 'fw_2_cpu1#hardware.cpu.temperature.celsius'=46C;;;0; 'fw_2_cpu_average_temp#hardware.cpu.average.temperature.celsius'=45C;;;0; 'hardware.temperature.count'=2;;;; From ecf38b7b8b2149d99c87a4e7bb0f1a09c2f6fd23 Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 18:00:36 +0200 Subject: [PATCH 40/50] reshaping + adding tests to connections.pm --- .../stormshield/snmp/mode/connections.pm | 36 +++----- .../stormshield/snmp/mode/properties.pm | 91 ------------------- .../network/stormshield/snmp/ha-cluster.robot | 22 ++++- 3 files changed, 32 insertions(+), 117 deletions(-) delete mode 100644 src/network/stormshield/snmp/mode/properties.pm diff --git a/src/network/stormshield/snmp/mode/connections.pm b/src/network/stormshield/snmp/mode/connections.pm index 761b90265c..13cccc505a 100644 --- a/src/network/stormshield/snmp/mode/connections.pm +++ b/src/network/stormshield/snmp/mode/connections.pm @@ -35,35 +35,35 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'udp', set => { + { label => 'udp', nlabel => 'connections.udp.count', set => { key_values => [ { name => 'udp' } ], output_template => 'UDP : %d connections', perfdatas => [ - { label => 'udp', template => '%d', min => 0, unit => 'con' } + { template => '%d', min => 0 } ] } }, - { label => 'tcp', set => { + { label => 'tcp', nlabel => 'connections.tcp.count', set => { key_values => [ { name => 'tcp' } ], output_template => 'TCP : %d connections', perfdatas => [ - { label => 'tcp', template => '%d', min => 0, unit => 'con' } + { template => '%d', min => 0 } ] } }, - { label => 'major', set => { + { label => 'major', nlabel => 'alarms.major.count', set => { key_values => [ { name => 'major' } ], output_template => 'Major Alarms : %d', perfdatas => [ - { label => 'major', template => '%d', min => 0, unit => 'alarms' } + { template => '%d', min => 0 } ] } }, - { label => 'minor', set => { + { label => 'minor', nlabel => 'alarms.minor.count', set => { key_values => [ { name => 'minor' } ], output_template => 'Minor Alarms : %d', perfdatas => [ - { label => 'minor', template => '%d', min => 0, unit => 'alarms' } + { template => '%d', min => 0 } ] } } @@ -73,28 +73,16 @@ sub set_counters { { label => 'policy-dummy', threshold => 0, set => { key_values => [ { name => 'index' }, { name => 'name' }, { name => 'slot_name' }, { name => 'active' }, { name => 'sync' } ], - closure_custom_output => $self->can('custom_policy_output'), + output_template => "Policy: '%{name}', slot: '%{slot_name}', active: '%{active}', sync: %{sync}", perfdatas => [] } } ]; } -sub custom_policy_output { - my ($self, %options) = @_; - my $obj = $options{new_datas}; - return sprintf( - "Policy: '%s', slot: '%s', active: '%s', sync: %s", - $self->{result_values}->{name}, - $self->{result_values}->{slot_name}, - $self->{result_values}->{active}, - $self->{result_values}->{sync} ? 'True' : 'False' - ); -} - sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { @@ -122,7 +110,7 @@ sub manage_selection { major => $result_asq->{$oid_snsASQStatsStatefulMajorAlarm}, minor => $result_asq->{$oid_snsASQStatsStatefulMinorAlarm} }; - + my $oid_snsPolicyIndex = '.1.3.6.1.4.1.11256.1.8.1.1.1'; my $oid_snsPolicyName = '.1.3.6.1.4.1.11256.1.8.1.1.2'; @@ -144,7 +132,7 @@ sub manage_selection { name => $result_policy->{"$oid_snsPolicyName.$idx"} // '', slot_name => $result_policy->{"$oid_snsPolicySlotName.$idx"} // '', active => $result_policy->{"$oid_snsPolicyActive.$idx"} // '', - sync => $result_policy->{"$oid_snsPolicySync.$idx"} // 0, + sync => ($result_policy->{"$oid_snsPolicySync.$idx"} // 0) ? 'True' : 'False', }; } } diff --git a/src/network/stormshield/snmp/mode/properties.pm b/src/network/stormshield/snmp/mode/properties.pm deleted file mode 100644 index 0d0acfeb7e..0000000000 --- a/src/network/stormshield/snmp/mode/properties.pm +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright 2024 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::stormshield::snmp::mode::properties; - -use base qw(centreon::plugins::templates::counter); - -use strict; -use warnings; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - return $self; -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $oid_system_name = '.1.3.6.1.4.1.11256.1.18.4.0'; - my $oid_system_node_name = '.1.3.6.1.4.1.11256.1.18.16.0'; - my $oid_bios_version = '.1.3.6.1.4.1.11256.1.18.17.0'; - my $oid_model = '.1.3.6.1.4.1.11256.1.18.1.0'; - my $oid_version = '.1.3.6.1.4.1.11256.1.18.2.0'; - my $oid_serial_number = '.1.3.6.1.4.1.11256.1.18.3.0'; - my $oid_date = '.1.3.6.1.4.1.11256.1.10.1.0'; - my $oid_uptime = '.1.3.6.1.4.1.11256.1.10.2.0'; - - my $oids = [ $oid_system_name, $oid_system_node_name, $oid_bios_version, $oid_model, $oid_version, $oid_serial_number, $oid_date, $oid_uptime ]; - - my $snmp_result = $options{snmp}->get_leef( - oids => $oids, - nothing_quit => 1 - ); - - my $system_name = $snmp_result->{$oid_system_name}; - my $system_node_name = $snmp_result->{$oid_system_node_name}; - my $bios_version = $snmp_result->{$oid_bios_version}; - my $model = $snmp_result->{$oid_model}; - my $version = $snmp_result->{$oid_version}; - my $serial_number = $snmp_result->{$oid_serial_number}; - my $date = $snmp_result->{$oid_date}; - my $uptime = $snmp_result->{$oid_uptime}; - - $self->{output}->output_add( - severity => 'OK', - short_msg => sprintf("Click to see more infos: ...\nSystem Name: %s \nSystem node Name: %s \nModel: %s \nSerial Number: %s \nVersion: %s \nBios Version: %s \nDate: %s \nUptime: %s", - $system_name, $system_node_name, $model, $serial_number, $version, $bios_version, $date, $uptime - ) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -This mode retrieves and displays basic properties of the Stormshield device such as system name, model, version, serial number, and date. - -=over 8 - -=item B<--warning-*> B<--critical-*> - -These options are not applicable for this mode as it does not generate performance data or thresholds. - -=back - -=cut \ No newline at end of file diff --git a/tests/network/stormshield/snmp/ha-cluster.robot b/tests/network/stormshield/snmp/ha-cluster.robot index 5da340a420..630a7ff039 100644 --- a/tests/network/stormshield/snmp/ha-cluster.robot +++ b/tests/network/stormshield/snmp/ha-cluster.robot @@ -15,14 +15,14 @@ ${CMD} ${CENTREON_PLUGINS} ... --hostname=${HOSTNAME} ... --snmp-port=${SNMPPORT} ... --snmp-version=${SNMPVERSION} -... --snmp-community=network/stormshield/snmp/sn910 *** Test Cases *** -Ha-cluster ${tc} +Ha-cluster SN910 ${tc} [Tags] network stormshield snmp ${command} Catenate ... ${CMD} + ... --snmp-community=network/stormshield/snmp/sn910 ... ${extra_options} Ctn Run Command And Check Result As Strings ${command} ${expected_result} @@ -59,3 +59,21 @@ Ha-cluster ${tc} ... 9 ... --critical-sync-status='${PERCENT}\\{sync_status\\} eq "False"' ... CRITICAL: Configuration Synced: False | 'ha.dead_nodes.count'=0;0:1;0:2;0;2 'ha.faulty_links.count'=0;0:1;0:2;0;2 'ha.active_firewalls.count'=1;;1:1;0;2 + +Ha-cluster fake ${tc} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... --snmp-community=network/stormshield/snmp/stormshield-fake + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... UNKNOWN: No HA cluster detected From 5a2beba3cbe798867546da2e9d808505cc2e59d4 Mon Sep 17 00:00:00 2001 From: omercier Date: Fri, 31 Jul 2026 18:08:08 +0200 Subject: [PATCH 41/50] add tests for connections --- .../stormshield/snmp/connections.robot | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/network/stormshield/snmp/connections.robot diff --git a/tests/network/stormshield/snmp/connections.robot b/tests/network/stormshield/snmp/connections.robot new file mode 100644 index 0000000000..f51af955a4 --- /dev/null +++ b/tests/network/stormshield/snmp/connections.robot @@ -0,0 +1,61 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=connections +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} + + +*** Test Cases *** +Connections SN910 ${tc} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... --snmp-community=network/stormshield/snmp/sn910 + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: UDP : 318 connections, TCP : 0 connections, Major Alarms : 0, Minor Alarms : 0 | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;;0; + ... 2 + ... --warning-tcp=1: + ... WARNING: TCP : 0 connections | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;1:;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;;0; + ... 3 + ... --warning-udp=1 + ... WARNING: UDP : 318 connections | 'connections.udp.count'=318;0:1;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;;0; + ... 4 + ... --warning-major=1: + ... WARNING: Major Alarms : 0 | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;1:;;0; 'alarms.minor.count'=0;;;0; + ... 5 + ... --warning-minor=1: + ... WARNING: Minor Alarms : 0 | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;1:;;0; + ... 6 + ... --critical-tcp=1: + ... CRITICAL: TCP : 0 connections | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;1:;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;;0; + ... 7 + ... --critical-udp=1 + ... CRITICAL: UDP : 318 connections | 'connections.udp.count'=318;;0:1;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;;0; + ... 8 + ... --critical-major=1: + ... CRITICAL: Major Alarms : 0 | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;1:;0; 'alarms.minor.count'=0;;;0; + ... 9 + ... --critical-minor=1: + ... CRITICAL: Minor Alarms : 0 | 'connections.udp.count'=318;;;0; 'connections.tcp.count'=0;;;0; 'alarms.major.count'=0;;;0; 'alarms.minor.count'=0;;1:;0; From 8a1e010b6e279e130fb071a9de13c5c11f5f3ced Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Tue, 4 Aug 2026 17:04:26 +0200 Subject: [PATCH 42/50] fix(stormshield-snmp): add tests and fix long output Refs:CTOR-2305 --- src/network/stormshield/snmp/mode/health.pm | 57 ++++++------------- tests/network/stormshield/snmp/health.robot | 49 ++++++++++++++++ tests/network/stormshield/snmp/sn910.snmpwalk | 26 +++++++-- 3 files changed, 87 insertions(+), 45 deletions(-) create mode 100644 tests/network/stormshield/snmp/health.robot diff --git a/src/network/stormshield/snmp/mode/health.pm b/src/network/stormshield/snmp/mode/health.pm index 0274498988..3cf2f7571f 100644 --- a/src/network/stormshield/snmp/mode/health.pm +++ b/src/network/stormshield/snmp/mode/health.pm @@ -27,59 +27,43 @@ use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); use centreon::plugins::constants qw/:counters :values/; -our $GLOBAL_PROBLEM; sub custom_service_status_output { my ($self, %options) = @_; - my $msg = sprintf( + return sprintf( "health: %s", $self->{result_values}->{health} ); - - my $health = $self->{result_values}->{health}; - - if ($health !~ /minor/i && $health !~ /major/i) { - if (!$GLOBAL_PROBLEM) { - $self->{output}->output_add( - long_msg => "service '" . $self->{result_values}->{service} . "' " . $msg - ); - } - } - - return $msg; } -sub firewall_long_output { +sub prefix_firewall_output { my ($self, %options) = @_; - my $display = $options{instance_value}->{display}; - if (defined $display && $display ne '') { - return "--------------Firewall $display--------------"; - } - return "------------------------------------------------------------"; + return "firewall '" . $options{instance_value}->{display} . "': "; } sub prefix_service_output { my ($self, %options) = @_; - return "service '" . $options{instance_value}->{service} . "' "; + return "firewall '" . $options{instance_value}->{firewall} . "' service '" . $options{instance_value}->{service} . "' "; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'firewalls', type => COUNTER_TYPE_GROUP, cb_long_output => 'firewall_long_output', - message_multiple => 'All firewalls are ok', + { name => 'firewalls', type => COUNTER_TYPE_GROUP, + cb_prefix_output => 'prefix_firewall_output', + indent_long_output => ' ', + message_multiple => 'All firewalls are ok', group => [ - { + { name => 'services', - display_long => 1, cb_prefix_output => 'prefix_service_output', message_multiple => 'All services are ok', type => COUNTER_TYPE_INSTANCE, - skipped_code => { -10 => 1 } } + skipped_code => { NO_VALUE => 1 } } ] } ]; @@ -91,7 +75,7 @@ sub set_counters { warning_default => '%{health} =~ /minor/i', critical_default => '%{health} =~ /major/i', set => { - key_values => [ { name => 'health' }, { name => 'service' } ], + key_values => [ { name => 'health' }, { name => 'service' }, { name => 'firewall' } ], closure_custom_output => $self->can('custom_service_status_output'), closure_custom_perfdata => sub { return 0; }, closure_custom_threshold_check => \&catalog_status_threshold_ng @@ -157,13 +141,9 @@ sub manage_selection { }; } - return if (scalar(keys %{$self->{firewalls}}) <= 0); - - $GLOBAL_PROBLEM = 0; - - my @instances = keys %{$self->{firewalls}}; - if (scalar(@instances) == 1) { - $self->{firewalls}->{ $instances[0] }->{display} = ''; + if (scalar(keys %{$self->{firewalls}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No firewall found with accepted serial."); + $self->{output}->option_exit(); } $options{snmp}->load( @@ -176,13 +156,10 @@ sub manage_selection { my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); foreach my $service (keys %$result) { - my $health = $result->{$service}; - if (defined $health && ($health =~ /minor/i || $health =~ /major/i)) { - $GLOBAL_PROBLEM = 1; - } $self->{firewalls}->{$_}->{services}->{$service} = { - service => $service, - health => $health + service => $service, + health => $result->{$service}, + firewall => $self->{firewalls}->{$_}->{display} }; } } diff --git a/tests/network/stormshield/snmp/health.robot b/tests/network/stormshield/snmp/health.robot new file mode 100644 index 0000000000..3cad4eb21a --- /dev/null +++ b/tests/network/stormshield/snmp/health.robot @@ -0,0 +1,49 @@ +*** Settings *** +Documentation Check Stormshield health equipment + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} --plugin=network::stormshield::snmp::plugin + + +*** Test Cases *** +hardware ${tc} + [Tags] network stormshield + ${command} Catenate + ... ${CMD} + ... --mode=health + ... --hostname=${HOSTNAME} + ... --snmp-version=${SNMPVERSION} + ... --snmp-port=${SNMPPORT} + ... --snmp-community=network/stormshield/snmp/sn910 + ... --snmp-timeout=1 + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... --filter-serial='notfoundSerial' + ... UNKNOWN: No firewall found with accepted serial. + ... 2 + ... --critical-service-status="" --warning-service-status="" + ... OK: All firewalls are ok + ... 3 + ... --verbose + ... CRITICAL: 2 problem(s) detected \ncritical: firewall 'Firewall_1_serial_number' service 'cpu' health: Major\nwarning: firewall 'Firewall_2_serial_number' service 'NTP' health: Minor + ... 4 + ... --warning-service-status="" + ... CRITICAL: 1 problem(s) detected + ... 5 + ... --critical-service-status="" + ... WARNING: 1 problem(s) detected diff --git a/tests/network/stormshield/snmp/sn910.snmpwalk b/tests/network/stormshield/snmp/sn910.snmpwalk index 5cc952a052..c241072bcf 100644 --- a/tests/network/stormshield/snmp/sn910.snmpwalk +++ b/tests/network/stormshield/snmp/sn910.snmpwalk @@ -1221,22 +1221,38 @@ .1.3.6.1.4.1.11256.1.15.1.1.10.11 = "" .1.3.6.1.4.1.11256.1.16.1.0 = STRING: "Major" .1.3.6.1.4.1.11256.1.16.2.1.1.1 = INTEGER: 1 -.1.3.6.1.4.1.11256.1.16.2.1.2.1 = STRING: "" +.1.3.6.1.4.1.11256.1.16.2.1.1.2 = INTEGER: 2 +.1.3.6.1.4.1.11256.1.16.2.1.2.1 = STRING: "Firewall_1_serial_number" +.1.3.6.1.4.1.11256.1.16.2.1.2.2 = STRING: "Firewall_2_serial_number" .1.3.6.1.4.1.11256.1.16.2.1.3.1 = STRING: "Active" +.1.3.6.1.4.1.11256.1.16.2.1.3.2 = STRING: "Active" .1.3.6.1.4.1.11256.1.16.2.1.4.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.4.2 = STRING: "Active" .1.3.6.1.4.1.11256.1.16.2.1.5.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.5.2 = STRING: "N/A" .1.3.6.1.4.1.11256.1.16.2.1.6.1 = STRING: "N/A" -.1.3.6.1.4.1.11256.1.16.2.1.7.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.6.2 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.7.1 = STRING: "Major" +.1.3.6.1.4.1.11256.1.16.2.1.7.2 = STRING: "Good" .1.3.6.1.4.1.11256.1.16.2.1.8.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.8.2 = STRING: "Good" .1.3.6.1.4.1.11256.1.16.2.1.9.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.9.2 = STRING: "Good" .1.3.6.1.4.1.11256.1.16.2.1.10.1 = STRING: "N/A" -.1.3.6.1.4.1.11256.1.16.2.1.11.1 = STRING: "Major" +.1.3.6.1.4.1.11256.1.16.2.1.10.2 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.11.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.11.2 = STRING: "N/A" .1.3.6.1.4.1.11256.1.16.2.1.12.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.12.2 = STRING: "Good" .1.3.6.1.4.1.11256.1.16.2.1.13.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.13.2 = STRING: "N/A" .1.3.6.1.4.1.11256.1.16.2.1.14.1 = STRING: "Good" -.1.3.6.1.4.1.11256.1.16.2.1.15.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.15.2 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.14.1 = STRING: "Good" +.1.3.6.1.4.1.11256.1.16.2.1.16.2 = STRING: "Good" .1.3.6.1.4.1.11256.1.16.2.1.16.1 = STRING: "Good" -.1.3.6.1.4.1.11256.1.16.2.1.17.1 = STRING: "N/A" +.1.3.6.1.4.1.11256.1.16.2.1.17.2 = STRING: "Minor" +.1.3.6.1.4.1.11256.1.16.2.1.17.1 = STRING: "Good" .1.3.6.1.4.1.11256.1.18.1.0 = STRING: "SN910" .1.3.6.1.4.1.11256.1.18.2.0 = STRING: "5.2.0.dev" .1.3.6.1.4.1.11256.1.18.3.0 = STRING: "" From b5172a2ae68e0c4593cf5079536eb0199cbf9efb Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Wed, 5 Aug 2026 11:49:31 +0200 Subject: [PATCH 43/50] fix(stormshield-snmp-memory-detailed): Fix metrics nlabel, remove generic threshold, fix pod Refs:CTOR-2305 --- .../stormshield/snmp/mode/memorydetailed.pm | 206 ++++++++++-------- 1 file changed, 113 insertions(+), 93 deletions(-) diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index 7878c93fd3..9c743c718f 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -37,59 +37,37 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'asq', set => { - key_values => [ { name => 'asq' } ], - output_template => "ASQ: %s%%", + { label => 'total', nlabel => 'memory.usage.percentage', set => { + key_values => [ { name => 'total' } ], + output_template => 'total: %.2f %%', perfdatas => [ - { - label => 'mem_asq', - value => 'asq', - template => '%s', - unit => '%', - min => 0, - max => 100, - } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, - { label => 'icmp', set => { - key_values => [ { name => 'icmp' } ], - output_template => "ICMP: %s%%", + { label => 'host', nlabel => 'memory.protected_host.percentage', set => { + key_values => [ { name => 'host' } ], + output_template => 'protected host: %.2f %%', perfdatas => [ - { - label => 'mem_icmp', - value => 'icmp', - template => '%s', - unit => '%', - min => 0, - max => 100, - } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, - { label => 'frag', set => { + { label => 'frag', nlabel => 'memory.fragmented.percentage', set => { key_values => [ { name => 'frag' } ], - output_template => "Frag: %s%%", + output_template => 'fragmented: %.2f %%', perfdatas => [ - { - label => 'mem_frag', - value => 'frag', - template => '%s', - unit => '%', - min => 0, - max => 100, - } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, - { label => 'host', set => { - key_values => [ { name => 'host' } ], - output_template => "Host: %s%%", + { label => 'asq', set => { + key_values => [ { name => 'asq' } ], + output_template => "ASQ: %.2f%%", perfdatas => [ { - label => 'mem_host', - value => 'host', - template => '%s', + label => 'mem_asq', + template => '%.2f', unit => '%', min => 0, max => 100, @@ -97,33 +75,35 @@ sub set_counters { ] } }, + { label => 'icmp', nlabel => 'memory.icmp.percentage', set => { + key_values => [ { name => 'icmp' } ], + output_template => 'icmp: %.2f %%', + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] + } + }, + { label => 'dtrack', nlabel => 'memory.data_tracking.percentage', set => { + key_values => [ { name => 'dtrack' } ], + output_template => "Data Tracking: %.2f%%", + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%' } + ] + } + }, { label => 'system', set => { key_values => [ { name => 'system' } ], output_template => "System: %s%%", perfdatas => [ - { - label => 'mem_system', - value => 'system', - template => '%s', - unit => '%', - min => 0, - max => 100, - } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, - { label => 'dtrack', set => { - key_values => [ { name => 'dtrack' } ], - output_template => "Data Tracking: %s%%", + { label => 'etherstate', nlabel => 'memory.ether_state.percentage', set => { + key_values => [ { name => 'etherstate' } ], + output_template => "EtherState: %s%%", perfdatas => [ - { - label => 'mem_dtrack', - value => 'dtrack', - template => '%s', - unit => '%', - min => 0, - max => 100, - } + { label=> "ether-state", template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, @@ -142,21 +122,7 @@ sub set_counters { ] } }, - { label => 'etherstate', set => { - key_values => [ { name => 'etherstate' } ], - output_template => "EtherState: %s%%", - perfdatas => [ - { - label => 'mem_etherstate', - value => 'etherstate', - template => '%s', - unit => '%', - min => 0, - max => 100, - } - ] - } - }, + # only for version >= 4.8.9 { label => 'user', set => { key_values => [ { name => 'user' } ], @@ -189,22 +155,6 @@ sub new { return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $label (@mem_labels) { - if (($self->{perfdata}->threshold_validate(label => 'warning-' . $label,value => $self->{option_results}->{warning_memory})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning_memory} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-' . $label,value => $self->{option_results}->{critical_memory})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical_memory} . "'."); - $self->{output}->option_exit(); - } - } -} - sub manage_selection { my ($self, %options) = @_; @@ -284,7 +234,6 @@ sub manage_selection { $self->{global} = \%mem_values; } - 1; __END__ @@ -295,13 +244,84 @@ Check memory utilization on Stormshield firewalls. =over 8 -=item B<--warning> +=item B<--warning-total> + +Threshold. + +=item B<--warning-host> + +Threshold. + +=item B<--warning-frag> + +Threshold. + +=item B<--warning-asq> + +Threshold, was conn metric before. + +=item B<--warning-icmp> + +Threshold. + +=item B<--warning-dtrack> + +Threshold. + +=item B<--warning-system> + +Threshold, was C metric before. + +=item B<--warning-etherstate> + +Threshold. + +=item B<--warning-socket> + +Threshold. +=item B<--warning-user> + +Threshold. only for version >= 4.8.9 + +=item B<--critical-total> + +Threshold. + +=item B<--critical-host> + +Threshold. + +=item B<--critical-frag> + +Threshold. + +=item B<--critical-asq> + +Threshold, was conn metric before. + +=item B<--critical-icmp> + +Threshold. + +=item B<--critical-dtrack> + +Threshold. + +=item B<--critical-system> + +Threshold, was C metric before. + +=item B<--critical-etherstate> + +Threshold. + +=item B<--critical-socket> -Set warning threshold for all memory types (asq, icmp, frag, host, system, dtrack, socket, etherstate, user). +Threshold. -=item B<--critical> +=item B<--critical-user> -Set critical threshold for all memory types (asq, icmp, frag, host, system, dtrack, socket, etherstate, user). +Threshold. only for version >= 4.8.9 =back From 43bf36dc4fda3b86bb57def5a3f0d808a513869e Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Wed, 5 Aug 2026 12:00:20 +0200 Subject: [PATCH 44/50] fix(stormshield-snmp-memory-detailed): Add back total metric calculation Refs:CTOR-2305 --- .../stormshield/snmp/mode/memorydetailed.pm | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index 9c743c718f..e3ec29bef3 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -27,8 +27,6 @@ use warnings; use centreon::plugins::constants qw/:counters :values/; use centreon::plugins::misc; -my @mem_labels = qw(asq icmp frag host system dtrack socket etherstate user); - sub set_counters { my ($self, %options) = @_; @@ -61,17 +59,11 @@ sub set_counters { ] } }, - { label => 'asq', set => { + { label => 'asq', nlabel => 'memory.asq.percentage', set => { key_values => [ { name => 'asq' } ], output_template => "ASQ: %.2f%%", perfdatas => [ - { - label => 'mem_asq', - template => '%.2f', - unit => '%', - min => 0, - max => 100, - } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, @@ -91,7 +83,7 @@ sub set_counters { ] } }, - { label => 'system', set => { + { label => 'system', nlabel => 'memory.system.percentage', set => { key_values => [ { name => 'system' } ], output_template => "System: %s%%", perfdatas => [ @@ -103,11 +95,11 @@ sub set_counters { key_values => [ { name => 'etherstate' } ], output_template => "EtherState: %s%%", perfdatas => [ - { label=> "ether-state", template => '%.2f', min => 0, max => 100, unit => '%' } + { template => '%.2f', min => 0, max => 100, unit => '%' } ] } }, - { label => 'socket', set => { + { label => 'socket',nlabel => 'memory.socket.percentage', set => { key_values => [ { name => 'socket' } ], output_template => "Socket: %s%%", perfdatas => [ @@ -124,7 +116,7 @@ sub set_counters { }, # only for version >= 4.8.9 - { label => 'user', set => { + { label => 'user', nlabel => 'memory.user.percentage', set => { key_values => [ { name => 'user' } ], output_template => "User: %s%%", perfdatas => [ @@ -217,7 +209,8 @@ sub manage_selection { } } - # Cleaning and Converting Values + # Cleaning and Converting Values + my $total = 0; foreach my $key (keys %mem_values) { if (defined $mem_values{$key}) { $mem_values{$key} =~ s/%//g; @@ -225,11 +218,14 @@ sub manage_selection { # If the value is not a number, it is removed if ($mem_values{$key} !~ /^\d+\.?\d*$/) { delete $mem_values{$key}; + next; } + $total += $mem_values{$key}; } else { delete $mem_values{$key}; } } + $mem_values{total} = $total; $self->{global} = \%mem_values; } From 02d621f756afda414ae7a2ea0b8786b5fa2860a0 Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Wed, 5 Aug 2026 15:49:28 +0200 Subject: [PATCH 45/50] fix(stormshield-snmp-memory-detailed): remove metrics renaming, keep using old name. Refs:CTOR-2305 --- .../stormshield/snmp/mode/memorydetailed.pm | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index e3ec29bef3..35ef2162dd 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -27,11 +27,17 @@ use warnings; use centreon::plugins::constants qw/:counters :values/; use centreon::plugins::misc; +sub prefix_memory_output { + my ($self, %options) = @_; + + return 'Memory usage '; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => COUNTER_TYPE_GLOBAL, skipped_code => { NO_VALUE() => 1 } } + { name => 'global', type => COUNTER_TYPE_GLOBAL, cb_prefix_output => 'prefix_memory_output', skipped_code => { NO_VALUE() => 1 } } ]; $self->{maps_counters}->{global} = [ @@ -59,7 +65,7 @@ sub set_counters { ] } }, - { label => 'asq', nlabel => 'memory.asq.percentage', set => { + { label => 'conn', nlabel => 'memory.connections.percentage', set => { key_values => [ { name => 'asq' } ], output_template => "ASQ: %.2f%%", perfdatas => [ @@ -83,9 +89,9 @@ sub set_counters { ] } }, - { label => 'system', nlabel => 'memory.system.percentage', set => { - key_values => [ { name => 'system' } ], - output_template => "System: %s%%", + { label => 'dyn', nlabel => 'memory.dynamic.percentage', set => { + key_values => [ { name => 'dyn' } ], + output_template => 'dynamic: %.2f %%', perfdatas => [ { template => '%.2f', min => 0, max => 100, unit => '%' } ] @@ -136,13 +142,10 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - $options{options}->add_options(arguments => { - "warning:s" => { name => 'warning_memory' }, - "critical:s" => { name => 'critical_memory' }, - }); + $options{options}->add_options(arguments => {}); return $self; } @@ -180,10 +183,10 @@ sub manage_selection { $mem_values{'host'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.2.1'}; $mem_values{'frag'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.3.1'}; $mem_values{'icmp'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.4.1'}; - $mem_values{'asq'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.5.1'}; + $mem_values{'conn'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.5.1'}; $mem_values{'etherstate'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.6.1'}; $mem_values{'dtrack'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.7.1'}; - $mem_values{'system'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.8.1'}; + $mem_values{'dyn'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.8.1'}; $mem_values{'user'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.9.1'}; $mem_values{'socket'} = $snmp_result->{'.1.3.6.1.4.1.11256.1.10.10.1.10.1'}; @@ -198,10 +201,10 @@ sub manage_selection { $mem_values{'host'} = $values[0]; $mem_values{'frag'} = $values[1]; $mem_values{'icmp'} = $values[2]; - $mem_values{'asq'} = $values[3]; + $mem_values{'conn'} = $values[3]; $mem_values{'etherstate'} = $values[4]; $mem_values{'dtrack'} = $values[5]; - $mem_values{'system'} = $values[6]; + $mem_values{'dyn'} = $values[6]; if ($fields == 8) { $mem_values{'socket'} = $values[7]; @@ -252,9 +255,9 @@ Threshold. Threshold. -=item B<--warning-asq> +=item B<--warning-conn> -Threshold, was conn metric before. +Threshold. =item B<--warning-icmp> @@ -264,9 +267,9 @@ Threshold. Threshold. -=item B<--warning-system> +=item B<--warning-dyn> -Threshold, was C metric before. +Threshold. =item B<--warning-etherstate> @@ -291,9 +294,9 @@ Threshold. Threshold. -=item B<--critical-asq> +=item B<--critical-conn> -Threshold, was conn metric before. +Threshold. =item B<--critical-icmp> @@ -303,9 +306,9 @@ Threshold. Threshold. -=item B<--critical-system> +=item B<--critical-dyn> -Threshold, was C metric before. +Threshold. =item B<--critical-etherstate> From ac2731ae76a653b21d09e8823b625216632d5597 Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Wed, 5 Aug 2026 16:23:26 +0200 Subject: [PATCH 46/50] test(stormshield-snmp-memory-detailed): add robot test Refs:CTOR-2305 --- .../stormshield/snmp/memory-detailed.robot | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/network/stormshield/snmp/memory-detailed.robot diff --git a/tests/network/stormshield/snmp/memory-detailed.robot b/tests/network/stormshield/snmp/memory-detailed.robot new file mode 100644 index 0000000000..01bc3a4247 --- /dev/null +++ b/tests/network/stormshield/snmp/memory-detailed.robot @@ -0,0 +1,43 @@ +*** Settings *** +Documentation network::stormshield::snmp::plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Ctn Generic Suite Setup +Suite Teardown Ctn Generic Suite Teardown +Test Timeout 120s + + +*** Variables *** +${CMD} ${CENTREON_PLUGINS} +... --plugin=network::stormshield::snmp::plugin +... --mode=memory-detailed +... --hostname=${HOSTNAME} +... --snmp-port=${SNMPPORT} +... --snmp-version=${SNMPVERSION} + + +*** Test Cases *** +Connections SN910 ${tc} + [Tags] network stormshield snmp + ${command} Catenate + ... ${CMD} + ... --snmp-community=network/stormshield/snmp/sn910 + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: + ... tc + ... extra_options + ... expected_result + ... -- + ... 1 + ... ${EMPTY} + ... OK: Memory usage total: 15.00 %, protected host: 0.00 %, fragmented: 0.00 %, icmp: 7.00 %, Data Tracking: 0.00%, dynamic: 1.00 %, EtherState: 0%, Socket: 0%, User: 7% | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 + ... 2 + ... --warning-total=4 + ... WARNING: Memory usage total: 15.00 % | 'memory.usage.percentage'=15.00%;0:4;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 + ... 3 + ... --critical-dyn=4: + ... CRITICAL: Memory usage dynamic: 1.00 % | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;4:;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 From 45d480c4a94770c57a41203b5e8c708c038b5e0e Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Wed, 5 Aug 2026 16:25:22 +0200 Subject: [PATCH 47/50] ci(githook): pre commit better debug info Refs:CTOR-2305 --- .githooks/pre-commit.d/20_plugins.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.githooks/pre-commit.d/20_plugins.sh b/.githooks/pre-commit.d/20_plugins.sh index a39c878265..9d19e8f5f6 100755 --- a/.githooks/pre-commit.d/20_plugins.sh +++ b/.githooks/pre-commit.d/20_plugins.sh @@ -72,7 +72,7 @@ for file in "${committed_files[@]}"; do pm|pl) # check that the perl file compiles info "--> Checking that file compiles" - perl -I ./src -I ./tests/connectors/vmware -I ./connectors/vmware/src -c "$file" >/dev/null 2>&1 || error "File $file does not compile with perl -c" + perl -I ./src -I ./tests/connectors/vmware -I ./connectors/vmware/src -c "$file" >/dev/null 2>&1 || error "File $file does not compile with perl -c $file" # check the copyright year info "--> Checking that file copyright is OK" grep "Copyright 20..-Present Centreon" "$file" >/dev/null || error "Copyright in $file does not contain \"Copyright $(date +%Y)-Present Centreon\"" @@ -81,10 +81,12 @@ for file in "${committed_files[@]}"; do grep -- '--warning-\*\|--critical-\*' "$file" >/dev/null && error "File $file contains help that is written as --warning-* or --critical-*" # check spelling info "--> Checking that spelling in file is OK" - perl .github/scripts/pod_spell_check.t "$file" ./tests/resources/spellcheck/stopwords.txt >$tmpfile 2>&1 + cmd_spell_check='perl .github/scripts/pod_spell_check.t '"$file"' ./tests/resources/spellcheck/stopwords.txt >$tmpfile 2>&1' + eval "$cmd_spell_check" rc=$? if [ $rc -ne 0 ] ; then error "Spellcheck error on file $file" + info "command: $cmd_spell_check" tail -n 2 $tmpfile | head -n 1 | sed 's/^[^:]*:/Invalid words:/' 2>/dev/null fi check_tabs_crlf "$file" From 9de47c531a0f7b209e7627c04dcc39336bf70f87 Mon Sep 17 00:00:00 2001 From: Evan-Adam <152897682+Evan-Adam@users.noreply.github.com> Date: Thu, 6 Aug 2026 09:41:15 +0200 Subject: [PATCH 48/50] fix(stormshield): change unit from b/s to B/s and fix health conn metric Co-authored-by: crsuser --- .../stormshield/snmp/mode/interfaces_disco.pm | 20 +++++++++---------- .../stormshield/snmp/mode/memorydetailed.pm | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/network/stormshield/snmp/mode/interfaces_disco.pm b/src/network/stormshield/snmp/mode/interfaces_disco.pm index 44ca98bcc4..60cd79ec29 100644 --- a/src/network/stormshield/snmp/mode/interfaces_disco.pm +++ b/src/network/stormshield/snmp/mode/interfaces_disco.pm @@ -68,20 +68,20 @@ sub set_counters { }, { label => 'throughput-in', - nlabel => 'interface.throughput.in.bitspersecond', + nlabel => 'interface.throughput.in.bytespersecond', type => COUNTER_KIND_METRIC, set => { key_values => [ { name => 'if_throughput_in' }, { name => 'if_name' } ], - output_template => 'Throughput In: %s b/s', + output_template => 'Throughput In: %s B/s', perfdatas => [ { label => 'throughput_in', value => 'if_throughput_in', template => '%s', - unit => 'b/s', + unit => 'B/s', min => 0, label_extra_instance => 1, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-throughput-in'), @@ -93,20 +93,20 @@ sub set_counters { }, { label => 'throughput-out', - nlabel => 'interface.throughput.out.bitspersecond', + nlabel => 'interface.throughput.out.bytespersecond', type => COUNTER_KIND_METRIC, set => { key_values => [ { name => 'if_throughput_out' }, { name => 'if_name' } ], - output_template => 'Throughput Out: %s b/s', + output_template => 'Throughput Out: %s B/s', perfdatas => [ { label => 'throughput_out', value => 'if_throughput_out', template => '%s', - unit => 'b/s', + unit => 'B/s', min => 0, label_extra_instance => 1, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-throughput-out'), @@ -427,19 +427,19 @@ Filter by name to only display this interface =item B<--warning-throughput-in> -Set the warning threshold for throughput in (bits per second). +Set the warning threshold for throughput in (bytes per second). =item B<--critical-throughput-in> -Set the critical threshold for throughput in (bits per second). +Set the critical threshold for throughput in (bytes per second). =item B<--warning-throughput-out> -Set the warning threshold for throughput out (bits per second). +Set the warning threshold for throughput out (bytes per second). =item B<--critical-throughput-out> -Set the critical threshold for throughput out (bits per second). +Set the critical threshold for throughput out (bytes per second). =item B<--warning-current-tcp> diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index 35ef2162dd..2db57b9f6c 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -66,7 +66,7 @@ sub set_counters { } }, { label => 'conn', nlabel => 'memory.connections.percentage', set => { - key_values => [ { name => 'asq' } ], + key_values => [ { name => 'conn' } ], output_template => "ASQ: %.2f%%", perfdatas => [ { template => '%.2f', min => 0, max => 100, unit => '%' } From 80d88dc0680921afbc25119102998593b54e592c Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Thu, 6 Aug 2026 10:07:48 +0200 Subject: [PATCH 49/50] tests(stormshield-snmp): fix robot tests Refs:CTOR-2305 --- src/network/stormshield/snmp/mode/memorydetailed.pm | 2 +- tests/network/stormshield/snmp/memory-detailed.robot | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/stormshield/snmp/mode/memorydetailed.pm b/src/network/stormshield/snmp/mode/memorydetailed.pm index 2db57b9f6c..b64d28c2a7 100644 --- a/src/network/stormshield/snmp/mode/memorydetailed.pm +++ b/src/network/stormshield/snmp/mode/memorydetailed.pm @@ -67,7 +67,7 @@ sub set_counters { }, { label => 'conn', nlabel => 'memory.connections.percentage', set => { key_values => [ { name => 'conn' } ], - output_template => "ASQ: %.2f%%", + output_template => "ASQ connections: %.2f%%", perfdatas => [ { template => '%.2f', min => 0, max => 100, unit => '%' } ] diff --git a/tests/network/stormshield/snmp/memory-detailed.robot b/tests/network/stormshield/snmp/memory-detailed.robot index 01bc3a4247..649b5b4b14 100644 --- a/tests/network/stormshield/snmp/memory-detailed.robot +++ b/tests/network/stormshield/snmp/memory-detailed.robot @@ -34,10 +34,10 @@ Connections SN910 ${tc} ... -- ... 1 ... ${EMPTY} - ... OK: Memory usage total: 15.00 %, protected host: 0.00 %, fragmented: 0.00 %, icmp: 7.00 %, Data Tracking: 0.00%, dynamic: 1.00 %, EtherState: 0%, Socket: 0%, User: 7% | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 + ... OK: Memory usage total: 15.00 %, protected host: 0.00 %, fragmented: 0.00 %, ASQ connections: 0.00%, icmp: 7.00 %, Data Tracking: 0.00%, dynamic: 1.00 %, EtherState: 0%, Socket: 0%, User: 7% | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.connections.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 ... 2 ... --warning-total=4 - ... WARNING: Memory usage total: 15.00 % | 'memory.usage.percentage'=15.00%;0:4;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 + ... WARNING: Memory usage total: 15.00 % | 'memory.usage.percentage'=15.00%;0:4;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.connections.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 ... 3 ... --critical-dyn=4: - ... CRITICAL: Memory usage dynamic: 1.00 % | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;4:;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 + ... CRITICAL: Memory usage dynamic: 1.00 % | 'memory.usage.percentage'=15.00%;;;0;100 'memory.protected_host.percentage'=0.00%;;;0;100 'memory.fragmented.percentage'=0.00%;;;0;100 'memory.connections.percentage'=0.00%;;;0;100 'memory.icmp.percentage'=7.00%;;;0;100 'memory.data_tracking.percentage'=0.00%;;;0;100 'memory.dynamic.percentage'=1.00%;;4:;0;100 'memory.ether_state.percentage'=0.00%;;;0;100 'memory.socket.percentage'=0%;;;0;100 'memory.user.percentage'=7%;;;0;100 From 6e92063c73b33276de7bdbf0b0663a76d58219e4 Mon Sep 17 00:00:00 2001 From: EvanAdam Date: Thu, 6 Aug 2026 16:45:49 +0200 Subject: [PATCH 50/50] ci(docker): add cryptography python lib Refs:CTOR-2305 --- .github/docker/testing/Dockerfile.testing-plugins-alma8 | 2 +- .github/docker/testing/Dockerfile.testing-plugins-alma9 | 2 +- .github/docker/testing/Dockerfile.testing-plugins-noble | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/docker/testing/Dockerfile.testing-plugins-alma8 b/.github/docker/testing/Dockerfile.testing-plugins-alma8 index 94f6a77e07..ba9336ec66 100644 --- a/.github/docker/testing/Dockerfile.testing-plugins-alma8 +++ b/.github/docker/testing/Dockerfile.testing-plugins-alma8 @@ -17,7 +17,7 @@ dnf clean all dnf install -y python3.11 python3.11-pip pip3.11 install robotframework robotframework-examples # Install snmpsim -pip3.11 install snmpsim pysmi +pip3.11 install snmpsim pysmi cryptography dnf module enable -y nodejs:24 dnf install -y nodejs diff --git a/.github/docker/testing/Dockerfile.testing-plugins-alma9 b/.github/docker/testing/Dockerfile.testing-plugins-alma9 index 0b9b5290da..89615655f9 100644 --- a/.github/docker/testing/Dockerfile.testing-plugins-alma9 +++ b/.github/docker/testing/Dockerfile.testing-plugins-alma9 @@ -22,7 +22,7 @@ dnf clean all dnf install -y python3.11 python3.11-pip pip3.11 install robotframework robotframework-examples # Install snmpsim -pip3.11 install snmpsim pysmi +pip3.11 install snmpsim pysmi cryptography dnf module enable -y nodejs:24 dnf install -y nodejs diff --git a/.github/docker/testing/Dockerfile.testing-plugins-noble b/.github/docker/testing/Dockerfile.testing-plugins-noble index 4a0d1970a4..325bd735ef 100644 --- a/.github/docker/testing/Dockerfile.testing-plugins-noble +++ b/.github/docker/testing/Dockerfile.testing-plugins-noble @@ -41,7 +41,7 @@ python3 -m venv .venv apt-get install -y python3 python3-dev python3-pip pip3 install robotframework robotframework-examples # Install snmpsim -pip3 install snmpsim pysmi +pip3 install snmpsim pysmi cryptography curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - apt-get install -y nodejs