Adding Sputnik UPS plugin with environment mode (#4880)

This commit is contained in:
omercier 2024-02-12 08:51:10 +01:00 committed by GitHub
parent 8cd09545eb
commit 764c39801c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 353 additions and 1 deletions

View File

@ -60,7 +60,9 @@ jobs:
python-version: '3.11'
- name: Install Robot Framework
run: pip3.11 install robotframework
run: |
pip3.11 install robotframework
pip3.11 install RobotFramework-Examples
shell: bash
- name: Run Robot Framework API tests

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libsnmp-perl"
]
}

View File

@ -0,0 +1,11 @@
{
"pkg_name": "centreon-plugin-Hardware-Ups-Inmatics-Sputnik-Snmp",
"pkg_summary": "Centreon Plugin - Hardware UPS Inmatics PSU Sputnik SNMP",
"plugin_name": "centreon_ups_sputnik_snmp.pl",
"files": [
"centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm",
"hardware/ups/standard/rfc1628/snmp/",
"hardware/ups/inmatics/sputnik/snmp/"
]
}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"perl(SNMP)"
]
}

View File

@ -0,0 +1,153 @@
#
# 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 hardware::ups::inmatics::sputnik::snmp::mode::environment;
use base qw(centreon::plugins::templates::counter);
# Needed libraries
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
# Declare options
$options{options}->add_options(arguments => {
'filter-id:s' => { name => 'filter_id' }
});
return $self;
}
sub prefix_sensors_output {
my ($self, %options) = @_;
return "'" . $options{instance_value}->{display} . "': ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sensors', type => 1, cb_prefix_output => 'prefix_sensors_output', message_multiple => 'All sensors are ok' }
];
$self->{maps_counters}->{sensors} = [
{ label => 'temperature', nlabel => 'environment.temperature.celsius', set => {
key_values => [ { name => 'temperature' }, { name => 'display' } ],
output_template => 'temperature %.2f C',
perfdatas => [
{ label => 'temperature', template => '%.2f', unit => 'C', label_extra_instance => 1, instance_use => 'display' }
]
}
},
{ label => 'humidity', nlabel => 'environment.humidity.percentage', set => {
key_values => [ { name => 'humidity' }, { name => 'display' } ],
output_template => 'humidity %s %%',
perfdatas => [
{ label => 'humidity', template => '%s', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }
]
}
}
];
}
sub manage_selection {
my ($self, %options) = @_;
# FI: upsEnvSensorCounts is not used but it gives the number of sensors
#my $oid_upsEnvSensorCounts = '.1.3.6.1.4.1.54661.1.1.1.2.1.0';
my $oid_upsEnvSensors = '.1.3.6.1.4.1.54661.1.1.1.2.2.1';
# FI: the actual MIB OIDs:
#my $oid_upsEnvSensorTemperature = '.1.3.6.1.4.1.54661.1.1.1.2.2.1.2';
#my $oid_upsEnvSensorHumidity = '.1.3.6.1.4.1.54661.1.1.1.2.2.1.3';
# Each sensor will provide a temperature (in 100th of degrees) and a humidity percentage
my $mapping = {
upsEnvSensorTemperature => { oid => $oid_upsEnvSensors.'.2' },
upsEnvSensorHumidity => { oid => $oid_upsEnvSensors.'.3' }
};
my $snmp_result = $options{snmp}->get_table(
oid => $oid_upsEnvSensors,
nothing_quit => 1
);
$self->{sensors} = {};
foreach my $oid (sort(keys %{$snmp_result})) {
next if ($oid !~ /^$oid_upsEnvSensors\.2\.(.*)$/);
# The index of the sensor will be used in the instance name
my $sensor_index = $1;
# Skip if a filter is defined and the current sensor does not match
if (defined($self->{option_results}->{filter_id}) && $sensor_index ne '' && $sensor_index !~ /$self->{option_results}->{filter_id}/ ) {
$self->{output}->output_add(
long_msg => "With filter-id: '$self->{option_results}->{filter_id}' - Skipping sensor '$sensor_index'.",
debug => 1
);
next;
}
# Get all the metrics for the current instance
my $result = $options{snmp}->map_instance(
mapping => $mapping,
results => $snmp_result,
instance => $sensor_index
);
# The temperature is given multiplied by 100, so we have to divide it by 100
# cf MIB: UNITS "0.01 degrees Centigrade"
$self->{sensors}->{$sensor_index} = {
display => 'Sensor '.$sensor_index,
temperature => $result->{upsEnvSensorTemperature} / 100,
humidity => $result->{upsEnvSensorHumidity}
};
}
# No results is not OK
if (scalar(keys %{$self->{sensors}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No sensors found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Monitor temperature and humidity using the device's environment sensors.
=over 8
=item B<--warning-*> B<--critical-*>
Thresholds. Can be: 'humidity' (%), 'temperature' (C).
=item B<--filter-id>
Define which sensors should be monitored based on their IDs. This option will be treated as a regular expression.
=back
=cut

View File

@ -0,0 +1,52 @@
#
# 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 hardware::ups::inmatics::sputnik::snmp::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_snmp);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{modes} = {
'alarms' => 'hardware::ups::standard::rfc1628::snmp::mode::alarms',
'battery-status' => 'hardware::ups::standard::rfc1628::snmp::mode::batterystatus',
'environment' => 'hardware::ups::inmatics::sputnik::snmp::mode::environment',
'input-lines' => 'hardware::ups::standard::rfc1628::snmp::mode::inputlines',
'output-lines' => 'hardware::ups::standard::rfc1628::snmp::mode::outputlines',
'output-source' => 'hardware::ups::standard::rfc1628::snmp::mode::outputsource'
};
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Sputnik UPS using SNMP.
=cut

View File

@ -0,0 +1,63 @@
*** Settings ***
Documentation Hardware UPS Sputnik SNMP plugin
Library OperatingSystem
Library String
Library Examples
Test Timeout 120s
*** Variables ***
${CENTREON_PLUGINS} ${CURDIR}${/}..${/}..${/}..${/}src${/}centreon_plugins.pl
${CMD} perl ${CENTREON_PLUGINS} --plugin=hardware::ups::inmatics::sputnik::snmp::plugin
*** Test Cases ***
Sputnik UPS - Environment ${tc}/9
[Tags] hardware UPS snmp
${command} Catenate
... ${CMD}
... --mode=environment
... --hostname=127.0.0.1
... --snmp-version=2c
... --snmp-port=2024
... --snmp-community=hardware-ups/hardware-ups-sputnik
# Append options to command
${opt} Append Option --warning-temperature ${w_temperature}
${command} Catenate ${command} ${opt}
${opt} Append Option --critical-temperature ${c_temperature}
${command} Catenate ${command} ${opt}
${opt} Append Option --warning-humidity ${w_humidity}
${command} Catenate ${command} ${opt}
${opt} Append Option --critical-humidity ${c_humidity}
${command} Catenate ${command} ${opt}
${opt} Append Option --filter-id ${filter_id}
${command} Catenate ${command} ${opt}
${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for compliance of ${expected_result}{\n}Command output:{\n}${output}{\n}{\n}{\n}
Examples: tc filter_id w_temperature c_temperature w_humidity c_humidity expected_result --
... 1 1 30 50 50 70 OK: 'Sensor 1': temperature 20.06 C, humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;0:30;0:50;; 'Sensor 1#environment.humidity.percentage'=33%;0:50;0:70;0;100
... 2 1 20 50 50 70 WARNING: 'Sensor 1': temperature 20.06 C | 'Sensor 1#environment.temperature.celsius'=20.06C;0:20;0:50;; 'Sensor 1#environment.humidity.percentage'=33%;0:50;0:70;0;100
... 3 1 10 20 50 70 CRITICAL: 'Sensor 1': temperature 20.06 C | 'Sensor 1#environment.temperature.celsius'=20.06C;0:10;0:20;; 'Sensor 1#environment.humidity.percentage'=33%;0:50;0:70;0;100
... 4 1 30 50 20 70 WARNING: 'Sensor 1': humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;0:30;0:50;; 'Sensor 1#environment.humidity.percentage'=33%;0:20;0:70;0;100
... 5 1 30 50 20 30 CRITICAL: 'Sensor 1': humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;0:30;0:50;; 'Sensor 1#environment.humidity.percentage'=33%;0:20;0:30;0;100
... 6 1 10 50 20 70 WARNING: 'Sensor 1': temperature 20.06 C, humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;0:10;0:50;; 'Sensor 1#environment.humidity.percentage'=33%;0:20;0:70;0;100
... 7 1 10 20 20 30 CRITICAL: 'Sensor 1': temperature 20.06 C, humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;0:10;0:20;; 'Sensor 1#environment.humidity.percentage'=33%;0:20;0:30;0;100
... 8 2 30 50 50 70 UNKNOWN: No sensors found.
... 9 1 _empty_ _empty_ _empty_ _empty_ OK: 'Sensor 1': temperature 20.06 C, humidity 33 % | 'Sensor 1#environment.temperature.celsius'=20.06C;;;; 'Sensor 1#environment.humidity.percentage'=33%;;;0;100
*** Keywords ***
Append Option
[Documentation] Concatenates the first argument (option) with the second (value) after having replaced the value with "" if its content is '_empty_'
[Arguments] ${option} ${value}
${value} Set Variable If '${value}' == '_empty_' '' ${value}
[return] ${option}=${value}

View File

@ -0,0 +1,61 @@
.1.3.6.1.4.1.54661.1.1.1.1.1.1.1.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.2.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.3.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.4.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.5.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.6.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.7.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.8.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.9.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.10.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.11.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.12.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.13.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.14.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.15.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.16.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.17.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.18.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.19.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.20.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.1.1.21.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.22.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.23.0 = INTEGER: 2
.1.3.6.1.4.1.54661.1.1.1.1.1.1.24.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.1.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.2.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.3.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.4.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.5.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.6.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.7.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.8.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.9.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.10.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.11.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.12.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.13.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.14.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.15.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.16.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.17.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.18.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.19.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.20.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.21.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.22.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.23.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.2.1.24.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.6.1.1.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.6.1.2.0 = INTEGER: 3
.1.3.6.1.4.1.54661.1.1.1.1.6.2.1.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.6.2.2.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.6.2.3.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.1.6.2.4.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.2.1.0 = INTEGER: 1
.1.3.6.1.4.1.54661.1.1.1.2.2.1.2.1 = INTEGER: 2006
.1.3.6.1.4.1.54661.1.1.1.2.2.1.3.1 = INTEGER: 33
.1.3.6.1.4.1.54661.1.1.1.2.3.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.2.4.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.2.5.0 = INTEGER: 0
.1.3.6.1.4.1.54661.1.1.1.3.1.0 = INTEGER: 0