add silverpeak plugin (#1037)

* added silverpeak plugin and modes

* fix type, oid  name and timealarms

* fix cache file name
This commit is contained in:
pkriko 2018-07-11 16:41:06 +02:00 committed by cgagnaire
parent 642e73b98e
commit c4a325ce03
4 changed files with 588 additions and 0 deletions

View File

@ -0,0 +1,228 @@
#
# Copyright 2018 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::silverpeak::snmp::mode::alarms;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use POSIX;
use centreon::plugins::misc;
use centreon::plugins::statefile;
my $instance_mode;
sub custom_status_threshold {
my ($self, %options) = @_;
my $status = 'ok';
my $message;
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' &&
eval "$instance_mode->{option_results}->{critical_status}") {
$status = 'critical';
} elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' &&
eval "$instance_mode->{option_results}->{warning_status}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
return $status;
}
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("alarm [severity: %s] [source: %s] [text: %s] %s", $self->{result_values}->{severity},
$self->{result_values}->{source}, $self->{result_values}->{text}, $self->{result_values}->{generation_time});
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{source} = $options{new_datas}->{$self->{instance} . '_spsActiveAlarmSource'};
$self->{result_values}->{text} = $options{new_datas}->{$self->{instance} . '_spsActiveAlarmDescr'};
$self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_spsActiveAlarmSeverity'};
$self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'};
$self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_spsActiveAlarmLogTime'};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 },
group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ]
}
];
$self->{maps_counters}->{alarm} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'spsActiveAlarmSource' }, { name => 'spsActiveAlarmDescr' }, { name => 'since' }, { name => 'spsActiveAlarmSeverity' }, { name => 'spsActiveAlarmLogTime' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_status_threshold'),
}
},
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"filter-msg:s" => { name => 'filter_msg' },
"warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /minor|warning/i' },
"critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' },
"memory" => { name => 'memory' },
});
centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse',
error_msg => "Cannot load module 'Date::Parse'.");
$self->{statefile_cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$instance_mode = $self;
$self->change_macros();
if (defined($self->{option_results}->{memory})) {
$self->{statefile_cache}->check_options(%options);
}
}
sub change_macros {
my ($self, %options) = @_;
foreach (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
}
}
my %map_severity = (0 => 'info', 1 => 'warning', 2 => 'minor', 3 => 'major',
4 => 'critical', 5 => 'cleared', 6 => 'acknowledged', 7 => 'unacknowledged', 8 => 'indeterminate');
my $mapping = {
spsActiveAlarmSource => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.6' },
spsActiveAlarmDescr => { oid => ' 1.3.6.1.4.1.23867.3.1.1.2.1.1.5' },
spsActiveAlarmLogTime => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.11' }, # timestamp
spsActiveAlarmSeverity => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.3', map => \%map_severity },
};
sub manage_selection {
my ($self, %options) = @_;
$self->{alarms}->{global} = { alarm => {} };
my $snmp_result = $options{snmp}->get_multiple_table(oids => [
{ oid => $mapping->{spsActiveAlarmSource}->{oid} },
{ oid => $mapping->{spsActiveAlarmDescr}->{oid} },
{ oid => $mapping->{spsActiveAlarmLogTime}->{oid} },
{ oid => $mapping->{spsActiveAlarmSeverity}->{oid} },
], return_type => 1);
my $last_time;
if (defined($self->{option_results}->{memory})) {
$self->{statefile_cache}->read(statefile => "cache_silverpeak_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port(). '_' . $self->{mode});
$last_time = $self->{statefile_cache}->get(name => 'last_time');
}
my ($i, $current_time) = (1, time());
foreach my $oid (keys %{$snmp_result}) {
next if ($oid !~ /^$mapping->{spsActiveAlarmSeverity}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance);
my $create_time = $result->{spsActiveAlarmLogTime};
if (!defined($create_time)) {
$self->{manager}->{output}->output_add(severity => 'UNKNOWN',
short_msg => "Can't get date '" . $result->{spsActiveAlarmLogTime} . "'");
next;
}
next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time);
if (defined($self->{option_results}->{filter_msg}) && $self->{option_results}->{filter_msg} ne '' &&
$result->{spsActiveAlarmDescr} !~ /$self->{option_results}->{filter_msg}/) {
$self->{output}->output_add(long_msg => "skipping '" . $result->{spsActiveAlarmDescr} . "': no matching filter.", debug => 1);
next;
}
my $diff_time = $current_time - $create_time;
$self->{alarms}->{global}->{alarm}->{$i} = { %$result, since => $diff_time };
$i++;
}
if (defined($self->{option_results}->{memory})) {
$self->{statefile_cache}->write(data => { last_time => $current_time });
}
}
1;
__END__
=head1 MODE
Check alarms.
=over 8
=item B<--filter-msg>
Filter by message (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i')
Can used special variables like: %{severity}, %{text}, %{source}, %{since}
=item B<--critical-status>
Set critical threshold for status (Default: '%{severity} =~ /critical|major/i').
Can used special variables like: %{severity}, %{text}, %{source}, %{since}
=item B<--memory>
Only check new alarms.
=back
=cut

View File

@ -0,0 +1,148 @@
#
# Copyright 2018 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::silverpeak::snmp::mode::status;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $instance_mode;
sub custom_status_threshold {
my ($self, %options) = @_;
my $status = 'ok';
my $message;
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' &&
eval "$instance_mode->{option_results}->{critical_status}") {
$status = 'critical';
} elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' &&
eval "$instance_mode->{option_results}->{warning_status}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
return $status;
}
sub custom_status_output {
my ($self, %options) = @_;
my $msg = "Operational state: '" . $self->{result_values}->{operStatus} . "' ";
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{operStatus} = $options{new_datas}->{$self->{instance} . '_operStatus'};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'operationnal_state', type => 0 },
];
$self->{maps_counters}->{operationnal_state} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'operStatus' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_status_threshold'),
}
},
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"warning-status:s" => { name => 'warning_status', default => '' },
"critical-status:s" => { name => 'critical_status', default => '%{operStatus} !~ /(Normal)/' },
});
return $self;
}
sub change_macros {
my ($self, %options) = @_;
foreach ('warning_status', 'critical_status') {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$instance_mode = $self;
$self->change_macros();
}
sub manage_selection {
my ($self, %options) = @_;
$self->{operationnal_state} = {};
my $oid_spsOperStatus = '.1.3.6.1.4.1.23867.3.1.1.1.3.0';
my $result = $options{snmp}->get_leef(oids => [ $oid_spsOperStatus ],
nothing_quit => 1);
$self->{operationnal_state} = { operStatus => $result->{$oid_spsOperStatus}};
}
1;
__END__
=head1 MODE
Check operational state of the Silverpeak appliance.
=item B<--warning-status>
Trigger warning on %{operStatus} values
=item B<--critical-status>
Trigger critical on %{operStatus} values
(default: '%{operStatus} !~ /(Normal)/')
=back
=cut

View File

@ -0,0 +1,160 @@
#
# Copyright 2018 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::silverpeak::snmp::mode::uptime;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use POSIX;
use centreon::plugins::misc;
use centreon::plugins::statefile;
use Time::HiRes qw(time);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
"force-oid:s" => { name => 'force_oid' },
"check-overload" => { name => 'check_overload' },
});
$self->{statefile_cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'.");
$self->{output}->option_exit();
}
$self->{statefile_cache}->check_options(%options);
}
sub check_overload {
my ($self, %options) = @_;
return $options{timeticks} if (!defined($self->{option_results}->{check_overload}));
my $current_time = floor(time() * 100);
$self->{new_datas} = { last_time => $current_time, uptime => $options{timeticks}, overload => 0 };
$self->{statefile_cache}->read(statefile => "cache_" . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode});
my $old_uptime = $self->{statefile_cache}->get(name => 'uptime');
my $last_time = $self->{statefile_cache}->get(name => 'last_time');
my $overload = $self->{statefile_cache}->get(name => 'overload');
if (defined($old_uptime) && $old_uptime < $current_time) {
my $diff_time = $current_time - $last_time;
my $overflow = ($old_uptime + $diff_time) % 4294967296;
my $division = ($old_uptime + $diff_time) / 4294967296;
if ($division >= 1 &&
$overflow >= ($options{timeticks} - 5000) &&
$overflow <= ($options{timeticks} + 5000)) {
$overload++;
}
$options{timeticks} += ($overload * 4294967296);
}
$self->{new_datas}->{overload} = $overload if (defined($overload));
$self->{statefile_cache}->write(data => $self->{new_datas});
return $options{timeticks};
}
sub run {
my ($self, %options) = @_;
$self->{snmp} = $options{snmp};
# spsSystemUptime from SILVERPEAK-MGMT-MIB 8.0
my $oid_hrSystemUptime = '.1.3.6.1.4.1.23867.3.1.1.1.5.0';
my ($result, $value);
if (defined($self->{option_results}->{force_oid})) {
$result = $self->{snmp}->get_leef(oids => [ $self->{option_results}->{force_oid} ], nothing_quit => 1);
$value = $result->{$self->{option_results}->{force_oid}};
} else {
$result = $self->{snmp}->get_leef(oids => [ $oid_hrSystemUptime ], nothing_quit => 1);
$value = $result->{$oid_hrSystemUptime};
}
$value = $self->check_overload(timeticks => $value);
$value = floor($value / 100);
my $exit_code = $self->{perfdata}->threshold_check(value => $value,
threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->perfdata_add(label => 'uptime', unit => 's',
value => $value,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0);
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("System uptime is: %s",
centreon::plugins::misc::change_seconds(value => $value, start => 'd')));
$self->{output}->display();
$self->{output}->exit();
}
1;
__END__
=head1 MODE
Check system uptime.
=over 8
=item B<--warning>
Threshold warning in seconds.
=item B<--critical>
Threshold critical in seconds.
=item B<--force-oid>
Can choose your oid (numeric format only).
=item B<--check-overload>
Uptime counter limit is 4294967296 and overflow.
With that option, we manage the counter going back. But there is a few chance we can miss a reboot.
=back
=cut

View File

@ -0,0 +1,52 @@
#
# Copyright 2018 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::silverpeak::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->{version} = '1.0';
%{$self->{modes}} = (
'interfaces' => 'snmp_standard::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'uptime' => 'network::silverpeak::snmp::mode::uptime',
'status' => 'network::silverpeak::snmp::mode::status',
'alarms' => 'network::silverpeak::snmp::mode::alarms',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Silverpeak SD-WAN in SNMP.
=cut