Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
39ceb31
feat: update and add modes for Stormshield SNMP monitoring
crsuser Jun 19, 2026
64f7c45
Fix: changed type in set_counters from 0 to "COUNTER_TYPE_GLOBAL" con…
crsuser Jun 23, 2026
8f5bc72
Fix: wrong oid name in ha_cluster.pm
crsuser Jun 30, 2026
4f7be03
Add discovery mode router_disco.pm
crsuser Jul 6, 2026
a42e012
Declared router_disco.pm in plugin.pm
crsuser Jul 6, 2026
3928ce8
Fix Latency and PacketLoss output
crsuser Jul 6, 2026
33791e3
Fix: add version-based filtering for OIDs in router_disco.pm
crsuser Jul 8, 2026
07bfb74
Added jitter in counters, file : router_disco.pm
crsuser Jul 10, 2026
6d28e54
Fix: OID name link -> halink in health.pm
crsuser Jul 15, 2026
b3476c8
fix: right thresholds for PSU and Disk
crsuser Jul 16, 2026
b1a666a
Add Stormshield SNMP mode properties
crsuser Apr 9, 2026
05d382a
fix: add version-based filtering for OIDs to avoid displaying unsuppo…
crsuser Apr 20, 2026
d8565d1
Fix: Add exact firmawre-version check for Stormshield SNMP properties
crsuser Apr 21, 2026
175e176
Fix: firmware-version check for 4.3.x and above
crsuser Apr 22, 2026
bef7bc5
Fix structure to match standards
crsuser Apr 29, 2026
a844641
Update plugin.pm
crsuser Apr 29, 2026
33bf6df
Fixing non ASCII concern
crsuser Apr 29, 2026
d086103
Fix: French to English output message
crsuser May 4, 2026
a37d4c0
Fix issues raised in code review
crsuser May 11, 2026
5804b36
Apply suggestions from code review
crsuser Jun 2, 2026
e4d01b6
Add new Uptime oid for version 5.1.0 and later
crsuser Jun 9, 2026
7f32fe3
review
omercier Jul 28, 2026
8743420
remove useless code
omercier Jul 28, 2026
2732e74
fix spelling
omercier Jul 28, 2026
f4f5847
force new perfdata on uptime
omercier Jul 28, 2026
da2a787
Feat: Add licences.pm mode
crsuser May 13, 2026
4cdd14e
Fix issues raised by "aikido-pr-checks"
crsuser May 15, 2026
db5e67e
Add Stormshield SNMP mode properties
crsuser Apr 9, 2026
225dcdb
anonymization was not specific enough
omercier Jul 30, 2026
896185a
make it work like a centreon-plugin
omercier Jul 30, 2026
d61de0b
rename licences to licenses + add tests
omercier Jul 30, 2026
f7e4536
modernize
omercier Jul 30, 2026
33c5071
fix missing dependency
omercier Jul 30, 2026
934208f
switch to counter text instead of metric
omercier Jul 30, 2026
b021ba5
fix memory help test
omercier Jul 30, 2026
75544b3
ha_cluster: first fix
omercier Jul 31, 2026
c318d73
reshape ha-cluster
omercier Jul 31, 2026
940e556
format hardware.robot
omercier Jul 31, 2026
3bf96ad
fix+complete hardware tests
omercier Jul 31, 2026
ecf38b7
reshaping + adding tests to connections.pm
omercier Jul 31, 2026
5a2beba
add tests for connections
omercier Jul 31, 2026
8a1e010
fix(stormshield-snmp): add tests and fix long output
Evan-Adam Aug 4, 2026
b5172a2
fix(stormshield-snmp-memory-detailed): Fix metrics nlabel, remove gen…
Evan-Adam Aug 5, 2026
43bf36d
fix(stormshield-snmp-memory-detailed): Add back total metric calculation
Evan-Adam Aug 5, 2026
02d621f
fix(stormshield-snmp-memory-detailed): remove metrics renaming, keep …
Evan-Adam Aug 5, 2026
ac2731a
test(stormshield-snmp-memory-detailed): add robot test
Evan-Adam Aug 5, 2026
45d480c
ci(githook): pre commit better debug info
Evan-Adam Aug 5, 2026
9de47c5
fix(stormshield): change unit from b/s to B/s and fix health conn metric
Evan-Adam Aug 6, 2026
80d88dc
tests(stormshield-snmp): fix robot tests
Evan-Adam Aug 6, 2026
6e92063
ci(docker): add cryptography python lib
Evan-Adam Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .githooks/pre-commit.d/20_plugins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function check_constants() {
grep -nH -- "-\(1\|2\|10\)[[:space:]]*=>[[:space:]]*1" "$file" > "$tmpfile"
grep -nH "\<type[[:space:]]*=>[[: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
}
Expand Down Expand Up @@ -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\""
Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion .github/docker/testing/Dockerfile.testing-plugins-alma8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/docker/testing/Dockerfile.testing-plugins-alma9
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/docker/testing/Dockerfile.testing-plugins-noble
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"dependencies": [
"perl(DateTime)",
"perl(SNMP)"
]
}
}
221 changes: 221 additions & 0 deletions src/network/stormshield/snmp/mode/auto_update.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# 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 centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::misc qw(is_empty);

use strict;
use warnings;
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 $display = $self->{result_values}->{display};

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 {
my ($self, %options) = @_;

$self->{maps_counters_type} = [
{
name => 'updates',
type => COUNTER_TYPE_INSTANCE,
message_multiple => 'All Updates and Webservices are up to date'
}
];

$self->{maps_counters}->{updates} = [
{
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 => \&catalog_status_threshold_ng
}
},
];
}

sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;

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 = 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 =~ /^(Uptodate|Failed|Disabled|Broken|Partially Failed)$/) ? $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

=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
Loading
Loading